From 6758380e5dd81ed9802b486b91e3212d3b666418 Mon Sep 17 00:00:00 2001 From: Luigi Garcia Date: Thu, 7 Mar 2024 14:55:37 +0000 Subject: [PATCH 1/3] feat: allow nested languageField on documents --- package-lock.json | 6 ++++++ package.json | 1 + src/actions/DeleteTranslationAction.tsx | 3 ++- src/badges/index.tsx | 3 ++- src/components/DocumentInternationalizationMenu.tsx | 3 ++- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 75b2253d..2b61c89e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@sanity/incompatible-plugin": "^1.0.4", "@sanity/ui": "^1.2.2", "@sanity/uuid": "^3.0.2", + "just-safe-get": "^4.2.0", "sanity-plugin-internationalized-array": "^1.10.3", "sanity-plugin-utils": "^1.6.2" }, @@ -10961,6 +10962,11 @@ "node": ">=4.0" } }, + "node_modules/just-safe-get": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/just-safe-get/-/just-safe-get-4.2.0.tgz", + "integrity": "sha512-+tS4Bvgr/FnmYxOGbwziJ8I2BFk+cP1gQHm6rm7zo61w1SbxBwWGEq/Ryy9Gb6bvnloPq6pz7Bmm4a0rjTNlXA==" + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", diff --git a/package.json b/package.json index c6f83954..211a9888 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "@sanity/incompatible-plugin": "^1.0.4", "@sanity/ui": "^1.2.2", "@sanity/uuid": "^3.0.2", + "just-safe-get": "^4.2.0", "sanity-plugin-internationalized-array": "^1.10.3", "sanity-plugin-utils": "^1.6.2" }, diff --git a/src/actions/DeleteTranslationAction.tsx b/src/actions/DeleteTranslationAction.tsx index dd9ad203..e2dd1c9d 100644 --- a/src/actions/DeleteTranslationAction.tsx +++ b/src/actions/DeleteTranslationAction.tsx @@ -1,5 +1,6 @@ import {TrashIcon} from '@sanity/icons' import {ButtonTone, useToast} from '@sanity/ui' +import get from 'just-safe-get' import {useCallback, useState} from 'react' import {DocumentActionComponent, SanityDocument, useClient} from 'sanity' @@ -16,7 +17,7 @@ export const DeleteTranslationAction: DocumentActionComponent = (props) => { const [isDialogOpen, setDialogOpen] = useState(false) const [translations, setTranslations] = useState([]) const onClose = useCallback(() => setDialogOpen(false), []) - const documentLanguage = doc ? doc[languageField] : null + const documentLanguage = doc ? get(doc, languageField) : null const toast = useToast() const client = useClient({apiVersion: API_VERSION}) diff --git a/src/badges/index.tsx b/src/badges/index.tsx index 8cab84bf..12405c04 100644 --- a/src/badges/index.tsx +++ b/src/badges/index.tsx @@ -1,3 +1,4 @@ +import get from 'just-safe-get' import {DocumentBadgeDescription, DocumentBadgeProps} from 'sanity' import {useDocumentInternationalizationContext} from '../components/DocumentInternationalizationContext' @@ -8,7 +9,7 @@ export function LanguageBadge( const source = props?.draft || props?.published const {languageField, supportedLanguages} = useDocumentInternationalizationContext() - const languageId = source?.[languageField] + const languageId = source ? get(source, languageField) : null if (!languageId) { return null diff --git a/src/components/DocumentInternationalizationMenu.tsx b/src/components/DocumentInternationalizationMenu.tsx index 3dc5660b..940c00c6 100644 --- a/src/components/DocumentInternationalizationMenu.tsx +++ b/src/components/DocumentInternationalizationMenu.tsx @@ -10,6 +10,7 @@ import { useClickOutside, } from '@sanity/ui' import {uuid} from '@sanity/uuid' +import get from 'just-safe-get' import {FormEvent, useCallback, useMemo, useState} from 'react' import {useEditState} from 'sanity' @@ -71,7 +72,7 @@ export function DocumentInternationalizationMenu( const documentIsInOneMetadataDocument = useMemo(() => { return Array.isArray(data) && data.length <= 1 }, [data]) - const sourceLanguageId = source?.[languageField] as string | undefined + const sourceLanguageId = source ? get(source, languageField) : undefined const sourceLanguageIsValid = supportedLanguages.some( (l) => l.id === sourceLanguageId ) From cee45487b9801fbc439dbf18953625e69d2765bf Mon Sep 17 00:00:00 2001 From: Luigi Garcia Date: Thu, 4 Apr 2024 21:10:41 +0100 Subject: [PATCH 2/3] docs: update readme --- README.md | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 19c1cc90..8c331afb 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ All new rewrite exclusively for Sanity Studio v3 - [Basic configuration](#basic-configuration) - [Advanced configuration](#advanced-configuration) - [Language field](#language-field) + - [Excluding fields](#excluding-fields) - [Querying translations](#querying-translations) - [Querying with GROQ](#querying-with-groq) - [Querying with GraphQL](#querying-with-graphql) @@ -154,7 +155,7 @@ export const createConfig({ ### Language field -The schema types that use document internationalization must also have a `string` field type with the same name configured in the `languageField` setting. Unless you want content creators to be able to change the language of a document, you may hide or disable this field since the plugin will handle writing patches to it. +The schema types that use document internationalization must also have a `string` field type with the same path name configured in the `languageField` setting. Unless you want content creators to be able to change the language of a document, you may hide or disable this field since the plugin will handle writing patches to it. ```ts // ./schema/lesson.ts @@ -163,12 +164,50 @@ The schema types that use document internationalization must also have a `string defineField({ // should match 'languageField' plugin configuration setting, if customized name: 'language', - type: 'string', + type: readOnly: true, hidden: true, -}) +}), + +// Nested value path name are also possible E.g: +{ + name: 'option' + type: 'object', + fields: [ + // ...other fields + // languageField: 'option.language' + defineField({ + name: 'language', + type: 'string', + readOnly: true, + hidden: true, + }), + ], +}, + +// or in array... +{ + name: 'options', + type: 'array', + of: [ + name: 'option' + type: 'object', + fields: [ + // languageField: 'options[0].language' + defineField({ + name: 'language', + type: 'string', + readOnly: true, + hidden: true, + }), + // ...other fields + ], + ], +} + ``` + ### Excluding fields The default behaviour of this plugin when creating a new translation is to duplicate the originating document, which is useful for then translating the fields directly in the new document - perhaps with [Sanity AI Assist](https://github.com/sanity-io/assist). However, sometimes you may want to exclude certain fields from being copied to the new document. You can do this by updating your schema to exclude certain types or fields with `options.documentInternationalization.exclude`: From 83282013c9a129278922cc6e6476612d490f4caa Mon Sep 17 00:00:00 2001 From: Luigi Garcia Date: Thu, 4 Apr 2024 21:15:07 +0100 Subject: [PATCH 3/3] docs: adjust readme spacing --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 8c331afb..44dff14d 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ The schema types that use document internationalization must also have a `string defineField({ // should match 'languageField' plugin configuration setting, if customized name: 'language', - type: + type: 'string', readOnly: true, hidden: true, }), @@ -207,7 +207,6 @@ defineField({ ``` - ### Excluding fields The default behaviour of this plugin when creating a new translation is to duplicate the originating document, which is useful for then translating the fields directly in the new document - perhaps with [Sanity AI Assist](https://github.com/sanity-io/assist). However, sometimes you may want to exclude certain fields from being copied to the new document. You can do this by updating your schema to exclude certain types or fields with `options.documentInternationalization.exclude`: