mirror of
https://github.com/wassname/talk.git
synced 2026-08-19 12:40:16 +08:00
[CORL-878] Upgrade dependencies (#2867)
* chore: upgrade fluent * chore: upgrade metascraper * chore: upgrade akismet-api * chore: upgrade apollo-server-express * chore: upgrade archiver * chore: upgrade bull * chore: upgrade express, cheerio, content-security-policy-builder * chore: upgrade convict * chore: upgrade cors, cron * chore: upgrade csv-stringify * chore: upgrade dompurify * chore: upgrade dotenv * chore: upgrade express-static-gzip * chore: upgrade fs-extra * chore: upgrade graphql-js * chore: upgrade graphql packages * chore: upgrade html-minifier * chore: upgrade html-to-text * chore: upgrade ioredis * chore: upgrade joi * chore: upgrade jsdom * chore: upgrade jsonwebtoken * chore: upgrade juice * chore: upgrade jwks-rsa ad linkifyjs * chore: upgrade lodash * chore: upgrade luxon * chore: upgrade metascraper * chore: upgrade mongodb * chore: upgrade ms * chore: upgrade node and node-fetch types * chore: upgrade nodemailer nunjucks and typescript-eslint * chore: Upgrade passport * upgrade: prom-client react-helmet source-map-support stack-utils * chore: upgrade uuid * chore: upgrade @babel packages * chore: upgrade types * chore: upgrade autoprefixer * chore: upgrade jest * chore: upgrade ts-jest * chore: remove linkify.d.ts * chore: upgrade bowser * chore: case-sensitive-paths-webpack-plugin * chore: upgrade classnames * chore: upgrade commander * chore: upgrade comment-json * chore: upgrade cross-spawn compression-webpack-plugin del * chore: upgrade build and watch related dependencies * chore: upgrade css-vars-ponyfill * chore: upgrade eslint and css-vars-ponyfill * chore: upgrade enzyme and eventemitter2 * fix: form bug * chore: upgrade farce * chore: upgrade final form * chore: upgrade react-popper * chore: upgrade flat and fork-ts-checker-webpack-plugin * chore: upgrade husky and gulp related, intersection observer * chore: upgrade lint-staged * chore: upgrade marked, loader-utils, mini-css-extract-plugin * chore: upgrade postcss-nested, proxy-polyfill, pstree.remy * chore: upgrade prettier * chore: fix prettier changes, upgrade react * chore: mute createFactory deprecated message * chore: upgrade react-copy-to-clipbard, react-axe, react-dom, react-test-renderer, react-timeago * chore: upgrade react-transistion-group, react-responsive * chore: upgrade types * chore: upgrade react-dev-utils, react-error-overlay regenerator-runtime * chore: upgrade types, sinon, sockjs-client, strip-ansi * chore: upgrade types, fonts * chore: upgrade nunjucks, ts-node, typescript-snapshot-plugin, wait-for-expect * chore: upgrade eslint packages * chore: upgrade fluent, types * chore: upgrade jsdom dep * chore: upgrade mongo * chore: upgrade deps * chore: upgrade typescript, recompose * chore: upgrade prettier * chore: remove obsolete prettier config * chore: upgrade jsdom types * chore: upgrade typescript-eslint * chore: upgrad deps * chore: upgrade deps * chore: upgrade relay related modules * chore: upgrade docz WIP * chore: upgrade docz * chore: add guard * chore: remove obsolete line * chore: comment * chore: refactors * fix: hook count change error
This commit is contained in:
@@ -7,7 +7,6 @@ import HtmlWebpackPlugin from "html-webpack-plugin";
|
||||
import { identity } from "lodash";
|
||||
import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
||||
import path from "path";
|
||||
import typescriptFormatter from "react-dev-utils/typescriptFormatter";
|
||||
import WatchMissingNodeModulesPlugin from "react-dev-utils/WatchMissingNodeModulesPlugin";
|
||||
import TerserPlugin from "terser-webpack-plugin";
|
||||
import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin";
|
||||
@@ -82,10 +81,6 @@ export default function createWebpackConfig(
|
||||
|
||||
const styleLoader = {
|
||||
loader: require.resolve("style-loader"),
|
||||
options: {
|
||||
sourceMap: !disableSourcemaps,
|
||||
hmr: watch,
|
||||
},
|
||||
};
|
||||
|
||||
const localesOptions = {
|
||||
@@ -367,9 +362,10 @@ export default function createWebpackConfig(
|
||||
{
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
modules: true,
|
||||
modules: {
|
||||
localIdentName: "[name]-[local]-[contenthash]",
|
||||
},
|
||||
importLoaders: 2,
|
||||
localIdentName: "[name]-[local]-[contenthash]",
|
||||
sourceMap: !disableSourcemaps,
|
||||
},
|
||||
},
|
||||
@@ -471,9 +467,10 @@ export default function createWebpackConfig(
|
||||
{
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
modules: true,
|
||||
modules: {
|
||||
localIdentName: "[name]-[local]-[hash:base64:5]",
|
||||
},
|
||||
importLoaders: 1,
|
||||
localIdentName: "[name]-[local]-[hash:base64:5]",
|
||||
sourceMap: !disableSourcemaps,
|
||||
},
|
||||
},
|
||||
@@ -525,11 +522,6 @@ export default function createWebpackConfig(
|
||||
useTypescriptIncrementalApi: false,
|
||||
checkSyntacticErrors: true,
|
||||
tsconfig: paths.appTsconfig,
|
||||
watch: paths.appSrc,
|
||||
// TODO: (cvle) ForkTsCheckerWebpackPlugin are currently not working, so we resort to default reporting.
|
||||
silent: false,
|
||||
// The formatter is normally invoked directly in WebpackDevServerUtils during development
|
||||
formatter: typescriptFormatter,
|
||||
})
|
||||
),
|
||||
// Makes some environment variables available to the JS code, for example:
|
||||
|
||||
@@ -40,7 +40,7 @@ function getFiles(target, pathToLocale, context) {
|
||||
|
||||
const files = fs.readdirSync(pathToLocale);
|
||||
|
||||
files.forEach(f => {
|
||||
files.forEach((f) => {
|
||||
if (commonFiles.includes(f)) {
|
||||
common.push(f);
|
||||
return;
|
||||
@@ -62,12 +62,12 @@ function generateTarget(target, context) {
|
||||
locales,
|
||||
bundled,
|
||||
} = context;
|
||||
const getLocalePath = locale => path.join(pathToLocales, locale);
|
||||
const getLocaleFiles = memoize(locale =>
|
||||
const getLocalePath = (locale) => path.join(pathToLocales, locale);
|
||||
const getLocaleFiles = memoize((locale) =>
|
||||
getFiles(target, getLocalePath(locale), context)
|
||||
);
|
||||
|
||||
const loadables = locales.filter(locale => !bundled.includes(locale));
|
||||
const loadables = locales.filter((locale) => !bundled.includes(locale));
|
||||
|
||||
return `
|
||||
var ret = {
|
||||
@@ -81,22 +81,22 @@ function generateTarget(target, context) {
|
||||
// Bundled locales are directly available in the main bundle.
|
||||
${bundled
|
||||
.map(
|
||||
locale => `
|
||||
(locale) => `
|
||||
{
|
||||
var suffixes = ${JSON.stringify(getLocaleFiles(locale).suffixes)};
|
||||
var contents = [];
|
||||
${getLocaleFiles(locale)
|
||||
.common.map(
|
||||
file => `
|
||||
(file) => `
|
||||
contents.push(require(${JSON.stringify(
|
||||
path.join(getLocalePath(locale), file).replace(/\\/g, "/")
|
||||
)}));
|
||||
)}).default);
|
||||
`
|
||||
)
|
||||
.join("\n")}
|
||||
contents = contents.concat(suffixes.map(function(suffix) { return require("${path
|
||||
.join(getLocalePath(locale), target)
|
||||
.replace(/\\/g, "/")}" + suffix); }));
|
||||
.replace(/\\/g, "/")}" + suffix).default; }));
|
||||
ret.bundled[${JSON.stringify(locale)}] = contents.join("\\n");
|
||||
}
|
||||
`
|
||||
@@ -106,13 +106,13 @@ function generateTarget(target, context) {
|
||||
// Loadables are in a separate bundle, that can be easily loaded.
|
||||
${loadables
|
||||
.map(
|
||||
locale => `
|
||||
(locale) => `
|
||||
ret.loadables[${JSON.stringify(locale)}] = function() {
|
||||
var suffixes = ${JSON.stringify(getLocaleFiles(locale).suffixes)};
|
||||
var promises = [];
|
||||
${getLocaleFiles(locale)
|
||||
.common.map(
|
||||
file => `
|
||||
(file) => `
|
||||
promises.push(
|
||||
import(
|
||||
/* webpackChunkName: ${JSON.stringify(
|
||||
@@ -147,7 +147,7 @@ function generateTarget(target, context) {
|
||||
`;
|
||||
}
|
||||
|
||||
module.exports = function(source) {
|
||||
module.exports = function (source) {
|
||||
const options = Object.assign(
|
||||
{},
|
||||
DEFAULT_QUERY_VALUES,
|
||||
@@ -165,7 +165,7 @@ module.exports = function(source) {
|
||||
|
||||
let locales = fs.readdirSync(pathToLocales);
|
||||
if (availableLocales) {
|
||||
availableLocales.forEach(locale => {
|
||||
availableLocales.forEach((locale) => {
|
||||
if (!locales.includes(locale)) {
|
||||
throw new Error(`locale ${fallbackLocale} not available`);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ const postcssAdvancedVariables = require("postcss-advanced-variables");
|
||||
delete require.cache[paths.appThemeVariables];
|
||||
const variables = require(paths.appThemeVariables).default;
|
||||
const flatKebabVariables = mapKeys(
|
||||
mapValues(flat(variables, { delimiter: "-" }), v => v.toString()),
|
||||
mapValues(flat(variables, { delimiter: "-" }), (v) => v.toString()),
|
||||
(_, k) => kebabCase(k)
|
||||
);
|
||||
|
||||
@@ -32,7 +32,7 @@ const mediaQueryVariables = mapValues(
|
||||
// with the smallest screen and gradually add styling for the
|
||||
// next bigger screen. This is realized using `min-width` without
|
||||
// ever using `max-width`.
|
||||
v => `${Number.parseInt(v, 10) + 1}px`
|
||||
(v) => `${Number.parseInt(v, 10) + 1}px`
|
||||
);
|
||||
|
||||
module.exports = {
|
||||
@@ -63,12 +63,6 @@ module.exports = {
|
||||
postcssFlexbugsFixes,
|
||||
// Vendor prefixing.
|
||||
autoprefixer({
|
||||
browsers: [
|
||||
">1%",
|
||||
"last 4 versions",
|
||||
"Firefox ESR",
|
||||
"not ie < 9", // React doesn't support IE8 anyway
|
||||
],
|
||||
flexbox: "no-2009",
|
||||
}),
|
||||
],
|
||||
|
||||
@@ -17,7 +17,7 @@ interface Props {
|
||||
onGotoComment?: React.EventHandler<React.MouseEvent>;
|
||||
}
|
||||
|
||||
const ApprovedComment: FunctionComponent<Props> = props => (
|
||||
const ApprovedComment: FunctionComponent<Props> = (props) => (
|
||||
<DecisionItem icon={<ApprovedIcon />}>
|
||||
<Localized
|
||||
id="decisionHistory-approvedCommentBy"
|
||||
|
||||
@@ -19,13 +19,13 @@ interface Props {
|
||||
onClosePopover: () => void;
|
||||
}
|
||||
|
||||
const DecisionHistory: FunctionComponent<Props> = props => (
|
||||
const DecisionHistory: FunctionComponent<Props> = (props) => (
|
||||
<div data-testid="decisionHistory-container">
|
||||
<Title />
|
||||
<Main>
|
||||
<DecisionList>
|
||||
{props.actions.length === 0 && <Empty />}
|
||||
{props.actions.map(action => (
|
||||
{props.actions.map((action) => (
|
||||
<DecisionHistoryItemContainer
|
||||
key={action.id}
|
||||
action={action}
|
||||
|
||||
@@ -23,7 +23,7 @@ export class DecisionHistoryContainer extends React.Component<
|
||||
|
||||
public render() {
|
||||
const actions = this.props.viewer.commentModerationActionHistory.edges.map(
|
||||
edge => edge.node
|
||||
(edge) => edge.node
|
||||
);
|
||||
return (
|
||||
<DecisionHistory
|
||||
@@ -43,7 +43,7 @@ export class DecisionHistoryContainer extends React.Component<
|
||||
this.setState({ disableLoadMore: true });
|
||||
this.props.relay.loadMore(
|
||||
10, // Fetch the next 10 feed items
|
||||
error => {
|
||||
(error) => {
|
||||
this.setState({ disableLoadMore: false });
|
||||
if (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { Component } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { graphql, QueryRenderer } from "coral-framework/lib/relay";
|
||||
import { QueryRenderer } from "coral-framework/lib/relay";
|
||||
|
||||
import { DecisionHistoryQuery as QueryTypes } from "coral-admin/__generated__/DecisionHistoryQuery.graphql";
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ interface Props {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const DecisionItem: FunctionComponent<Props> = props => (
|
||||
const DecisionItem: FunctionComponent<Props> = (props) => (
|
||||
<li className={styles.root}>
|
||||
<Flex>
|
||||
<div className={styles.leftCol}>{props.icon}</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { FunctionComponent } from "react";
|
||||
|
||||
import styles from "./DecisionList.css";
|
||||
|
||||
const DecisionList: FunctionComponent = props => (
|
||||
const DecisionList: FunctionComponent = (props) => (
|
||||
<ul className={styles.root}>{props.children}</ul>
|
||||
);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ interface Props {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Footer: FunctionComponent<Props> = props => (
|
||||
const Footer: FunctionComponent<Props> = (props) => (
|
||||
<Flex className={styles.root} alignItems="baseline">
|
||||
{props.children}
|
||||
</Flex>
|
||||
|
||||
@@ -11,7 +11,7 @@ interface Props {
|
||||
onClick?: React.EventHandler<React.MouseEvent>;
|
||||
}
|
||||
|
||||
const GoToCommentLink: FunctionComponent<Props> = props => {
|
||||
const GoToCommentLink: FunctionComponent<Props> = (props) => {
|
||||
return (
|
||||
<Link
|
||||
as={TextLink}
|
||||
|
||||
@@ -6,7 +6,7 @@ interface Props {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Info: FunctionComponent<Props> = props => (
|
||||
const Info: FunctionComponent<Props> = (props) => (
|
||||
<span className={styles.root}>{props.children}</span>
|
||||
);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { FunctionComponent } from "react";
|
||||
|
||||
import styles from "./Main.css";
|
||||
|
||||
const Main: FunctionComponent = props => (
|
||||
const Main: FunctionComponent = (props) => (
|
||||
<div className={styles.root}>{props.children}</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ interface Props {
|
||||
onGotoComment?: React.EventHandler<React.MouseEvent>;
|
||||
}
|
||||
|
||||
const RejectedComment: FunctionComponent<Props> = props => (
|
||||
const RejectedComment: FunctionComponent<Props> = (props) => (
|
||||
<DecisionItem icon={<RejectedIcon />}>
|
||||
<Localized
|
||||
id="decisionHistory-rejectedCommentBy"
|
||||
|
||||
@@ -10,7 +10,7 @@ interface Props {
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
const ShowMoreButton: FunctionComponent<Props> = props => (
|
||||
const ShowMoreButton: FunctionComponent<Props> = (props) => (
|
||||
<Localized id="decisionHistory-showMoreButton">
|
||||
<BaseButton
|
||||
className={styles.root}
|
||||
|
||||
@@ -8,7 +8,7 @@ interface Props {
|
||||
children: string;
|
||||
}
|
||||
|
||||
const DecisionHistory: FunctionComponent<Props> = props => (
|
||||
const DecisionHistory: FunctionComponent<Props> = (props) => (
|
||||
<Timestamp className={styles.root}>{props.children}</Timestamp>
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
<ForwardRef(render)
|
||||
<Link
|
||||
as={[Function]}
|
||||
className="GoToCommentLink-root"
|
||||
onClick={[Function]}
|
||||
@@ -18,5 +18,5 @@ exports[`renders correctly 1`] = `
|
||||
<ForwardRef(forwardRef)>
|
||||
chevron_right
|
||||
</ForwardRef(forwardRef)>
|
||||
</ForwardRef(render)>
|
||||
</Link>
|
||||
`;
|
||||
|
||||
@@ -6,9 +6,9 @@ interface State {
|
||||
}
|
||||
|
||||
type Action =
|
||||
| {
|
||||
| ({
|
||||
type: "SET_MESSAGE";
|
||||
} & State
|
||||
} & State)
|
||||
| {
|
||||
type: "CLEAR_MESSAGE";
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { graphql } from "coral-framework/lib/relay";
|
||||
import { withRouteConfig } from "coral-framework/lib/router";
|
||||
|
||||
import { MainRouteQueryResponse } from "coral-admin/__generated__/MainRouteQuery.graphql";
|
||||
|
||||
@@ -9,7 +9,7 @@ interface Props {
|
||||
showConfigure: boolean;
|
||||
}
|
||||
|
||||
const Navigation: FunctionComponent<Props> = props => (
|
||||
const Navigation: FunctionComponent<Props> = (props) => (
|
||||
<AppBarNavigation>
|
||||
<Localized id="navigation-moderate">
|
||||
<NavigationLink to="/admin/moderate">Moderate</NavigationLink>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { Ability, can } from "coral-admin/permissions";
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import {
|
||||
SignOutMutation,
|
||||
withSignOutMutation,
|
||||
|
||||
@@ -8,7 +8,7 @@ interface Props {
|
||||
to: string | LocationDescriptor;
|
||||
}
|
||||
|
||||
const NavigationLink: FunctionComponent<Props> = props => (
|
||||
const NavigationLink: FunctionComponent<Props> = (props) => (
|
||||
<Link to={props.to} as={AppBarNavigationItem as any} activePropName="active">
|
||||
{props.children}
|
||||
</Link>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
<ForwardRef(render)
|
||||
<Link
|
||||
activePropName="active"
|
||||
as={[Function]}
|
||||
to="/moderate"
|
||||
>
|
||||
link
|
||||
</ForwardRef(render)>
|
||||
</Link>
|
||||
`;
|
||||
|
||||
@@ -18,7 +18,7 @@ interface Props {
|
||||
onSignOut: React.EventHandler<React.MouseEvent>;
|
||||
}
|
||||
|
||||
const UserMenu: FunctionComponent<Props> = props => (
|
||||
const UserMenu: FunctionComponent<Props> = (props) => (
|
||||
<Localized id="userMenu-popover" attrs={{ description: true }}>
|
||||
<Popover
|
||||
id="userMenu"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import {
|
||||
SignOutMutation,
|
||||
withSignOutMutation,
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { FunctionComponent } from "react";
|
||||
|
||||
import styles from "./ButtonPadding.css";
|
||||
|
||||
const ButtonPadding: FunctionComponent = props => (
|
||||
const ButtonPadding: FunctionComponent = (props) => (
|
||||
<div className={styles.root}>{props.children}</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ $comment-link: var(--v2-palette-primary-main);
|
||||
$comment-link-active: var(--v2-palette-primary-darkest);
|
||||
|
||||
.root {
|
||||
composes: bodyCommentV2 from "coral-ui/shared/typography.css";
|
||||
composes: bodyCommentV2 from "~coral-ui/shared/typography.css";
|
||||
font-family: var(--v2-font-family-primary);
|
||||
font-size: var(--v2-font-size-3);
|
||||
line-height: var(--v2-line-height-body-comment);
|
||||
|
||||
@@ -8,7 +8,7 @@ export interface UsernameProps {
|
||||
children: string;
|
||||
}
|
||||
|
||||
const Username: FunctionComponent<UsernameProps> = props => {
|
||||
const Username: FunctionComponent<UsernameProps> = (props) => {
|
||||
return (
|
||||
<span className={cn(props.className, styles.root)}>{props.children}</span>
|
||||
);
|
||||
|
||||
+3
-3
@@ -1,8 +1,9 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import cn from "classnames";
|
||||
import React, { FunctionComponent, useCallback, useState } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import {
|
||||
Button,
|
||||
Flex,
|
||||
@@ -10,13 +11,12 @@ import {
|
||||
Timestamp,
|
||||
} from "coral-ui/components/v2";
|
||||
|
||||
import ConversationModalRepliesQuery from "./ConversationModalRepliesQuery";
|
||||
|
||||
import { ConversationModalCommentContainer_comment } from "coral-admin/__generated__/ConversationModalCommentContainer_comment.graphql";
|
||||
import { ConversationModalCommentContainer_settings } from "coral-admin/__generated__/ConversationModalCommentContainer_settings.graphql";
|
||||
|
||||
import { CommentContent, InReplyTo, UsernameButton } from "../Comment";
|
||||
import { Circle, Line } from "../Timeline";
|
||||
import ConversationModalRepliesQuery from "./ConversationModalRepliesQuery";
|
||||
|
||||
import styles from "./ConversationModalCommentContainer.css";
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ const ConversationModalContainer: FunctionComponent<Props> = ({
|
||||
onUsernameClicked,
|
||||
}) => {
|
||||
const [loadMore] = useLoadMore(relay, 5);
|
||||
const parents = comment.parents.edges.map(edge => edge.node);
|
||||
const parents = comment.parents.edges.map((edge) => edge.node);
|
||||
return (
|
||||
<HorizontalGutter className={styles.root}>
|
||||
{comment.parentCount > parents.length && (
|
||||
@@ -60,7 +60,7 @@ const ConversationModalContainer: FunctionComponent<Props> = ({
|
||||
</Flex>
|
||||
</div>
|
||||
)}
|
||||
{parents.map(parent => (
|
||||
{parents.map((parent) => (
|
||||
<ConversationModalComment
|
||||
key={parent.id}
|
||||
isParent={true}
|
||||
|
||||
+2
-1
@@ -1,9 +1,10 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import { useRouter } from "found";
|
||||
import React, { FunctionComponent, RefObject, useCallback } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { getModerationLink } from "coral-framework/helpers";
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { Button, HorizontalGutter, ModalHeader } from "coral-ui/components/v2";
|
||||
|
||||
import { ConversationModalHeaderContainer_comment } from "coral-admin/__generated__/ConversationModalHeaderContainer_comment.graphql";
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import {
|
||||
graphql,
|
||||
QueryRenderData,
|
||||
QueryRenderer,
|
||||
} from "coral-framework/lib/relay";
|
||||
import { QueryRenderData, QueryRenderer } from "coral-framework/lib/relay";
|
||||
import { CallOut, Card, Spinner } from "coral-ui/components/v2";
|
||||
|
||||
import { ConversationModalQuery as QueryTypes } from "coral-admin/__generated__/ConversationModalQuery.graphql";
|
||||
|
||||
+12
-4
@@ -1,17 +1,22 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent, useCallback, useState } from "react";
|
||||
import React, {
|
||||
FunctionComponent,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import { graphql, RelayPaginationProp } from "react-relay";
|
||||
|
||||
import {
|
||||
useLoadMore,
|
||||
withPaginationContainer,
|
||||
} from "coral-framework/lib/relay";
|
||||
import { Omit } from "coral-framework/types";
|
||||
import { Button, HorizontalGutter } from "coral-ui/components/v2";
|
||||
|
||||
import { ConversationModalRepliesContainer_comment } from "coral-admin/__generated__/ConversationModalRepliesContainer_comment.graphql";
|
||||
import { ConversationModalRepliesContainer_settings } from "coral-admin/__generated__/ConversationModalRepliesContainer_settings.graphql";
|
||||
import { ConversationModalRepliesContainerPaginationQueryVariables } from "coral-admin/__generated__/ConversationModalRepliesContainerPaginationQuery.graphql";
|
||||
|
||||
import ConversationModalCommentContainer from "./ConversationModalCommentContainer";
|
||||
|
||||
import styles from "./ConversationModalRepliesContainer.css";
|
||||
@@ -31,7 +36,10 @@ const ConversationModalRepliesContainer: FunctionComponent<Props> = ({
|
||||
onUsernameClicked,
|
||||
}) => {
|
||||
const [loadMore] = useLoadMore(relay, 5);
|
||||
const replies = comment.replies.edges.map(edge => edge.node);
|
||||
const replies = useMemo(
|
||||
() => comment.replies.edges.map((edge) => edge.node, comment.replies),
|
||||
[comment.replies]
|
||||
);
|
||||
const [showReplies, setShowReplies] = useState(false);
|
||||
const onShowReplies = useCallback(() => {
|
||||
setShowReplies(true);
|
||||
@@ -39,7 +47,7 @@ const ConversationModalRepliesContainer: FunctionComponent<Props> = ({
|
||||
return (
|
||||
<HorizontalGutter>
|
||||
{showReplies &&
|
||||
replies.map(reply => (
|
||||
replies.map((reply) => (
|
||||
<div key={reply.id} className={styles.comment}>
|
||||
<ConversationModalCommentContainer
|
||||
key={reply.id}
|
||||
|
||||
+9
-8
@@ -1,14 +1,12 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import React, { FunctionComponent, useMemo } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import {
|
||||
graphql,
|
||||
QueryRenderData,
|
||||
QueryRenderer,
|
||||
} from "coral-framework/lib/relay";
|
||||
import { QueryRenderData, QueryRenderer } from "coral-framework/lib/relay";
|
||||
import { CallOut, Spinner } from "coral-ui/components/v2";
|
||||
|
||||
import { ConversationModalRepliesQuery as QueryTypes } from "coral-admin/__generated__/ConversationModalRepliesQuery.graphql";
|
||||
|
||||
import ConversationModalCommentContainer from "./ConversationModalCommentContainer";
|
||||
|
||||
interface Props {
|
||||
@@ -62,10 +60,13 @@ const ConversationModalRepliesQuery: FunctionComponent<Props> = ({
|
||||
);
|
||||
}
|
||||
|
||||
const replies = props.comment.replies.edges.map(edge => edge.node);
|
||||
const replies = useMemo(
|
||||
() => props.comment!.replies.edges.map((edge) => edge.node),
|
||||
[props.comment.replies]
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
{replies.map(reply => (
|
||||
{replies.map((reply) => (
|
||||
<div key={reply.id}>
|
||||
<ConversationModalCommentContainer
|
||||
key={reply.id}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { BaseButton, Icon } from "coral-ui/components/v2";
|
||||
|
||||
import styles from "./ApproveButton.css";
|
||||
|
||||
interface Props extends PropTypesOf<typeof BaseButton> {
|
||||
interface Props extends Omit<PropTypesOf<typeof BaseButton>, "ref"> {
|
||||
invert?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,12 +34,12 @@ const BanCommentUserMutation = createMutation(
|
||||
clientMutationId: clientMutationId.toString(),
|
||||
},
|
||||
},
|
||||
updater: store => {
|
||||
updater: (store) => {
|
||||
const user = store.get(input.userID);
|
||||
if (user) {
|
||||
const comments = user.getLinkedRecords("comments");
|
||||
if (comments) {
|
||||
comments.forEach(comment => {
|
||||
comments.forEach((comment) => {
|
||||
if (comment) {
|
||||
comment.setLinkedRecord(user, "author");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { Tag } from "coral-ui/components/v2";
|
||||
|
||||
import { CommentAuthorContainer_comment as CommentData } from "coral-admin/__generated__/CommentAuthorContainer_comment.graphql";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { HorizontalGutter, Timestamp } from "coral-ui/components/v2";
|
||||
|
||||
import { CommentRevisionContainer_comment as CommentData } from "coral-admin/__generated__/CommentRevisionContainer_comment.graphql";
|
||||
@@ -22,12 +23,12 @@ const CommentRevisionContainer: FunctionComponent<Props> = ({
|
||||
{comment.revisionHistory
|
||||
.concat()
|
||||
.reverse()
|
||||
.filter(c =>
|
||||
.filter((c) =>
|
||||
comment && comment.revision && comment.revision.id
|
||||
? comment.revision.id !== c.id
|
||||
: true
|
||||
)
|
||||
.map(c => (
|
||||
.map((c) => (
|
||||
<div key={c.id}>
|
||||
<Timestamp>{c.createdAt}</Timestamp>
|
||||
<CommentContent phrases={settings}>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { BaseButton } from "coral-ui/components/v2";
|
||||
|
||||
import styles from "./FeatureButton.css";
|
||||
|
||||
interface Props extends PropTypesOf<typeof BaseButton> {
|
||||
interface Props extends Omit<PropTypesOf<typeof BaseButton>, "ref"> {
|
||||
featured: boolean;
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ const FeatureCommentMutation = createMutation(
|
||||
},
|
||||
storyID: input.storyID,
|
||||
},
|
||||
optimisticUpdater: store => {
|
||||
optimisticUpdater: (store) => {
|
||||
const comment = store.get(input.commentID)!;
|
||||
const tags = comment.getLinkedRecords("tags");
|
||||
if (tags) {
|
||||
@@ -67,14 +67,14 @@ const FeatureCommentMutation = createMutation(
|
||||
comment.setValue(GQLCOMMENT_STATUS.APPROVED, "status");
|
||||
}
|
||||
},
|
||||
updater: store => {
|
||||
updater: (store) => {
|
||||
const connections = [
|
||||
getQueueConnection(store, "PENDING", input.storyID),
|
||||
getQueueConnection(store, "REPORTED", input.storyID),
|
||||
getQueueConnection(store, "UNMODERATED", input.storyID),
|
||||
getQueueConnection(store, "REJECTED", input.storyID),
|
||||
].filter(c => c);
|
||||
connections.forEach(con =>
|
||||
].filter((c) => c);
|
||||
connections.forEach((con) =>
|
||||
ConnectionHandler.deleteNode(con!, input.commentID)
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import CopyToClipboard from "react-copy-to-clipboard";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { getURLWithCommentID } from "coral-framework/helpers";
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { getLocationOrigin } from "coral-framework/utils";
|
||||
import { Button, Icon } from "coral-ui/components/v2";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React from "react";
|
||||
import React, { useMemo } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
@@ -26,17 +26,17 @@ function hasDetails(c: MarkersContainer_comment) {
|
||||
}
|
||||
|
||||
let keyCounter = 0;
|
||||
const markers: Array<
|
||||
(c: MarkersContainer_comment) => React.ReactElement<any> | null
|
||||
> = [
|
||||
c =>
|
||||
const markers: Array<(
|
||||
c: MarkersContainer_comment
|
||||
) => React.ReactElement<any> | null> = [
|
||||
(c) =>
|
||||
(c.status === "PREMOD" && (
|
||||
<Localized id="moderate-marker-preMod" key={keyCounter++}>
|
||||
<Marker color="pending">Pre-Mod</Marker>
|
||||
</Localized>
|
||||
)) ||
|
||||
null,
|
||||
c =>
|
||||
(c) =>
|
||||
(c.revision &&
|
||||
c.revision.actionCounts.flag.reasons.COMMENT_DETECTED_LINKS && (
|
||||
<Localized id="moderate-marker-link" key={keyCounter++}>
|
||||
@@ -44,7 +44,7 @@ const markers: Array<
|
||||
</Localized>
|
||||
)) ||
|
||||
null,
|
||||
c =>
|
||||
(c) =>
|
||||
(c.revision &&
|
||||
c.revision.actionCounts.flag.reasons.COMMENT_DETECTED_BANNED_WORD && (
|
||||
<Localized id="moderate-marker-bannedWord" key={keyCounter++}>
|
||||
@@ -52,7 +52,7 @@ const markers: Array<
|
||||
</Localized>
|
||||
)) ||
|
||||
null,
|
||||
c =>
|
||||
(c) =>
|
||||
(c.revision &&
|
||||
c.revision.actionCounts.flag.reasons.COMMENT_DETECTED_SUSPECT_WORD && (
|
||||
<Localized id="moderate-marker-suspectWord" key={keyCounter++}>
|
||||
@@ -60,7 +60,7 @@ const markers: Array<
|
||||
</Localized>
|
||||
)) ||
|
||||
null,
|
||||
c =>
|
||||
(c) =>
|
||||
(c.revision &&
|
||||
c.revision.actionCounts.flag.reasons.COMMENT_DETECTED_SPAM && (
|
||||
<Localized id="moderate-marker-spamDetected" key={keyCounter++}>
|
||||
@@ -68,7 +68,7 @@ const markers: Array<
|
||||
</Localized>
|
||||
)) ||
|
||||
null,
|
||||
c =>
|
||||
(c) =>
|
||||
(c.revision &&
|
||||
c.revision.actionCounts.flag.reasons.COMMENT_DETECTED_TOXIC && (
|
||||
<Localized id="moderate-marker-toxic" key={keyCounter++}>
|
||||
@@ -76,7 +76,7 @@ const markers: Array<
|
||||
</Localized>
|
||||
)) ||
|
||||
null,
|
||||
c =>
|
||||
(c) =>
|
||||
(c.revision &&
|
||||
c.revision.actionCounts.flag.reasons.COMMENT_DETECTED_REPEAT_POST && (
|
||||
<Localized id="moderate-marker-repeatPost" key={keyCounter++}>
|
||||
@@ -84,7 +84,7 @@ const markers: Array<
|
||||
</Localized>
|
||||
)) ||
|
||||
null,
|
||||
c =>
|
||||
(c) =>
|
||||
(c.revision &&
|
||||
c.revision.actionCounts.flag.reasons.COMMENT_DETECTED_RECENT_HISTORY && (
|
||||
<Localized id="moderate-marker-recentHistory" key={keyCounter++}>
|
||||
@@ -92,7 +92,7 @@ const markers: Array<
|
||||
</Localized>
|
||||
)) ||
|
||||
null,
|
||||
c =>
|
||||
(c) =>
|
||||
(c.revision &&
|
||||
c.revision.actionCounts.flag.reasons.COMMENT_REPORTED_OFFENSIVE && (
|
||||
<Marker key={keyCounter++} color="reported">
|
||||
@@ -105,7 +105,7 @@ const markers: Array<
|
||||
</Marker>
|
||||
)) ||
|
||||
null,
|
||||
c =>
|
||||
(c) =>
|
||||
(c.revision &&
|
||||
c.revision.actionCounts.flag.reasons.COMMENT_REPORTED_SPAM && (
|
||||
<Marker key={keyCounter++} color="reported">
|
||||
@@ -118,7 +118,7 @@ const markers: Array<
|
||||
</Marker>
|
||||
)) ||
|
||||
null,
|
||||
c =>
|
||||
(c) =>
|
||||
(c.revision &&
|
||||
c.revision.actionCounts.flag.reasons.COMMENT_DETECTED_NEW_COMMENTER && (
|
||||
<Localized id="moderate-marker-newCommenter" key={keyCounter++}>
|
||||
@@ -128,33 +128,38 @@ const markers: Array<
|
||||
null,
|
||||
];
|
||||
|
||||
export class MarkersContainer extends React.Component<MarkersContainerProps> {
|
||||
public render() {
|
||||
const elements = markers.map(cb => cb(this.props.comment)).filter(m => m);
|
||||
const doesHaveDetails = hasDetails(this.props.comment);
|
||||
if (elements.length === 0 && !doesHaveDetails) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Markers
|
||||
details={
|
||||
doesHaveDetails || this.props.comment.editing.edited ? (
|
||||
<ModerateCardDetailsContainer
|
||||
hasDetails={!!doesHaveDetails}
|
||||
hasRevisions={this.props.comment.editing.edited}
|
||||
onUsernameClick={this.props.onUsernameClick}
|
||||
comment={this.props.comment}
|
||||
settings={this.props.settings}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
>
|
||||
{elements}
|
||||
</Markers>
|
||||
);
|
||||
export const MarkersContainer: React.FunctionComponent<MarkersContainerProps> = (
|
||||
props
|
||||
) => {
|
||||
const elements = useMemo(
|
||||
() => markers.map((cb) => cb(props.comment)).filter((m) => m),
|
||||
[markers, props.comment]
|
||||
);
|
||||
const doesHaveDetails = useMemo(() => hasDetails(props.comment), [
|
||||
props.comment,
|
||||
]);
|
||||
if (elements.length === 0 && !doesHaveDetails) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Markers
|
||||
details={
|
||||
doesHaveDetails || props.comment.editing.edited ? (
|
||||
<ModerateCardDetailsContainer
|
||||
hasDetails={!!doesHaveDetails}
|
||||
hasRevisions={props.comment.editing.edited}
|
||||
onUsernameClick={props.onUsernameClick}
|
||||
comment={props.comment}
|
||||
settings={props.settings}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
>
|
||||
{elements}
|
||||
</Markers>
|
||||
);
|
||||
};
|
||||
|
||||
const enhanced = withFragmentContainer<MarkersContainerProps>({
|
||||
comment: graphql`
|
||||
|
||||
@@ -64,7 +64,7 @@ function getStatus(comment: ModerateCardContainer_comment) {
|
||||
}
|
||||
|
||||
function isFeatured(comment: ModerateCardContainer_comment) {
|
||||
return comment.tags.some(t => t.code === GQLTAG.FEATURED);
|
||||
return comment.tags.some((t) => t.code === GQLTAG.FEATURED);
|
||||
}
|
||||
|
||||
const ModerateCardContainer: FunctionComponent<Props> = ({
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent, useState } from "react";
|
||||
import React, { FunctionComponent, useCallback, useState } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { ModerateCardDetailsContainer_comment as CommentData } from "coral-admin/__generated__/ModerateCardDetailsContainer_comment.graphql";
|
||||
import { ModerateCardDetailsContainer_settings as SettingsData } from "coral-admin/__generated__/ModerateCardDetailsContainer_settings.graphql";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import {
|
||||
Flex,
|
||||
@@ -13,6 +11,9 @@ import {
|
||||
TabBar,
|
||||
} from "coral-ui/components/v2";
|
||||
|
||||
import { ModerateCardDetailsContainer_comment as CommentData } from "coral-admin/__generated__/ModerateCardDetailsContainer_comment.graphql";
|
||||
import { ModerateCardDetailsContainer_settings as SettingsData } from "coral-admin/__generated__/ModerateCardDetailsContainer_settings.graphql";
|
||||
|
||||
import CommentRevisionContainer from "./CommentRevisionContainer";
|
||||
import FlagDetailsContainer from "./FlagDetailsContainer";
|
||||
import LinkDetailsContainer from "./LinkDetailsContainer";
|
||||
@@ -40,13 +41,13 @@ const ModerateCardDetailsContainer: FunctionComponent<Props> = ({
|
||||
hasDetails ? "DETAILS" : "HISTORY"
|
||||
);
|
||||
|
||||
const onTabClick = useCallback((id) => setActiveTab(id as DetailsTabs), [
|
||||
setActiveTab,
|
||||
]);
|
||||
|
||||
return (
|
||||
<HorizontalGutter>
|
||||
<TabBar
|
||||
variant="default"
|
||||
activeTab={activeTab}
|
||||
onTabClick={id => setActiveTab(id as DetailsTabs)}
|
||||
>
|
||||
<TabBar variant="default" activeTab={activeTab} onTabClick={onTabClick}>
|
||||
{hasDetails && (
|
||||
<Tab tabID="DETAILS" classes={styles}>
|
||||
<Flex alignItems="center" itemGutter>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { BaseButton, Icon } from "coral-ui/components/v2";
|
||||
|
||||
import styles from "./RejectButton.css";
|
||||
|
||||
interface Props extends PropTypesOf<typeof BaseButton> {
|
||||
interface Props extends Omit<PropTypesOf<typeof BaseButton>, "ref"> {
|
||||
invert?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,11 @@ const UnfeatureCommentMutation = createMutation(
|
||||
}
|
||||
}
|
||||
`,
|
||||
optimisticUpdater: store => {
|
||||
optimisticUpdater: (store) => {
|
||||
const comment = store.get(input.commentID)!;
|
||||
const tags = comment.getLinkedRecords("tags")!;
|
||||
comment.setLinkedRecords(
|
||||
tags.filter(t => t!.getValue("code") === GQLTAG.FEATURED),
|
||||
tags.filter((t) => t.getValue("code") === GQLTAG.FEATURED),
|
||||
"tags"
|
||||
);
|
||||
},
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`viewer's username shows on moderation cards moderated by viewer 1`] = `
|
||||
<ForwardRef(Relay(ModeratedByContainer))
|
||||
<Relay(ModeratedByContainer)
|
||||
comment={
|
||||
Object {
|
||||
"id": "comment-id",
|
||||
|
||||
@@ -3,7 +3,7 @@ import React, { FunctionComponent } from "react";
|
||||
|
||||
import styles from "./NotAvailable.css";
|
||||
|
||||
const NotAvailable: FunctionComponent = props => (
|
||||
const NotAvailable: FunctionComponent = (props) => (
|
||||
<Localized id="general-notAvailable">
|
||||
<span className={styles.root}>Not available</span>
|
||||
</Localized>
|
||||
|
||||
@@ -10,7 +10,7 @@ export interface CircleProps {
|
||||
color?: "light" | "regular";
|
||||
}
|
||||
|
||||
const Circle: FunctionComponent<CircleProps> = props => {
|
||||
const Circle: FunctionComponent<CircleProps> = (props) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(styles.root, props.className, {
|
||||
|
||||
@@ -8,7 +8,7 @@ interface LineProps {
|
||||
dotted?: boolean;
|
||||
}
|
||||
|
||||
const Line: FunctionComponent<LineProps> = props => {
|
||||
const Line: FunctionComponent<LineProps> = (props) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(styles.root, props.className, {
|
||||
|
||||
@@ -19,7 +19,7 @@ function createElement(
|
||||
}
|
||||
}
|
||||
|
||||
const TranslatedRole: React.FunctionComponent<Props> = props => {
|
||||
const TranslatedRole: React.FunctionComponent<Props> = (props) => {
|
||||
switch (props.children) {
|
||||
case GQLUSER_ROLE.COMMENTER:
|
||||
return (
|
||||
|
||||
@@ -19,7 +19,7 @@ function createElement(
|
||||
}
|
||||
}
|
||||
|
||||
const TranslatedRole: React.FunctionComponent<Props> = props => {
|
||||
const TranslatedRole: React.FunctionComponent<Props> = (props) => {
|
||||
switch (props.children) {
|
||||
case GQLSTORY_STATUS.OPEN:
|
||||
return (
|
||||
|
||||
@@ -25,7 +25,7 @@ const CreateModeratorNoteMutation = createMutation(
|
||||
) => {
|
||||
const viewer = getViewer(environment)!;
|
||||
const notes =
|
||||
lookup<GQLUser>(environment, input.userID)!.moderatorNotes.map(note => {
|
||||
lookup<GQLUser>(environment, input.userID)!.moderatorNotes.map((note) => {
|
||||
const createdBy = pick(note.createdBy, ["username", "id"]);
|
||||
return {
|
||||
...pick(note, ["id", "body", "createdAt"]),
|
||||
@@ -40,6 +40,7 @@ const CreateModeratorNoteMutation = createMutation(
|
||||
) {
|
||||
createModeratorNote(input: $input) {
|
||||
user {
|
||||
id
|
||||
moderatorNotes {
|
||||
id
|
||||
body
|
||||
|
||||
@@ -23,7 +23,7 @@ const DeleteModeratorNoteMutation = createMutation(
|
||||
{ uuidGenerator }: CoralContext
|
||||
) => {
|
||||
const notes =
|
||||
lookup<GQLUser>(environment, input.userID)!.moderatorNotes.map(note => {
|
||||
lookup<GQLUser>(environment, input.userID)!.moderatorNotes.map((note) => {
|
||||
const createdBy = pick(note.createdBy, ["username", "id"]);
|
||||
return {
|
||||
...pick(note, ["id", "body", "createdAt"]),
|
||||
@@ -37,6 +37,7 @@ const DeleteModeratorNoteMutation = createMutation(
|
||||
) {
|
||||
deleteModeratorNote(input: $input) {
|
||||
user {
|
||||
id
|
||||
moderatorNotes {
|
||||
id
|
||||
body
|
||||
@@ -61,7 +62,7 @@ const DeleteModeratorNoteMutation = createMutation(
|
||||
deleteModeratorNote: {
|
||||
user: {
|
||||
id: input.userID,
|
||||
moderatorNotes: notes.filter(note => note.id !== input.id),
|
||||
moderatorNotes: notes.filter((note) => note.id !== input.id),
|
||||
},
|
||||
clientMutationId: (clientMutationId++).toString(),
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { FunctionComponent, useMemo } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { GQLCOMMENT_STATUS } from "coral-framework/schema";
|
||||
|
||||
import { RecentHistoryContainer_settings } from "coral-admin/__generated__/RecentHistoryContainer_settings.graphql";
|
||||
|
||||
@@ -17,7 +17,7 @@ const UserBadgesContainer: FunctionComponent<Props> = ({ user }) => {
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{user.badges.map(badge => (
|
||||
{user.badges.map((badge) => (
|
||||
<Tag
|
||||
key={badge}
|
||||
color="dark"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent, useMemo } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { useCoralContext } from "coral-framework/lib/bootstrap";
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import {
|
||||
CallOut,
|
||||
HorizontalGutter,
|
||||
@@ -53,7 +54,7 @@ const UserDrawerAccountHistory: FunctionComponent<Props> = ({ user }) => {
|
||||
const history: HistoryRecord[] = [];
|
||||
|
||||
// Merge in all the suspension history items.
|
||||
user.status.suspension.history.forEach(record => {
|
||||
user.status.suspension.history.forEach((record) => {
|
||||
const from: From = {
|
||||
start: new Date(record.from.start),
|
||||
finish: new Date(record.from.finish),
|
||||
@@ -96,7 +97,7 @@ const UserDrawerAccountHistory: FunctionComponent<Props> = ({ user }) => {
|
||||
});
|
||||
|
||||
// Merge in all the ban status history items.
|
||||
user.status.ban.history.forEach(record => {
|
||||
user.status.ban.history.forEach((record) => {
|
||||
history.push({
|
||||
kind: "ban",
|
||||
action: {
|
||||
@@ -108,7 +109,7 @@ const UserDrawerAccountHistory: FunctionComponent<Props> = ({ user }) => {
|
||||
});
|
||||
|
||||
// Merge in all the premod history items.
|
||||
user.status.premod.history.forEach(record => {
|
||||
user.status.premod.history.forEach((record) => {
|
||||
history.push({
|
||||
kind: "premod",
|
||||
action: {
|
||||
|
||||
+2
-5
@@ -1,11 +1,8 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import {
|
||||
graphql,
|
||||
QueryRenderData,
|
||||
QueryRenderer,
|
||||
} from "coral-framework/lib/relay";
|
||||
import { QueryRenderData, QueryRenderer } from "coral-framework/lib/relay";
|
||||
import { CallOut, Spinner } from "coral-ui/components/v2";
|
||||
|
||||
import { UserDrawerAccountHistoryQuery as QueryTypes } from "coral-admin/__generated__/UserDrawerAccountHistoryQuery.graphql";
|
||||
|
||||
@@ -2,12 +2,9 @@ import { Localized } from "@fluent/react/compat";
|
||||
import { FormApi } from "final-form";
|
||||
import React, { FunctionComponent, useCallback } from "react";
|
||||
import { Field, Form } from "react-final-form";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import {
|
||||
graphql,
|
||||
useMutation,
|
||||
withFragmentContainer,
|
||||
} from "coral-framework/lib/relay";
|
||||
import { useMutation, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { required } from "coral-framework/lib/validation";
|
||||
import {
|
||||
Button,
|
||||
@@ -91,7 +88,7 @@ const UserDrawerNotesContainer: FunctionComponent<Props> = ({
|
||||
.concat()
|
||||
.reverse()
|
||||
.map(
|
||||
note =>
|
||||
(note) =>
|
||||
note && (
|
||||
<ModeratorNote
|
||||
key={note.id}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { graphql, QueryRenderer } from "coral-framework/lib/relay";
|
||||
import { QueryRenderer } from "coral-framework/lib/relay";
|
||||
import { CallOut, Spinner } from "coral-ui/components/v2";
|
||||
|
||||
import { UserDrawerNotesQuery as QueryTypes } from "coral-admin/__generated__/UserDrawerNotesQuery.graphql";
|
||||
|
||||
@@ -37,7 +37,7 @@ const UserHistoryDrawerAllComments: FunctionComponent<Props> = ({
|
||||
}, [loadMore]);
|
||||
|
||||
const hasMore = relay.hasMore();
|
||||
const comments = user ? user.allComments.edges.map(edge => edge.node) : [];
|
||||
const comments = user ? user.allComments.edges.map((edge) => edge.node) : [];
|
||||
|
||||
if (comments.length === 0) {
|
||||
return (
|
||||
@@ -59,7 +59,7 @@ const UserHistoryDrawerAllComments: FunctionComponent<Props> = ({
|
||||
<ModerateCardContainer
|
||||
comment={c}
|
||||
settings={settings}
|
||||
danglingLogic={status => false}
|
||||
danglingLogic={(status) => false}
|
||||
hideUsername
|
||||
showStoryInfo
|
||||
mini
|
||||
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { graphql, QueryRenderer } from "coral-framework/lib/relay";
|
||||
import { QueryRenderer } from "coral-framework/lib/relay";
|
||||
import { CallOut, Spinner } from "coral-ui/components/v2";
|
||||
|
||||
import { UserHistoryDrawerAllCommentsQuery as QueryTypes } from "coral-admin/__generated__/UserHistoryDrawerAllCommentsQuery.graphql";
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { UserStatusChangeContainer } from "coral-admin/components/UserStatus";
|
||||
import { CopyButton } from "coral-framework/components";
|
||||
import { useCoralContext } from "coral-framework/lib/bootstrap";
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import {
|
||||
Button,
|
||||
Divider,
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import {
|
||||
graphql,
|
||||
QueryRenderData,
|
||||
QueryRenderer,
|
||||
} from "coral-framework/lib/relay";
|
||||
import { QueryRenderData, QueryRenderer } from "coral-framework/lib/relay";
|
||||
import { CallOut, Spinner } from "coral-ui/components/v2";
|
||||
|
||||
import { UserHistoryDrawerQuery as QueryTypes } from "coral-admin/__generated__/UserHistoryDrawerQuery.graphql";
|
||||
|
||||
+4
-2
@@ -15,6 +15,8 @@ import { UserHistoryDrawerRejectedCommentsPaginationQueryVariables } from "coral
|
||||
|
||||
import styles from "./UserHistoryDrawerRejectedComments.css";
|
||||
|
||||
const danglingLogic = () => false;
|
||||
|
||||
interface Props {
|
||||
user: UserHistoryDrawerRejectedComments_user;
|
||||
settings: UserHistoryDrawerRejectedComments_settings;
|
||||
@@ -38,7 +40,7 @@ const UserHistoryDrawerRejectedComments: FunctionComponent<Props> = ({
|
||||
|
||||
const hasMore = relay.hasMore();
|
||||
const comments = user
|
||||
? user.rejectedComments.edges.map(edge => edge.node)
|
||||
? user.rejectedComments.edges.map((edge) => edge.node)
|
||||
: [];
|
||||
|
||||
if (comments.length === 0) {
|
||||
@@ -61,7 +63,7 @@ const UserHistoryDrawerRejectedComments: FunctionComponent<Props> = ({
|
||||
<ModerateCardContainer
|
||||
comment={c}
|
||||
settings={settings}
|
||||
danglingLogic={status => false}
|
||||
danglingLogic={danglingLogic}
|
||||
hideUsername
|
||||
showStoryInfo
|
||||
mini
|
||||
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { graphql, QueryRenderer } from "coral-framework/lib/relay";
|
||||
import { QueryRenderer } from "coral-framework/lib/relay";
|
||||
import { CallOut, Spinner } from "coral-ui/components/v2";
|
||||
|
||||
import UserHistoryDrawerRejectedComments from "./UserHistoryDrawerRejectedComments";
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Localized } from "@fluent/react/compat";
|
||||
import React, { FunctionComponent, useMemo } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { useCoralContext } from "coral-framework/lib/bootstrap";
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import {
|
||||
BaseButton,
|
||||
Box,
|
||||
@@ -25,11 +26,11 @@ const UserStatusDetailsContainer: FunctionComponent<Props> = ({ user }) => {
|
||||
}
|
||||
|
||||
const activeBan = useMemo(() => {
|
||||
return user.status.ban.history.find(item => item.active);
|
||||
return user.status.ban.history.find((item) => item.active);
|
||||
}, [user]);
|
||||
|
||||
const activeSuspension = useMemo(() => {
|
||||
return user.status.suspension.history.find(item => item.active);
|
||||
return user.status.suspension.history.find((item) => item.active);
|
||||
}, [user]);
|
||||
|
||||
const { locales } = useCoralContext();
|
||||
@@ -122,7 +123,7 @@ const UserStatusDetailsContainer: FunctionComponent<Props> = ({ user }) => {
|
||||
>
|
||||
{({ toggleVisibility, ref }) => (
|
||||
<BaseButton
|
||||
onClick={evt => {
|
||||
onClick={(evt) => {
|
||||
evt.stopPropagation();
|
||||
toggleVisibility();
|
||||
}}
|
||||
|
||||
@@ -21,7 +21,7 @@ interface Props {
|
||||
role: GQLUSER_ROLE_RL;
|
||||
}
|
||||
|
||||
const UserRoleChange: FunctionComponent<Props> = props => (
|
||||
const UserRoleChange: FunctionComponent<Props> = (props) => (
|
||||
<Localized id="community-role-popover" attrs={{ description: true }}>
|
||||
<Popover
|
||||
id="community-roleChange"
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import React, { FunctionComponent, useCallback } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { Ability, can } from "coral-admin/permissions";
|
||||
import {
|
||||
graphql,
|
||||
useMutation,
|
||||
withFragmentContainer,
|
||||
} from "coral-framework/lib/relay";
|
||||
import { useMutation, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { GQLUSER_ROLE_RL } from "coral-framework/schema";
|
||||
|
||||
import { UserRoleChangeContainer_user } from "coral-admin/__generated__/UserRoleChangeContainer_user.graphql";
|
||||
@@ -21,7 +18,7 @@ interface Props {
|
||||
user: UserRoleChangeContainer_user;
|
||||
}
|
||||
|
||||
const UserRoleChangeContainer: FunctionComponent<Props> = props => {
|
||||
const UserRoleChangeContainer: FunctionComponent<Props> = (props) => {
|
||||
const updateUserRole = useMutation(UpdateUserRoleMutation);
|
||||
const handleOnChangeRole = useCallback(
|
||||
(role: GQLUSER_ROLE_RL) => {
|
||||
|
||||
@@ -11,7 +11,7 @@ interface Props {
|
||||
children: PropTypesOf<typeof TranslatedRole>["children"];
|
||||
}
|
||||
|
||||
const UserRoleText: FunctionComponent<Props> = props => (
|
||||
const UserRoleText: FunctionComponent<Props> = (props) => (
|
||||
<TranslatedRole
|
||||
container={
|
||||
<span
|
||||
|
||||
@@ -62,7 +62,9 @@ const BanModal: FunctionComponent<Props> = ({
|
||||
<Localized
|
||||
id="community-banModal-areYouSure"
|
||||
strong={<ModalHeaderUsername />}
|
||||
$username={username || <NotAvailable />}
|
||||
username={React.createElement(() => (
|
||||
<strong>{username || <NotAvailable />}</strong>
|
||||
))}
|
||||
>
|
||||
<ChangeStatusModalHeader id="banModal-title">
|
||||
Are you sure you want to ban{" "}
|
||||
|
||||
@@ -31,7 +31,7 @@ const ChangeStatusModal: FunctionComponent<Props> = ({
|
||||
}) => {
|
||||
return (
|
||||
<Modal {...rest} onClose={onClose}>
|
||||
{renderProps => (
|
||||
{(renderProps) => (
|
||||
<Card className={styles.root}>
|
||||
<Flex justifyContent="flex-end">
|
||||
<CardCloseButton
|
||||
|
||||
@@ -2,9 +2,9 @@ import React, { FunctionComponent, HTMLAttributes } from "react";
|
||||
|
||||
import styles from "./ChangeStatusModalHeader.css";
|
||||
|
||||
const ChangeStatusModalHeader: FunctionComponent<
|
||||
HTMLAttributes<HTMLHeadingElement>
|
||||
> = ({ children, ...rest }) => {
|
||||
const ChangeStatusModalHeader: FunctionComponent<HTMLAttributes<
|
||||
HTMLHeadingElement
|
||||
>> = ({ children, ...rest }) => {
|
||||
return (
|
||||
<h2 {...rest} className={styles.root}>
|
||||
{children}
|
||||
|
||||
@@ -54,7 +54,7 @@ const RemoveUserBanMutation = createMutation(
|
||||
current: lookup<GQLUser>(
|
||||
environment,
|
||||
input.userID
|
||||
)!.status.current.filter(s => s !== GQLUSER_STATUS.BANNED),
|
||||
)!.status.current.filter((s) => s !== GQLUSER_STATUS.BANNED),
|
||||
ban: {
|
||||
active: false,
|
||||
history: [],
|
||||
|
||||
@@ -57,7 +57,7 @@ const RemoveUserPremodMutation = createMutation(
|
||||
current: lookup<GQLUser>(
|
||||
environment,
|
||||
input.userID
|
||||
)!.status.current.filter(s => s !== GQLUSER_STATUS.PREMOD),
|
||||
)!.status.current.filter((s) => s !== GQLUSER_STATUS.PREMOD),
|
||||
premod: {
|
||||
active: false,
|
||||
history: [
|
||||
|
||||
@@ -23,7 +23,7 @@ const RemoveUserSuspensionMutation = createMutation(
|
||||
MutationTypes["response"]["removeUserSuspension"]["user"]["status"]["suspension"]["history"]
|
||||
> = [];
|
||||
if (user.status.suspension.history) {
|
||||
newHistory = user.status.suspension.history.map(h =>
|
||||
newHistory = user.status.suspension.history.map((h) =>
|
||||
pick(h, [
|
||||
"active",
|
||||
"from.start",
|
||||
|
||||
@@ -65,7 +65,7 @@ const SuspendForm: FunctionComponent<Props> = ({
|
||||
|
||||
const onFormSubmit = useCallback(
|
||||
({ duration, emailMessage }) => {
|
||||
const unit = DURATIONS.find(d => d.value === duration);
|
||||
const unit = DURATIONS.find((d) => d.value === duration);
|
||||
onSubmit(unit!, emailMessage);
|
||||
},
|
||||
[onSubmit]
|
||||
@@ -76,7 +76,7 @@ const SuspendForm: FunctionComponent<Props> = ({
|
||||
if (state.lastFormState) {
|
||||
const { duration, emailMessage } = state.lastFormState
|
||||
.values as FormStateValues;
|
||||
const unit = DURATIONS.find(d => d.value === duration);
|
||||
const unit = DURATIONS.find((d) => d.value === duration);
|
||||
const expectedEmailMessage = getMessageWithDuration(unit!);
|
||||
if (expectedEmailMessage === emailMessage) {
|
||||
changeValue(state, name, () => newValue);
|
||||
@@ -94,7 +94,7 @@ const SuspendForm: FunctionComponent<Props> = ({
|
||||
if (state.lastFormState && !checked) {
|
||||
const { duration, emailMessage } = state.lastFormState
|
||||
.values as FormStateValues;
|
||||
const unit = DURATIONS.find(d => d.value === duration);
|
||||
const unit = DURATIONS.find((d) => d.value === duration);
|
||||
const expectedEmailMessage = getMessageWithDuration(unit!);
|
||||
if (expectedEmailMessage !== emailMessage) {
|
||||
changeValue(state, name, () => expectedEmailMessage);
|
||||
@@ -141,7 +141,7 @@ const SuspendForm: FunctionComponent<Props> = ({
|
||||
<RadioButton
|
||||
{...input}
|
||||
id={`duration-${value}`}
|
||||
onChange={event => {
|
||||
onChange={(event) => {
|
||||
form.mutators.setMessageValue(
|
||||
"emailMessage",
|
||||
getMessageWithDuration({ scaled, unit })
|
||||
@@ -165,7 +165,7 @@ const SuspendForm: FunctionComponent<Props> = ({
|
||||
<CheckBox
|
||||
{...input}
|
||||
id="suspendModal-editMessage"
|
||||
onChange={event => {
|
||||
onChange={(event) => {
|
||||
form.mutators.resetMessageValue(
|
||||
"emailMessage",
|
||||
!input.checked
|
||||
|
||||
@@ -20,7 +20,7 @@ const render = (className: string, content: React.ReactNode) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const UserStatus: FunctionComponent<Props> = props => {
|
||||
const UserStatus: FunctionComponent<Props> = (props) => {
|
||||
if (props.banned) {
|
||||
return render(
|
||||
styles.error,
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import React, { FunctionComponent, useCallback, useState } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import {
|
||||
graphql,
|
||||
useMutation,
|
||||
withFragmentContainer,
|
||||
} from "coral-framework/lib/relay";
|
||||
import { useMutation, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { GQLUSER_ROLE } from "coral-framework/schema";
|
||||
|
||||
import { UserStatusChangeContainer_settings as SettingsData } from "coral-admin/__generated__/UserStatusChangeContainer_settings.graphql";
|
||||
@@ -29,7 +26,7 @@ interface Props {
|
||||
bordered?: boolean;
|
||||
}
|
||||
|
||||
const UserStatusChangeContainer: FunctionComponent<Props> = props => {
|
||||
const UserStatusChangeContainer: FunctionComponent<Props> = (props) => {
|
||||
const { user, settings, fullWidth, bordered } = props;
|
||||
const banUser = useMutation(BanUserMutation);
|
||||
const suspendUser = useMutation(SuspendUserMutation);
|
||||
|
||||
@@ -12,7 +12,7 @@ interface Props {
|
||||
user: UserData;
|
||||
}
|
||||
|
||||
const UserStatusContainer: FunctionComponent<Props> = props => {
|
||||
const UserStatusContainer: FunctionComponent<Props> = (props) => {
|
||||
return (
|
||||
<UserStatus
|
||||
banned={props.user.status.current.includes(GQLUSER_STATUS.BANNED)}
|
||||
|
||||
@@ -50,7 +50,7 @@ const cache: Cache = {
|
||||
value: null,
|
||||
};
|
||||
|
||||
export default function(options: GetPhrasesRegExpOptions) {
|
||||
export default function (options: GetPhrasesRegExpOptions) {
|
||||
// We assume that the cache is valid unless one of the below checks fails.
|
||||
let expired = false;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ function markPhrasesHTML(text: string, expression: RegExp) {
|
||||
// markHTMLNode manipulates the node by looking for #text nodes and adding
|
||||
// markers.
|
||||
export default function markHTMLNode(parentNode: Node, expression: RegExp) {
|
||||
parentNode.childNodes.forEach(node => {
|
||||
parentNode.childNodes.forEach((node) => {
|
||||
// Anchor links are already marked by default, skip them now.
|
||||
if (node.nodeName === "A") {
|
||||
return;
|
||||
|
||||
@@ -62,7 +62,7 @@ export default async function initLocalState(
|
||||
|
||||
await initLocalBaseState(environment, context, accessToken);
|
||||
|
||||
commitLocalUpdate(environment, s => {
|
||||
commitLocalUpdate(environment, (s) => {
|
||||
const localRecord = s.get(LOCAL_ID)!;
|
||||
|
||||
localRecord.setValue(redirectPath, "redirectPath");
|
||||
|
||||
@@ -65,19 +65,19 @@ const ApproveCommentMutation = createMutation(
|
||||
},
|
||||
storyID: input.storyID,
|
||||
},
|
||||
optimisticUpdater: store => {
|
||||
optimisticUpdater: (store) => {
|
||||
const proxy = store.get(input.commentID)!;
|
||||
proxy.setValue("APPROVED", "status");
|
||||
proxy.setValue(true, "viewerDidModerate");
|
||||
},
|
||||
updater: store => {
|
||||
updater: (store) => {
|
||||
const connections = [
|
||||
getQueueConnection(store, "REPORTED", input.storyID),
|
||||
getQueueConnection(store, "PENDING", input.storyID),
|
||||
getQueueConnection(store, "UNMODERATED", input.storyID),
|
||||
getQueueConnection(store, "REJECTED", input.storyID),
|
||||
].filter(c => c);
|
||||
connections.forEach(con =>
|
||||
].filter((c) => c);
|
||||
connections.forEach((con) =>
|
||||
ConnectionHandler.deleteNode(con!, input.commentID)
|
||||
);
|
||||
},
|
||||
|
||||
@@ -65,19 +65,19 @@ const RejectCommentMutation = createMutation(
|
||||
},
|
||||
storyID: input.storyID,
|
||||
},
|
||||
optimisticUpdater: store => {
|
||||
optimisticUpdater: (store) => {
|
||||
const proxy = store.get(input.commentID)!;
|
||||
proxy.setValue("REJECTED", "status");
|
||||
proxy.setValue(true, "viewerDidModerate");
|
||||
},
|
||||
updater: store => {
|
||||
updater: (store) => {
|
||||
const connections = [
|
||||
getQueueConnection(store, "REPORTED", input.storyID),
|
||||
getQueueConnection(store, "PENDING", input.storyID),
|
||||
getQueueConnection(store, "UNMODERATED", input.storyID),
|
||||
getQueueConnection(store, "APPROVED", input.storyID),
|
||||
].filter(c => c);
|
||||
connections.forEach(con =>
|
||||
].filter((c) => c);
|
||||
connections.forEach((con) =>
|
||||
ConnectionHandler.deleteNode(con!, input.commentID)
|
||||
);
|
||||
},
|
||||
|
||||
@@ -21,7 +21,7 @@ const SetRedirectPathMutation = createMutation(
|
||||
await localStorage.setItem(REDIRECT_PATH_KEY, input.path);
|
||||
}
|
||||
|
||||
return commitLocalUpdate(environment, store => {
|
||||
return commitLocalUpdate(environment, (store) => {
|
||||
const record = store.get(LOCAL_ID)!;
|
||||
record.setValue(input.path, "redirectPath");
|
||||
});
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Match, Router, withRouter } from "found";
|
||||
import React from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { SetRedirectPathMutation } from "coral-admin/mutations";
|
||||
import { AbilityType, can } from "coral-admin/permissions";
|
||||
import { roleIsAtLeast } from "coral-framework/helpers";
|
||||
import { graphql, MutationProp, withMutation } from "coral-framework/lib/relay";
|
||||
import { MutationProp, withMutation } from "coral-framework/lib/relay";
|
||||
import { withRouteConfig } from "coral-framework/lib/router";
|
||||
import { GQLUSER_ROLE } from "coral-framework/schema";
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { RouteProps } from "found";
|
||||
import React, { Component } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { SetRedirectPathMutation } from "coral-admin/mutations";
|
||||
import { timeout } from "coral-common/utils";
|
||||
import {
|
||||
graphql,
|
||||
MutationProp,
|
||||
withFragmentContainer,
|
||||
withMutation,
|
||||
|
||||
@@ -11,7 +11,7 @@ interface Props {
|
||||
query: PropTypesOf<typeof UserTableContainer>["query"];
|
||||
}
|
||||
|
||||
const Community: FunctionComponent<Props> = props => (
|
||||
const Community: FunctionComponent<Props> = (props) => (
|
||||
<MainLayout className={styles.root} data-testid="community-container">
|
||||
<UserTableContainer query={props.query} />
|
||||
</MainLayout>
|
||||
|
||||
@@ -13,7 +13,7 @@ interface Props {
|
||||
form: FormApi;
|
||||
}
|
||||
|
||||
const CommunityRoute: FunctionComponent<Props> = props => {
|
||||
const CommunityRoute: FunctionComponent<Props> = (props) => {
|
||||
return <Community query={props.data} />;
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import React, { FunctionComponent } from "react";
|
||||
|
||||
import styles from "./EmptyMessage.css";
|
||||
|
||||
const EmptyMessage: FunctionComponent = props => (
|
||||
const EmptyMessage: FunctionComponent = (props) => (
|
||||
<Localized id="community-emptyMessage">
|
||||
<div className={styles.root}>
|
||||
We could not find anyone in your community matching your criteria.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { Ability, can } from "coral-admin/permissions";
|
||||
import { graphql, withFragmentContainer } from "coral-framework/lib/relay";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
|
||||
import { InviteUsersContainer_settings } from "coral-admin/__generated__/InviteUsersContainer_settings.graphql";
|
||||
import { InviteUsersContainer_viewer } from "coral-admin/__generated__/InviteUsersContainer_viewer.graphql";
|
||||
|
||||
@@ -17,7 +17,7 @@ interface Props {
|
||||
onUsernameClicked?: (userID: string) => void;
|
||||
}
|
||||
|
||||
const UserRowContainer: FunctionComponent<Props> = props => {
|
||||
const UserRowContainer: FunctionComponent<Props> = (props) => {
|
||||
const { locales } = useCoralContext();
|
||||
return (
|
||||
<UserRow
|
||||
|
||||
@@ -83,7 +83,7 @@ const UserTable: FunctionComponent<Props> = ({
|
||||
{!props.loading &&
|
||||
settings &&
|
||||
viewer &&
|
||||
props.users.map(u => (
|
||||
props.users.map((u) => (
|
||||
<UserRowContainer
|
||||
key={u.id}
|
||||
user={u}
|
||||
|
||||
@@ -21,9 +21,9 @@ interface Props {
|
||||
relay: RelayPaginationProp;
|
||||
}
|
||||
|
||||
const UserTableContainer: FunctionComponent<Props> = props => {
|
||||
const UserTableContainer: FunctionComponent<Props> = (props) => {
|
||||
const users = props.query
|
||||
? props.query.users.edges.map(edge => edge.node)
|
||||
? props.query.users.edges.map((edge) => edge.node)
|
||||
: [];
|
||||
|
||||
const [loadMore, isLoadingMore] = useLoadMore(props.relay, 10);
|
||||
|
||||
@@ -34,7 +34,7 @@ interface Props {
|
||||
settings: PropTypesOf<typeof InviteUsersContainer>["settings"];
|
||||
}
|
||||
|
||||
const UserTableFilter: FunctionComponent<Props> = props => (
|
||||
const UserTableFilter: FunctionComponent<Props> = (props) => (
|
||||
<Flex justifyContent="space-between" alignItems="flex-end">
|
||||
<Flex itemGutter="double">
|
||||
<FieldSet>
|
||||
@@ -105,7 +105,7 @@ const UserTableFilter: FunctionComponent<Props> = props => (
|
||||
aria-label="Search by role"
|
||||
value={props.roleFilter || ""}
|
||||
className={styles.selectField}
|
||||
onChange={e =>
|
||||
onChange={(e) =>
|
||||
props.onSetRoleFilter((e.target.value as any) || null)
|
||||
}
|
||||
>
|
||||
@@ -148,7 +148,7 @@ const UserTableFilter: FunctionComponent<Props> = props => (
|
||||
aria-label="Search by status"
|
||||
value={props.statusFilter || ""}
|
||||
className={styles.selectField}
|
||||
onChange={e =>
|
||||
onChange={(e) =>
|
||||
props.onSetStatusFilter((e.target.value as any) || null)
|
||||
}
|
||||
>
|
||||
|
||||
@@ -4,11 +4,11 @@ import { LanguageCode, LOCALES_MAP } from "coral-common/helpers/i18n";
|
||||
import { PropTypesOf } from "coral-framework/types";
|
||||
import { Option, SelectField } from "coral-ui/components/v2";
|
||||
|
||||
interface Props extends PropTypesOf<typeof SelectField> {
|
||||
interface Props extends Omit<PropTypesOf<typeof SelectField>, "ref"> {
|
||||
value: LanguageCode;
|
||||
}
|
||||
|
||||
const LocaleField: FunctionComponent<Props> = props => {
|
||||
const LocaleField: FunctionComponent<Props> = (props) => {
|
||||
return (
|
||||
<SelectField {...props}>
|
||||
{Object.keys(LOCALES_MAP).map((lang: LanguageCode) => {
|
||||
|
||||
@@ -9,7 +9,7 @@ interface Props {
|
||||
to: string | LocationDescriptor;
|
||||
}
|
||||
|
||||
const Link: FunctionComponent<Props> = props => (
|
||||
const Link: FunctionComponent<Props> = (props) => (
|
||||
<li className={props.className}>
|
||||
<FoundLink
|
||||
to={props.to}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { FunctionComponent } from "react";
|
||||
|
||||
import { FieldMeta, hasError } from "coral-framework/lib/form/helpers";
|
||||
import { DeepPartial, Omit } from "coral-framework/types";
|
||||
import { DeepPartial } from "coral-framework/types";
|
||||
import HorizontalGutter from "coral-ui/components/HorizontalGutter";
|
||||
import TextField, { TextFieldProps } from "coral-ui/components/v2/TextField";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { FunctionComponent } from "react";
|
||||
|
||||
import { FieldMeta, hasError } from "coral-framework/lib/form/helpers";
|
||||
import { Omit } from "coral-framework/types";
|
||||
|
||||
import { ValidationMessage as UIValidationMessage } from "coral-ui/components/v2";
|
||||
import { ValidationMessageProps } from "coral-ui/components/v2/ValidationMessage";
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user