diff --git a/packages/console/src/assets/images/circle-plus.svg b/packages/console/src/assets/images/circle-plus.svg index 1d2315bc1..686f04f26 100644 --- a/packages/console/src/assets/images/circle-plus.svg +++ b/packages/console/src/assets/images/circle-plus.svg @@ -1,5 +1,3 @@ - + diff --git a/packages/console/src/components/Button/index.module.scss b/packages/console/src/components/Button/index.module.scss index d0a2c533e..dd2414f15 100644 --- a/packages/console/src/components/Button/index.module.scss +++ b/packages/console/src/components/Button/index.module.scss @@ -40,9 +40,8 @@ } .icon { - display: block; - width: 20px; - height: 20px; + display: flex; + align-items: center; &:not(:last-child) { margin-right: _.unit(2); @@ -62,6 +61,12 @@ &.text { height: 24px; } + + .icon { + &:not(:last-child) { + margin-right: _.unit(1); + } + } } &.medium { diff --git a/packages/console/src/components/MultiTextInput/index.tsx b/packages/console/src/components/MultiTextInput/index.tsx index 0e61ed2f8..dda2ec39b 100644 --- a/packages/console/src/components/MultiTextInput/index.tsx +++ b/packages/console/src/components/MultiTextInput/index.tsx @@ -5,6 +5,7 @@ import type { KeyboardEvent } from 'react'; import { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import CirclePlus from '@/assets/images/circle-plus.svg'; import Minus from '@/assets/images/minus.svg'; import Button from '../Button'; @@ -106,6 +107,7 @@ const MultiTextInput = ({ type="text" title="general.add_another" className={styles.addAnother} + icon={} onClick={handleAdd} />
{ )} - + { )} /> - - ( - + )} + /> + + )}
); }; diff --git a/packages/console/src/pages/Connectors/components/Guide/index.tsx b/packages/console/src/pages/Connectors/components/Guide/index.tsx index ef7f791a0..8ee20b6e6 100644 --- a/packages/console/src/pages/Connectors/components/Guide/index.tsx +++ b/packages/console/src/pages/Connectors/components/Guide/index.tsx @@ -6,6 +6,7 @@ import i18next from 'i18next'; import { FormProvider, useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router-dom'; import Close from '@/assets/images/close.svg'; import Button from '@/components/Button'; @@ -30,6 +31,7 @@ type Props = { const Guide = ({ connector, onClose }: Props) => { const api = useApi(); + const navigate = useNavigate(); const { updateSettings } = useSettings(); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { id: connectorId, type: connectorType, name, readme, isStandard } = connector; @@ -65,19 +67,24 @@ const Guide = ({ connector, onClose }: Props) => { const { id: connectorId } = connector; - await api + const basePayload = { + config: result.data, + connectorId, + metadata: conditional( + isStandard && { + ...otherData, + name: { en: name }, + } + ), + }; + + const payload = isSocialConnector + ? { ...basePayload, syncProfile: syncProfile === SyncProfileMode.EachSignIn } + : basePayload; + + const createdConnector = await api .post('/api/connectors', { - json: { - config: result.data, - connectorId, - syncProfile: syncProfile === SyncProfileMode.EachSignIn, - metadata: conditional( - isStandard && { - ...otherData, - name: { en: name }, - } - ), - }, + json: payload, }) .json(); @@ -88,6 +95,7 @@ const Guide = ({ connector, onClose }: Props) => { onClose(); toast.success(t('general.saved')); + navigate(`/connectors/${createdConnector.id}`); }); return ( diff --git a/packages/console/src/pages/SignInExperience/components/Preview/index.tsx b/packages/console/src/pages/SignInExperience/components/Preview/index.tsx index 27b42155f..cc9f7d355 100644 --- a/packages/console/src/pages/SignInExperience/components/Preview/index.tsx +++ b/packages/console/src/pages/SignInExperience/components/Preview/index.tsx @@ -194,7 +194,7 @@ const Preview = ({ signInExperience, className }: Props) => { style={conditional( platform === 'desktopWeb' && { // Set background color to match iframe's background color on both dark and light mode. - backgroundColor: mode === AppearanceMode.DarkMode ? '#2A2C31' : '#e5e1ec', + backgroundColor: mode === AppearanceMode.DarkMode ? '#000' : '#e5e1ec', } )} > diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SignInMethodEditBox/AddButton.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SignInMethodEditBox/AddButton.tsx index e0a516fe0..78e6e9280 100644 --- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SignInMethodEditBox/AddButton.tsx +++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SignInMethodEditBox/AddButton.tsx @@ -3,6 +3,7 @@ import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; import { snakeCase } from 'snake-case'; +import CirclePlus from '@/assets/images/circle-plus.svg'; import Plus from '@/assets/images/plus.svg'; import ActionMenu from '@/components/ActionMenu'; import type { Props as ButtonProps } from '@/components/Button'; @@ -33,6 +34,7 @@ const AddButton = ({ options, onSelected, hasSelectedIdentifiers }: Props) => { type: 'text', size: 'small', title: 'general.add_another', + icon: , }; return ( diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SocialConnectorEditBox/AddButton.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SocialConnectorEditBox/AddButton.tsx index dbc1a50e1..08183c726 100644 --- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SocialConnectorEditBox/AddButton.tsx +++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignIn/components/SocialConnectorEditBox/AddButton.tsx @@ -1,5 +1,6 @@ import classNames from 'classnames'; +import CirclePlus from '@/assets/images/circle-plus.svg'; import Plus from '@/assets/images/plus.svg'; import ActionMenu from '@/components/ActionMenu'; import type { Props as ButtonProps } from '@/components/Button'; @@ -32,6 +33,7 @@ const AddButton = ({ options, onSelected, hasSelectedConnectors }: Props) => { type: 'text', size: 'small', title: 'general.add_another', + icon: , }; return ( diff --git a/packages/console/src/utilities/a11y.ts b/packages/console/src/utilities/a11y.ts index e46b51f8b..6f65b62c1 100644 --- a/packages/console/src/utilities/a11y.ts +++ b/packages/console/src/utilities/a11y.ts @@ -15,7 +15,11 @@ export const onKeyDownHandler = } if (typeof callback === 'object') { - callback[key]?.(event); - event.preventDefault(); + const handler = callback[key]; + + if (handler) { + handler(event); + event.preventDefault(); + } } }; diff --git a/packages/core/src/queries/user.test.ts b/packages/core/src/queries/user.test.ts index 523c514ca..98db64fd1 100644 --- a/packages/core/src/queries/user.test.ts +++ b/packages/core/src/queries/user.test.ts @@ -307,6 +307,7 @@ describe('user query', () => { where ${fields.primaryEmail} ilike $1 or ${fields.primaryPhone} ilike $2 or ${ fields.username } ilike $3 or ${fields.name} ilike $4 + order by "created_at" desc limit $5 offset $6 `; @@ -339,6 +340,7 @@ describe('user query', () => { and (${fields.primaryEmail} ilike $2 or ${fields.primaryPhone} ilike $3 or ${ fields.username } ilike $4 or ${fields.name} ilike $5) + order by "created_at" desc limit $6 offset $7 `; @@ -371,6 +373,7 @@ describe('user query', () => { where ${fields.primaryEmail} like $1 or ${fields.primaryPhone} like $2 or ${ fields.username } like $3 or ${fields.name} like $4 + order by "created_at" desc limit $5 offset $6 `; diff --git a/packages/core/src/queries/user.ts b/packages/core/src/queries/user.ts index 3f099f56a..a53fb165b 100644 --- a/packages/core/src/queries/user.ts +++ b/packages/core/src/queries/user.ts @@ -145,6 +145,7 @@ export const findUsers = async ( select ${sql.join(Object.values(fields), sql`,`)} from ${table} ${buildUserConditions(search, hideAdminUser, isCaseSensitive)} + order by ${fields.createdAt} desc limit ${limit} offset ${offset} ` diff --git a/packages/core/src/routes/connector.test.ts b/packages/core/src/routes/connector.test.ts index f0fd3caa6..e4398ac9b 100644 --- a/packages/core/src/routes/connector.test.ts +++ b/packages/core/src/routes/connector.test.ts @@ -188,7 +188,6 @@ describe('connector route', () => { metadata: { ...mockConnectorFactory.metadata, id: 'connectorId' }, }, ]); - countConnectorByConnectorId.mockResolvedValueOnce({ count: 0 }); const response = await connectorRequest.post('/connectors').send({ connectorId: 'id0', config: { cliend_id: 'client_id', client_secret: 'client_secret' }, @@ -255,7 +254,7 @@ describe('connector route', () => { { ...mockConnectorFactory, type: ConnectorType.Sms, - metadata: { ...mockConnectorFactory.metadata, id: 'id0', isStandard: true }, + metadata: { ...mockConnectorFactory.metadata, id: 'id1' }, }, ]); getLogtoConnectors.mockResolvedValueOnce([ @@ -266,20 +265,19 @@ describe('connector route', () => { ...mockLogtoConnector, }, ]); + countConnectorByConnectorId.mockResolvedValueOnce({ count: 0 }); const response = await connectorRequest.post('/connectors').send({ - connectorId: 'id0', + connectorId: 'id1', config: { cliend_id: 'client_id', client_secret: 'client_secret' }, - metadata: { target: 'target', name: { en: '' }, logo: '', logoDark: null }, }); expect(response).toHaveProperty('statusCode', 200); expect(response.body).toMatchObject( expect.objectContaining({ - connectorId: 'id0', + connectorId: 'id1', config: { cliend_id: 'client_id', client_secret: 'client_secret', }, - metadata: { target: 'target' }, }) ); expect(deleteConnectorByIds).toHaveBeenCalledWith(['id']); @@ -347,6 +345,7 @@ describe('connector route', () => { ]); const response = await connectorRequest.post('/connectors').send({ connectorId: 'id0', + metadata: { target: 'target' }, }); expect(response).toHaveProperty('statusCode', 422); }); diff --git a/packages/core/src/routes/connector.ts b/packages/core/src/routes/connector.ts index b30fb5e68..8673c615d 100644 --- a/packages/core/src/routes/connector.ts +++ b/packages/core/src/routes/connector.ts @@ -3,7 +3,6 @@ import { emailRegEx, phoneRegEx } from '@logto/core-kit'; import type { ConnectorFactoryResponse, ConnectorResponse } from '@logto/schemas'; import { arbitraryObjectGuard, Connectors, ConnectorType } from '@logto/schemas'; import { buildIdGenerator } from '@logto/shared'; -import { conditional } from '@silverhand/essentials'; import cleanDeep from 'clean-deep'; import { object, string } from 'zod'; @@ -114,9 +113,9 @@ export default function connectorRoutes(router: T) { // eslint-disable-next-line complexity async (ctx, next) => { const { - body: { connectorId }, - body, + body: { connectorId, metadata, config, syncProfile }, } = ctx.guard; + const connectorFactories = await loadConnectorFactories(); const connectorFactory = connectorFactories.find( ({ metadata: { id } }) => id === connectorId @@ -129,6 +128,15 @@ export default function connectorRoutes(router: T) { }); } + assertThat( + connectorFactory.metadata.isStandard !== true || metadata?.target, + 'connector.can_not_modify_target' + ); + assertThat( + connectorFactory.metadata.isStandard === true || metadata === undefined, + 'connector.cannot_change_metadata_for_non_standard_connector' + ); + const { count } = await countConnectorByConnectorId(connectorId); assertThat( count === 0 || connectorFactory.metadata.isStandard === true, @@ -140,25 +148,23 @@ export default function connectorRoutes(router: T) { if (connectorFactory.type === ConnectorType.Social) { const connectors = await getLogtoConnectors(); - const connectorTarget = body.metadata?.target ?? connectorFactory.metadata.target; assertThat( !connectors .filter(({ type }) => type === ConnectorType.Social) .some( ({ metadata: { target, platform } }) => - target === connectorTarget && platform === connectorFactory.metadata.platform + target === cleanDeep(metadata)?.target && + platform === connectorFactory.metadata.platform ), new RequestError({ code: 'connector.multiple_target_with_same_platform', status: 422 }) ); } const insertConnectorId = generateConnectorId(); - const { metadata, ...rest } = body; - ctx.body = await insertConnector({ id: insertConnectorId, - ...conditional(metadata && { metadata: cleanDeep(metadata) }), - ...rest, + connectorId, + ...cleanDeep({ syncProfile, config, metadata }), }); /** @@ -194,17 +200,25 @@ export default function connectorRoutes(router: T) { .pick({ config: true, metadata: true, syncProfile: true }) .partial(), }), - async (ctx, next) => { const { params: { id }, - body: { config }, - body, + body: { config, metadata, syncProfile }, } = ctx.guard; - const { type, validateConfig } = await getLogtoConnectorById(id); + const { type, validateConfig, metadata: originalMetadata } = await getLogtoConnectorById(id); - if (body.syncProfile) { + assertThat( + originalMetadata.isStandard !== true || metadata?.target === originalMetadata.target, + 'connector.can_not_modify_target' + ); + + assertThat( + originalMetadata.isStandard === true || metadata === undefined, + 'connector.cannot_change_metadata_for_non_standard_connector' + ); + + if (syncProfile) { assertThat( type === ConnectorType.Social, new RequestError({ code: 'connector.invalid_type_for_syncing_profile', status: 422 }) @@ -214,12 +228,9 @@ export default function connectorRoutes(router: T) { if (config) { validateConfig(config); } - // Once created, target can not be modified. - assertThat(body.metadata?.target === undefined, 'connector.can_not_modify_target'); - const { metadata: databaseMetadata, ...rest } = body; await updateConnector({ - set: databaseMetadata ? { metadata: cleanDeep(databaseMetadata), ...rest } : rest, + set: cleanDeep({ config, metadata, syncProfile }), where: { id }, jsonbMode: 'replace', }); diff --git a/packages/core/src/routes/connector.update.test.ts b/packages/core/src/routes/connector.update.test.ts index b295476e5..f71e1bae0 100644 --- a/packages/core/src/routes/connector.update.test.ts +++ b/packages/core/src/routes/connector.update.test.ts @@ -120,7 +120,7 @@ describe('connector PATCH routes', () => { updateConnector.mockResolvedValueOnce({ ...mockConnector, metadata: { - target: 'target', + target: 'connector', name: { en: 'connector_name', fr: 'connector_name' }, logo: 'new_logo.png', }, @@ -131,6 +131,7 @@ describe('connector PATCH routes', () => { name: { en: 'connector_name', fr: 'connector_name' }, logo: 'new_logo.png', logoDark: null, + target: 'connector', }, }); expect(updateConnector).toHaveBeenCalledWith( @@ -141,6 +142,7 @@ describe('connector PATCH routes', () => { metadata: { name: { en: 'connector_name', fr: 'connector_name' }, logo: 'new_logo.png', + target: 'connector', }, }, jsonbMode: 'replace', @@ -161,24 +163,20 @@ describe('connector PATCH routes', () => { updateConnector.mockResolvedValueOnce({ ...mockConnector, metadata: { - target: '', + target: 'connector', name: { en: '' }, logo: '', logoDark: '', }, }); const response = await connectorRequest.patch('/connectors/id').send({ - metadata: { - name: { en: '' }, - logo: '', - logoDark: '', - }, + metadata: { target: 'connector', name: { en: '' }, logo: '', logoDark: '' }, }); expect(updateConnector).toHaveBeenCalledWith( expect.objectContaining({ where: { id: 'id' }, set: { - metadata: {}, + metadata: { target: 'connector' }, }, jsonbMode: 'replace', }) diff --git a/packages/integration-tests/src/api/connector.ts b/packages/integration-tests/src/api/connector.ts index aff29c381..2f82d2f66 100644 --- a/packages/integration-tests/src/api/connector.ts +++ b/packages/integration-tests/src/api/connector.ts @@ -9,22 +9,26 @@ export const getConnector = async (connectorId: string) => authedAdminApi.get(`connectors/${connectorId}`).json(); // FIXME @Darcy: correct use of `id` and `connectorId`. -export const postConnector = async (connectorId: string) => +export const postConnector = async (connectorId: string, metadata?: Record) => authedAdminApi .post({ url: `connectors`, - json: { connectorId }, + json: { connectorId, metadata }, }) .json(); export const deleteConnectorById = async (id: string) => authedAdminApi.delete({ url: `connectors/${id}` }).json(); -export const updateConnectorConfig = async (connectorId: string, config: Record) => +export const updateConnectorConfig = async ( + connectorId: string, + config: Record, + metadata?: Record +) => authedAdminApi .patch({ url: `connectors/${connectorId}`, - json: { config }, + json: { config, metadata }, }) .json(); diff --git a/packages/integration-tests/src/tests/api/connector.test.ts b/packages/integration-tests/src/tests/api/connector.test.ts index 00c3d1dca..bbf5d4208 100644 --- a/packages/integration-tests/src/tests/api/connector.test.ts +++ b/packages/integration-tests/src/tests/api/connector.test.ts @@ -71,13 +71,18 @@ test('connector set-up flow', async () => { /* * Change to another SMS/Email connector */ - const { id } = await postConnector(mockStandardEmailConnectorId); - await updateConnectorConfig(id, mockStandardEmailConnectorConfig); + const { id } = await postConnector(mockStandardEmailConnectorId, { + target: 'mock-standard-mail', + }); // TODO [LOG-4862]: update mock connector + await updateConnectorConfig(id, mockStandardEmailConnectorConfig, { + target: 'mock-standard-mail', + }); // TODO [LOG-4862]: update mock connector connectorIdMap.set(mockStandardEmailConnectorId, id); const currentConnectors = await listConnectors(); expect( currentConnectors.some((connector) => connector.connectorId === mockEmailConnectorId) ).toBeFalsy(); + connectorIdMap.delete(mockEmailConnectorId); expect( currentConnectors.some((connector) => connector.connectorId === mockStandardEmailConnectorId) ).toBeTruthy(); @@ -85,7 +90,6 @@ test('connector set-up flow', async () => { currentConnectors.find((connector) => connector.connectorId === mockStandardEmailConnectorId) ?.config ).toEqual(mockStandardEmailConnectorConfig); - connectorIdMap.delete(mockEmailConnectorId); /* * Delete (i.e. disable) a connector diff --git a/packages/phrases/src/locales/de/errors.ts b/packages/phrases/src/locales/de/errors.ts index 00bcdeefa..a5097f1dd 100644 --- a/packages/phrases/src/locales/de/errors.ts +++ b/packages/phrases/src/locales/de/errors.ts @@ -112,6 +112,8 @@ const errors = { can_not_modify_target: 'The connector target can not be modified.', multiple_target_with_same_platform: 'You can not have multiple social connectors that have same target and platform.', + cannot_change_metadata_for_non_standard_connector: + "This connector's `metadata` cannot be changed.", }, passcode: { phone_email_empty: 'Telefonnummer oder E-Mail darf nicht leer sein.', diff --git a/packages/phrases/src/locales/de/translation/admin-console/application-details.ts b/packages/phrases/src/locales/de/translation/admin-console/application-details.ts index 5a906234a..b804c71d4 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/application-details.ts @@ -33,7 +33,6 @@ const application_details = { cors_allowed_origins_placeholder: 'https://your.website.de', cors_allowed_origins_tip: 'Es sind standardmäßig alle Umleitungs-URI Origins erlaubt. Normalerweise ist dieses Feld nicht erforderlich. See the MDN doc for detailed info.', // UNTRANSLATED - add_another: 'Weitere hinzufügen', id_token_expiration: 'ID Token Ablaufzeit', refresh_token_expiration: 'Refresh Token Ablaufzeit', token_endpoint: 'Token Endpoint', diff --git a/packages/phrases/src/locales/de/translation/admin-console/general.ts b/packages/phrases/src/locales/de/translation/admin-console/general.ts index f8d3bbe52..03af0d8ec 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/general.ts @@ -30,7 +30,7 @@ const general = { copying: 'Kopiere', copied: 'Kopiert', required: 'Erforderlich', - add_another: '+ Weitere hinzufügen', + add_another: 'Weitere hinzufügen', deletion_confirmation: 'Willst du {{title}} wirklich löschen?', settings_nav: 'Einstellungen', unsaved_changes_warning: diff --git a/packages/phrases/src/locales/en/errors.ts b/packages/phrases/src/locales/en/errors.ts index ffe1a535e..eed909db1 100644 --- a/packages/phrases/src/locales/en/errors.ts +++ b/packages/phrases/src/locales/en/errors.ts @@ -111,6 +111,8 @@ const errors = { can_not_modify_target: 'The connector target can not be modified.', multiple_target_with_same_platform: 'You can not have multiple social connectors that have same target and platform.', + cannot_change_metadata_for_non_standard_connector: + "This connector's `metadata` cannot be changed.", }, passcode: { phone_email_empty: 'Both phone and email are empty.', diff --git a/packages/phrases/src/locales/en/translation/admin-console/application-details.ts b/packages/phrases/src/locales/en/translation/admin-console/application-details.ts index 71d51326c..4d6724103 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/application-details.ts @@ -33,7 +33,6 @@ const application_details = { cors_allowed_origins_placeholder: 'https://your.website.com', cors_allowed_origins_tip: 'By default, all the origins of Redirect URIs will be allowed. Usually no action is required for this field. See the MDN doc for detailed info.', - add_another: 'Add Another', id_token_expiration: 'ID Token expiration', refresh_token_expiration: 'Refresh Token expiration', token_endpoint: 'Token Endpoint', diff --git a/packages/phrases/src/locales/en/translation/admin-console/general.ts b/packages/phrases/src/locales/en/translation/admin-console/general.ts index 8ee71ab3d..809110051 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/general.ts @@ -30,7 +30,7 @@ const general = { copying: 'Copying', copied: 'Copied', required: 'Required', - add_another: '+ Add Another', + add_another: 'Add Another', deletion_confirmation: 'Are you sure you want to delete this {{title}}?', settings_nav: 'Settings', unsaved_changes_warning: 'You have made some changes. Are you sure you want to leave this page?', diff --git a/packages/phrases/src/locales/fr/errors.ts b/packages/phrases/src/locales/fr/errors.ts index dd75d6499..97ff0bec0 100644 --- a/packages/phrases/src/locales/fr/errors.ts +++ b/packages/phrases/src/locales/fr/errors.ts @@ -118,6 +118,8 @@ const errors = { can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED multiple_target_with_same_platform: 'You can not have multiple social connectors that have same target and platform.', // UNTRANSLATED + cannot_change_metadata_for_non_standard_connector: + "This connector's `metadata` cannot be changed.", // UNTRANSLATED }, passcode: { phone_email_empty: "Le téléphone et l'email sont vides.", diff --git a/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts b/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts index c927d50ad..73fb6ec15 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts @@ -33,7 +33,6 @@ const application_details = { cors_allowed_origins_placeholder: 'https://votre.site.com', cors_allowed_origins_tip: "Par défaut, toutes les origines des URI de redirection seront autorisées. En général, aucune action n'est requise pour ce champ. See the MDN doc for detailed info.", // UNTRANSLATED - add_another: 'Ajouter un autre', id_token_expiration: "Expiration du jeton d'identification", refresh_token_expiration: "Rafraîchir l'expiration du jeton", token_endpoint: 'Token Endpoint', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/general.ts b/packages/phrases/src/locales/fr/translation/admin-console/general.ts index 2c584e716..cf7a76f47 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/general.ts @@ -30,7 +30,7 @@ const general = { copying: 'Copie', copied: 'Copié', required: 'Requis', - add_another: '+ Ajouter un autre', + add_another: 'Ajouter un autre', deletion_confirmation: 'Êtes-vous sûr de vouloir supprimer ce {{title}} ?', settings_nav: 'Paramètres', unsaved_changes_warning: diff --git a/packages/phrases/src/locales/ko/errors.ts b/packages/phrases/src/locales/ko/errors.ts index 2cf32646b..f1ee88d42 100644 --- a/packages/phrases/src/locales/ko/errors.ts +++ b/packages/phrases/src/locales/ko/errors.ts @@ -110,6 +110,8 @@ const errors = { can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED multiple_target_with_same_platform: 'You can not have multiple social connectors that have same target and platform.', // UNTRANSLATED + cannot_change_metadata_for_non_standard_connector: + "This connector's `metadata` cannot be changed.", // UNTRANSLATED }, passcode: { phone_email_empty: '휴대전화번호 그리고 이메일이 비어있어요.', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts b/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts index f611c5229..dd92631c9 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts @@ -33,7 +33,6 @@ const application_details = { cors_allowed_origins_placeholder: 'https://your.website.com', cors_allowed_origins_tip: '기본으로 모든 리다이렉트의 오리진들은 허용되요. 대체적으로 이 값을 건들 필요는 없어요. See the MDN doc for detailed info.', // UNTRANSLATED - add_another: '새로 추가', id_token_expiration: 'ID 토큰 만료', refresh_token_expiration: 'Refresh 토큰 만료', token_endpoint: '토큰 End-Point', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/general.ts b/packages/phrases/src/locales/ko/translation/admin-console/general.ts index 65468a1f5..a0917946c 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/general.ts @@ -30,7 +30,7 @@ const general = { copying: '복사 중', copied: '복사됨', required: '필수', - add_another: '+ 새로 추가', + add_another: '새로 추가', deletion_confirmation: '정말로 {{title}}을/를 삭제할까요?', settings_nav: '설정', unsaved_changes_warning: '수정된 내용이 있어요. 정말로 현재 페이지를 벗어날까요?', diff --git a/packages/phrases/src/locales/pt-br/errors.ts b/packages/phrases/src/locales/pt-br/errors.ts index fc22265e5..71439ef8a 100644 --- a/packages/phrases/src/locales/pt-br/errors.ts +++ b/packages/phrases/src/locales/pt-br/errors.ts @@ -115,6 +115,8 @@ const errors = { can_not_modify_target: 'O destino do conector não pode ser modificado.', multiple_target_with_same_platform: 'Você não pode ter vários conectores sociais com o mesmo destino e plataforma.', + cannot_change_metadata_for_non_standard_connector: + "This connector's `metadata` cannot be changed.", // UNTRANSLATED }, passcode: { phone_email_empty: 'Telefone e e-mail estão vazios.', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts index daab4da54..e84b034c7 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts @@ -33,7 +33,6 @@ const application_details = { cors_allowed_origins_placeholder: 'https://your.website.com', cors_allowed_origins_tip: 'Por padrão, todas as origens de URIs de redirecionamento serão permitidas. Normalmente, nenhuma ação é necessária para este campo. See the MDN doc for detailed info.', // UNTRANSLATED - add_another: 'Adicionar outro', id_token_expiration: 'Expiração do token de ID', refresh_token_expiration: 'Expiração Refresh Token', token_endpoint: 'Token Endpoint', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts index ff8c68750..a640d2e5f 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts @@ -30,7 +30,7 @@ const general = { copying: 'Copiando', copied: 'Copiado', required: 'Obrigatório', - add_another: '+ Adicionar outro', + add_another: 'Adicionar outro', deletion_confirmation: 'Tem certeza de que deseja excluir este {{title}}?', settings_nav: 'Configurações', unsaved_changes_warning: diff --git a/packages/phrases/src/locales/pt-pt/errors.ts b/packages/phrases/src/locales/pt-pt/errors.ts index df664d633..919084e60 100644 --- a/packages/phrases/src/locales/pt-pt/errors.ts +++ b/packages/phrases/src/locales/pt-pt/errors.ts @@ -113,6 +113,8 @@ const errors = { can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED multiple_target_with_same_platform: 'You can not have multiple social connectors that have same target and platform.', // UNTRANSLATED + cannot_change_metadata_for_non_standard_connector: + "This connector's `metadata` cannot be changed.", // UNTRANSLATED }, passcode: { phone_email_empty: 'O campos telefone e email estão vazios.', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts index 29f16112b..7bbbf69de 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts @@ -33,7 +33,6 @@ const application_details = { cors_allowed_origins_placeholder: 'https://your.website.com', cors_allowed_origins_tip: 'Por padrão, todas as origens de redirecionamento serão permitidas. Recomenda-se restringir isto. See the MDN doc for detailed info.', // UNTRANSLATED - add_another: 'Adicionar outro', id_token_expiration: 'Expiração do token de ID', refresh_token_expiration: 'Expiração do token de atualização', token_endpoint: 'Endpoint Token', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts index b0560d298..becbc80e5 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts @@ -30,7 +30,7 @@ const general = { copying: 'Copiando', copied: 'Copiado', required: 'Necessário', - add_another: '+ Adicionar outro', + add_another: 'Adicionar outro', deletion_confirmation: 'Tem a certeza que deseja eliminar isso {{title}}?', settings_nav: 'Definições', unsaved_changes_warning: 'Fez algumas alterações. Tem a certeza que deseja sair desta página?', diff --git a/packages/phrases/src/locales/tr-tr/errors.ts b/packages/phrases/src/locales/tr-tr/errors.ts index 5c8343819..a213c2254 100644 --- a/packages/phrases/src/locales/tr-tr/errors.ts +++ b/packages/phrases/src/locales/tr-tr/errors.ts @@ -112,6 +112,8 @@ const errors = { can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED multiple_target_with_same_platform: 'You can not have multiple social connectors that have same target and platform.', // UNTRANSLATED + cannot_change_metadata_for_non_standard_connector: + "This connector's `metadata` cannot be changed.", // UNTRANSLATED }, passcode: { phone_email_empty: 'Hem telefon hem de e-posta adresi yok.', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts index 5b2d977fd..408fd0747 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts @@ -33,7 +33,6 @@ const application_details = { cors_allowed_origins_placeholder: 'https://your.website.com', cors_allowed_origins_tip: 'Varsayılan olarak, Yönlendirme URIlerinin tüm originlerine izin verilir. Genellikle bu alan için herhangi bir işlem gerekmez. See the MDN doc for detailed info.', // UNTRANSLATED - add_another: 'Bir tane daha ekle', id_token_expiration: 'ID Token sona erme süresi', refresh_token_expiration: 'Refresh Token sona erme süresi', token_endpoint: 'Token bitiş noktası', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts index 59be64348..7e715c678 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts @@ -30,7 +30,7 @@ const general = { copying: 'Kopyalanıyor', copied: 'Kopyalandı', required: 'Gerekli', - add_another: '+ Bir tane daha ekle', + add_another: 'Bir tane daha ekle', deletion_confirmation: 'Bu dosyayı silmek istediğinize emin misiniz: {{title}}?', settings_nav: 'Ayarlar', unsaved_changes_warning: diff --git a/packages/phrases/src/locales/zh-cn/errors.ts b/packages/phrases/src/locales/zh-cn/errors.ts index c432762e6..a4b3f66f4 100644 --- a/packages/phrases/src/locales/zh-cn/errors.ts +++ b/packages/phrases/src/locales/zh-cn/errors.ts @@ -103,6 +103,7 @@ const errors = { invalid_type_for_syncing_profile: '只有社交连接器可以开启用户档案同步。', can_not_modify_target: '不可修改连接器 target。', multiple_target_with_same_platform: '不能同时存在多个有相同 target 和平台类型的社交连接器。', + cannot_change_metadata_for_non_standard_connector: '不可配置该连接器的 metadata 参数。', }, passcode: { phone_email_empty: '手机号与邮箱地址均为空', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts index 4f0821285..a75e1a1b0 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts @@ -33,7 +33,6 @@ const application_details = { cors_allowed_origins_placeholder: 'https://your.website.com', cors_allowed_origins_tip: '所有 Redirect URI 的 origin 将默认被允许。通常不需要对此字段进行操作。参见 MDN 文档以了解更多', - add_another: '新增', id_token_expiration: 'ID Token 过期时间', refresh_token_expiration: 'Refresh Token 过期时间', token_endpoint: 'Token Endpoint', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts index 112557c35..44c7c4a3f 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts @@ -30,7 +30,7 @@ const general = { copying: '复制中', copied: '已复制', required: '必填', - add_another: '+ 新增', + add_another: '新增', deletion_confirmation: '你确定要删除这个 {{title}} 吗?', settings_nav: '设置', unsaved_changes_warning: '还有未保存的变更, 确定要离开吗?',