From 418c09faeb9fa10082f29721e3880024f885e335 Mon Sep 17 00:00:00 2001 From: Tommy Petty Date: Thu, 2 Nov 2023 16:18:02 -0400 Subject: [PATCH] feat(i18n): adds translation for desk panes (#5085) --- .../sanity/src/core/i18n/bundles/studio.ts | 3 + packages/sanity/src/desk/i18n/resources.ts | 157 ++++++++++++++++++ .../document/DocumentOperationResults.tsx | 40 +---- .../src/desk/panes/document/DocumentPane.tsx | 48 ++++-- .../panes/document/DocumentPaneProvider.tsx | 4 +- .../documentPanel/DeletedDocumentBanner.tsx | 8 +- .../documentPanel/PermissionCheckBanner.tsx | 15 +- .../documentPanel/ReferenceChangedBanner.tsx | 22 ++- .../documentPanel/documentViews/FormView.tsx | 11 +- .../header/DocumentHeaderTitle.test.tsx | 121 ++++++++++---- .../header/DocumentHeaderTitle.tsx | 24 ++- .../header/DocumentPanelHeader.tsx | 12 +- .../panes/document/inspectDialog/Search.tsx | 5 +- .../validation/ValidationInspector.tsx | 2 +- .../document/statusBar/ActionMenuButton.tsx | 10 +- .../document/statusBar/ActionStateDialog.tsx | 1 + .../desk/panes/document/timeline/timeline.tsx | 2 +- .../panes/documentList/DocumentListPane.tsx | 16 +- .../documentList/DocumentListPaneContent.tsx | 32 +++- .../desk/panes/unknown/UnknownPaneType.tsx | 2 +- .../sanity/test/testUtils/TestProvider.tsx | 10 +- 21 files changed, 418 insertions(+), 127 deletions(-) diff --git a/packages/sanity/src/core/i18n/bundles/studio.ts b/packages/sanity/src/core/i18n/bundles/studio.ts index a82b60410e4c..cc7faa22c5aa 100644 --- a/packages/sanity/src/core/i18n/bundles/studio.ts +++ b/packages/sanity/src/core/i18n/bundles/studio.ts @@ -68,6 +68,9 @@ export const studioLocaleStrings = { /** Label for loading history */ 'timeline.loading-history': 'Loading history', + /** The aria-label for the list of revisions in the timeline */ + 'timeline.list.aria-label': 'Document revisions', + /** * Label for determining since which version the changes for timeline menu dropdown are showing. * Receives the time label as a parameter. diff --git a/packages/sanity/src/desk/i18n/resources.ts b/packages/sanity/src/desk/i18n/resources.ts index a30801bd2aae..30ef9eb8a41d 100644 --- a/packages/sanity/src/desk/i18n/resources.ts +++ b/packages/sanity/src/desk/i18n/resources.ts @@ -166,6 +166,160 @@ const deskLocaleStrings = { /** --- "PRODUCTION PREVIEW", eg link to content --- */ 'production-preview.menu-item.title': 'Open preview', + /** -- DESK PANES -- */ + /** The tool tip for the split pane button on the document panel header */ + 'buttons.split-pane-button.tooltip': 'Split pane right', + + /** The aria-label for the split pane button on the document panel header */ + 'buttons.split-pane-button.aria-label': 'Split pane right', + + /** The title for the close button on the split pane on the document panel header */ + 'buttons.split-pane-close-button.title': 'Close split pane', + + /** The title for the close group button on the split pane on the document panel header */ + 'buttons.split-pane-close-group-button.title': 'Close pane group', + + /** The text content for the deleted document banner */ + 'banners.deleted-document-banner.text': 'This document has been deleted.', + + /** The text for the restore button on the deleted document banner */ + 'banners.deleted-document-banner.restore-button.text': 'Restore most recent version', + + /** The text for the reference change banner if the reason is that the reference has been changed */ + 'banners.reference-changed-banner.reason-changed.text': + 'This reference has changed since you opened it.', + + /** The text for the reload button */ + 'banners.reference-changed-banner.reason-changed.reload-button.text': 'Reload reference', + + /** The text for the reference change banner if the reason is that the reference has been deleted */ + 'banners.reference-changed-banner.reason-removed.text': + 'This reference has been removed since you opened it.', + + /** The text for the close button */ + 'banners.reference-changed-banner.reason-removed.close-button.text': 'Close reference', + + /** The text for the permission check banner if there is only one role */ + 'banners.permission-check-banner.singular-role.text': + 'Your role {{roles}} does not have permissions to {{requiredPermission}} this document.', + + /** The text for the permission check banner if there is are multiple roles */ + 'banners.permission-check-banner.plural-roles.text': + 'Your roles {{roles}} do not have permissions to {{requiredPermission}} this document.', + + /** The text for when a form is hidden */ + 'document-view.form-view.form-hidden': 'This form is hidden', + + /** The text for when the form view is loading a document */ + 'document-view.form-view.loading': 'Loading document', + + /** The title of the sync lock toast on the form view */ + 'document-view.form-view.sync-lock-toast.title': 'Syncing document…', + + /** The description of the sync lock toast on the form view */ + 'document-view.form-view.sync-lock-toast.description': + 'Please hold tight while the document is synced. This usually happens right after the document has been published, and it should not take more than a few seconds', + + /** The title of the reconnecting toast */ + 'panes.document-pane-provider.reconnecting.title': 'Connection lost. Reconnecting…', + + /** The loading message for the document not found pane */ + 'panes.document-pane.document-not-found.loading': 'Loading document…', + + /** The title of the document not found pane if the schema is known */ + 'panes.document-pane.document-not-found.title': 'The document was not found', + + /** The text of the document not found pane if the schema is known */ + 'panes.document-pane.document-not-found.text': + 'The document type is not defined, and a document with the {{id}} identifier could not be found.', + + /** The title of the document not found pane if the schema is not found or unknown */ + 'panes.document-pane.document-unknown-type.title': + 'Unknown document type: {{documentType}}', + + /** The text of the document not found pane if the schema is not found */ + 'panes.document-pane.document-unknown-type.text': + 'This document has the schema type {{documentType}}, which is not defined as a type in the local content studio schema.', + + /** The title of the document not found pane if the schema is unknown */ + 'panes.document-pane.document-unknown-type.without-schema.text': + 'This document does not exist, and no schema type was specified for it.', + + /** The text of the document list pane if more than a maximum number of documents are returned */ + 'panes.document-list-pane.max-items.text': 'Displaying a maximum of {{limit}} documents', + + /** The text of the document list pane if no documents are found */ + 'panes.document-list-pane.no-documents.text': 'No results found', + + /** The text of the document list pane if no documents are found matching specified criteria */ + 'panes.document-list-pane.no-matching-documents.text': 'No matching documents', + + /** The text of the document list pane if no documents are found for a specified type */ + 'panes.document-list-pane.no-documents-of-type.text': 'No documents of this type', + + /** The error title on the document list pane */ + 'panes.document-list-pane.error.title': 'Could not fetch list items', + + /** The error text on the document list pane */ + 'panes.document-list-pane.error.text': 'Error: {{error}}', + + /** The text for the retry button on the document list pane */ + 'panes.document-list-pane.error.retry-button.text': 'Retry', + + /** The summary title when displaying an error for a document operation result */ + 'panes.document-operation-results.error.summary.title': 'Details', + + /** The text when a delete operation failed */ + 'panes.document-operation-results.operation-error_delete': + 'An error occurred while attempting to delete this document. This usually means that there are other documents that refers to it.', + + /** The text when an unpublish operation failed */ + 'panes.document-operation-results.operation-error_unpublish': + 'An error occurred while attempting to unpublish this document. This usually means that there are other documents that refers to it.', + + /** The text when a generic operation failed */ + 'panes.document-operation-results.operation-error': 'An error occurred during {{context}}', + + /** The text when a publish operation succeded */ + 'panes.document-operation-results.operation-success_publish': 'The document was published', + + /** The text when an unpublish operation succeded */ + 'panes.document-operation-results.operation-success_unpublish': + 'The document was unpublished. A draft has been created from the latest published version.', + + /** The text when a discard changes operation succeded */ + 'panes.document-operation-results.operation-success_discardChanges': + 'All changes since last publish has now been discarded. The discarded draft can still be recovered from history', + + /** The text when a delete operation succeded */ + 'panes.document-operation-results.operation-success_delete': + 'The document was successfully deleted', + + /** The text when a generic operation succeded */ + 'panes.document-operation-results.operation-success': + 'Successfully performed {{context}} on document', + + /** The text used in the document header title if creating a new item */ + 'panes.document-header-title.new.text': 'New {{schemaType}}', + + /** The text used in the document header title if there is an error */ + 'panes.document-header-title.error.text': 'Error: {{error}}', + + /** The text used in the document header title if no other title can be determined */ + 'panes.document-header-title.untitled.text': 'Untitled', + + /** The aria-label for the search input on the document list pane */ + 'panes.document-list-pane.search-input.aria-label': 'Search list', + + /** The search input for the search input on the document list pane */ + 'panes.document-list-pane.search-input.placeholder': 'Search list', + + /** The action menu button aria-label */ + 'buttons.action-menu-button.aria-label': 'Open document actions', + + /** the placeholder text for the search input on the inspect dialog */ + 'inputs.inspect-dialog.search.placeholder': 'Search', + /** -- UNKNOWN PANE TYPE */ /** The text to display when type is missing */ @@ -175,6 +329,9 @@ const deskLocaleStrings = { /** The text to display when type is unknown */ 'panes.unknown-pane-type.unknown-type.text': 'Structure item of type {{type}} is not a known entity.', + + /** The title of the unknown pane */ + 'panes.unknown-pane-type.title': 'Unknown pane type', } /** diff --git a/packages/sanity/src/desk/panes/document/DocumentOperationResults.tsx b/packages/sanity/src/desk/panes/document/DocumentOperationResults.tsx index 089c173a5d94..cfb9b3fabd8a 100644 --- a/packages/sanity/src/desk/panes/document/DocumentOperationResults.tsx +++ b/packages/sanity/src/desk/panes/document/DocumentOperationResults.tsx @@ -1,36 +1,9 @@ import {useToast} from '@sanity/ui' import React, {memo, useEffect, useRef} from 'react' import {useDocumentPane} from './useDocumentPane' -import {useDocumentOperationEvent} from 'sanity' +import {useDocumentOperationEvent, useTranslation} from 'sanity' import {usePaneRouter} from '../../components' - -function getOpErrorTitle(op: string): string { - if (op === 'delete') { - return `An error occurred while attempting to delete this document. - This usually means that there are other documents that refers to it.` - } - if (op === 'unpublish') { - return `An error occurred while attempting to unpublish this document. - This usually means that there are other documents that refers to it.` - } - return `An error occurred during ${op}` -} - -function getOpSuccessTitle(op: string): string { - if (op === 'publish') { - return `The document was published` - } - if (op === 'unpublish') { - return `The document was unpublished. A draft has been created from the latest published version.` - } - if (op === 'discardChanges') { - return `All changes since last publish has now been discarded. The discarded draft can still be recovered from history` - } - if (op === 'delete') { - return `The document was successfully deleted` - } - return `Successfully performed ${op} on document` -} +import {deskLocaleNamespace} from '../../i18n' const IGNORE_OPS = ['patch', 'commit'] @@ -40,6 +13,7 @@ export const DocumentOperationResults = memo(function DocumentOperationResults() const event: any = useDocumentOperationEvent(documentId, documentType) const prevEvent = useRef(event) const paneRouter = usePaneRouter() + const {t} = useTranslation(deskLocaleNamespace) useEffect(() => { if (!event || event === prevEvent.current) return @@ -51,10 +25,10 @@ export const DocumentOperationResults = memo(function DocumentOperationResults() closable: true, duration: 30000, // 30s status: 'error', - title: getOpErrorTitle(event.op), + title: t('panes.document-operation-results.operation-error', {context: event.op}), description: (
- Details + {t('panes.document-operation-results.error.summary.title')} {event.error.message}
), @@ -65,7 +39,7 @@ export const DocumentOperationResults = memo(function DocumentOperationResults() pushToast({ closable: true, status: 'success', - title: getOpSuccessTitle(event.op), + title: t('panes.document-operation-results.operation-success', {context: event.op}), }) } @@ -81,7 +55,7 @@ export const DocumentOperationResults = memo(function DocumentOperationResults() // eslint-disable-next-line consistent-return return () => clearTimeout(cleanupId) - }, [event, paneRouter, pushToast]) + }, [event, paneRouter, pushToast, t]) return null }) diff --git a/packages/sanity/src/desk/panes/document/DocumentPane.tsx b/packages/sanity/src/desk/panes/document/DocumentPane.tsx index 7f1e090700ae..c622c743474b 100644 --- a/packages/sanity/src/desk/panes/document/DocumentPane.tsx +++ b/packages/sanity/src/desk/panes/document/DocumentPane.tsx @@ -31,15 +31,18 @@ import { DOCUMENT_PANEL_INITIAL_MIN_WIDTH, DOCUMENT_PANEL_MIN_WIDTH, } from './constants' +import {deskLocaleNamespace} from '../../i18n' import { ChangeConnectorRoot, ReferenceInputOptionsProvider, SourceProvider, isDev, + Translate, useDocumentType, useSource, useTemplatePermissions, useTemplates, + useTranslation, useZIndex, } from 'sanity' @@ -121,8 +124,17 @@ function DocumentPaneInner(props: DocumentPaneProviderProps) { : {path: [], state: 'none'} }, [parentRefPath, groupIndex, routerPanesStateLength]) + const {t} = useTranslation(deskLocaleNamespace) + if (options.type === '*' && !isLoaded) { - return + return ( + + ) } if (!documentType) { @@ -131,12 +143,16 @@ function DocumentPaneInner(props: DocumentPaneProviderProps) { flex={2.5} minWidth={320} paneKey={paneKey} - title={<>The document was not found} + title={t('panes.document-pane.document-not-found.title')} > - The document type is not defined, and a document with the {options.id}{' '} - identifier could not be found. + {children}}} + values={{id: options.id}} + /> @@ -243,6 +259,7 @@ function InnerDocumentPane() { DOCUMENT_PANEL_INITIAL_MIN_WIDTH + (inspector ? DOCUMENT_INSPECTOR_MIN_WIDTH : 0) const minWidth = DOCUMENT_PANEL_MIN_WIDTH + (inspector ? DOCUMENT_INSPECTOR_MIN_WIDTH : 0) + const {t} = useTranslation(deskLocaleNamespace) if (!schemaType) { return ( @@ -252,27 +269,33 @@ function InnerDocumentPane() { minWidth={minWidth} paneKey={paneKey} title={ - <> - Unknown document type: {documentType} - + {children}}} + values={{documentType}} + /> } tone="caution" > {documentType && ( - This document has the schema type {documentType}, which is not defined as - a type in the local content studio schema. + {children}}} + values={{documentType}} + /> )} {!documentType && ( - - This document does not exist, and no schema type was specified for it. - + {t('panes.document-pane.document-unknown-type.without-schema.text')} )} {isDev && value && ( + /* eslint-disable i18next/no-literal-string */ <> Here is the JSON representation of the document: @@ -281,6 +304,7 @@ function InnerDocumentPane() { + /* eslint-enable i18next/no-literal-string */ )} diff --git a/packages/sanity/src/desk/panes/document/DocumentPaneProvider.tsx b/packages/sanity/src/desk/panes/document/DocumentPaneProvider.tsx index d7f3cc4e5b14..5c5042d88e16 100644 --- a/packages/sanity/src/desk/panes/document/DocumentPaneProvider.tsx +++ b/packages/sanity/src/desk/panes/document/DocumentPaneProvider.tsx @@ -661,10 +661,10 @@ export const DocumentPaneProvider = memo((props: DocumentPaneProviderProps) => { pushToast({ id: 'sanity/desk/reconnecting', status: 'warning', - title: <>Connection lost. Reconnecting…, + title: t('panes.document-pane-provider.reconnecting.title'), }) } - }, [connectionState, pushToast]) + }, [connectionState, pushToast, t]) const disableBlurRef = useRef(false) diff --git a/packages/sanity/src/desk/panes/document/documentPanel/DeletedDocumentBanner.tsx b/packages/sanity/src/desk/panes/document/documentPanel/DeletedDocumentBanner.tsx index f4bca949be4a..e932b94f7df3 100644 --- a/packages/sanity/src/desk/panes/document/documentPanel/DeletedDocumentBanner.tsx +++ b/packages/sanity/src/desk/panes/document/documentPanel/DeletedDocumentBanner.tsx @@ -3,8 +3,9 @@ import {Button, Card, Container, Flex, Text} from '@sanity/ui' import {ReadOnlyIcon} from '@sanity/icons' import styled from 'styled-components' import {useDocumentPane} from '../useDocumentPane' -import {useDocumentOperation} from 'sanity' +import {useDocumentOperation, useTranslation} from 'sanity' import {useRouter} from 'sanity/router' +import {deskLocaleNamespace} from '../../../i18n' const Root = styled(Card)` position: relative; @@ -25,6 +26,7 @@ export function DeletedDocumentBanner({revisionId}: DeletedDocumentBannerProps) navigateIntent('edit', {id: documentId, type: documentType}) } }, [documentId, documentType, navigateIntent, restore, revisionId]) + const {t} = useTranslation(deskLocaleNamespace) return ( @@ -35,7 +37,7 @@ export function DeletedDocumentBanner({revisionId}: DeletedDocumentBannerProps) - This document has been deleted. + {t('banners.deleted-document-banner.text')} {revisionId && (