From 918ba1086719282ddda04593abe5e1404182d0ac Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Fri, 4 Oct 2019 20:22:31 +0000 Subject: [PATCH] [CORL-681] Configurable Staff Badges (#2620) * feat: added configurable staff badge * fix: removed ambigous styles --- .../sections/General/GeneralConfig.tsx | 7 ++ .../General/GeneralConfigContainer.tsx | 1 + .../sections/General/StaffConfig.css | 3 + .../sections/General/StaffConfig.tsx | 78 +++++++++++++++++++ .../sections/General/StaffConfigContainer.tsx | 37 +++++++++ .../__snapshots__/general.spec.tsx.snap | 70 +++++++++++++++++ src/core/client/admin/test/fixtures.ts | 3 + .../Comments/Comment/CommentContainer.tsx | 2 + .../Comments/Comment/UserTagsContainer.tsx | 29 ++++--- .../CommentContainer.spec.tsx.snap | 49 ++++++++++++ .../ConversationThreadContainer.tsx | 2 + .../FeaturedCommentContainer.tsx | 2 + src/core/client/stream/test/fixtures.ts | 3 + .../server/graph/tenant/schema/schema.graphql | 40 +++++++++- src/core/server/index.ts | 6 +- src/core/server/locales/da/common.ftl | 1 + src/core/server/locales/en-US/common.ftl | 2 + src/core/server/locales/es/common.ftl | 1 + src/core/server/locales/nl-NL/common.ftl | 1 + src/core/server/locales/pt-BR/common.ftl | 1 + src/core/server/models/settings.ts | 1 + src/core/server/models/tenant/helpers.ts | 11 ++- src/core/server/models/tenant/tenant.ts | 12 ++- src/core/server/services/migrate/manager.ts | 17 ++-- src/core/server/services/migrate/migration.ts | 15 +++- .../migrate/migrations/1570118392071_staff.ts | 38 +++++++++ src/locales/da/stream.ftl | 23 +++--- src/locales/en-US/admin.ftl | 13 +++- src/locales/en-US/stream.ftl | 1 - src/locales/es/stream.ftl | 1 - src/locales/nl-NL/stream.ftl | 1 - src/locales/pt-BR/stream.ftl | 1 - 32 files changed, 428 insertions(+), 44 deletions(-) create mode 100644 src/core/client/admin/routes/Configure/sections/General/StaffConfig.css create mode 100644 src/core/client/admin/routes/Configure/sections/General/StaffConfig.tsx create mode 100644 src/core/client/admin/routes/Configure/sections/General/StaffConfigContainer.tsx create mode 100644 src/core/server/locales/da/common.ftl create mode 100644 src/core/server/locales/es/common.ftl create mode 100644 src/core/server/locales/nl-NL/common.ftl create mode 100644 src/core/server/services/migrate/migrations/1570118392071_staff.ts diff --git a/src/core/client/admin/routes/Configure/sections/General/GeneralConfig.tsx b/src/core/client/admin/routes/Configure/sections/General/GeneralConfig.tsx index 8819802db..30315cc29 100644 --- a/src/core/client/admin/routes/Configure/sections/General/GeneralConfig.tsx +++ b/src/core/client/admin/routes/Configure/sections/General/GeneralConfig.tsx @@ -11,6 +11,7 @@ import GuidelinesConfigContainer from "./GuidelinesConfigContainer"; import LocaleConfigContainer from "./LocaleConfigContainer"; import ReactionConfigContainer from "./ReactionConfigContainer"; import SitewideCommentingConfigContainer from "./SitewideCommentingConfigContainer"; +import StaffConfigContainer from "./StaffConfigContainer"; interface Props { disabled: boolean; @@ -19,6 +20,7 @@ interface Props { PropTypesOf["settings"] & PropTypesOf["settings"] & PropTypesOf["settings"] & + PropTypesOf["settings"] & PropTypesOf["settings"] & PropTypesOf["settings"] & PropTypesOf["settings"]; @@ -71,6 +73,11 @@ const General: FunctionComponent = ({ settings={settings} onInitValues={onInitValues} /> + ); diff --git a/src/core/client/admin/routes/Configure/sections/General/GeneralConfigContainer.tsx b/src/core/client/admin/routes/Configure/sections/General/GeneralConfigContainer.tsx index 212cef2e3..833b97bd6 100644 --- a/src/core/client/admin/routes/Configure/sections/General/GeneralConfigContainer.tsx +++ b/src/core/client/admin/routes/Configure/sections/General/GeneralConfigContainer.tsx @@ -53,6 +53,7 @@ const enhanced = withFragmentContainer({ ...ClosingCommentStreamsConfigContainer_settings ...SitewideCommentingConfigContainer_settings ...ReactionConfigContainer_settings + ...StaffConfigContainer_settings } `, })(GeneralConfigContainer); diff --git a/src/core/client/admin/routes/Configure/sections/General/StaffConfig.css b/src/core/client/admin/routes/Configure/sections/General/StaffConfig.css new file mode 100644 index 000000000..c597ee7a6 --- /dev/null +++ b/src/core/client/admin/routes/Configure/sections/General/StaffConfig.css @@ -0,0 +1,3 @@ +.textInput { + min-width: 300px; +} diff --git a/src/core/client/admin/routes/Configure/sections/General/StaffConfig.tsx b/src/core/client/admin/routes/Configure/sections/General/StaffConfig.tsx new file mode 100644 index 000000000..c2bb77268 --- /dev/null +++ b/src/core/client/admin/routes/Configure/sections/General/StaffConfig.tsx @@ -0,0 +1,78 @@ +import { Localized } from "fluent-react/compat"; +import React, { FunctionComponent } from "react"; +import { Field } from "react-final-form"; + +import { StaffConfigContainer_settings as SettingsData } from "coral-admin/__generated__/StaffConfigContainer_settings.graphql"; +import { required } from "coral-framework/lib/validation"; +import { + FieldSet, + Flex, + FormField, + HorizontalGutter, + InputLabel, + Tag, + TextField, + Typography, +} from "coral-ui/components"; + +import Header from "../../Header"; +import SectionContent from "../../SectionContent"; +import ValidationMessage from "../../ValidationMessage"; + +import styles from "./StaffConfig.css"; + +interface Props { + disabled: boolean; + settings: SettingsData; +} + +const StaffConfig: FunctionComponent = ({ disabled, settings }) => ( + }> + +
Staff member badge
+
+ + + + Show a custom badge for staff members of your organization. This badge + appears on the comment stream and in the admin interface. + + + + + + {({ input, meta }) => ( + + + + Badge text + + + + + + + + + Preview + + {input.value && {input.value}} + + + )} + + + + +
+); + +export default StaffConfig; diff --git a/src/core/client/admin/routes/Configure/sections/General/StaffConfigContainer.tsx b/src/core/client/admin/routes/Configure/sections/General/StaffConfigContainer.tsx new file mode 100644 index 000000000..48383d597 --- /dev/null +++ b/src/core/client/admin/routes/Configure/sections/General/StaffConfigContainer.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import { graphql } from "react-relay"; + +import { StaffConfigContainer_settings as SettingsData } from "coral-admin/__generated__/StaffConfigContainer_settings.graphql"; +import { withFragmentContainer } from "coral-framework/lib/relay"; + +import StaffConfig from "./StaffConfig"; + +interface Props { + settings: SettingsData; + onInitValues: (values: SettingsData) => void; + disabled: boolean; +} + +class StaffConfigContainer extends React.Component { + constructor(props: Props) { + super(props); + props.onInitValues(props.settings); + } + + public render() { + const { disabled, settings } = this.props; + return ; + } +} + +const enhanced = withFragmentContainer({ + settings: graphql` + fragment StaffConfigContainer_settings on Settings { + staff { + label + } + } + `, +})(StaffConfigContainer); + +export default enhanced; diff --git a/src/core/client/admin/test/configure/__snapshots__/general.spec.tsx.snap b/src/core/client/admin/test/configure/__snapshots__/general.spec.tsx.snap index 0a1717db3..f2df78eff 100644 --- a/src/core/client/admin/test/configure/__snapshots__/general.spec.tsx.snap +++ b/src/core/client/admin/test/configure/__snapshots__/general.spec.tsx.snap @@ -1063,6 +1063,76 @@ each other's comments. +
+ + Staff member badge + +
+

