Skip to content

Commit

Permalink
add method of redress to DSA tenant settings
Browse files Browse the repository at this point in the history
  • Loading branch information
nick-funk committed Nov 14, 2023
1 parent d0cbc39 commit 6a2a586
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ import { Localized } from "@fluent/react/compat";
import React, { FunctionComponent } from "react";
import { graphql } from "react-relay";

import { FieldSet, FormField, HelperText, Label } from "coral-ui/components/v2";

import ConfigBox from "../../ConfigBox";
import Header from "../../Header";
import ConfigBoxWithToggleField from "../Auth/ConfigBoxWithToggleField";
import OnOffField from "../../OnOffField";
import DSAMethodOfRedressOptions from "./DSAMethodOfRedressOptions";

// eslint-disable-next-line no-unused-expressions
graphql`
fragment DSAConfigContainer_formValues on Settings {
dsa {
enabled
methodOfRedress
}
}
`;
Expand All @@ -20,17 +25,37 @@ interface Props {

export const DSAConfigContainer: FunctionComponent<Props> = ({ disabled }) => {
return (
<ConfigBoxWithToggleField
<ConfigBox
data-testid="configure-general-dsaConfig"
title={
<Localized id="configure-general-dsaConfig-title">
<Header container="h2">DSA Features (TODO)</Header>
<Header container="h2">Digital services act</Header>
</Localized>
}
name="dsa.enabled"
disabled={disabled}
>
{(disabledInside) => <>TODO</>}
</ConfigBoxWithToggleField>
<FormField container={<FieldSet />}>
<Localized id="configure-general-dsaConfig-reportingAndModerationExperience">
<Label component="legend">
DSA reporting and moderation experience
</Label>
</Localized>
<OnOffField name="dsa.enabled" disabled={disabled} />
</FormField>

<FormField container={<FieldSet />}>
<Localized id="configure-general-dsaConfig-methodOfRedress">
<Label component="legend">Select your method of redress</Label>
</Localized>
<Localized id="configure-general-dsaConfig-methodOfRedress-explanation">
<HelperText>
Let users know if and how they can appeal a moderation decision
</HelperText>
</Localized>
<DSAMethodOfRedressOptions
name="dsa.methodOfRedress"
disabled={disabled}
/>
</FormField>
</ConfigBox>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { Localized } from "@fluent/react/compat";
import React, { FunctionComponent } from "react";
import { Field } from "react-final-form";

import { Validator } from "coral-framework/lib/validation";
import { RadioButton } from "coral-ui/components/v2";

interface Props {
validate?: Validator;
name: string;
disabled: boolean;
format?: (value: any, name: string) => any;
testIDs?: {
on: string;
off: string;
};
className?: string;
}

export enum DSAMethodOfRedress {
None = "NONE",
Email = "EMAIL",
URL = "URL",
}

export const parseVal = (v: any, name: string) => {
if (v === DSAMethodOfRedress.None) {
return DSAMethodOfRedress.None;
}
if (v === DSAMethodOfRedress.Email) {
return DSAMethodOfRedress.Email;
}
if (v === DSAMethodOfRedress.URL) {
return DSAMethodOfRedress.URL;
}

return DSAMethodOfRedress.None;
};

export const format = (v: string, name: string) => {
return v;
};

const DSAMethodOfRedressOptions: FunctionComponent<Props> = ({
name,
disabled,
className,
}) => (
<div className={className}>
<Field
name={name}
type="radio"
value={DSAMethodOfRedress.None}
parse={parseVal}
format={format}
>
{({ input }) => (
<RadioButton {...input} id={`${input.name}-none`} disabled={disabled}>
<Localized id="configure-general-dsaConfig-methodOfRedress-none">
<span>None</span>
</Localized>
</RadioButton>
)}
</Field>
<Field
name={name}
type="radio"
value={DSAMethodOfRedress.Email}
parse={parseVal}
format={format}
>
{({ input }) => (
<RadioButton {...input} id={`${input.name}-email`} disabled={disabled}>
<Localized id="configure-general-dsaConfig-methodOfRedress-email">
<span>Email</span>
</Localized>
</RadioButton>
)}
</Field>
<Field
name={name}
type="radio"
parse={parseVal}
value={DSAMethodOfRedress.URL}
format={format}
>
{({ input }) => {
return (
<RadioButton {...input} id={`${input.name}-url`} disabled={disabled}>
<Localized id="configure-general-dsaConfig-methodOfRedress-url">
<span>URL</span>
</Localized>
</RadioButton>
);
}}
</Field>
</div>
);

export default DSAMethodOfRedressOptions;
2 changes: 2 additions & 0 deletions client/src/core/client/admin/test/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
GQLCOMMENT_STATUS,
GQLCommentModerationAction,
GQLCommentsConnection,
GQLDSA_METHOD_OF_REDRESS,
GQLDSAReport,
GQLDSAReportDecisionLegality,
GQLDSAReportStatus,
Expand Down Expand Up @@ -235,6 +236,7 @@ export const settings = createFixture<GQLSettings>({
},
dsa: {
enabled: false,
methodOfRedress: GQLDSA_METHOD_OF_REDRESS.NONE,
},
});

Expand Down
11 changes: 10 additions & 1 deletion locales/en-US/admin.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -1612,7 +1612,16 @@ configure-general-rte-spoilerDesc =
Words and phrases formatted as Spoiler are hidden behind a
dark background until the reader chooses to reveal the text.
configure-general-dsaConfig-title = DSA Features (TODO)
configure-general-dsaConfig-title = Digital services act
configure-general-dsaConfig-reportingAndModerationExperience =
DSA reporting and moderation experience
configure-general-dsaConfig-methodOfRedress =
Select your method of redress
configure-general-dsaConfig-methodOfRedress-explanation =
Let users know if and how they can appeal a moderation decision
configure-general-dsaConfig-methodOfRedress-none = None
configure-general-dsaConfig-methodOfRedress-email = Email
configure-general-dsaConfig-methodOfRedress-url = URL
configure-account-features-title = Commenter account management features
configure-account-features-explanation =
Expand Down
9 changes: 8 additions & 1 deletion server/src/core/server/graph/resolvers/DSAConfiguration.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import * as settings from "coral-server/models/settings";

import { GQLDSAConfigurationTypeResolver } from "coral-server/graph/schema/__generated__/types";
import {
GQLDSA_METHOD_OF_REDRESS,
GQLDSAConfigurationTypeResolver,
} from "coral-server/graph/schema/__generated__/types";

export const DSAConfiguration: GQLDSAConfigurationTypeResolver<settings.RTEConfiguration> =
{
enabled: (config, args, { tenant }) =>
tenant.dsa && tenant.dsa.enabled ? tenant.dsa.enabled : false,
methodOfRedress: (config, args, { tenant }) =>
tenant.dsa && tenant.dsa.methodOfRedress
? tenant.dsa.methodOfRedress
: GQLDSA_METHOD_OF_REDRESS.NONE,
};
22 changes: 22 additions & 0 deletions server/src/core/server/graph/schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -1948,12 +1948,24 @@ type RTEConfiguration {
sarcasm: Boolean!
}

enum DSA_METHOD_OF_REDRESS {
NONE
EMAIL
URL
}

type DSAConfiguration {
"""
enabled when true turns on the European Union DSA compliance
features for commenting, reporting, and moderation flows.
"""
enabled: Boolean!

"""
methodOfRedress lets users know if and how they can appeal a
moderation decision
"""
methodOfRedress: DSA_METHOD_OF_REDRESS!
}

"""
Expand Down Expand Up @@ -6053,7 +6065,17 @@ DSAConfigurationInput specifies the configuration for DSA European Union
moderation and reporting features.
"""
input DSAConfigurationInput {
"""
enabled when true turns on the European Union DSA compliance
features for commenting, reporting, and moderation flows.
"""
enabled: Boolean

"""
methodOfRedress lets users know if and how they can appeal a
moderation decision
"""
methodOfRedress: DSA_METHOD_OF_REDRESS
}

"""
Expand Down
2 changes: 2 additions & 0 deletions server/src/core/server/models/tenant/tenant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { dotize } from "coral-server/utils/dotize";

import {
GQLAnnouncement,
GQLDSA_METHOD_OF_REDRESS,
GQLFEATURE_FLAG,
GQLMODERATION_MODE,
GQLSettings,
Expand Down Expand Up @@ -301,6 +302,7 @@ export async function createTenant(
},
dsa: {
enabled: false,
methodOfRedress: GQLDSA_METHOD_OF_REDRESS.NONE,
},
};

Expand Down
2 changes: 2 additions & 0 deletions server/src/core/server/test/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Token, User } from "coral-server/models/user";
import {
GQLCOMMENT_STATUS,
GQLDIGEST_FREQUENCY,
GQLDSA_METHOD_OF_REDRESS,
GQLMODERATION_MODE,
GQLUSER_ROLE,
} from "coral-server/graph/schema/__generated__/types";
Expand Down Expand Up @@ -186,6 +187,7 @@ export const createTenantFixture = (
emailDomainModeration: [],
dsa: {
enabled: false,
methodOfRedress: GQLDSA_METHOD_OF_REDRESS.NONE,
},
embeddedComments: {
allowReplies: true,
Expand Down

0 comments on commit 6a2a586

Please sign in to comment.