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

feat(i18n): adds translation for desk panes #5085

Merged
merged 6 commits into from
Nov 2, 2023
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
3 changes: 3 additions & 0 deletions packages/sanity/src/core/i18n/bundles/studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
157 changes: 157 additions & 0 deletions packages/sanity/src/desk/i18n/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Code>{{id}}</Code> identifier could not be found.',
jtpetty marked this conversation as resolved.
Show resolved Hide resolved

/** 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: <Code>{{documentType}}</Code>',

/** 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 <Code>{{documentType}}</Code>, 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: <Code>{{error}}</Code>',

/** 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 */
Expand All @@ -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 <Code>{{type}}</Code> is not a known entity.',

/** The title of the unknown pane */
'panes.unknown-pane-type.title': 'Unknown pane type',
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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']

Expand All @@ -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
Expand All @@ -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>
<summary>Details</summary>
<summary>{t('panes.document-operation-results.error.summary.title')}</summary>
{event.error.message}
</details>
),
Expand All @@ -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}),
})
}

Expand All @@ -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
})
48 changes: 36 additions & 12 deletions packages/sanity/src/desk/panes/document/DocumentPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -119,8 +122,17 @@ function DocumentPaneInner(props: DocumentPaneProviderProps) {
: {path: [], state: 'none'}
}, [parentRefPath, groupIndex, routerPanesStateLength])

const {t} = useTranslation(deskLocaleNamespace)

if (options.type === '*' && !isLoaded) {
return <LoadingPane flex={2.5} minWidth={320} paneKey={paneKey} title="Loading document…" />
return (
<LoadingPane
flex={2.5}
minWidth={320}
paneKey={paneKey}
title={t('panes.document-pane.document-not-found.loading')}
/>
)
}

if (!documentType) {
Expand All @@ -129,12 +141,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')}
>
<Stack space={4}>
<Text as="p">
The document type is not defined, and a document with the <code>{options.id}</code>{' '}
identifier could not be found.
<Translate
t={t}
i18nKey="panes.document-pane.document-not-found.text"
components={{Code: ({children}) => <code>{children}</code>}}
values={{id: options.id}}
/>
</Text>
</Stack>
</ErrorPane>
Expand Down Expand Up @@ -241,6 +257,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 (
Expand All @@ -250,27 +267,33 @@ function InnerDocumentPane() {
minWidth={minWidth}
paneKey={paneKey}
title={
<>
Unknown document type: <code>{documentType}</code>
</>
<Translate
t={t}
i18nKey="panes.document-pane.document-unknown-type.title"
components={{Code: ({children}) => <code>{children}</code>}}
values={{documentType}}
/>
}
tone="caution"
>
<Stack space={4}>
{documentType && (
<Text as="p">
This document has the schema type <code>{documentType}</code>, which is not defined as
a type in the local content studio schema.
<Translate
t={t}
i18nKey="panes.document-pane.document-unknown-type.text"
components={{Code: ({children}) => <code>{children}</code>}}
values={{documentType}}
/>
</Text>
)}

{!documentType && (
<Text as="p">
This document does not exist, and no schema type was specified for it.
</Text>
<Text as="p">{t('panes.document-pane.document-unknown-type.without-schema.text')}</Text>
)}

{isDev && value && (
/* eslint-disable i18next/no-literal-string */
<>
<Text as="p">Here is the JSON representation of the document:</Text>
<Card padding={3} overflow="auto" radius={2} shadow={1} tone="inherit">
Expand All @@ -279,6 +302,7 @@ function InnerDocumentPane() {
</Code>
</Card>
</>
/* eslint-enable i18next/no-literal-string */
)}
</Stack>
</ErrorPane>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -643,10 +643,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])

// Reset `focusPath` when `documentId` or `params.path` changes
useEffect(() => {
Expand Down
Loading
Loading