+ Show a custom badge for staff members of your organization. This badge +appears on the comment stream and in the admin interface. +

+
+
+
+
+ +
+ +
+
+
+

+ Preview +

+ + Staff + +
+
+
+
+
+
diff --git a/src/core/client/admin/test/fixtures.ts b/src/core/client/admin/test/fixtures.ts index a63a36344..34ea69a56 100644 --- a/src/core/client/admin/test/fixtures.ts +++ b/src/core/client/admin/test/fixtures.ts @@ -50,6 +50,9 @@ export const settings = createFixture({ timeout: 604800, message: "Comments are closed on this story.", }, + staff: { + label: "Staff", + }, reaction: { label: "Reaction", labelActive: "reacted", diff --git a/src/core/client/stream/tabs/Comments/Comment/CommentContainer.tsx b/src/core/client/stream/tabs/Comments/Comment/CommentContainer.tsx index 7ff67004c..15984a9d3 100644 --- a/src/core/client/stream/tabs/Comments/Comment/CommentContainer.tsx +++ b/src/core/client/stream/tabs/Comments/Comment/CommentContainer.tsx @@ -253,6 +253,7 @@ export class CommentContainer extends Component { = props => { - const { comment } = props; +const UserTagsContainer: FunctionComponent = ({ + settings, + comment, + className, +}) => { const staffTag = comment.tags.find(t => t.code === "STAFF"); return ( - <> - {staffTag && ( - - Staff - - )} - + <>{staffTag && {settings.staff.label}} ); }; @@ -33,6 +31,13 @@ const enhanced = withFragmentContainer({ } } `, + settings: graphql` + fragment UserTagsContainer_settings on Settings { + staff { + label + } + } + `, })(UserTagsContainer); export default enhanced; diff --git a/src/core/client/stream/tabs/Comments/Comment/__snapshots__/CommentContainer.spec.tsx.snap b/src/core/client/stream/tabs/Comments/Comment/__snapshots__/CommentContainer.spec.tsx.snap index be64f1bd4..934f9ca29 100644 --- a/src/core/client/stream/tabs/Comments/Comment/__snapshots__/CommentContainer.spec.tsx.snap +++ b/src/core/client/stream/tabs/Comments/Comment/__snapshots__/CommentContainer.spec.tsx.snap @@ -143,6 +143,13 @@ exports[`hide reply button 1`] = ` "tags": Array [], } } + settings={ + Object { + "disableCommenting": Object { + "enabled": false, + }, + } + } /> } /> @@ -192,6 +193,7 @@ const enhanced = withContext(ctx => ({ fragment ConversationThreadContainer_settings on Settings { ...CommentContainer_settings ...LocalReplyListContainer_settings + ...UserTagsContainer_settings } `, comment: graphql` diff --git a/src/core/client/stream/tabs/Comments/Stream/FeaturedComments/FeaturedCommentContainer.tsx b/src/core/client/stream/tabs/Comments/Stream/FeaturedComments/FeaturedCommentContainer.tsx index add01104e..4eef96309 100644 --- a/src/core/client/stream/tabs/Comments/Stream/FeaturedComments/FeaturedCommentContainer.tsx +++ b/src/core/client/stream/tabs/Comments/Stream/FeaturedComments/FeaturedCommentContainer.tsx @@ -71,6 +71,7 @@ const FeaturedCommentContainer: FunctionComponent = props => { @@ -174,6 +175,7 @@ const enhanced = withSetCommentIDMutation( settings: graphql` fragment FeaturedCommentContainer_settings on Settings { ...ReactionButtonContainer_settings + ...UserTagsContainer_settings } `, })(FeaturedCommentContainer) diff --git a/src/core/client/stream/test/fixtures.ts b/src/core/client/stream/test/fixtures.ts index b4669081c..9ad509e7b 100644 --- a/src/core/client/stream/test/fixtures.ts +++ b/src/core/client/stream/test/fixtures.ts @@ -88,6 +88,9 @@ export const settings = createFixture({ }, }, }, + staff: { + label: "Staff", + }, reaction: { icon: "thumb_up", label: "Respect", diff --git a/src/core/server/graph/tenant/schema/schema.graphql b/src/core/server/graph/tenant/schema/schema.graphql index 0ee661f29..464ca2493 100644 --- a/src/core/server/graph/tenant/schema/schema.graphql +++ b/src/core/server/graph/tenant/schema/schema.graphql @@ -1085,16 +1085,29 @@ type CommenterAccountFeatures { changeUsername when true, non-sso user may change username every 14 days """ changeUsername: Boolean! + """ downloadComments when true, user may download their comment history """ downloadComments: Boolean! + """ deleteAccount when true, non-sso user may permanently delete their account """ deleteAccount: Boolean! } +""" +StaffConfiguration specifies the configuration for the staff badges assigned to +users with any role above COMMENTER. +""" +type StaffConfiguration { + """ + label is the string used when displaying the STAFF badge to users. + """ + label: String! +} + """ Settings stores the global settings for a given Tenant. """ @@ -1210,6 +1223,12 @@ type Settings { """ reaction: ReactionConfiguration! + """ + staff specifies the configuration for the staff badges assigned to users with + any role above COMMENTER. + """ + staff: StaffConfiguration! + """ accountFeatures stores the configuration for commenter account features. """ @@ -3280,8 +3299,8 @@ input StoryConfigurationInput { } """ -ReactionConfigurationInput stores the configuration for reactions used across this -Tenant. +ReactionConfigurationInput stores the configuration for reactions used across +this Tenant. """ input ReactionConfigurationInput { """ @@ -3318,6 +3337,17 @@ input ReactionConfigurationInput { color: String } +""" +StaffConfigurationInput specifies the configuration for the staff badges +assigned to users with any role above COMMENTER. +""" +input StaffConfigurationInput { + """ + label is the string used when displaying the STAFF badge to users. + """ + label: String +} + """ CommenterAccountFeatures stores the configuration for commenter account features. """ @@ -3435,6 +3465,12 @@ input SettingsInput { """ reaction: ReactionConfigurationInput + """ + staff specifies the configuration for the staff badges assigned to users with + any role above COMMENTER. + """ + staff: StaffConfigurationInput + """ accountFeatures specifies the configuration for accounts. """ diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 7cbef303b..72790dcf2 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -158,7 +158,10 @@ class Server { ); // Create the migration manager. - this.migrationManager = new MigrationManager(this.tenantCache); + this.migrationManager = new MigrationManager({ + tenantCache: this.tenantCache, + i18n: this.i18n, + }); // Load and upsert the persisted queries. this.persistedQueryCache = new PersistedQueryCache({ mongo: this.mongo }); @@ -198,6 +201,7 @@ class Server { // Run migrations if there is already a Tenant installed. if (await isInstalled(this.tenantCache)) { await this.migrationManager.executePendingMigrations(this.mongo); + await this.tenantCache.primeAll(); } else { logger.info("no tenants are installed, skipping running migrations"); } diff --git a/src/core/server/locales/da/common.ftl b/src/core/server/locales/da/common.ftl new file mode 100644 index 000000000..1bf00df73 --- /dev/null +++ b/src/core/server/locales/da/common.ftl @@ -0,0 +1 @@ +staff-label = Personale diff --git a/src/core/server/locales/en-US/common.ftl b/src/core/server/locales/en-US/common.ftl index 4255dcee0..70c8e964d 100644 --- a/src/core/server/locales/en-US/common.ftl +++ b/src/core/server/locales/en-US/common.ftl @@ -11,3 +11,5 @@ comment-count = [one] Comment *[other] Comments } + +staff-label = Staff diff --git a/src/core/server/locales/es/common.ftl b/src/core/server/locales/es/common.ftl new file mode 100644 index 000000000..bb91c17ff --- /dev/null +++ b/src/core/server/locales/es/common.ftl @@ -0,0 +1 @@ +staff-label = Miembro del equipo diff --git a/src/core/server/locales/nl-NL/common.ftl b/src/core/server/locales/nl-NL/common.ftl new file mode 100644 index 000000000..566f11f7f --- /dev/null +++ b/src/core/server/locales/nl-NL/common.ftl @@ -0,0 +1 @@ +staff-label = Staf diff --git a/src/core/server/locales/pt-BR/common.ftl b/src/core/server/locales/pt-BR/common.ftl index 7b93d0b15..27a3cf8b7 100644 --- a/src/core/server/locales/pt-BR/common.ftl +++ b/src/core/server/locales/pt-BR/common.ftl @@ -4,3 +4,4 @@ disableCommentingDefaultMessage = Comentários foram fechados nessa história. reaction-labelRespect = Respeitar reaction-labelActiveRespected = Respeitado reaction-sortLabelMostRespected = Respeitados +staff-label = Staff diff --git a/src/core/server/models/settings.ts b/src/core/server/models/settings.ts index 3897ae0ea..402c4e2d9 100644 --- a/src/core/server/models/settings.ts +++ b/src/core/server/models/settings.ts @@ -94,6 +94,7 @@ export type Settings = GlobalModerationSettings & | "wordList" | "integrations" | "reaction" + | "staff" | "editCommentWindowLength" | "customCSSURL" | "communityGuidelines" diff --git a/src/core/server/models/tenant/helpers.ts b/src/core/server/models/tenant/helpers.ts index e05b0e01e..be5a75881 100644 --- a/src/core/server/models/tenant/helpers.ts +++ b/src/core/server/models/tenant/helpers.ts @@ -1,7 +1,10 @@ import crypto from "crypto"; import { FluentBundle } from "fluent/compat"; -import { GQLReactionConfiguration } from "coral-server/graph/tenant/schema/__generated__/types"; +import { + GQLReactionConfiguration, + GQLStaffConfiguration, +} from "coral-server/graph/tenant/schema/__generated__/types"; import { translate } from "coral-server/services/i18n"; export const getDefaultReactionConfiguration = ( @@ -19,6 +22,12 @@ export const getDefaultReactionConfiguration = ( icon: "thumb_up", }); +export const getDefaultStaffConfiguration = ( + bundle: FluentBundle +): GQLStaffConfiguration => ({ + label: translate(bundle, "Staff", "staff-label"), +}); + export function generateSSOKey() { // Generate a new key. We generate a key of minimum length 32 up to 37 bytes, // as 16 was the minimum length recommended. diff --git a/src/core/server/models/tenant/tenant.ts b/src/core/server/models/tenant/tenant.ts index f1f1288c2..5972367d4 100644 --- a/src/core/server/models/tenant/tenant.ts +++ b/src/core/server/models/tenant/tenant.ts @@ -13,7 +13,11 @@ import { Settings } from "coral-server/models/settings"; import { I18n } from "coral-server/services/i18n"; import { tenants as collection } from "coral-server/services/mongodb/collections"; -import { generateSSOKey, getDefaultReactionConfiguration } from "./helpers"; +import { + generateSSOKey, + getDefaultReactionConfiguration, + getDefaultStaffConfiguration, +} from "./helpers"; /** * TenantResource references a given resource that should be owned by a specific @@ -64,6 +68,9 @@ export async function createTenant( input: CreateTenantInput, now = new Date() ) { + // Get the tenant's bundle. + const bundle = i18n.getBundle(input.locale); + const defaults: Sub = { // Create a new ID. id: uuid.v4(), @@ -168,7 +175,8 @@ export async function createTenant( doNotStore: true, }, }, - reaction: getDefaultReactionConfiguration(i18n.getBundle(input.locale)), + reaction: getDefaultReactionConfiguration(bundle), + staff: getDefaultStaffConfiguration(bundle), stories: { scraping: { enabled: true, diff --git a/src/core/server/services/migrate/manager.ts b/src/core/server/services/migrate/manager.ts index 41acc779c..726324f5f 100644 --- a/src/core/server/services/migrate/manager.ts +++ b/src/core/server/services/migrate/manager.ts @@ -12,6 +12,7 @@ import { retrieveAllMigrationRecords, startMigration, } from "coral-server/models/migration"; +import { I18n } from "coral-server/services/i18n"; import TenantCache from "coral-server/services/tenant/cache"; import { @@ -23,16 +24,21 @@ import Migration from "./migration"; // Extract the id from the filename with this regex. const fileNamePattern = /^(\d+)_([\S_]+)\.[tj]s$/; +export interface ManagerOptions { + tenantCache: TenantCache; + i18n: I18n; +} + export default class Manager { private clientID: string; private migrations: Migration[]; - private tenants: TenantCache; + private tenantCache: TenantCache; private ran: boolean = false; - constructor(tenants: TenantCache) { + constructor({ tenantCache, i18n }: ManagerOptions) { this.clientID = uuid.v4(); this.migrations = []; - this.tenants = tenants; + this.tenantCache = tenantCache; const fileNames = fs.readdirSync(path.join(__dirname, "migrations")); for (const fileName of fileNames) { @@ -60,9 +66,10 @@ export default class Manager { throw new Error("fileName format is invalid"); } const id = parseInt(matches[1], 10); + const name = matches[2]; // Create the migration instance. - const migration = new m.default(id, matches[2]); + const migration = new m.default({ id, name, i18n }); // Insert the migration into the migrations array. if (!(migration instanceof Migration)) { @@ -179,7 +186,7 @@ export default class Manager { if (migration.up) { // The migration provides an up method, we should run this per Tenant. - for await (const tenant of this.tenants) { + for await (const tenant of this.tenantCache) { log = log.child({ tenantID: tenant.id }, true); const migrationStartTime = now(); diff --git a/src/core/server/services/migrate/migration.ts b/src/core/server/services/migrate/migration.ts index 3d2505f61..8858861d0 100644 --- a/src/core/server/services/migrate/migration.ts +++ b/src/core/server/services/migrate/migration.ts @@ -2,6 +2,7 @@ import Logger from "bunyan"; import { Db } from "mongodb"; import logger from "coral-server/logger"; +import { I18n } from "coral-server/services/i18n"; interface Migration { indexes?(mongo: Db): Promise; @@ -10,18 +11,26 @@ interface Migration { down?(mongo: Db, tenantID: string): Promise; } +export interface MigrationOptions { + id: number; + name: string; + i18n: I18n; +} + abstract class Migration { public readonly name: string; public readonly id: number; public readonly logger: Logger; + public readonly i18n: I18n; - constructor(version: number, name: string) { - this.id = version; + constructor({ id, name, i18n }: MigrationOptions) { + this.id = id; this.name = name; + this.i18n = i18n; this.logger = logger.child( { migrationName: this.name, - migrationVersion: this.id, + migrationID: this.id, }, true ); diff --git a/src/core/server/services/migrate/migrations/1570118392071_staff.ts b/src/core/server/services/migrate/migrations/1570118392071_staff.ts new file mode 100644 index 000000000..fd3b25664 --- /dev/null +++ b/src/core/server/services/migrate/migrations/1570118392071_staff.ts @@ -0,0 +1,38 @@ +import { Db } from "mongodb"; + +import { getDefaultStaffConfiguration } from "coral-server/models/tenant"; +import Migration from "coral-server/services/migrate/migration"; +import collections from "coral-server/services/mongodb/collections"; + +import { MigrationError } from "../error"; + +export default class extends Migration { + private async getTenant(mongo: Db, id: string) { + const tenant = await collections.tenants(mongo).findOne({ id }); + if (!tenant) { + throw new MigrationError(id, "tenant not found", "tenants", [id]); + } + + return tenant; + } + + public async test(mongo: Db, id: string) { + const tenant = await this.getTenant(mongo, id); + if (!tenant.staff) { + throw new MigrationError(id, "staff not set", "tenants", [id]); + } + } + + public async up(mongo: Db, id: string) { + const tenant = await this.getTenant(mongo, id); + const bundle = this.i18n.getBundle(tenant.locale); + await collections.tenants(mongo).updateOne( + { id, staff: null }, + { + $set: { + staff: getDefaultStaffConfiguration(bundle), + }, + } + ); + } +} diff --git a/src/locales/da/stream.ftl b/src/locales/da/stream.ftl index affd768ba..4f3379e6c 100644 --- a/src/locales/da/stream.ftl +++ b/src/locales/da/stream.ftl @@ -114,8 +114,8 @@ comments-userPopover-ignore = Ignorere comments-userIgnorePopover-ignoreUser = Ignorerer {$username}? comments-userIgnorePopover-description = - Når du ignorerer en kommentator, vil alle kommentarer, - de skrev på webstedet, være skjult for dig. Du kan fortryde + Når du ignorerer en kommentator, vil alle kommentarer, + de skrev på webstedet, være skjult for dig. Du kan fortryde dette senere fra Min profil. comments-userIgnorePopover-ignore = Ignorerer comments-userIgnorePopover-cancel = Annuller @@ -136,7 +136,6 @@ comments-rejectedTombstone = Du har afvist denne kommentar. Gå til moderation for at gennemgå denne beslutning. comments-featuredTag = Fremhævet -comments-staffTag = Personale ### Featured Comments comments-featured-gotoConversation = Gå til samtale @@ -196,7 +195,7 @@ comments-reportPopover-submit = Indsend comments-reportPopover-thankYou = Mange tak comments-reportPopover-receivedMessage = Vi har modtaget din besked. - Rapporteringer fra medlemmer som dig, + Rapporteringer fra medlemmer som dig, hjælper til at holde en god tone. comments-reportPopover-dismiss = Luk @@ -228,8 +227,8 @@ configure-liveUpdates-description = configure-messageBox-title = Aktivér meddelelsesboks til denne stream configure-messageBox-description = - Tilføj en besked øverst i kommentarfeltet for dine læsere. Brug dette til at stille et emne, - stille et spørgsmål eller offentliggøre meddelelser vedrørende denne historie. + Tilføj en besked øverst i kommentarfeltet for dine læsere. Brug dette til at stille et emne, + stille et spørgsmål eller offentliggøre meddelelser vedrørende denne historie. configure-messageBox-preview = Forhåndsvisning configure-messageBox-selectAnIcon = Vælg et ikon configure-messageBox-noIcon = Intet ikon @@ -237,8 +236,8 @@ configure-messageBox-writeAMessage = Skriv en besked configure-closeStream-title = Luk kommentarer configure-closeStream-description = - Kommentarerne er i øjeblikket åbne. - Ved at lukke kommentarerne kan der ikke indsendes nye kommentarer, + Kommentarerne er i øjeblikket åbne. + Ved at lukke kommentarerne kan der ikke indsendes nye kommentarer, og alle tidligere indsendte kommentarer vises stadig. configure-closeStream-closeStream = Luk kommentarer @@ -251,8 +250,8 @@ configure-openStream-openStream = Åbn kommentarer comments-tombstone-ignore = Denne kommentar er skjult, fordi du ignorerede {$username} suspendInfo-heading = Din konto er midlertidigt suspenderet for at kommentere. -suspendInfo-info = - I overensstemmelse med fællesskabsretningslinjerne for { $organization} - er din konto midlertidigt suspenderet. Mens du er suspenderet, - kan du ikke kommentere, respektere eller rapportere kommentarer. +suspendInfo-info = + I overensstemmelse med fællesskabsretningslinjerne for { $organization} + er din konto midlertidigt suspenderet. Mens du er suspenderet, + kan du ikke kommentere, respektere eller rapportere kommentarer. Gå igen med til samtalen på { $until }. diff --git a/src/locales/en-US/admin.ftl b/src/locales/en-US/admin.ftl index 8c37c936d..0e1c2a945 100644 --- a/src/locales/en-US/admin.ftl +++ b/src/locales/en-US/admin.ftl @@ -541,10 +541,10 @@ moderate-user-drawer-recent-history-tooltip-button = .aria-label = Toggle recent comment history tooltip moderate-user-drawer-recent-history-tooltip-submitted = Submitted -moderate-user-drawer-notes-field = +moderate-user-drawer-notes-field = .placeholder = Leave a note... moderate-user-drawer-notes-button = Add note -moderatorNote-left-by = Left by: +moderatorNote-left-by = Left by: moderatorNote-delete = Delete ## Create Username @@ -780,6 +780,15 @@ configure-general-reactions-sort-input = configure-general-reactions-preview = Preview configure-general-reaction-sortMenu-sortBy = Sort by +configure-general-staff-title = Staff member badge +configure-general-staff-explanation = + Show a custom badge for staff members of your organization. This badge + appears on the comment stream and in the admin interface. +configure-general-staff-label = Badge text +configure-general-staff-input = + .placeholder = E.g. Staff +configure-general-staff-preview = Preview + configure-account-features-title = Commenter account management features configure-account-features-explanation = You can enable and disable certain features for your commenters to use diff --git a/src/locales/en-US/stream.ftl b/src/locales/en-US/stream.ftl index a2cc3585d..9156281d0 100644 --- a/src/locales/en-US/stream.ftl +++ b/src/locales/en-US/stream.ftl @@ -157,7 +157,6 @@ comments-rejectedTombstone = You have rejected this comment. Go to Moderate to review this decision. comments-featuredTag = Featured -comments-staffTag = Staff ### Account Deletion Stream diff --git a/src/locales/es/stream.ftl b/src/locales/es/stream.ftl index e574180e2..b6773dd11 100644 --- a/src/locales/es/stream.ftl +++ b/src/locales/es/stream.ftl @@ -135,7 +135,6 @@ comments-rejectedTombstone = Has rechazado este comentario.Vaya a moderación para revisar esta decisión. comments-featuredTag = Resaltado -comments-staffTag = Miembro del equipo ### Featured Comments comments-featured-gotoConversation = Ir a conversación diff --git a/src/locales/nl-NL/stream.ftl b/src/locales/nl-NL/stream.ftl index 1d9f7bf99..9fd1e41b9 100644 --- a/src/locales/nl-NL/stream.ftl +++ b/src/locales/nl-NL/stream.ftl @@ -135,7 +135,6 @@ comments-rejectedTombstone = U heeft deze reactie afgewezen. Ga naar modereren om dit besluit te herzien. comments-featuredTag = Uitgelicht -comments-staffTag = Staf ### Featured Comments comments-featured-gotoConversation = Ga naar het gesprek diff --git a/src/locales/pt-BR/stream.ftl b/src/locales/pt-BR/stream.ftl index d77c0355d..ed06b0cc2 100644 --- a/src/locales/pt-BR/stream.ftl +++ b/src/locales/pt-BR/stream.ftl @@ -149,7 +149,6 @@ comments-rejectedTombstone = Você rejeitou este comentário. Vá para Moderados para rever esta decisão. comments-featuredTag = Destaques -comments-staffTag = Staff ### Account Deletion Stream