@sanity/document-internationalization 5.0.0 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,7 @@
10
10
  - [Advanced configuration](#advanced-configuration)
11
11
  - [Language field](#language-field)
12
12
  - [Excluding fields](#excluding-fields)
13
+ - [Document actions](#document-actions)
13
14
  - [Querying translations](#querying-translations)
14
15
  - [Querying with GROQ](#querying-with-groq)
15
16
  - [Querying with GraphQL](#querying-with-graphql)
@@ -120,7 +121,7 @@ export const defineConfig({
120
121
 
121
122
  // Optional
122
123
  // Customizes the name of the language field
123
- languageField: `language`, // defauts to "language"
124
+ languageField: `language`, // defaults to "language"
124
125
 
125
126
  // Optional
126
127
  // Keep translation.metadata references weak
@@ -199,6 +200,37 @@ defineField({
199
200
  }),
200
201
  ```
201
202
 
203
+ ### Document actions
204
+
205
+ This package exports hook-based document actions that you can add in your Studio `document.actions` configuration:
206
+
207
+ - `useDeleteTranslationAction`
208
+ - `useDuplicateWithTranslationsAction`
209
+
210
+ The legacy action exports `DeleteTranslationAction` and `DuplicateWithTranslationsAction` are deprecated.
211
+
212
+ ```ts
213
+ import {
214
+ useDeleteTranslationAction,
215
+ useDuplicateWithTranslationsAction,
216
+ } from '@sanity/document-internationalization'
217
+
218
+ export default defineConfig({
219
+ // ... all other config
220
+ document: {
221
+ actions: (prev, context) => {
222
+ const translatedSchemaTypes = ['lesson', 'article']
223
+
224
+ if (translatedSchemaTypes.includes(context.schemaType)) {
225
+ return [...prev, useDeleteTranslationAction, useDuplicateWithTranslationsAction]
226
+ }
227
+
228
+ return prev
229
+ },
230
+ },
231
+ })
232
+ ```
233
+
202
234
  ## Querying translations
203
235
 
204
236
  ### Querying with GROQ
package/dist/index.d.ts CHANGED
@@ -1,7 +1,62 @@
1
1
  import * as sanity0 from "sanity";
2
- import { DocumentActionComponent, FieldDefinition, KeyedObject, ObjectSchemaType, Reference, SanityClient, SanityDocument, SanityDocumentLike } from "sanity";
3
- declare const DeleteTranslationAction: DocumentActionComponent;
4
- declare const DuplicateWithTranslationsAction: DocumentActionComponent;
2
+ import { DocumentActionDescription, DocumentActionProps, FieldDefinition, ObjectSchemaType, Reference, SanityClient, SanityDocument, SanityDocumentLike } from "sanity";
3
+ import { InternationalizedArrayItem } from "sanity-plugin-internationalized-array";
4
+ /**
5
+ * Optional Document action that removes a single translation from the metadata document
6
+ * and optionally deletes the translation document. Opens a confirmation dialog
7
+ * showing which metadata entries reference the document and any other references
8
+ * that may exist. When the document has translation references, those references
9
+ * are unset; otherwise the document is deleted directly.
10
+ *
11
+ * To use it, you need to add it to the document actions config
12
+ * ```
13
+ * const translatedSchemaTypes = ['lesson', 'article'];
14
+ * document: {
15
+ * actions: (prev, {schemaType}) => {
16
+ * if (translatedSchemaTypes.includes(schemaType)) {
17
+ * return [...prev, useDeleteTranslationAction]
18
+ * }
19
+ * return prev
20
+ * },
21
+ * },
22
+ * ```
23
+ */
24
+ declare const useDeleteTranslationAction: {
25
+ (props: DocumentActionProps): DocumentActionDescription;
26
+ action: string;
27
+ displayName: string;
28
+ };
29
+ /**
30
+ * @deprecated use useDeleteTranslationAction instead
31
+ * Will be removed in the next major version
32
+ */
33
+ declare const DeleteTranslationAction: (props: DocumentActionProps) => DocumentActionDescription;
34
+ /**
35
+ * Optional Document action that duplicates a document along with all its translations
36
+ * and the associated metadata document. The workflow duplicates each translated
37
+ * document, duplicates the metadata document, patches the new metadata to
38
+ * reference the new translation copies, and navigates to the duplicated document.
39
+ * Disabled when the user lacks permissions, metadata is missing or ambiguous,
40
+ * or the underlying duplicate operation is unavailable.
41
+ */
42
+ declare const useDuplicateWithTranslationsAction: {
43
+ ({
44
+ id,
45
+ type,
46
+ onComplete
47
+ }: DocumentActionProps): DocumentActionDescription;
48
+ action: string;
49
+ displayName: string;
50
+ };
51
+ /**
52
+ * @deprecated use useDuplicateWithTranslationsAction instead
53
+ * Will be removed in the next major version
54
+ */
55
+ declare const DuplicateWithTranslationsAction: {
56
+ (props: DocumentActionProps): DocumentActionDescription;
57
+ action: string;
58
+ displayName: string;
59
+ };
5
60
  type Language = {
6
61
  id: Intl.UnicodeBCP47LocaleIdentifier;
7
62
  title: string;
@@ -29,7 +84,7 @@ type PluginConfig = {
29
84
  type PluginConfigContext = Required<PluginConfig> & {
30
85
  supportedLanguages: Language[];
31
86
  };
32
- type TranslationReference = KeyedObject & {
87
+ type TranslationReference = InternationalizedArrayItem<Reference> & {
33
88
  _type: 'internationalizedArrayReferenceValue';
34
89
  value: Reference;
35
90
  };
@@ -73,5 +128,5 @@ declare module 'sanity' {
73
128
  declare function useDocumentInternationalizationContext(): PluginConfigContext;
74
129
  declare function DocumentInternationalizationMenu(props: DocumentInternationalizationMenuProps): React.JSX.Element | null;
75
130
  declare const documentInternationalization: sanity0.Plugin<PluginConfig>;
76
- export { DeleteTranslationAction, DocumentInternationalizationMenu, DocumentInternationalizationMenuProps, DocumentInternationalizationSchemaOpts, DuplicateWithTranslationsAction, Language, Metadata, MetadataDocument, PluginCallbackArgs, PluginConfig, PluginConfigContext, SupportedLanguages, TranslationReference, documentInternationalization, useDocumentInternationalizationContext };
131
+ export { DeleteTranslationAction, DocumentInternationalizationMenu, DocumentInternationalizationMenuProps, DocumentInternationalizationSchemaOpts, DuplicateWithTranslationsAction, Language, Metadata, MetadataDocument, PluginCallbackArgs, PluginConfig, PluginConfigContext, SupportedLanguages, TranslationReference, documentInternationalization, useDeleteTranslationAction, useDocumentInternationalizationContext, useDuplicateWithTranslationsAction };
77
132
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/actions/DeleteTranslationAction.tsx","../src/actions/DuplicateWithTranslationsAction.tsx","../src/types.ts","../src/components/DocumentInternationalizationContext.tsx","../src/components/DocumentInternationalizationMenu.tsx","../src/plugin.tsx"],"mappings":";;cAUa,uBAAA,EAAyB,uBAAA;AAAA,cCiCzB,+BAAA,EAAiC,uBAAA;AAAA,KCjClC,QAAA;EACV,EAAA,EAAI,IAAA,CAAK,4BAAA;EACT,KAAA;AAAA;AAAA,KAGU,kBAAA,GAAqB,QAAA,OAAe,MAAA,EAAQ,YAAA,KAAiB,OAAA,CAAQ,QAAA;AAAA,KAErE,kBAAA;EACV,cAAA,EAAgB,cAAA;EAChB,WAAA,EAAa,cAAA;EACb,gBAAA;EACA,qBAAA;EACA,cAAA;EACA,MAAA,EAAQ,YAAA;AAAA;AAAA,KAGE,YAAA;EACV,kBAAA,EAAoB,kBAAA;EACpB,WAAA;EACA,aAAA;EACA,cAAA;EACA,WAAA;EACA,cAAA,GAAiB,eAAA;EACjB,UAAA;EACA,kBAAA;EACA,QAAA,KAAa,IAAA,EAAM,kBAAA,KAAuB,OAAA;AAAA;AAAA,KAMhC,mBAAA,GAAsB,QAAA,CAAS,YAAA;EACzC,kBAAA,EAAoB,QAAA;AAAA;AAAA,KAGV,oBAAA,GAAuB,WAAA;EACjC,KAAA;EACA,KAAA,EAAO,SAAA;AAAA;AAAA,KAGG,QAAA;EACV,GAAA;EACA,UAAA;EACA,YAAA,EAAc,oBAAA;AAAA;AAAA,KAGJ,gBAAA,GAAmB,kBAAA;EAC7B,WAAA;EACA,YAAA,EAAc,oBAAA;AAAA;AAAA,KAGJ,qCAAA;EACV,UAAA,EAAY,gBAAA;EACZ,UAAA;AAAA;AAAA,UAIe,sCAAA;EACf,4BAAA;IA7CoB,+DA+ClB,OAAA;EAAA;AAAA;AAAA;EAAA,UAKQ,YAAA,SAAqB,sCAAA;EAAA,UACrB,YAAA,SAAqB,sCAAA;EAAA,UACrB,cAAA,SAAuB,sCAAA;EAAA,UACvB,4BAAA,SAAqC,sCAAA;EAAA,UACrC,WAAA,SAAoB,sCAAA;EAAA,UACpB,eAAA,SAAwB,sCAAA;EAAA,UACxB,WAAA,SAAoB,sCAAA;EAAA,UACpB,eAAA,SAAwB,sCAAA;EAAA,UACxB,YAAA,SAAqB,sCAAA;EAAA,UACrB,aAAA,SAAsB,sCAAA;EAAA,UACtB,aAAA,SAAsB,sCAAA;EAAA,UACtB,oBAAA,SAA6B,sCAAA;EAAA,UAC7B,WAAA,SAAoB,sCAAA;EAAA,UACpB,aAAA,SAAsB,sCAAA;EAAA,UACtB,WAAA,SAAoB,sCAAA;EAAA,UACpB,UAAA,SAAmB,sCAAA;EAAA,UACnB,YAAA,SAAqB,sCAAA;AAAA;AAAA,iBChFjB,sCAAA,CAAA,GAA0C,mBAAA;AAAA,iBCM1C,gCAAA,CACd,KAAA,EAAO,qCAAA,GACN,KAAA,CAAM,GAAA,CAAI,OAAA;AAAA,cCHA,4BAAA,EAA4B,OAAA,CAAA,MAAA,CAAA,YAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/actions/DeleteTranslationAction.tsx","../src/actions/DuplicateWithTranslationsAction.tsx","../src/types.ts","../src/components/DocumentInternationalizationContext.tsx","../src/components/DocumentInternationalizationMenu.tsx","../src/plugin.tsx"],"mappings":";;;;;;AAkCA;;;;;;;;;;;AA+FA;;;;;;cA/Fa,0BAAA;EAAA,QACJ,mBAAA,GACN,yBAAA;;;;;;;;cA6FU,uBAAA,GAA2B,KAAA,EAAO,mBAAA,KAAsB,yBAAA;;;;AA/FrE;;;;;cCkBa,kCAAA;EAAA;;;;KAKV,mBAAA,GAAsB,yBAAA;;;;;ADwEzB;;;cC2Ha,+BAAA;EAAA,QACJ,mBAAA,GACN,yBAAA;;;;KCpPS,QAAA;EACV,EAAA,EAAI,IAAA,CAAK,4BAAA;EACT,KAAA;AAAA;AAAA,KAGU,kBAAA,GAAqB,QAAA,OAAe,MAAA,EAAQ,YAAA,KAAiB,OAAA,CAAQ,QAAA;AAAA,KAErE,kBAAA;EACV,cAAA,EAAgB,cAAA;EAChB,WAAA,EAAa,cAAA;EACb,gBAAA;EACA,qBAAA;EACA,cAAA;EACA,MAAA,EAAQ,YAAA;AAAA;AAAA,KAGE,YAAA;EACV,kBAAA,EAAoB,kBAAA;EACpB,WAAA;EACA,aAAA;EACA,cAAA;EACA,WAAA;EACA,cAAA,GAAiB,eAAA;EACjB,UAAA;EACA,kBAAA;EACA,QAAA,KAAa,IAAA,EAAM,kBAAA,KAAuB,OAAA;AAAA;AAAA,KAMhC,mBAAA,GAAsB,QAAA,CAAS,YAAA;EACzC,kBAAA,EAAoB,QAAA;AAAA;AAAA,KAGV,oBAAA,GAAuB,0BAAA,CAA2B,SAAA;EAC5D,KAAA;EACA,KAAA,EAAO,SAAA;AAAA;AAAA,KAGG,QAAA;EACV,GAAA;EACA,UAAA;EACA,YAAA,EAAc,oBAAA;AAAA;AAAA,KAGJ,gBAAA,GAAmB,kBAAA;EAC7B,WAAA;EACA,YAAA,EAAc,oBAAA;AAAA;AAAA,KAGJ,qCAAA;EACV,UAAA,EAAY,gBAAA;EACZ,UAAA;AAAA;AAAA,UAIe,sCAAA;EACf,4BAAA;ID4LD,+DC1LG,OAAA;EAAA;AAAA;AAAA;EAAA,UAKQ,YAAA,SAAqB,sCAAA;EAAA,UACrB,YAAA,SAAqB,sCAAA;EAAA,UACrB,cAAA,SAAuB,sCAAA;EAAA,UACvB,4BAAA,SAAqC,sCAAA;EAAA,UACrC,WAAA,SAAoB,sCAAA;EAAA,UACpB,eAAA,SAAwB,sCAAA;EAAA,UACxB,WAAA,SAAoB,sCAAA;EAAA,UACpB,eAAA,SAAwB,sCAAA;EAAA,UACxB,YAAA,SAAqB,sCAAA;EAAA,UACrB,aAAA,SAAsB,sCAAA;EAAA,UACtB,aAAA,SAAsB,sCAAA;EAAA,UACtB,oBAAA,SAA6B,sCAAA;EAAA,UAC7B,WAAA,SAAoB,sCAAA;EAAA,UACpB,aAAA,SAAsB,sCAAA;EAAA,UACtB,WAAA,SAAoB,sCAAA;EAAA,UACpB,UAAA,SAAmB,sCAAA;EAAA,UACnB,YAAA,SAAqB,sCAAA;AAAA;AAAA,iBChFjB,sCAAA,CAAA,GAA0C,mBAAA;AAAA,iBCO1C,gCAAA,CACd,KAAA,EAAO,qCAAA,GACN,KAAA,CAAM,GAAA,CAAI,OAAA;AAAA,cCJA,4BAAA,EAA4B,OAAA,CAAA,MAAA,CAAA,YAAA"}
package/dist/index.js CHANGED
@@ -1,16 +1,16 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { c } from "react/compiler-runtime";
2
3
  import { TrashIcon, CopyIcon, CogIcon, SplitVerticalIcon, CheckmarkIcon, AddIcon, EditIcon, TranslateIcon, InfoOutlineIcon } from "@sanity/icons";
3
4
  import { Flex, Spinner, Card, Text, Stack, Grid, Button, useToast, Tooltip, Box, Badge, useClickOutsideEvent, TextInput, Popover, Inline, Dialog } from "@sanity/ui";
4
- import { useEffect, createContext, use, useContext, useState, useCallback, useRef, useMemo } from "react";
5
+ import { useEffect, createContext, use, useContext, useState, useRef } from "react";
5
6
  import { useSchema, Preview, useClient, useWorkspace, defineLocaleResourceBundle, useDocumentStore, useDocumentOperation, useDocumentPairPermissions, DEFAULT_STUDIO_CLIENT_OPTIONS, useTranslation, useCurrentUser, InsufficientPermissionsMessage, isDocumentSchemaType, pathToString, useEditState, useValidationStatus, TextWithTone, PatchEvent, unset, defineType, defineField, definePlugin, isSanityDocument } from "sanity";
6
- import { c } from "react/compiler-runtime";
7
+ import { LANGUAGE_FIELD_NAME, internationalizedArray } from "sanity-plugin-internationalized-array";
7
8
  import { Feedback, useListeningQuery } from "sanity-plugin-utils";
8
9
  import { uuid } from "@sanity/uuid";
9
10
  import { firstValueFrom, filter } from "rxjs";
10
11
  import { useRouter } from "sanity/router";
11
12
  import { structureLocaleNamespace, usePaneRouter, useDocumentPane } from "sanity/structure";
12
13
  import { Mutation, extractWithPath } from "@sanity/mutator";
13
- import { internationalizedArray } from "sanity-plugin-internationalized-array";
14
14
  function DocumentPreview(props) {
15
15
  const $ = c(7), schema = useSchema();
16
16
  let t0;
@@ -63,7 +63,7 @@ function DeleteTranslationDialog(props) {
63
63
  const {
64
64
  data,
65
65
  loading
66
- } = useListeningQuery("*[references($id)]{_id, _type}", t2), t3 = data;
66
+ } = useListeningQuery("*[references($id)]{_id, _type, translations}", t2), t3 = data;
67
67
  let t4;
68
68
  $[5] !== t3 ? (t4 = separateReferences(t3), $[5] = t3, $[6] = t4) : t4 = $[6];
69
69
  const {
@@ -93,7 +93,7 @@ function DeleteTranslationDialog(props) {
93
93
  " ",
94
94
  "must be removed"
95
95
  ] }),
96
- translations.map(_temp$4)
96
+ translations.map(_temp$5)
97
97
  ] }) : null, $[18] = translations, $[19] = t10) : t10 = $[19];
98
98
  let t11;
99
99
  $[20] !== otherReferences ? (t11 = otherReferences && otherReferences.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -124,7 +124,7 @@ function DeleteTranslationDialog(props) {
124
124
  function _temp2$3(reference) {
125
125
  return /* @__PURE__ */ jsx(DocumentPreview, { value: reference, type: reference._type }, reference._id);
126
126
  }
127
- function _temp$4(translation) {
127
+ function _temp$5(translation) {
128
128
  return /* @__PURE__ */ jsx(DocumentPreview, { value: translation, type: translation._type }, translation._id);
129
129
  }
130
130
  function DeleteTranslationFooter(props) {
@@ -193,20 +193,31 @@ function DocumentInternationalizationProvider(props) {
193
193
  let t5;
194
194
  return $[15] !== t3 || $[16] !== t4 ? (t5 = /* @__PURE__ */ jsx(DocumentInternationalizationContext.Provider, { value: t3, children: t4 }), $[15] = t3, $[16] = t4, $[17] = t5) : t5 = $[17], t5;
195
195
  }
196
- const DeleteTranslationAction = (props) => {
197
- const {
196
+ const useDeleteTranslationAction = (props) => {
197
+ const $ = c(19), {
198
198
  id: documentId,
199
199
  published,
200
200
  draft
201
201
  } = props, doc = draft || published, {
202
202
  languageField
203
- } = useDocumentInternationalizationContext(), [isDialogOpen, setDialogOpen] = useState(!1), [translations, setTranslations] = useState([]), onClose = useCallback(() => setDialogOpen(!1), []), rawDocumentLanguage = doc ? doc[languageField] : null, documentLanguage = typeof rawDocumentLanguage == "string" ? rawDocumentLanguage : null, toast = useToast(), client = useClient({
203
+ } = useDocumentInternationalizationContext(), [isDialogOpen, setDialogOpen] = useState(!1);
204
+ let t0;
205
+ $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = [], $[0] = t0) : t0 = $[0];
206
+ const [translations, setTranslations] = useState(t0);
207
+ let t1;
208
+ $[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = () => setDialogOpen(!1), $[1] = t1) : t1 = $[1];
209
+ const onClose = t1, rawDocumentLanguage = doc ? doc[languageField] : null, documentLanguage = typeof rawDocumentLanguage == "string" ? rawDocumentLanguage : null, toast = useToast();
210
+ let t2;
211
+ $[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t2 = {
204
212
  apiVersion: API_VERSION
205
- }), onProceed = useCallback(() => {
213
+ }, $[2] = t2) : t2 = $[2];
214
+ const client = useClient(t2);
215
+ let t3;
216
+ $[3] !== client || $[4] !== documentId || $[5] !== documentLanguage || $[6] !== toast || $[7] !== translations ? (t3 = () => {
206
217
  const tx = client.transaction();
207
218
  let operation = "DELETE";
208
219
  documentLanguage && translations.length > 0 ? (operation = "UNSET", translations.forEach((translation) => {
209
- tx.patch(translation._id, (patch) => patch.unset([`${TRANSLATIONS_ARRAY_NAME}[_key == "${documentLanguage}"]`]));
220
+ tx.patch(translation._id, (patch) => patch.unset([`${TRANSLATIONS_ARRAY_NAME}[${LANGUAGE_FIELD_NAME} == "${documentLanguage}"]`]));
210
221
  })) : (tx.delete(documentId), tx.delete(`drafts.${documentId}`)), tx.commit().then(() => {
211
222
  operation === "DELETE" && onClose(), toast.push({
212
223
  status: "success",
@@ -216,28 +227,37 @@ const DeleteTranslationAction = (props) => {
216
227
  }).catch((err) => {
217
228
  toast.push({
218
229
  status: "error",
219
- title: operation === "unset" ? "Failed to unset translation reference" : "Failed to delete document",
230
+ title: operation === "UNSET" ? "Failed to unset translation reference" : "Failed to delete document",
220
231
  description: err.message
221
232
  });
222
233
  });
223
- }, [client, documentLanguage, translations, documentId, onClose, toast]);
224
- return {
234
+ }, $[3] = client, $[4] = documentId, $[5] = documentLanguage, $[6] = toast, $[7] = translations, $[8] = t3) : t3 = $[8];
235
+ const onProceed = t3, t4 = !doc || !documentLanguage;
236
+ let t5;
237
+ $[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t5 = () => {
238
+ setDialogOpen(!0);
239
+ }, $[9] = t5) : t5 = $[9];
240
+ let t6;
241
+ $[10] !== doc || $[11] !== documentId || $[12] !== isDialogOpen || $[13] !== onProceed || $[14] !== translations ? (t6 = isDialogOpen && {
242
+ type: "dialog",
243
+ onClose,
244
+ header: "Delete translation",
245
+ content: doc ? /* @__PURE__ */ jsx(DeleteTranslationDialog, { doc, documentId, setTranslations }) : null,
246
+ footer: /* @__PURE__ */ jsx(DeleteTranslationFooter, { onClose, onProceed, translations })
247
+ }, $[10] = doc, $[11] = documentId, $[12] = isDialogOpen, $[13] = onProceed, $[14] = translations, $[15] = t6) : t6 = $[15];
248
+ let t7;
249
+ return $[16] !== t4 || $[17] !== t6 ? (t7 = {
225
250
  label: "Delete translation...",
226
- disabled: !doc || !documentLanguage,
251
+ disabled: t4,
227
252
  icon: TrashIcon,
228
253
  tone: "critical",
229
- onHandle: () => {
230
- setDialogOpen(!0);
231
- },
232
- dialog: isDialogOpen && {
233
- type: "dialog",
234
- onClose,
235
- header: "Delete translation",
236
- content: doc ? /* @__PURE__ */ jsx(DeleteTranslationDialog, { doc, documentId, setTranslations }) : null,
237
- footer: /* @__PURE__ */ jsx(DeleteTranslationFooter, { onClose, onProceed, translations })
238
- }
239
- };
240
- }, query = `*[_type == $translationSchema && $id in translations[].value._ref]{
254
+ onHandle: t5,
255
+ dialog: t6
256
+ }, $[16] = t4, $[17] = t6, $[18] = t7) : t7 = $[18], t7;
257
+ };
258
+ useDeleteTranslationAction.action = "deleteTranslation";
259
+ useDeleteTranslationAction.displayName = "DeleteTranslationAction";
260
+ const DeleteTranslationAction = (props) => useDeleteTranslationAction(props), query = `*[_type == $translationSchema && $id in translations[].value._ref]{
241
261
  _id,
242
262
  _createdAt,
243
263
  translations
@@ -272,7 +292,7 @@ const documenti18nLocaleNamespace = "document-internationalization", documentInt
272
292
  MULTIPLE_METADATA: "action.duplicate.disabled.multiple-metadata",
273
293
  NOTHING_TO_DUPLICATE: "action.duplicate.disabled.nothing-to-duplicate",
274
294
  NOT_READY: "action.duplicate.disabled.not-ready"
275
- }, DuplicateWithTranslationsAction = (t0) => {
295
+ }, useDuplicateWithTranslationsAction = (t0) => {
276
296
  const $ = c(44), {
277
297
  id,
278
298
  type,
@@ -301,14 +321,19 @@ const documenti18nLocaleNamespace = "document-internationalization", documentInt
301
321
  setDuplicating(!0), (async function() {
302
322
  if (!metadataDocument)
303
323
  return Promise.reject(new Error("Metadata document not found"));
324
+ const translationsArray = metadataDocument[TRANSLATIONS_ARRAY_NAME];
325
+ if (!translationsArray || translationsArray.length === 0)
326
+ return Promise.reject(new Error("No translations found in metadata document"));
304
327
  const translations = /* @__PURE__ */ new Map();
305
- await Promise.all(metadataDocument[TRANSLATIONS_ARRAY_NAME].map(async (translation) => {
306
- const dupeId = uuid(), locale = translation._key, docId = translation.value?._ref;
328
+ await Promise.all(translationsArray.map(async (translation) => {
329
+ const dupeId = uuid(), locale = translation[LANGUAGE_FIELD_NAME], docId = translation.value?._ref;
330
+ if (typeof locale != "string" || locale.trim().length === 0)
331
+ return Promise.reject(new Error("Invalid locale for translation"));
307
332
  if (!docId)
308
333
  return Promise.reject(new Error("Translation document not found"));
309
334
  const {
310
335
  duplicate: duplicateTranslation
311
- } = await firstValueFrom(documentStore.pair.editOperations(docId, type).pipe(filter(_temp$3)));
336
+ } = await firstValueFrom(documentStore.pair.editOperations(docId, type).pipe(filter(_temp$4)));
312
337
  if (duplicateTranslation.disabled)
313
338
  return Promise.reject(new Error("Cannot duplicate document"));
314
339
  const duplicateTranslationSuccess = firstValueFrom(documentStore.pair.operationEvents(docId, type).pipe(filter(_temp2$2)));
@@ -399,9 +424,12 @@ const documenti18nLocaleNamespace = "document-internationalization", documentInt
399
424
  }
400
425
  return t3;
401
426
  };
427
+ useDuplicateWithTranslationsAction.action = "duplicate";
428
+ useDuplicateWithTranslationsAction.displayName = "DuplicateWithTranslationsAction";
429
+ const DuplicateWithTranslationsAction = (props) => useDuplicateWithTranslationsAction(props);
402
430
  DuplicateWithTranslationsAction.action = "duplicate";
403
431
  DuplicateWithTranslationsAction.displayName = "DuplicateWithTranslationsAction";
404
- function _temp$3(op) {
432
+ function _temp$4(op) {
405
433
  return op.duplicate.disabled !== "NOT_READY";
406
434
  }
407
435
  function _temp2$2(e) {
@@ -415,7 +443,7 @@ function _temp4(e_0) {
415
443
  }
416
444
  function _temp5(t0) {
417
445
  const [locale_0, documentId] = t0;
418
- return [`${TRANSLATIONS_ARRAY_NAME}[_key == "${locale_0}"].value._ref`, documentId];
446
+ return [`${TRANSLATIONS_ARRAY_NAME}[${LANGUAGE_FIELD_NAME} == "${locale_0}"].value._ref`, documentId];
419
447
  }
420
448
  function useOpenInNewPane(id, type) {
421
449
  const $ = c(6), router = useRouter(), {
@@ -448,9 +476,11 @@ function useOpenInNewPane(id, type) {
448
476
  });
449
477
  }, $[0] = groupIndex, $[1] = id, $[2] = router, $[3] = routerPanesState, $[4] = type, $[5] = t0) : t0 = $[5], t0;
450
478
  }
451
- function createReference(key, ref, type, strengthenOnPublish = !0) {
479
+ function createReference(language, ref, type, strengthenOnPublish = !0) {
452
480
  return {
453
- _key: key,
481
+ // TODO: Update in next major version when we migrate to the new format
482
+ // ...(LANGUAGE_FIELD_NAME === "_key"? {} : {_key: createRandomKey()} )
483
+ [LANGUAGE_FIELD_NAME]: language,
454
484
  _type: "internationalizedArrayReferenceValue",
455
485
  value: {
456
486
  _type: "reference",
@@ -528,7 +558,7 @@ function extractPaths(doc, schemaType, path) {
528
558
  const fieldPath = [...path, field.name], fieldSchema = field.type, {
529
559
  value
530
560
  } = extractWithPath(pathToString(fieldPath), doc)[0] ?? {};
531
- if (!value)
561
+ if (value == null)
532
562
  continue;
533
563
  const thisFieldWithPath = {
534
564
  path: fieldPath,
@@ -742,7 +772,7 @@ function DocumentInternationalizationMenu(props) {
742
772
  }, $[0] = t0) : t0 = $[0];
743
773
  const handleQuery = t0, [open, setOpen] = useState(!1);
744
774
  let t1;
745
- $[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = () => setOpen(_temp$2), $[1] = t1) : t1 = $[1];
775
+ $[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = () => setOpen(_temp$3), $[1] = t1) : t1 = $[1];
746
776
  const handleClick = t1, buttonRef = useRef(null), popoverRef = useRef(null);
747
777
  let t2;
748
778
  $[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t2 = () => setOpen(!1), $[2] = t2) : t2 = $[2];
@@ -785,7 +815,7 @@ function DocumentInternationalizationMenu(props) {
785
815
  supportedLanguages.length > 4 ? /* @__PURE__ */ jsx(TextInput, { onChange: handleQuery, value: query2, placeholder: "Filter languages" }) : null,
786
816
  supportedLanguages.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
787
817
  loading ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
788
- data && documentIsInOneMetadataDocument ? null : /* @__PURE__ */ jsx(Warning, { children: "This document has been found in more than one Translations Metadata documents" }),
818
+ data && documentIsInOneMetadataDocument ? null : /* @__PURE__ */ jsx(Warning, { children: "This document has been found in more than one Translations Metadata document" }),
789
819
  allLanguagesAreValid ? null : /* @__PURE__ */ jsx(Warning, { children: "Not all language objects are valid. See the console." }),
790
820
  sourceLanguageId ? null : /* @__PURE__ */ jsxs(Warning, { children: [
791
821
  "Choose a language to apply to ",
@@ -797,7 +827,7 @@ function DocumentInternationalizationMenu(props) {
797
827
  /* @__PURE__ */ jsx("code", { children: sourceLanguageId })
798
828
  ] }) : null
799
829
  ] }),
800
- supportedLanguages.filter((language) => query2 ? language.title.toLowerCase().includes(query2.toLowerCase()) : !0).map((language_0) => !loading && sourceLanguageId && sourceLanguageIsValid ? /* @__PURE__ */ jsx(LanguageOption, { language: language_0, schemaType, documentId, disabled: !allLanguagesAreValid, current: language_0.id === sourceLanguageId, metadata: metadata2, metadataId, source, sourceLanguageId }, language_0.id) : /* @__PURE__ */ jsx(LanguagePatch, { source, language: language_0, disabled: (loading || !allLanguagesAreValid || metadata2?.translations.filter((t) => t?.value?._ref !== documentId).some((t_0) => t_0._key === language_0.id)) ?? !1 }, language_0.id))
830
+ supportedLanguages.filter((language) => query2 ? language.title.toLowerCase().includes(query2.toLowerCase()) : !0).map((language_0) => !loading && sourceLanguageId && sourceLanguageIsValid ? /* @__PURE__ */ jsx(LanguageOption, { language: language_0, schemaType, documentId, disabled: !allLanguagesAreValid, current: language_0.id === sourceLanguageId, metadata: metadata2, metadataId, source, sourceLanguageId }, language_0.id) : /* @__PURE__ */ jsx(LanguagePatch, { source, language: language_0, disabled: (loading || !allLanguagesAreValid || metadata2?.translations.filter((t) => t?.value?._ref !== documentId).some((t_0) => t_0[LANGUAGE_FIELD_NAME] === language_0.id)) ?? !1 }, language_0.id))
801
831
  ] }) : null
802
832
  ] }) }), $[13] = allLanguagesAreValid, $[14] = data, $[15] = documentId, $[16] = documentIsInOneMetadataDocument, $[17] = error, $[18] = loading, $[19] = metadata2, $[20] = metadataId, $[21] = query2, $[22] = schemaType, $[23] = source, $[24] = sourceLanguageId, $[25] = sourceLanguageIsValid, $[26] = supportedLanguages, $[27] = t7) : t7 = $[27];
803
833
  const content = t7, issueWithTranslations = !loading && sourceLanguageId && !sourceLanguageIsValid;
@@ -812,22 +842,30 @@ function DocumentInternationalizationMenu(props) {
812
842
  function _temp2$1(l_0) {
813
843
  return l_0.id && l_0.title;
814
844
  }
815
- function _temp$2(o) {
845
+ function _temp$3(o) {
816
846
  return !o;
817
847
  }
818
- const DeleteMetadataAction = (props) => {
819
- const {
848
+ const useDeleteMetadataAction = (props) => {
849
+ const $ = c(17), {
820
850
  id: documentId,
821
851
  published,
822
852
  draft
823
- } = props, doc = draft || published, [isDialogOpen, setDialogOpen] = useState(!1), onClose = useCallback(() => setDialogOpen(!1), []), translations = useMemo(() => doc && Array.isArray(doc[TRANSLATIONS_ARRAY_NAME]) ? (
824
- // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion
825
- doc[TRANSLATIONS_ARRAY_NAME]
826
- ) : [], [doc]), toast = useToast(), client = useClient({
853
+ } = props, doc = draft || published, [isDialogOpen, setDialogOpen] = useState(!1);
854
+ let t0;
855
+ $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = () => setDialogOpen(!1), $[0] = t0) : t0 = $[0];
856
+ const onClose = t0;
857
+ let t1;
858
+ $[1] !== doc ? (t1 = doc && Array.isArray(doc[TRANSLATIONS_ARRAY_NAME]) ? doc[TRANSLATIONS_ARRAY_NAME] : [], $[1] = doc, $[2] = t1) : t1 = $[2];
859
+ const translations = t1, toast = useToast();
860
+ let t2;
861
+ $[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t2 = {
827
862
  apiVersion: API_VERSION
828
- }), onProceed = useCallback(() => {
863
+ }, $[3] = t2) : t2 = $[3];
864
+ const client = useClient(t2);
865
+ let t3;
866
+ $[4] !== client || $[5] !== documentId || $[6] !== toast || $[7] !== translations ? (t3 = () => {
829
867
  const tx = client.transaction();
830
- tx.patch(documentId, (patch) => patch.unset([TRANSLATIONS_ARRAY_NAME])), translations.length > 0 && translations.forEach((translation) => {
868
+ tx.patch(documentId, _temp$2), translations.length > 0 && translations.forEach((translation) => {
831
869
  tx.delete(translation.value._ref), tx.delete(`drafts.${translation.value._ref}`);
832
870
  }), tx.delete(documentId), tx.delete(`drafts.${documentId}`), tx.commit().then(() => {
833
871
  onClose(), toast.push({
@@ -841,26 +879,35 @@ const DeleteMetadataAction = (props) => {
841
879
  description: err.message
842
880
  });
843
881
  });
844
- }, [client, translations, documentId, onClose, toast]);
845
- return {
882
+ }, $[4] = client, $[5] = documentId, $[6] = toast, $[7] = translations, $[8] = t3) : t3 = $[8];
883
+ const onProceed = t3, t4 = !doc || !translations.length;
884
+ let t5;
885
+ $[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t5 = () => {
886
+ setDialogOpen(!0);
887
+ }, $[9] = t5) : t5 = $[9];
888
+ let t6;
889
+ $[10] !== isDialogOpen || $[11] !== onProceed || $[12] !== translations ? (t6 = isDialogOpen && {
890
+ type: "confirm",
891
+ onCancel: onClose,
892
+ onConfirm: () => {
893
+ onProceed(), onClose();
894
+ },
895
+ tone: "critical",
896
+ message: translations.length === 1 ? "Delete 1 translation and this document" : `Delete all ${translations.length} translations and this document`
897
+ }, $[10] = isDialogOpen, $[11] = onProceed, $[12] = translations, $[13] = t6) : t6 = $[13];
898
+ let t7;
899
+ return $[14] !== t4 || $[15] !== t6 ? (t7 = {
846
900
  label: "Delete all translations",
847
- disabled: !doc || !translations.length,
901
+ disabled: t4,
848
902
  icon: TrashIcon,
849
903
  tone: "critical",
850
- onHandle: () => {
851
- setDialogOpen(!0);
852
- },
853
- dialog: isDialogOpen && {
854
- type: "confirm",
855
- onCancel: onClose,
856
- onConfirm: () => {
857
- onProceed(), onClose();
858
- },
859
- tone: "critical",
860
- message: translations.length === 1 ? "Delete 1 translation and this document" : `Delete all ${translations.length} translations and this document`
861
- }
862
- };
904
+ onHandle: t5,
905
+ dialog: t6
906
+ }, $[14] = t4, $[15] = t6, $[16] = t7) : t7 = $[16], t7;
863
907
  };
908
+ function _temp$2(patch) {
909
+ return patch.unset([TRANSLATIONS_ARRAY_NAME]);
910
+ }
864
911
  function LanguageBadge(props) {
865
912
  const source = props?.draft || props?.published, {
866
913
  languageField,
@@ -1031,7 +1078,7 @@ function BulkPublish(props) {
1031
1078
  invalidIds && invalidIds.length > 0 ? /* @__PURE__ */ jsxs(TextWithTone, { tone: "critical", size: 1, children: [
1032
1079
  invalidIds.length === 1 ? "1 draft document has" : `${invalidIds.length} draft documents have`,
1033
1080
  " ",
1034
- "validation issues that must addressed first"
1081
+ "validation issues that must be addressed first"
1035
1082
  ] }) : /* @__PURE__ */ jsx(TextWithTone, { tone: "positive", size: 1, children: "All drafts are valid and can be bulk published" })
1036
1083
  ] }) : null,
1037
1084
  /* @__PURE__ */ jsx(Stack, { space: 1, children: translations.filter(_temp2).map((translation_1) => /* @__PURE__ */ jsx(DocumentCheck, { id: translation_1.value._ref, onCheckComplete, addInvalidId, removeInvalidId, addDraftId, removeDraftId }, translation_1._key)) }),
@@ -1123,7 +1170,7 @@ var metadata = (schemaTypes, metadataFields) => defineType({
1123
1170
  const {
1124
1171
  translations = [],
1125
1172
  documentSchemaTypes = []
1126
- } = selection, title = translations.length === 1 ? "1 Translation" : `${translations.length} Translations`, languageKeys = translations.length ? translations.map((t) => t._key.toUpperCase()).join(", ") : "", subtitle = [languageKeys ? `(${languageKeys})` : null, documentSchemaTypes?.length ? documentSchemaTypes.map((s) => s).join(", ") : ""].filter(Boolean).join(" ");
1173
+ } = selection, title = translations.length === 1 ? "1 Translation" : `${translations.length} Translations`, languageKeys = translations.length ? translations.map((t) => t[LANGUAGE_FIELD_NAME].toUpperCase()).join(", ") : "", subtitle = [languageKeys ? `(${languageKeys})` : null, documentSchemaTypes?.length ? documentSchemaTypes.map((s) => s).join(", ") : ""].filter(Boolean).join(" ");
1127
1174
  return {
1128
1175
  title,
1129
1176
  subtitle
@@ -1148,10 +1195,7 @@ const documentInternationalization = definePlugin((config) => {
1148
1195
  name: "@sanity/document-internationalization",
1149
1196
  studio: {
1150
1197
  components: {
1151
- layout: (props) => DocumentInternationalizationProvider({
1152
- ...props,
1153
- pluginConfig
1154
- })
1198
+ layout: (props) => /* @__PURE__ */ jsx(DocumentInternationalizationProvider, { ...props, pluginConfig })
1155
1199
  }
1156
1200
  },
1157
1201
  i18n: {
@@ -1200,7 +1244,7 @@ const documentInternationalization = definePlugin((config) => {
1200
1244
  }) => schemaTypes.includes(schemaType) ? [(props) => LanguageBadge(props), ...prev] : prev,
1201
1245
  actions: (prev, {
1202
1246
  schemaType
1203
- }) => schemaType === METADATA_SCHEMA_NAME ? [...prev, DeleteMetadataAction] : prev
1247
+ }) => schemaType === METADATA_SCHEMA_NAME ? [...prev, useDeleteMetadataAction] : prev
1204
1248
  },
1205
1249
  // Adds:
1206
1250
  // - The `Translations metadata` document type to the schema
@@ -1303,6 +1347,8 @@ export {
1303
1347
  DocumentInternationalizationMenu,
1304
1348
  DuplicateWithTranslationsAction,
1305
1349
  documentInternationalization,
1306
- useDocumentInternationalizationContext
1350
+ useDeleteTranslationAction,
1351
+ useDocumentInternationalizationContext,
1352
+ useDuplicateWithTranslationsAction
1307
1353
  };
1308
1354
  //# sourceMappingURL=index.js.map