Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CORL-296]7 view conversation rejection reasons #4405

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
import { RemoveIcon, SvgIcon } from "coral-ui/components/icons";
import {
Button,
ClickOutside,
Dropdown,
Flex,
HorizontalGutter,
Popover,
Timestamp,
} from "coral-ui/components/v2";

Expand All @@ -32,6 +35,8 @@
import { Circle, Line } from "../Timeline";
import ConversationModalRepliesQuery from "./ConversationModalRepliesQuery";

import { RejectCommentReasonInput } from "coral-stream/__generated__/RejectCommentMutation.graphql";
import ModerationReason from "../ModerationReason/ModerationReason";
import styles from "./ConversationModalCommentContainer.css";

interface Props {
Expand All @@ -52,10 +57,11 @@
const rejectComment = useMutation(RejectCommentMutation);
const { match } = useRouter();
const { storyID, siteID, section } = parseModerationOptions(match);
const [{ moderationQueueSort }] =
const [{ moderationQueueSort, dsaFeaturesEnabled }] =
useLocal<ConversationModalCommentContainerLocal>(graphql`
fragment ConversationModalCommentContainerLocal on Local {
moderationQueueSort
dsaFeaturesEnabled
}
`);
const commentAuthorClick = useCallback(() => {
Expand All @@ -72,28 +78,32 @@
const onShowReplies = useCallback(() => {
setShowReplies(true);
}, []);
const onRejectComment = useCallback(async () => {
if (!comment.revision) {
return;
}
await rejectComment({
commentID: comment.id,
commentRevisionID: comment.revision.id,
const onRejectComment = useCallback(
async (reason?: RejectCommentReasonInput) => {
if (!comment.revision) {
return;
}
await rejectComment({
commentID: comment.id,
commentRevisionID: comment.revision.id,
storyID,
siteID,
section,
orderBy: moderationQueueSort,
reason,
});
},
[

Check warning on line 96 in client/src/core/client/admin/components/ConversationModal/ConversationModalCommentContainer.tsx

View workflow job for this annotation

GitHub Actions / Build and Test

React Hook useCallback has an unnecessary dependency: 'match'. Either exclude it or remove the dependency array
comment.id,
comment.revision,
match,
moderationQueueSort,
rejectComment,
storyID,
siteID,
section,
orderBy: moderationQueueSort,
});
}, [
comment.id,
comment.revision,
match,
moderationQueueSort,
rejectComment,
storyID,
siteID,
section,
]);
]
);
const rejectButtonOptions = useMemo((): {
localization: string;
variant: "regular" | "outlined";
Expand Down Expand Up @@ -170,24 +180,54 @@
</Flex>
</Flex>
<Flex>
<Localized
id={rejectButtonOptions.localization}
attrs={{ "aria-label": true }}
elems={{ icon: <SvgIcon size="xs" Icon={RemoveIcon} /> }}
<Popover
id={`reject-reason-${comment.id}`}
modifiers={{
arrow: { enabled: false },
offset: { offset: "0, 4" },
}}
placement="bottom-start"
body={({ toggleVisibility, visible }) => (
<ClickOutside onClickOutside={toggleVisibility}>
<Dropdown>
<ModerationReason
id={comment.id}
onCancel={toggleVisibility}
onReason={(reason) => {
void onRejectComment(reason);
toggleVisibility();
}}
/>
</Dropdown>
</ClickOutside>
)}
>
<Button
className={styles.rejectButton}
color="alert"
variant={rejectButtonOptions.variant}
iconLeft
disabled={rejectButtonOptions.disabled}
onClick={onRejectComment}
aria-label={rejectButtonOptions.ariaLabel}
>
<SvgIcon size="xs" Icon={RemoveIcon} />
{rejectButtonOptions.text}
</Button>
</Localized>
{({ toggleVisibility, ref }) => (
<Localized
id={rejectButtonOptions.localization}
attrs={{ "aria-label": true }}
elems={{ icon: <SvgIcon size="xs" Icon={RemoveIcon} /> }}
>
<Button
ref={ref}
className={styles.rejectButton}
color="alert"
variant={rejectButtonOptions.variant}
iconLeft
disabled={rejectButtonOptions.disabled}
onClick={
dsaFeaturesEnabled
? toggleVisibility
: () => onRejectComment()
}
aria-label={rejectButtonOptions.ariaLabel}
>
<SvgIcon size="xs" Icon={RemoveIcon} />
{rejectButtonOptions.text}
</Button>
</Localized>
)}
</Popover>
</Flex>
</Flex>
</HorizontalGutter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,6 @@ $moderateCardLinkTextColor: $colors-teal-700;
padding-bottom: var(--spacing-1);
}

.moderationReasonDropdown {
opacity: 1;
}

.moderationReasonCard {
padding: 0;
margin: 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,12 @@ const ModerateCard: FunctionComponent<Props> = ({
body={({ toggleVisibility, visible }) => {
return (
<ClickOutside onClickOutside={toggleVisibility}>
<Dropdown className={styles.moderationReasonDropdown}>
<Dropdown>
<ModerationReason
onReason={onReason}
onReason={(reason) => {
onReason(reason);
toggleVisibility();
}}
onCancel={toggleVisibility}
id={id}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const DetailedExplanation: FunctionComponent<Props> = ({
name={code}
key={code}
checked
readOnly
>
{unsnake(code)}
</RadioButton>
Expand Down
12 changes: 10 additions & 2 deletions server/src/core/server/services/users/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { retrieveTenant } from "coral-server/models/tenant";
import {
GQLCOMMENT_STATUS,
GQLDSAReportStatus,
GQLREJECTION_REASON_CODE,
GQLRejectionReason,
} from "coral-server/graph/schema/__generated__/types";

import { moderate } from "../comments/moderation";
Expand Down Expand Up @@ -131,7 +133,8 @@ async function moderateComments(
filter: FilterQuery<Comment>,
targetStatus: GQLCOMMENT_STATUS,
now: Date,
isArchived = false
isArchived = false,
rejectionReason?: GQLRejectionReason
) {
const tenant = await retrieveTenant(mongo, tenantID);
if (!tenant) {
Expand Down Expand Up @@ -169,6 +172,7 @@ async function moderateComments(
commentRevisionID: getLatestRevision(comment).id,
moderatorID: null,
status: targetStatus,
rejectionReason,
},
now,
isArchived,
Expand Down Expand Up @@ -309,7 +313,11 @@ async function deleteUserComments(
},
GQLCOMMENT_STATUS.REJECTED,
now,
isArchived
isArchived,
{
code: GQLREJECTION_REASON_CODE.OTHER,
detailedExplanation: "User account deleted",
Copy link
Contributor

@nick-funk nick-funk Nov 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can translate this using the following:

import { I18n, translate } from "coral-server/services/i18n";
...

const text = "User account deleted";
const key = "common-userDeletion-userAccountDeleted";
const args = {};

const bundle = this.i18n.getBundle(tenant.locale);
const result = translate(bundle, text, key, args);

Then the translations for this can be specified in common.ftl under server/src/core/server/lcoales/en-US.

}
);

const collection =
Expand Down
Loading