diff --git a/src/core/client/admin/components/UserHistoryDrawer/BanAction.tsx b/src/core/client/admin/components/UserHistoryDrawer/BanAction.tsx new file mode 100644 index 000000000..60ec6cf3a --- /dev/null +++ b/src/core/client/admin/components/UserHistoryDrawer/BanAction.tsx @@ -0,0 +1,19 @@ +import { Localized } from "fluent-react/compat"; +import React, { FunctionComponent } from "react"; + +export interface BanActionProps { + action: "created" | "removed"; +} + +const BanAction: FunctionComponent = ({ action }) => + action === "created" ? ( + + Banned + + ) : ( + + Ban removed + + ); + +export default BanAction; diff --git a/src/core/client/admin/components/UserHistoryDrawer/SuspensionAction.tsx b/src/core/client/admin/components/UserHistoryDrawer/SuspensionAction.tsx new file mode 100644 index 000000000..6da38318c --- /dev/null +++ b/src/core/client/admin/components/UserHistoryDrawer/SuspensionAction.tsx @@ -0,0 +1,75 @@ +import { Localized } from "fluent-react/compat"; +import React, { FunctionComponent } from "react"; + +import { DURATION_UNIT } from "coral-framework/components"; + +interface From { + start: Date; + finish: Date; +} + +export interface SuspensionActionProps { + action: "created" | "removed" | "ended"; + from: From; +} + +const UNITS = [ + DURATION_UNIT.WEEKS, + DURATION_UNIT.DAYS, + DURATION_UNIT.HOURS, + DURATION_UNIT.MINUTES, + DURATION_UNIT.SECONDS, +]; + +const UNIT_MAP = { + [DURATION_UNIT.SECONDS]: "second", + [DURATION_UNIT.MINUTES]: "minute", + [DURATION_UNIT.HOURS]: "hour", + [DURATION_UNIT.DAYS]: "day", + [DURATION_UNIT.WEEKS]: "week", +}; + +function reduceValue(value: number) { + // Find the largest match for the smallest number. + const unit: keyof typeof UNIT_MAP = + UNITS.find(compare => value >= compare) || DURATION_UNIT.SECONDS; + + return { + value: Math.round((value / unit) * 100) / 100, + unit: UNIT_MAP[unit], + }; +} + +const SuspensionAction: FunctionComponent = ({ + action, + from, +}) => { + if (action === "created") { + const seconds = (from.finish.getTime() - from.start.getTime()) / 1000; + const { value, unit } = reduceValue(seconds); + + return ( + + Suspension, {seconds} seconds + + ); + } else if (action === "removed") { + return ( + + Suspension removed + + ); + } + + return ( + + Suspension ended + + ); +}; + +export default SuspensionAction; diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryTabs.css b/src/core/client/admin/components/UserHistoryDrawer/Tabs.css similarity index 85% rename from src/core/client/admin/components/UserHistoryDrawer/UserHistoryTabs.css rename to src/core/client/admin/components/UserHistoryDrawer/Tabs.css index 1ab501b06..7fb176ef1 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryTabs.css +++ b/src/core/client/admin/components/UserHistoryDrawer/Tabs.css @@ -41,7 +41,7 @@ } .container { - height: calc(100% - 2 * var(--spacing-2)); + height: calc(100% - var(--spacing-2) - var(--spacing-3)); display: flex; flex-direction: column; @@ -51,9 +51,10 @@ overflow: hidden; margin-bottom: var(--spacing-2); - margin-top: var(--spacing-2); + margin-top: var(--spacing-3); } .scrollable { - overflow: auto; + overflow-x: hidden; + overflow-y: auto; } \ No newline at end of file diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryTabs.tsx b/src/core/client/admin/components/UserHistoryDrawer/Tabs.tsx similarity index 51% rename from src/core/client/admin/components/UserHistoryDrawer/UserHistoryTabs.tsx rename to src/core/client/admin/components/UserHistoryDrawer/Tabs.tsx index 06c856d25..1fb5f097e 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryTabs.tsx +++ b/src/core/client/admin/components/UserHistoryDrawer/Tabs.tsx @@ -4,22 +4,23 @@ import React, { FunctionComponent, useCallback, useState } from "react"; import { Icon, Tab, TabBar, TabContent, TabPane } from "coral-ui/components"; -import UserHistoryAllCommentsContainer from "./UserHistoryAllCommentsContainer"; -import UserHistoryRejectedCommentsContainer from "./UserHistoryRejectedCommentsContainer"; +import UserDrawerAccountHistoryQuery from "./UserDrawerAccountHistoryQuery"; +import UserHistoryDrawerAllCommentsQuery from "./UserHistoryDrawerAllCommentsQuery"; +import UserHistoryDrawerRejectedCommentsQuery from "./UserHistoryDrawerRejectedCommentsQuery"; -import styles from "./UserHistoryTabs.css"; +import styles from "./Tabs.css"; -type TabType = "ALL" | "REJECTED"; +type UserTabs = "ALL_COMMENTS" | "REJECTED_COMMENTS" | "ACCOUNT_HISTORY"; interface Props { userID: string; } const UserHistoryTabs: FunctionComponent = ({ userID }) => { - const [currentTab, setCurrentTab] = useState("ALL"); + const [currentTab, setCurrentTab] = useState("ALL_COMMENTS"); const onTabChanged = useCallback( - (tab: TabType) => { + (tab: UserTabs) => { setCurrentTab(tab); }, [setCurrentTab] @@ -33,10 +34,10 @@ const UserHistoryTabs: FunctionComponent = ({ userID }) => { onTabClick={onTabChanged} className={styles.tabBar} > - +
@@ -47,10 +48,10 @@ const UserHistoryTabs: FunctionComponent = ({ userID }) => {
- +
@@ -61,19 +62,40 @@ const UserHistoryTabs: FunctionComponent = ({ userID }) => {
+ +
+ + history + + + Account History + +
+
- +
- +
- +
- + +
+
+
+ +
+
+
diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistory.css b/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistory.css new file mode 100644 index 000000000..f5d851fea --- /dev/null +++ b/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistory.css @@ -0,0 +1,49 @@ +.tableHeader { + border-width: 0px; + border-style: none; + background-color: var(--palette-grey-lightest); +} + +.row:first-child:hover { + border-top: none; +} + +.row:nth-child(even) { + /* NOTE: differs from pallate colors */ + background-color: rgba(242, 242, 242, 0.4); +} + +.row:nth-child(even):hover { + /* NOTE: differs from pallate colors */ + background-color: rgba(242, 242, 242, 0.4); + box-shadow: none; +} + +.row:nth-child(odd):hover { + background-color: transparent; + box-shadow: none; +} + +.date { + min-width: 120px; +} + +.action { + min-width: 200px; + font-weight: 600; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.user { + min-width: 200px; + max-width: 200px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.user > * { + vertical-align: sub; +} diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistory.tsx b/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistory.tsx new file mode 100644 index 000000000..f53a382d5 --- /dev/null +++ b/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistory.tsx @@ -0,0 +1,206 @@ +import { Localized } from "fluent-react/compat"; +import React, { FunctionComponent, useMemo } from "react"; + +import { UserDrawerAccountHistory_user } from "coral-admin/__generated__/UserDrawerAccountHistory_user.graphql"; + +import { useCoralContext } from "coral-framework/lib/bootstrap"; +import { graphql, withFragmentContainer } from "coral-framework/lib/relay"; +import { + CallOut, + HorizontalGutter, + Icon, + Table, + TableBody, + TableCell, + TableHead, + TableRow, +} from "coral-ui/components"; + +import BanAction, { BanActionProps } from "./BanAction"; +import SuspensionAction, { SuspensionActionProps } from "./SuspensionAction"; + +import styles from "./UserDrawerAccountHistory.css"; + +interface Props { + user: UserDrawerAccountHistory_user; +} + +interface From { + start: any; + finish: any; +} + +interface SuspensionHistoryRecord { + kind: "suspension"; + action: SuspensionActionProps; + date: Date; + takenBy: React.ReactNode; +} + +interface BanHistoryRecord { + kind: "ban"; + action: BanActionProps; + date: Date; + takenBy: React.ReactNode; +} + +type HistoryRecord = SuspensionHistoryRecord | BanHistoryRecord; + +const UserDrawerAccountHistory: FunctionComponent = ({ user }) => { + const system = ( + computer} + > + + computer System + + + ); + const { locales } = useCoralContext(); + const combinedHistory = useMemo(() => { + // Collect all the different types of history items. + const history: HistoryRecord[] = []; + + // Merge in all the suspension history items. + user.status.suspension.history.forEach(record => { + const from: From = { + start: new Date(record.from.start), + finish: new Date(record.from.finish), + }; + + if (record.modifiedAt) { + // Merge in the suspension removals. + history.push({ + kind: "suspension", + action: { + action: "removed", + from, + }, + date: new Date(record.modifiedAt), + takenBy: record.modifiedBy ? record.modifiedBy.username : system, + }); + } else if (!record.active) { + // Merge in the suspension expiries. + history.push({ + kind: "suspension", + action: { + action: "ended", + from, + }, + date: from.finish, + takenBy: system, + }); + } + + // Merge in the suspension created. + history.push({ + kind: "suspension", + action: { + action: "created", + from, + }, + date: new Date(record.createdAt), + takenBy: record.createdBy ? record.createdBy.username : system, + }); + }); + + // Merge in all the ban status history items. + user.status.ban.history.forEach(record => { + history.push({ + kind: "ban", + action: { + action: record.active ? "created" : "removed", + }, + date: new Date(record.createdAt), + takenBy: record.createdBy ? record.createdBy.username : system, + }); + }); + + // Sort the history so that it's in the right order. + return history.sort((a, b) => b.date.getTime() - a.date.getTime()); + }, [user]); + const formatter = new Intl.DateTimeFormat(locales, { + year: "numeric", + month: "long", + day: "numeric", + }); + + if (combinedHistory.length === 0) { + return ( + + + No actions have been taken on this account + + + ); + } + + return ( + + + + + Date + Action + Taken By + + + + {combinedHistory.map((history, index) => ( + + + {formatter.format(history.date)} + + + {history.kind === "suspension" ? ( + + ) : ( + + )} + + {history.takenBy} + + ))} + +
+
+ ); +}; + +const enhanced = withFragmentContainer({ + user: graphql` + fragment UserDrawerAccountHistory_user on User { + status { + ban { + history { + active + createdBy { + username + } + createdAt + } + } + suspension { + history { + active + from { + start + finish + } + createdBy { + username + } + modifiedAt + modifiedBy { + username + } + createdAt + } + } + } + } + `, +})(UserDrawerAccountHistory); + +export default enhanced; diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistoryQuery.css b/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistoryQuery.css new file mode 100644 index 000000000..d488ff572 --- /dev/null +++ b/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistoryQuery.css @@ -0,0 +1,10 @@ +.spinner { + text-align: center; +} + +.callout { + width: 100%; + font-family: var(--font-family-sans-serif); + align-content: center; + text-align: center; +} \ No newline at end of file diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistoryQuery.tsx b/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistoryQuery.tsx new file mode 100644 index 000000000..e457a812b --- /dev/null +++ b/src/core/client/admin/components/UserHistoryDrawer/UserDrawerAccountHistoryQuery.tsx @@ -0,0 +1,67 @@ +import { graphql, QueryRenderer } from "coral-framework/lib/relay"; +import { Localized } from "fluent-react/compat"; +import React, { FunctionComponent } from "react"; +import { ReadyState } from "react-relay"; + +import { UserDrawerAccountHistoryQuery as QueryTypes } from "coral-admin/__generated__/UserDrawerAccountHistoryQuery.graphql"; + +import { CallOut, Spinner } from "coral-ui/components"; + +import UserDrawerAccountHistory from "./UserDrawerAccountHistory"; + +import styles from "./UserDrawerAccountHistoryQuery.css"; + +interface Props { + userID: string; +} + +const UserDrawerAccountHistoryQuery: FunctionComponent = ({ + userID, +}) => { + return ( + + query={graphql` + query UserDrawerAccountHistoryQuery($userID: ID!) { + user(id: $userID) { + ...UserDrawerAccountHistory_user + } + } + `} + variables={{ userID }} + cacheConfig={{ force: true }} + render={({ error, props }: ReadyState) => { + if (error) { + return ( +
+ {error.message} +
+ ); + } + + if (!props) { + return ( +
+ +
+ ); + } + + if (!props.user) { + return ( +
+ + + User not found. + + +
+ ); + } + + return ; + }} + /> + ); +}; + +export default UserDrawerAccountHistoryQuery; diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryAllComments.css b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllComments.css similarity index 100% rename from src/core/client/admin/components/UserHistoryDrawer/UserHistoryAllComments.css rename to src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllComments.css diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryAllComments.tsx b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllComments.tsx similarity index 70% rename from src/core/client/admin/components/UserHistoryDrawer/UserHistoryAllComments.tsx rename to src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllComments.tsx index 55e8d1573..475171f07 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryAllComments.tsx +++ b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllComments.tsx @@ -6,24 +6,24 @@ import { Localized } from "fluent-react/compat"; import React, { FunctionComponent, useCallback } from "react"; import { graphql, RelayPaginationProp } from "react-relay"; +import { UserHistoryDrawerAllComments_settings } from "coral-admin/__generated__/UserHistoryDrawerAllComments_settings.graphql"; +import { UserHistoryDrawerAllComments_user } from "coral-admin/__generated__/UserHistoryDrawerAllComments_user.graphql"; +import { UserHistoryDrawerAllComments_viewer } from "coral-admin/__generated__/UserHistoryDrawerAllComments_viewer.graphql"; +import { UserHistoryDrawerAllCommentsPaginationQueryVariables } from "coral-admin/__generated__/UserHistoryDrawerAllCommentsPaginationQuery.graphql"; + import { ModerateCardContainer } from "coral-admin/components/ModerateCard"; import { Button, CallOut, Typography } from "coral-ui/components"; -import { UserHistoryAllComments_settings } from "coral-admin/__generated__/UserHistoryAllComments_settings.graphql"; -import { UserHistoryAllComments_user } from "coral-admin/__generated__/UserHistoryAllComments_user.graphql"; -import { UserHistoryAllComments_viewer } from "coral-admin/__generated__/UserHistoryAllComments_viewer.graphql"; -import { UserHistoryAllCommentsPaginationQueryVariables } from "coral-admin/__generated__/UserHistoryAllCommentsPaginationQuery.graphql"; - -import styles from "./UserHistoryAllComments.css"; +import styles from "./UserHistoryDrawerAllComments.css"; interface Props { - user: UserHistoryAllComments_user; - viewer: UserHistoryAllComments_viewer; - settings: UserHistoryAllComments_settings; + user: UserHistoryDrawerAllComments_user; + viewer: UserHistoryDrawerAllComments_viewer; + settings: UserHistoryDrawerAllComments_settings; relay: RelayPaginationProp; } -const UserHistoryAllComments: FunctionComponent = ({ +const UserHistoryDrawerAllComments: FunctionComponent = ({ user, viewer, settings, @@ -85,33 +85,33 @@ const UserHistoryAllComments: FunctionComponent = ({ ); }; -type FragmentVariables = UserHistoryAllCommentsPaginationQueryVariables; +type FragmentVariables = UserHistoryDrawerAllCommentsPaginationQueryVariables; const enhanced = withPaginationContainer< Props, - UserHistoryAllCommentsPaginationQueryVariables, + UserHistoryDrawerAllCommentsPaginationQueryVariables, FragmentVariables >( { viewer: graphql` - fragment UserHistoryAllComments_viewer on User { + fragment UserHistoryDrawerAllComments_viewer on User { ...ModerateCardContainer_viewer } `, settings: graphql` - fragment UserHistoryAllComments_settings on Settings { + fragment UserHistoryDrawerAllComments_settings on Settings { ...ModerateCardContainer_settings } `, user: graphql` - fragment UserHistoryAllComments_user on User + fragment UserHistoryDrawerAllComments_user on User @argumentDefinitions( count: { type: "Int!", defaultValue: 5 } cursor: { type: "Cursor" } ) { username allComments(first: $count, after: $cursor) - @connection(key: "UserHistoryAll_allComments") { + @connection(key: "UserHistoryDrawer_allComments") { edges { node { id @@ -141,18 +141,18 @@ const enhanced = withPaginationContainer< }; }, query: graphql` - query UserHistoryAllCommentsPaginationQuery( + query UserHistoryDrawerAllCommentsPaginationQuery( $userID: ID! $count: Int! $cursor: Cursor ) { user(id: $userID) { - ...UserHistoryAllComments_user + ...UserHistoryDrawerAllComments_user @arguments(count: $count, cursor: $cursor) } } `, } -)(UserHistoryAllComments); +)(UserHistoryDrawerAllComments); export default enhanced; diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryAllCommentsContainer.css b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllCommentsQuery.css similarity index 100% rename from src/core/client/admin/components/UserHistoryDrawer/UserHistoryAllCommentsContainer.css rename to src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllCommentsQuery.css diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryAllCommentsContainer.tsx b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllCommentsQuery.tsx similarity index 67% rename from src/core/client/admin/components/UserHistoryDrawer/UserHistoryAllCommentsContainer.tsx rename to src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllCommentsQuery.tsx index 1fafad613..7a2d7c4d2 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryAllCommentsContainer.tsx +++ b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllCommentsQuery.tsx @@ -4,32 +4,32 @@ import { ReadyState } from "react-relay"; import { CallOut, Spinner } from "coral-ui/components"; -import { UserHistoryAllCommentsContainerQuery as QueryTypes } from "coral-admin/__generated__/UserHistoryAllCommentsContainerQuery.graphql"; +import { UserHistoryDrawerAllCommentsQuery as QueryTypes } from "coral-admin/__generated__/UserHistoryDrawerAllCommentsQuery.graphql"; import { graphql, QueryRenderer } from "coral-framework/lib/relay"; -import UserHistoryAllComments from "./UserHistoryAllComments"; +import UserHistoryDrawerAllComments from "./UserHistoryDrawerAllComments"; -import styles from "./UserHistoryAllCommentsContainer.css"; +import styles from "./UserHistoryDrawerAllCommentsQuery.css"; interface Props { userID: string; } -const UserHistoryAllCommentsContainer: FunctionComponent = ({ +const UserHistoryDrawerAllCommentsQuery: FunctionComponent = ({ userID, }) => { return ( query={graphql` - query UserHistoryAllCommentsContainerQuery($userID: ID!) { + query UserHistoryDrawerAllCommentsQuery($userID: ID!) { user(id: $userID) { - ...UserHistoryAllComments_user + ...UserHistoryDrawerAllComments_user } viewer { - ...UserHistoryAllComments_viewer + ...UserHistoryDrawerAllComments_viewer } settings { - ...UserHistoryAllComments_settings + ...UserHistoryDrawerAllComments_settings } } `} @@ -57,7 +57,7 @@ const UserHistoryAllCommentsContainer: FunctionComponent = ({ } return ( - = ({ ); }; -export default UserHistoryAllCommentsContainer; +export default UserHistoryDrawerAllCommentsQuery; diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerQuery.css b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerQuery.css index 315b69b61..074b3a082 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerQuery.css +++ b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerQuery.css @@ -99,18 +99,23 @@ hr { } .userStatusLabel { - margin-right: var(--spacing-1); - margin-bottom: 2px; + display: inline-block; - line-height: calc(36em / 24); + margin-right: var(--spacing-1); + + font-family: var(--font-family-sans-serif); + font-style: normal; + font-weight: 600; + font-size: 16px; + line-height: 14px; } .userStatusChange { + display: inline-block; border-style: solid; border-color: var(--palette-grey-lighter); border-width: 1px; border-radius: 2px; - padding-left: var(--spacing-2); padding-right: var(--spacing-1); } \ No newline at end of file diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerQuery.tsx b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerQuery.tsx index 7e699ed9b..182735322 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerQuery.tsx +++ b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerQuery.tsx @@ -1,10 +1,12 @@ -import { graphql, QueryRenderer } from "coral-framework/lib/relay"; import { Localized } from "fluent-react/compat"; import React, { FunctionComponent } from "react"; import { ReadyState } from "react-relay"; +import { UserHistoryDrawerQuery as QueryTypes } from "coral-admin/__generated__/UserHistoryDrawerQuery.graphql"; import { UserStatusChangeContainer } from "coral-admin/components/UserStatus"; import { CopyButton } from "coral-framework/components"; +import { useCoralContext } from "coral-framework/lib/bootstrap"; +import { graphql, QueryRenderer } from "coral-framework/lib/relay"; import { Button, CallOut, @@ -14,9 +16,7 @@ import { Typography, } from "coral-ui/components"; -import { UserHistoryDrawerQuery as QueryTypes } from "coral-admin/__generated__/UserHistoryDrawerQuery.graphql"; - -import UserHistoryTabs from "./UserHistoryTabs"; +import Tabs from "./Tabs"; import styles from "./UserHistoryDrawerQuery.css"; @@ -31,6 +31,13 @@ const UserHistoryDrawerQuery: FunctionComponent = ({ userID, onClose, }) => { + const { locales } = useCoralContext(); + const formatter = new Intl.DateTimeFormat(locales, { + month: "long", + day: "numeric", + year: "numeric", + }); + return ( query={graphql` @@ -78,20 +85,10 @@ const UserHistoryDrawerQuery: FunctionComponent = ({ {user.username}
- -
- - - - Status: - - - -
-
- -
-
+
Status:
+
+ +
@@ -130,11 +127,7 @@ const UserHistoryDrawerQuery: FunctionComponent = ({ - {new Date(user.createdAt).toLocaleDateString("en-us", { - month: "long", - day: "numeric", - year: "numeric", - })} + {formatter.format(new Date(user.createdAt))} @@ -162,7 +155,7 @@ const UserHistoryDrawerQuery: FunctionComponent = ({

- +
); diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryRejectedComments.css b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedComments.css similarity index 100% rename from src/core/client/admin/components/UserHistoryDrawer/UserHistoryRejectedComments.css rename to src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedComments.css diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryRejectedComments.tsx b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedComments.tsx similarity index 69% rename from src/core/client/admin/components/UserHistoryDrawer/UserHistoryRejectedComments.tsx rename to src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedComments.tsx index acc77da78..7dbc219fe 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryRejectedComments.tsx +++ b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedComments.tsx @@ -6,24 +6,24 @@ import { Localized } from "fluent-react/compat"; import React, { FunctionComponent, useCallback } from "react"; import { graphql, RelayPaginationProp } from "react-relay"; +import { UserHistoryDrawerRejectedComments_settings } from "coral-admin/__generated__/UserHistoryDrawerRejectedComments_settings.graphql"; +import { UserHistoryDrawerRejectedComments_user } from "coral-admin/__generated__/UserHistoryDrawerRejectedComments_user.graphql"; +import { UserHistoryDrawerRejectedComments_viewer } from "coral-admin/__generated__/UserHistoryDrawerRejectedComments_viewer.graphql"; +import { UserHistoryDrawerRejectedCommentsPaginationQueryVariables } from "coral-admin/__generated__/UserHistoryDrawerRejectedCommentsPaginationQuery.graphql"; + import { ModerateCardContainer } from "coral-admin/components/ModerateCard"; import { Button, CallOut, Typography } from "coral-ui/components"; -import { UserHistoryRejectedComments_settings } from "coral-admin/__generated__/UserHistoryRejectedComments_settings.graphql"; -import { UserHistoryRejectedComments_user } from "coral-admin/__generated__/UserHistoryRejectedComments_user.graphql"; -import { UserHistoryRejectedComments_viewer } from "coral-admin/__generated__/UserHistoryRejectedComments_viewer.graphql"; -import { UserHistoryRejectedCommentsPaginationQueryVariables } from "coral-admin/__generated__/UserHistoryRejectedCommentsPaginationQuery.graphql"; - -import styles from "./UserHistoryRejectedComments.css"; +import styles from "./UserHistoryDrawerRejectedComments.css"; interface Props { - user: UserHistoryRejectedComments_user; - viewer: UserHistoryRejectedComments_viewer; - settings: UserHistoryRejectedComments_settings; + user: UserHistoryDrawerRejectedComments_user; + viewer: UserHistoryDrawerRejectedComments_viewer; + settings: UserHistoryDrawerRejectedComments_settings; relay: RelayPaginationProp; } -const UserHistoryRejectedComments: FunctionComponent = ({ +const UserHistoryDrawerRejectedComments: FunctionComponent = ({ user, viewer, settings, @@ -87,33 +87,33 @@ const UserHistoryRejectedComments: FunctionComponent = ({ ); }; -type FragmentVariables = UserHistoryRejectedCommentsPaginationQueryVariables; +type FragmentVariables = UserHistoryDrawerRejectedCommentsPaginationQueryVariables; const enhanced = withPaginationContainer< Props, - UserHistoryRejectedCommentsPaginationQueryVariables, + UserHistoryDrawerRejectedCommentsPaginationQueryVariables, FragmentVariables >( { viewer: graphql` - fragment UserHistoryRejectedComments_viewer on User { + fragment UserHistoryDrawerRejectedComments_viewer on User { ...ModerateCardContainer_viewer } `, settings: graphql` - fragment UserHistoryRejectedComments_settings on Settings { + fragment UserHistoryDrawerRejectedComments_settings on Settings { ...ModerateCardContainer_settings } `, user: graphql` - fragment UserHistoryRejectedComments_user on User + fragment UserHistoryDrawerRejectedComments_user on User @argumentDefinitions( count: { type: "Int!", defaultValue: 5 } cursor: { type: "Cursor" } ) { username rejectedComments(first: $count, after: $cursor) - @connection(key: "UserHistoryRejected_rejectedComments") { + @connection(key: "UserHistoryDrawer_rejectedComments") { edges { node { id @@ -143,18 +143,18 @@ const enhanced = withPaginationContainer< }; }, query: graphql` - query UserHistoryRejectedCommentsPaginationQuery( + query UserHistoryDrawerRejectedCommentsPaginationQuery( $userID: ID! $count: Int! $cursor: Cursor ) { user(id: $userID) { - ...UserHistoryRejectedComments_user + ...UserHistoryDrawerRejectedComments_user @arguments(count: $count, cursor: $cursor) } } `, } -)(UserHistoryRejectedComments); +)(UserHistoryDrawerRejectedComments); export default enhanced; diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryRejectedCommentsContainer.css b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedCommentsQuery.css similarity index 100% rename from src/core/client/admin/components/UserHistoryDrawer/UserHistoryRejectedCommentsContainer.css rename to src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedCommentsQuery.css diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryRejectedCommentsContainer.tsx b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedCommentsQuery.tsx similarity index 65% rename from src/core/client/admin/components/UserHistoryDrawer/UserHistoryRejectedCommentsContainer.tsx rename to src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedCommentsQuery.tsx index cd351e6f4..3ed290c62 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryRejectedCommentsContainer.tsx +++ b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedCommentsQuery.tsx @@ -2,34 +2,34 @@ import { Localized } from "fluent-react/compat"; import React, { FunctionComponent } from "react"; import { ReadyState } from "react-relay"; +import { UserHistoryDrawerRejectedCommentsQuery as QueryTypes } from "coral-admin/__generated__/UserHistoryDrawerRejectedCommentsQuery.graphql"; + +import { graphql, QueryRenderer } from "coral-framework/lib/relay"; import { CallOut, Spinner } from "coral-ui/components"; -import { UserHistoryRejectedCommentsContainerQuery as QueryTypes } from "coral-admin/__generated__/UserHistoryRejectedCommentsContainerQuery.graphql"; -import { graphql, QueryRenderer } from "coral-framework/lib/relay"; +import UserHistoryDrawerRejectedComments from "./UserHistoryDrawerRejectedComments"; -import UserHistoryRejectedComments from "./UserHistoryRejectedComments"; - -import styles from "./UserHistoryRejectedCommentsContainer.css"; +import styles from "./UserHistoryDrawerRejectedCommentsQuery.css"; interface Props { userID: string; } -const UserHistoryRejectedCommentsContainer: FunctionComponent = ({ +const UserHistoryDrawerRejectedCommentsQuery: FunctionComponent = ({ userID, }) => { return ( query={graphql` - query UserHistoryRejectedCommentsContainerQuery($userID: ID!) { + query UserHistoryDrawerRejectedCommentsQuery($userID: ID!) { user(id: $userID) { - ...UserHistoryRejectedComments_user + ...UserHistoryDrawerRejectedComments_user } viewer { - ...UserHistoryRejectedComments_viewer + ...UserHistoryDrawerRejectedComments_viewer } settings { - ...UserHistoryRejectedComments_settings + ...UserHistoryDrawerRejectedComments_settings } } `} @@ -57,7 +57,7 @@ const UserHistoryRejectedCommentsContainer: FunctionComponent = ({ } return ( - = ({ ); }; -export default UserHistoryRejectedCommentsContainer; +export default UserHistoryDrawerRejectedCommentsQuery; diff --git a/src/core/client/admin/components/UserStatus/UserStatusChangeContainer.tsx b/src/core/client/admin/components/UserStatus/UserStatusChangeContainer.tsx index 96acf8dfe..3f27c323f 100644 --- a/src/core/client/admin/components/UserStatus/UserStatusChangeContainer.tsx +++ b/src/core/client/admin/components/UserStatus/UserStatusChangeContainer.tsx @@ -22,7 +22,7 @@ interface Props { const UserStatusChangeContainer: FunctionComponent = ({ user, - fullWidth = true, + fullWidth = false, }) => { const banUser = useMutation(BanUserMutation); const removeUserBan = useMutation(RemoveUserBanMutation); diff --git a/src/core/client/admin/routes/Community/UserRow.css b/src/core/client/admin/routes/Community/UserRow.css index e2c9ef888..2ee8f0eb1 100644 --- a/src/core/client/admin/routes/Community/UserRow.css +++ b/src/core/client/admin/routes/Community/UserRow.css @@ -27,5 +27,5 @@ font-family: var(--font-family-sans-serif); font-weight: var(--font-weight-regular); font-size: calc(14rem / var(--rem-base)); - line-height: calc(14em / 14); + line-height: calc(16em / 14); } diff --git a/src/core/client/admin/routes/Community/UserRow.tsx b/src/core/client/admin/routes/Community/UserRow.tsx index b8cbbf0ee..a7c6bb3a9 100644 --- a/src/core/client/admin/routes/Community/UserRow.tsx +++ b/src/core/client/admin/routes/Community/UserRow.tsx @@ -53,7 +53,7 @@ const UserRow: FunctionComponent = ({ - + ); diff --git a/src/core/client/admin/test/components/UserHistoryDrawer/UserHistoryDrawer.spec.tsx b/src/core/client/admin/test/components/UserHistoryDrawer/UserHistoryDrawer.spec.tsx index b1da7f59e..5fdf7869d 100644 --- a/src/core/client/admin/test/components/UserHistoryDrawer/UserHistoryDrawer.spec.tsx +++ b/src/core/client/admin/test/components/UserHistoryDrawer/UserHistoryDrawer.spec.tsx @@ -32,7 +32,6 @@ Notes: */ /* - import { createSettings, createStory, diff --git a/src/locales/en-US/admin.ftl b/src/locales/en-US/admin.ftl index 573d1daa6..d33c535cd 100644 --- a/src/locales/en-US/admin.ftl +++ b/src/locales/en-US/admin.ftl @@ -436,12 +436,53 @@ moderate-user-drawer-member-id = .title = Member ID moderate-user-drawer-tab-all-comments = All Comments moderate-user-drawer-tab-rejected-comments = Rejected +moderate-user-drawer-tab-account-history = Account History moderate-user-drawer-load-more = Load More moderate-user-drawer-all-no-comments = {$username} has not submitted any comments. moderate-user-drawer-rejected-no-comments = {$username} does not have any rejected comments. moderate-user-drawer-user-not-found = User not found. moderate-user-drawer-status-label = Status: +moderate-user-drawer-account-history-system = computer System +moderate-user-drawer-account-history-suspension-ended = Suspension ended +moderate-user-drawer-account-history-suspension-removed = Suspension removed +moderate-user-drawer-account-history-banned = Banned +moderate-user-drawer-account-history-ban-removed = Ban removed +moderate-user-drawer-account-history-no-history = No actions have been taken on this account + +moderate-user-drawer-suspension = + Suspension, { $value } { $unit -> + [second] { $value -> + [1] second + *[other] seconds + } + [minute] { $value -> + [1] minute + *[other] minutes + } + [hour] { $value -> + [1] hour + *[other] hours + } + [day] { $value -> + [1] day + *[other] days + } + [week] { $value -> + [1] week + *[other] weeks + } + [month] { $value -> + [1] month + *[other] months + } + [year] { $value -> + [1] year + *[other] years + } + *[other] unknown unit + } + ## Create Username createUsername-createUsernameHeader = Create Username