sanity-plugin-internationalized-array 3.2.1 → 4.0.0
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/LICENSE +1 -1
- package/README.md +3 -34
- package/{lib → dist}/index.d.ts +41 -61
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +882 -0
- package/dist/index.js.map +1 -0
- package/package.json +37 -75
- package/lib/index.d.mts +0 -149
- package/lib/index.esm.js +0 -933
- package/lib/index.esm.js.map +0 -1
- package/lib/index.js +0 -942
- package/lib/index.js.map +0 -1
- package/lib/index.mjs +0 -933
- package/lib/index.mjs.map +0 -1
- package/sanity.json +0 -8
- package/src/cache.ts +0 -148
- package/src/components/AddButtons.tsx +0 -60
- package/src/components/DocumentAddButtons.tsx +0 -183
- package/src/components/Feedback.tsx +0 -28
- package/src/components/InternationalizedArray.tsx +0 -286
- package/src/components/InternationalizedArrayContext.tsx +0 -136
- package/src/components/InternationalizedField.tsx +0 -57
- package/src/components/InternationalizedInput.tsx +0 -257
- package/src/components/Preload.tsx +0 -31
- package/src/components/createFieldName.ts +0 -20
- package/src/components/getSelectedValue.ts +0 -31
- package/src/components/getToneFromValidation.ts +0 -20
- package/src/constants.ts +0 -18
- package/src/fieldActions/index.ts +0 -138
- package/src/index.ts +0 -3
- package/src/plugin.tsx +0 -87
- package/src/schema/array.ts +0 -148
- package/src/schema/object.ts +0 -36
- package/src/types.ts +0 -135
- package/src/utils/checkAllLanguagesArePresent.ts +0 -14
- package/src/utils/createAddAllTitle.ts +0 -16
- package/src/utils/createAddLanguagePatches.ts +0 -84
- package/src/utils/createValueSchemaTypeName.ts +0 -5
- package/src/utils/flattenSchemaType.ts +0 -63
- package/src/utils/getDocumentsToTranslate.ts +0 -66
- package/src/utils/getLanguageDisplay.ts +0 -13
- package/src/utils/getLanguagesFieldOption.ts +0 -16
- package/v2-incompatible.js +0 -11
package/dist/index.js
ADDED
|
@@ -0,0 +1,882 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { isSanityDocument, useSchema, setIfMissing, insert, PatchEvent, useClient, useWorkspace, defineDocumentFieldAction, useFormValue, ArrayOfObjectsItem, MemberItemError, set, defineField, unset, isDocumentSchemaType, definePlugin, isObjectInputProps } from "sanity";
|
|
3
|
+
import { c } from "react/compiler-runtime";
|
|
4
|
+
import { useLanguageFilterStudioContext } from "@sanity/language-filter";
|
|
5
|
+
import { Grid, Button, useToast, Stack, Box, Text, Card, Code, Spinner, Label, MenuButton, Menu, MenuItem, Flex, Tooltip } from "@sanity/ui";
|
|
6
|
+
import { createContext, useContext, useDeferredValue, use, useCallback, useEffect, createElement } from "react";
|
|
7
|
+
import { useDocumentPane } from "sanity/structure";
|
|
8
|
+
import { AddIcon, TranslateIcon, RemoveCircleIcon } from "@sanity/icons";
|
|
9
|
+
import { get, upperFirst, camelCase } from "lodash-es";
|
|
10
|
+
const namespace = "sanity-plugin-internationalized-array", functionCache = /* @__PURE__ */ new Map(), functionKeyCache = /* @__PURE__ */ new WeakMap(), promiseCache = /* @__PURE__ */ new Map();
|
|
11
|
+
function stringifyCacheKey(key) {
|
|
12
|
+
return JSON.stringify(key);
|
|
13
|
+
}
|
|
14
|
+
const preloadWithKey = (fn, key) => {
|
|
15
|
+
const keyStr = stringifyCacheKey(key);
|
|
16
|
+
promiseCache.has(keyStr) || promiseCache.set(keyStr, fn());
|
|
17
|
+
}, clear = () => {
|
|
18
|
+
promiseCache.clear();
|
|
19
|
+
}, peek = (selectedValue) => {
|
|
20
|
+
const key = stringifyCacheKey(["v1", namespace, selectedValue]), promise = promiseCache.get(key);
|
|
21
|
+
if (promise && promise._status === "fulfilled")
|
|
22
|
+
return promise._value;
|
|
23
|
+
}, createCacheKey = (selectedValue, workspaceId) => {
|
|
24
|
+
const selectedValueHash = JSON.stringify(selectedValue);
|
|
25
|
+
return workspaceId ? ["v1", namespace, selectedValueHash, workspaceId] : ["v1", namespace, selectedValueHash];
|
|
26
|
+
}, createOrGetPromise = (fn, key) => {
|
|
27
|
+
const keyStr = stringifyCacheKey(key);
|
|
28
|
+
if (promiseCache.has(keyStr))
|
|
29
|
+
return promiseCache.get(keyStr);
|
|
30
|
+
const promise = fn();
|
|
31
|
+
return promiseCache.set(keyStr, promise), promise;
|
|
32
|
+
}, getFunctionKey = (fn) => {
|
|
33
|
+
const cachedKey = functionKeyCache.get(fn);
|
|
34
|
+
if (cachedKey)
|
|
35
|
+
return cachedKey;
|
|
36
|
+
const fnStr = fn.toString();
|
|
37
|
+
let hash = 0;
|
|
38
|
+
const maxLength = Math.min(fnStr.length, 100);
|
|
39
|
+
for (let i = 0; i < maxLength; i++) {
|
|
40
|
+
const char = fnStr.charCodeAt(i);
|
|
41
|
+
hash = (hash << 5) - hash + char, hash &= hash;
|
|
42
|
+
}
|
|
43
|
+
const key = `anonymous_${Math.abs(hash)}`;
|
|
44
|
+
return functionKeyCache.set(fn, key), key;
|
|
45
|
+
}, createFunctionCacheKey = (fn, selectedValue, workspaceId) => {
|
|
46
|
+
const functionKey = getFunctionKey(fn), selectedValueHash = JSON.stringify(selectedValue);
|
|
47
|
+
return workspaceId ? `${functionKey}:${selectedValueHash}:${workspaceId}` : `${functionKey}:${selectedValueHash}`;
|
|
48
|
+
}, getFunctionCache = (fn, selectedValue, workspaceId) => {
|
|
49
|
+
const key = createFunctionCacheKey(fn, selectedValue, workspaceId);
|
|
50
|
+
return functionCache.get(key);
|
|
51
|
+
}, setFunctionCache = (fn, selectedValue, languages, workspaceId) => {
|
|
52
|
+
const key = createFunctionCacheKey(fn, selectedValue, workspaceId);
|
|
53
|
+
functionCache.set(key, languages);
|
|
54
|
+
}, MAX_COLUMNS = {
|
|
55
|
+
codeOnly: 5,
|
|
56
|
+
titleOnly: 4,
|
|
57
|
+
titleAndCode: 3
|
|
58
|
+
}, CONFIG_DEFAULT = {
|
|
59
|
+
languages: [],
|
|
60
|
+
select: {},
|
|
61
|
+
defaultLanguages: [],
|
|
62
|
+
fieldTypes: [],
|
|
63
|
+
apiVersion: "2025-10-15",
|
|
64
|
+
buttonLocations: ["field"],
|
|
65
|
+
buttonAddAll: !0,
|
|
66
|
+
languageDisplay: "codeOnly"
|
|
67
|
+
}, getDocumentsToTranslate = (value, rootPath = []) => {
|
|
68
|
+
if (Array.isArray(value)) {
|
|
69
|
+
const arrayRootPath = [...rootPath], internationalizedValues = value.filter((item) => {
|
|
70
|
+
if (Array.isArray(item)) return !1;
|
|
71
|
+
if (typeof item == "object") {
|
|
72
|
+
const type = item?._type;
|
|
73
|
+
return type?.startsWith("internationalizedArray") && type?.endsWith("Value");
|
|
74
|
+
}
|
|
75
|
+
return !1;
|
|
76
|
+
});
|
|
77
|
+
return internationalizedValues.length > 0 ? internationalizedValues.map((internationalizedValue) => Object.assign({}, internationalizedValue, {
|
|
78
|
+
path: arrayRootPath,
|
|
79
|
+
pathString: arrayRootPath.join(".")
|
|
80
|
+
})) : value.length > 0 ? value.flatMap((item, index) => getDocumentsToTranslate(item, [...arrayRootPath, index])) : [];
|
|
81
|
+
}
|
|
82
|
+
if (typeof value == "object" && value) {
|
|
83
|
+
const startsWithUnderscoreRegex = /^_/;
|
|
84
|
+
return Object.keys(value).filter((key) => !key.match(startsWithUnderscoreRegex)).flatMap((item) => {
|
|
85
|
+
const selectedValue = value[item], path = [...rootPath, item];
|
|
86
|
+
return getDocumentsToTranslate(selectedValue, path);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return [];
|
|
90
|
+
};
|
|
91
|
+
function getLanguageDisplay(languageDisplay, title, code) {
|
|
92
|
+
return languageDisplay === "codeOnly" ? code.toUpperCase() : languageDisplay === "titleOnly" ? title : languageDisplay === "titleAndCode" ? `${title} (${code.toUpperCase()})` : title;
|
|
93
|
+
}
|
|
94
|
+
function AddButtons(props) {
|
|
95
|
+
const $ = c(6), {
|
|
96
|
+
languages,
|
|
97
|
+
readOnly,
|
|
98
|
+
value,
|
|
99
|
+
onClick
|
|
100
|
+
} = props, {
|
|
101
|
+
languageDisplay
|
|
102
|
+
} = useInternationalizedArrayContext();
|
|
103
|
+
let t0;
|
|
104
|
+
return $[0] !== languageDisplay || $[1] !== languages || $[2] !== onClick || $[3] !== readOnly || $[4] !== value ? (t0 = languages.length > 0 ? /* @__PURE__ */ jsx(Grid, { columns: Math.min(languages.length, MAX_COLUMNS[languageDisplay]), gap: 2, children: languages.map((language) => {
|
|
105
|
+
const languageTitle = getLanguageDisplay(languageDisplay, language.title, language.id);
|
|
106
|
+
return /* @__PURE__ */ jsx(Button, { tone: "primary", mode: "ghost", fontSize: 1, disabled: readOnly || !!value?.find((item) => item._key === language.id), text: languageTitle, icon: languages.length > MAX_COLUMNS[languageDisplay] && languageDisplay === "codeOnly" ? void 0 : AddIcon, value: language.id, onClick }, language.id);
|
|
107
|
+
}) }) : null, $[0] = languageDisplay, $[1] = languages, $[2] = onClick, $[3] = readOnly, $[4] = value, $[5] = t0) : t0 = $[5], t0;
|
|
108
|
+
}
|
|
109
|
+
function DocumentAddButtons(props) {
|
|
110
|
+
const $ = c(13), {
|
|
111
|
+
filteredLanguages
|
|
112
|
+
} = useInternationalizedArrayContext(), value = isSanityDocument(props.value) ? props.value : void 0, toast = useToast(), {
|
|
113
|
+
onChange
|
|
114
|
+
} = useDocumentPane(), schema = useSchema();
|
|
115
|
+
let t0;
|
|
116
|
+
$[0] !== value ? (t0 = getDocumentsToTranslate(value, []), $[0] = value, $[1] = t0) : t0 = $[1];
|
|
117
|
+
const documentsToTranslation = t0;
|
|
118
|
+
let t1;
|
|
119
|
+
$[2] !== schema ? (t1 = (typeName) => {
|
|
120
|
+
if (!typeName)
|
|
121
|
+
return;
|
|
122
|
+
const match = typeName.match(/^internationalizedArray(.+)Value$/);
|
|
123
|
+
if (!match || !match[1])
|
|
124
|
+
return;
|
|
125
|
+
const baseTypeName = match[1].charAt(0).toLowerCase() + match[1].slice(1), arrayBasedTypes = /* @__PURE__ */ new Set(["body", "htmlContent", "blockContent", "portableText"]);
|
|
126
|
+
if (arrayBasedTypes.has(baseTypeName))
|
|
127
|
+
return [];
|
|
128
|
+
const schemaType = schema.get(typeName);
|
|
129
|
+
if (schemaType && "fields" in schemaType) {
|
|
130
|
+
const valueField = schemaType.fields.find(_temp$2);
|
|
131
|
+
if (valueField) {
|
|
132
|
+
const fieldType = valueField.type;
|
|
133
|
+
if (fieldType?.jsonType === "array" || fieldType?.name === "array" || fieldType?.type === "array" || fieldType?.of !== void 0 || fieldType?.name && arrayBasedTypes.has(fieldType.name))
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}, $[2] = schema, $[3] = t1) : t1 = $[3];
|
|
138
|
+
const getInitialValueForType = t1;
|
|
139
|
+
let t2;
|
|
140
|
+
$[4] !== documentsToTranslation || $[5] !== getInitialValueForType || $[6] !== onChange || $[7] !== toast ? (t2 = async (event) => {
|
|
141
|
+
const languageId = event.currentTarget.value;
|
|
142
|
+
if (!languageId) {
|
|
143
|
+
toast.push({
|
|
144
|
+
status: "error",
|
|
145
|
+
title: "No language selected"
|
|
146
|
+
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const alreadyTranslated = documentsToTranslation.filter((translation) => translation?._key === languageId), removeDuplicates = documentsToTranslation.reduce((filteredTranslations, translation_0) => (alreadyTranslated.filter((alreadyTranslation) => alreadyTranslation.pathString === translation_0.pathString).length > 0 || filteredTranslations.filter((filteredTranslation) => filteredTranslation.path === translation_0.path).length > 0 || filteredTranslations.push(translation_0), filteredTranslations), []);
|
|
150
|
+
if (removeDuplicates.length === 0) {
|
|
151
|
+
toast.push({
|
|
152
|
+
status: "error",
|
|
153
|
+
title: "No internationalizedArray fields found in document root"
|
|
154
|
+
});
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const patches = [];
|
|
158
|
+
for (const toTranslate of removeDuplicates) {
|
|
159
|
+
const path = toTranslate.path, initialValue = getInitialValueForType(toTranslate._type), ifMissing = setIfMissing([], path), insertValue = insert([{
|
|
160
|
+
_key: languageId,
|
|
161
|
+
_type: toTranslate._type,
|
|
162
|
+
value: initialValue
|
|
163
|
+
}], "after", [...path, -1]);
|
|
164
|
+
patches.push(ifMissing), patches.push(insertValue);
|
|
165
|
+
}
|
|
166
|
+
onChange(PatchEvent.from(patches.flat()));
|
|
167
|
+
}, $[4] = documentsToTranslation, $[5] = getInitialValueForType, $[6] = onChange, $[7] = toast, $[8] = t2) : t2 = $[8];
|
|
168
|
+
const handleDocumentButtonClick = t2;
|
|
169
|
+
let t3;
|
|
170
|
+
$[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t3 = /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", children: "Add translation to internationalized fields" }) }), $[9] = t3) : t3 = $[9];
|
|
171
|
+
let t4;
|
|
172
|
+
return $[10] !== filteredLanguages || $[11] !== handleDocumentButtonClick ? (t4 = /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
|
|
173
|
+
t3,
|
|
174
|
+
/* @__PURE__ */ jsx(AddButtons, { languages: filteredLanguages, readOnly: !1, value: void 0, onClick: handleDocumentButtonClick })
|
|
175
|
+
] }), $[10] = filteredLanguages, $[11] = handleDocumentButtonClick, $[12] = t4) : t4 = $[12], t4;
|
|
176
|
+
}
|
|
177
|
+
function _temp$2(f) {
|
|
178
|
+
return f.name === "value";
|
|
179
|
+
}
|
|
180
|
+
const getSelectedValue = (select, document) => {
|
|
181
|
+
if (!select || !document)
|
|
182
|
+
return {};
|
|
183
|
+
const selection = select || {}, selectedValue = {};
|
|
184
|
+
for (const [key, path] of Object.entries(selection)) {
|
|
185
|
+
let value = get(document, path);
|
|
186
|
+
Array.isArray(value) && (value = value.filter((item) => typeof item == "object" ? item?._type === "reference" && "_ref" in item : !0)), selectedValue[key] = value;
|
|
187
|
+
}
|
|
188
|
+
return selectedValue;
|
|
189
|
+
}, InternationalizedArrayContext = createContext({
|
|
190
|
+
...CONFIG_DEFAULT,
|
|
191
|
+
languages: [],
|
|
192
|
+
filteredLanguages: []
|
|
193
|
+
});
|
|
194
|
+
function useInternationalizedArrayContext() {
|
|
195
|
+
return useContext(InternationalizedArrayContext);
|
|
196
|
+
}
|
|
197
|
+
function InternationalizedArrayProvider(props) {
|
|
198
|
+
const $ = c(38), {
|
|
199
|
+
internationalizedArray: internationalizedArray2
|
|
200
|
+
} = props;
|
|
201
|
+
let t0;
|
|
202
|
+
$[0] !== internationalizedArray2.apiVersion ? (t0 = {
|
|
203
|
+
apiVersion: internationalizedArray2.apiVersion
|
|
204
|
+
}, $[0] = internationalizedArray2.apiVersion, $[1] = t0) : t0 = $[1];
|
|
205
|
+
const client = useClient(t0), workspace = useWorkspace(), {
|
|
206
|
+
formState
|
|
207
|
+
} = useDocumentPane(), deferredDocument = useDeferredValue(formState?.value);
|
|
208
|
+
let t1;
|
|
209
|
+
$[2] !== deferredDocument || $[3] !== internationalizedArray2.select ? (t1 = getSelectedValue(internationalizedArray2.select, deferredDocument), $[2] = deferredDocument, $[3] = internationalizedArray2.select, $[4] = t1) : t1 = $[4];
|
|
210
|
+
const selectedValue = t1;
|
|
211
|
+
let t2;
|
|
212
|
+
bb0: {
|
|
213
|
+
if (workspace?.name) {
|
|
214
|
+
t2 = workspace.name;
|
|
215
|
+
break bb0;
|
|
216
|
+
}
|
|
217
|
+
const t32 = workspace?.name, t42 = workspace?.title;
|
|
218
|
+
let t52;
|
|
219
|
+
$[5] !== t32 || $[6] !== t42 ? (t52 = JSON.stringify({
|
|
220
|
+
name: t32,
|
|
221
|
+
title: t42
|
|
222
|
+
}), $[5] = t32, $[6] = t42, $[7] = t52) : t52 = $[7], t2 = t52;
|
|
223
|
+
}
|
|
224
|
+
const workspaceId = t2;
|
|
225
|
+
let t3;
|
|
226
|
+
$[8] !== selectedValue || $[9] !== workspaceId ? (t3 = createCacheKey(selectedValue, workspaceId), $[8] = selectedValue, $[9] = workspaceId, $[10] = t3) : t3 = $[10];
|
|
227
|
+
const cacheKey = t3;
|
|
228
|
+
let t4;
|
|
229
|
+
bb1: {
|
|
230
|
+
if (Array.isArray(internationalizedArray2.languages)) {
|
|
231
|
+
t4 = null;
|
|
232
|
+
break bb1;
|
|
233
|
+
}
|
|
234
|
+
let t52;
|
|
235
|
+
$[11] !== client || $[12] !== internationalizedArray2 || $[13] !== selectedValue || $[14] !== workspaceId ? (t52 = async () => {
|
|
236
|
+
if (typeof internationalizedArray2.languages == "function") {
|
|
237
|
+
const result = await internationalizedArray2.languages(client, selectedValue);
|
|
238
|
+
return setFunctionCache(internationalizedArray2.languages, selectedValue, result, workspaceId), result;
|
|
239
|
+
}
|
|
240
|
+
return internationalizedArray2.languages;
|
|
241
|
+
}, $[11] = client, $[12] = internationalizedArray2, $[13] = selectedValue, $[14] = workspaceId, $[15] = t52) : t52 = $[15];
|
|
242
|
+
let t62;
|
|
243
|
+
$[16] !== cacheKey || $[17] !== t52 ? (t62 = createOrGetPromise(t52, cacheKey), $[16] = cacheKey, $[17] = t52, $[18] = t62) : t62 = $[18], t4 = t62;
|
|
244
|
+
}
|
|
245
|
+
const languagesPromise = t4, languages = languagesPromise ? use(languagesPromise) : internationalizedArray2.languages, {
|
|
246
|
+
selectedLanguageIds,
|
|
247
|
+
options: languageFilterOptions
|
|
248
|
+
} = useLanguageFilterStudioContext(), documentType = deferredDocument ? deferredDocument._type : void 0;
|
|
249
|
+
let t5;
|
|
250
|
+
$[19] !== documentType || $[20] !== languageFilterOptions ? (t5 = typeof documentType == "string" && languageFilterOptions.documentTypes.includes(documentType), $[19] = documentType, $[20] = languageFilterOptions, $[21] = t5) : t5 = $[21];
|
|
251
|
+
const languageFilterEnabled = t5;
|
|
252
|
+
let t6;
|
|
253
|
+
$[22] !== languageFilterEnabled || $[23] !== languages || $[24] !== selectedLanguageIds ? (t6 = languageFilterEnabled ? languages.filter((language) => selectedLanguageIds.includes(language.id)) : languages, $[22] = languageFilterEnabled, $[23] = languages, $[24] = selectedLanguageIds, $[25] = t6) : t6 = $[25];
|
|
254
|
+
const filteredLanguages = t6;
|
|
255
|
+
let t7;
|
|
256
|
+
$[26] !== internationalizedArray2.buttonLocations ? (t7 = internationalizedArray2.buttonLocations.includes("document"), $[26] = internationalizedArray2.buttonLocations, $[27] = t7) : t7 = $[27];
|
|
257
|
+
const showDocumentButtons = t7;
|
|
258
|
+
let t8;
|
|
259
|
+
$[28] !== filteredLanguages || $[29] !== internationalizedArray2 || $[30] !== languages ? (t8 = {
|
|
260
|
+
...internationalizedArray2,
|
|
261
|
+
languages,
|
|
262
|
+
filteredLanguages
|
|
263
|
+
}, $[28] = filteredLanguages, $[29] = internationalizedArray2, $[30] = languages, $[31] = t8) : t8 = $[31];
|
|
264
|
+
const context = t8;
|
|
265
|
+
let t9;
|
|
266
|
+
$[32] !== props || $[33] !== showDocumentButtons ? (t9 = showDocumentButtons ? /* @__PURE__ */ jsxs(Stack, { space: 5, children: [
|
|
267
|
+
/* @__PURE__ */ jsx(DocumentAddButtons, { value: props.value }),
|
|
268
|
+
props.renderDefault(props)
|
|
269
|
+
] }) : props.renderDefault(props), $[32] = props, $[33] = showDocumentButtons, $[34] = t9) : t9 = $[34];
|
|
270
|
+
let t10;
|
|
271
|
+
return $[35] !== context || $[36] !== t9 ? (t10 = /* @__PURE__ */ jsx(InternationalizedArrayContext.Provider, { value: context, children: t9 }), $[35] = context, $[36] = t9, $[37] = t10) : t10 = $[37], t10;
|
|
272
|
+
}
|
|
273
|
+
function InternationalizedField(props) {
|
|
274
|
+
const $ = c(9), {
|
|
275
|
+
languages
|
|
276
|
+
} = useInternationalizedArrayContext(), pathSegment = props.path.slice(0, -1)[1], languageId = typeof pathSegment == "object" && "_key" in pathSegment ? pathSegment._key : void 0, hasValidLanguageId = languageId ? languages.some((l) => l.id === languageId) : !1, t0 = props.title?.toLowerCase() === "value" && hasValidLanguageId ? "" : props.title;
|
|
277
|
+
let t1;
|
|
278
|
+
$[0] !== props || $[1] !== t0 ? (t1 = {
|
|
279
|
+
...props,
|
|
280
|
+
title: t0
|
|
281
|
+
}, $[0] = props, $[1] = t0, $[2] = t1) : t1 = $[2];
|
|
282
|
+
const customProps = t1;
|
|
283
|
+
if (!customProps.schemaType.name.startsWith("internationalizedArray")) {
|
|
284
|
+
let t22;
|
|
285
|
+
return $[3] !== customProps ? (t22 = customProps.renderDefault(customProps), $[3] = customProps, $[4] = t22) : t22 = $[4], t22;
|
|
286
|
+
}
|
|
287
|
+
if (customProps.schemaType.name === "reference" && customProps.value) {
|
|
288
|
+
let t22;
|
|
289
|
+
return $[5] !== customProps ? (t22 = customProps.renderDefault({
|
|
290
|
+
...customProps,
|
|
291
|
+
title: "",
|
|
292
|
+
level: 0
|
|
293
|
+
}), $[5] = customProps, $[6] = t22) : t22 = $[6], t22;
|
|
294
|
+
}
|
|
295
|
+
if (customProps.schemaType.name === "string" || customProps.schemaType.name === "number" || customProps.schemaType.name === "text")
|
|
296
|
+
return customProps.children;
|
|
297
|
+
let t2;
|
|
298
|
+
return $[7] !== customProps ? (t2 = customProps.renderDefault({
|
|
299
|
+
...customProps,
|
|
300
|
+
level: 0
|
|
301
|
+
}), $[7] = customProps, $[8] = t2) : t2 = $[8], t2;
|
|
302
|
+
}
|
|
303
|
+
function Preload(props) {
|
|
304
|
+
const $ = c(2);
|
|
305
|
+
let t0;
|
|
306
|
+
$[0] !== props.apiVersion ? (t0 = {
|
|
307
|
+
apiVersion: props.apiVersion
|
|
308
|
+
}, $[0] = props.apiVersion, $[1] = t0) : t0 = $[1];
|
|
309
|
+
const client = useClient(t0), cacheKey = createCacheKey({});
|
|
310
|
+
return Array.isArray(peek({})) || preloadWithKey(async () => {
|
|
311
|
+
if (Array.isArray(props.languages))
|
|
312
|
+
return props.languages;
|
|
313
|
+
const result = await props.languages(client, {});
|
|
314
|
+
return setFunctionCache(props.languages, {}, result), result;
|
|
315
|
+
}, cacheKey), null;
|
|
316
|
+
}
|
|
317
|
+
function checkAllLanguagesArePresent(languages, value) {
|
|
318
|
+
const filteredLanguageIds = languages.map((l) => l.id), languagesInUseIds = value ? value.map((v) => v._key) : [];
|
|
319
|
+
return languagesInUseIds.length === filteredLanguageIds.length && languagesInUseIds.every((l) => filteredLanguageIds.includes(l));
|
|
320
|
+
}
|
|
321
|
+
function createAddAllTitle(value, languages) {
|
|
322
|
+
return value?.length ? `Add missing ${languages.length - value.length === 1 ? "language" : "languages"}` : languages.length === 1 && languages[0] ? `Add ${languages[0].title} Field` : "Add all languages";
|
|
323
|
+
}
|
|
324
|
+
function createValueSchemaTypeName(schemaType) {
|
|
325
|
+
return `${schemaType.name}Value`;
|
|
326
|
+
}
|
|
327
|
+
function createAddLanguagePatches(config) {
|
|
328
|
+
const {
|
|
329
|
+
addLanguageKeys,
|
|
330
|
+
schemaType,
|
|
331
|
+
languages,
|
|
332
|
+
filteredLanguages,
|
|
333
|
+
value,
|
|
334
|
+
path = []
|
|
335
|
+
} = config, itemBase = {
|
|
336
|
+
_type: createValueSchemaTypeName(schemaType)
|
|
337
|
+
}, newItems = Array.isArray(addLanguageKeys) && addLanguageKeys.length > 0 ? addLanguageKeys.map((id) => Object.assign({}, itemBase, {
|
|
338
|
+
_key: id
|
|
339
|
+
})) : filteredLanguages.filter((language) => value?.length ? !value.find((v) => v._key === language.id) : !0).map((language) => Object.assign({}, itemBase, {
|
|
340
|
+
_key: language.id
|
|
341
|
+
})), languagesInUse = value?.length ? value.map((v) => v) : [];
|
|
342
|
+
return newItems.map((item) => {
|
|
343
|
+
const languageIndex = languages.findIndex((l) => item._key === l.id), remainingLanguages = languages.slice(languageIndex + 1), nextLanguageIndex = languagesInUse.findIndex((l) => remainingLanguages.find((r) => r.id === l._key));
|
|
344
|
+
return nextLanguageIndex < 0 ? languagesInUse.push(item) : languagesInUse.splice(nextLanguageIndex, 0, item), nextLanguageIndex < 0 ? (
|
|
345
|
+
// No next language (-1), add to end of array
|
|
346
|
+
insert([item], "after", [...path, nextLanguageIndex])
|
|
347
|
+
) : (
|
|
348
|
+
// Next language found, insert before that
|
|
349
|
+
insert([item], "before", [...path, nextLanguageIndex])
|
|
350
|
+
);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
const createTranslateFieldActions = (fieldActionProps, {
|
|
354
|
+
languages,
|
|
355
|
+
filteredLanguages
|
|
356
|
+
}) => languages.map((language) => {
|
|
357
|
+
const value = useFormValue(fieldActionProps.path), disabled = value && Array.isArray(value) ? !!value?.find((item) => item._key === language.id) : !1, hidden = !filteredLanguages.some((f) => f.id === language.id), {
|
|
358
|
+
onChange
|
|
359
|
+
} = useDocumentPane(), onAction = useCallback(() => {
|
|
360
|
+
const {
|
|
361
|
+
schemaType,
|
|
362
|
+
path
|
|
363
|
+
} = fieldActionProps, addLanguageKeys = [language.id], patches = createAddLanguagePatches({
|
|
364
|
+
addLanguageKeys,
|
|
365
|
+
schemaType,
|
|
366
|
+
languages,
|
|
367
|
+
filteredLanguages,
|
|
368
|
+
value,
|
|
369
|
+
path
|
|
370
|
+
});
|
|
371
|
+
onChange(PatchEvent.from([setIfMissing([], path), ...patches]));
|
|
372
|
+
}, [language.id, value, onChange]);
|
|
373
|
+
return {
|
|
374
|
+
type: "action",
|
|
375
|
+
icon: AddIcon,
|
|
376
|
+
onAction,
|
|
377
|
+
title: language.title,
|
|
378
|
+
hidden,
|
|
379
|
+
disabled
|
|
380
|
+
};
|
|
381
|
+
}), AddMissingTranslationsFieldAction = (fieldActionProps, {
|
|
382
|
+
languages,
|
|
383
|
+
filteredLanguages
|
|
384
|
+
}) => {
|
|
385
|
+
const value = useFormValue(fieldActionProps.path), disabled = value && value.length === filteredLanguages.length, hidden = checkAllLanguagesArePresent(filteredLanguages, value), {
|
|
386
|
+
onChange
|
|
387
|
+
} = useDocumentPane(), onAction = useCallback(() => {
|
|
388
|
+
const {
|
|
389
|
+
schemaType,
|
|
390
|
+
path
|
|
391
|
+
} = fieldActionProps, patches = createAddLanguagePatches({
|
|
392
|
+
addLanguageKeys: [],
|
|
393
|
+
schemaType,
|
|
394
|
+
languages,
|
|
395
|
+
filteredLanguages,
|
|
396
|
+
value,
|
|
397
|
+
path
|
|
398
|
+
});
|
|
399
|
+
onChange(PatchEvent.from([setIfMissing([], path), ...patches]));
|
|
400
|
+
}, [fieldActionProps, filteredLanguages, languages, onChange, value]);
|
|
401
|
+
return {
|
|
402
|
+
type: "action",
|
|
403
|
+
icon: AddIcon,
|
|
404
|
+
onAction,
|
|
405
|
+
title: createAddAllTitle(value, filteredLanguages),
|
|
406
|
+
disabled,
|
|
407
|
+
hidden
|
|
408
|
+
};
|
|
409
|
+
}, internationalizedArrayFieldAction = defineDocumentFieldAction({
|
|
410
|
+
name: "internationalizedArray",
|
|
411
|
+
useAction(fieldActionProps) {
|
|
412
|
+
const isInternationalizedArrayField = fieldActionProps?.schemaType?.type?.name.startsWith("internationalizedArray"), {
|
|
413
|
+
languages,
|
|
414
|
+
filteredLanguages
|
|
415
|
+
} = useInternationalizedArrayContext(), translateFieldActions = createTranslateFieldActions(fieldActionProps, {
|
|
416
|
+
languages,
|
|
417
|
+
filteredLanguages
|
|
418
|
+
});
|
|
419
|
+
return {
|
|
420
|
+
type: "group",
|
|
421
|
+
icon: TranslateIcon,
|
|
422
|
+
title: "Add Translation",
|
|
423
|
+
renderAsButton: !0,
|
|
424
|
+
children: isInternationalizedArrayField ? [...translateFieldActions, AddMissingTranslationsFieldAction(fieldActionProps, {
|
|
425
|
+
languages,
|
|
426
|
+
filteredLanguages
|
|
427
|
+
})] : [],
|
|
428
|
+
hidden: !isInternationalizedArrayField
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
function pascalCase(string) {
|
|
433
|
+
return upperFirst(camelCase(string));
|
|
434
|
+
}
|
|
435
|
+
function createFieldName(name, addValue = !1) {
|
|
436
|
+
return addValue ? ["internationalizedArray", pascalCase(name), "Value"].join("") : ["internationalizedArray", pascalCase(name)].join("");
|
|
437
|
+
}
|
|
438
|
+
const schemaExample = {
|
|
439
|
+
languages: [{
|
|
440
|
+
id: "en",
|
|
441
|
+
title: "English"
|
|
442
|
+
}, {
|
|
443
|
+
id: "no",
|
|
444
|
+
title: "Norsk"
|
|
445
|
+
}]
|
|
446
|
+
};
|
|
447
|
+
function Feedback() {
|
|
448
|
+
const $ = c(4);
|
|
449
|
+
let t0;
|
|
450
|
+
$[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = /* @__PURE__ */ jsx("code", { children: "internationalizedArray" }), $[0] = t0) : t0 = $[0];
|
|
451
|
+
let t1;
|
|
452
|
+
$[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = /* @__PURE__ */ jsx("code", { children: "id" }), $[1] = t1) : t1 = $[1];
|
|
453
|
+
let t2;
|
|
454
|
+
$[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t2 = /* @__PURE__ */ jsxs(Text, { children: [
|
|
455
|
+
"An array of language objects must be passed into the ",
|
|
456
|
+
t0,
|
|
457
|
+
" ",
|
|
458
|
+
"helper function, each with an ",
|
|
459
|
+
t1,
|
|
460
|
+
" and ",
|
|
461
|
+
/* @__PURE__ */ jsx("code", { children: "title" }),
|
|
462
|
+
" field. Example:"
|
|
463
|
+
] }), $[2] = t2) : t2 = $[2];
|
|
464
|
+
let t3;
|
|
465
|
+
return $[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t3 = /* @__PURE__ */ jsx(Card, { tone: "caution", border: !0, radius: 2, padding: 3, children: /* @__PURE__ */ jsxs(Stack, { space: 4, children: [
|
|
466
|
+
t2,
|
|
467
|
+
/* @__PURE__ */ jsx(Card, { padding: 2, border: !0, radius: 2, children: /* @__PURE__ */ jsx(Code, { size: 1, language: "javascript", children: JSON.stringify(schemaExample, null, 2) }) })
|
|
468
|
+
] }) }), $[3] = t3) : t3 = $[3], t3;
|
|
469
|
+
}
|
|
470
|
+
function InternationalizedArray(props) {
|
|
471
|
+
const $ = c(85), {
|
|
472
|
+
members,
|
|
473
|
+
value,
|
|
474
|
+
schemaType,
|
|
475
|
+
onChange,
|
|
476
|
+
readOnly: documentReadOnly
|
|
477
|
+
} = props, readOnly = typeof schemaType.readOnly == "boolean" ? schemaType.readOnly : !1, toast = useToast(), {
|
|
478
|
+
languages,
|
|
479
|
+
filteredLanguages,
|
|
480
|
+
defaultLanguages,
|
|
481
|
+
buttonAddAll,
|
|
482
|
+
buttonLocations
|
|
483
|
+
} = useInternationalizedArrayContext(), {
|
|
484
|
+
selectedLanguageIds,
|
|
485
|
+
options: languageFilterOptions
|
|
486
|
+
} = useLanguageFilterStudioContext();
|
|
487
|
+
let t0;
|
|
488
|
+
$[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = ["_type"], $[0] = t0) : t0 = $[0];
|
|
489
|
+
const documentType = useFormValue(t0);
|
|
490
|
+
let t1;
|
|
491
|
+
$[1] !== documentType || $[2] !== languageFilterOptions ? (t1 = typeof documentType == "string" && languageFilterOptions.documentTypes.includes(documentType), $[1] = documentType, $[2] = languageFilterOptions, $[3] = t1) : t1 = $[3];
|
|
492
|
+
const languageFilterEnabled = t1;
|
|
493
|
+
let t2;
|
|
494
|
+
$[4] !== languageFilterEnabled || $[5] !== languageFilterOptions || $[6] !== members || $[7] !== selectedLanguageIds ? (t2 = languageFilterEnabled ? members.filter((member) => {
|
|
495
|
+
if (member.kind !== "item")
|
|
496
|
+
return !1;
|
|
497
|
+
const valueMember = member.item.members[0];
|
|
498
|
+
return !valueMember || valueMember.kind !== "field" ? !1 : languageFilterOptions.filterField(member.item.schemaType, valueMember, selectedLanguageIds);
|
|
499
|
+
}) : members, $[4] = languageFilterEnabled, $[5] = languageFilterOptions, $[6] = members, $[7] = selectedLanguageIds, $[8] = t2) : t2 = $[8];
|
|
500
|
+
const filteredMembers = t2;
|
|
501
|
+
let t3;
|
|
502
|
+
$[9] !== filteredLanguages || $[10] !== languages || $[11] !== onChange || $[12] !== schemaType || $[13] !== value ? (t3 = async (param) => {
|
|
503
|
+
if (!filteredLanguages?.length)
|
|
504
|
+
return;
|
|
505
|
+
const addLanguageKeys = Array.isArray(param) ? param : [param?.currentTarget?.value].filter(Boolean), patches = createAddLanguagePatches({
|
|
506
|
+
addLanguageKeys,
|
|
507
|
+
schemaType,
|
|
508
|
+
languages,
|
|
509
|
+
filteredLanguages,
|
|
510
|
+
value
|
|
511
|
+
});
|
|
512
|
+
onChange([setIfMissing([]), ...patches]);
|
|
513
|
+
}, $[9] = filteredLanguages, $[10] = languages, $[11] = onChange, $[12] = schemaType, $[13] = value, $[14] = t3) : t3 = $[14];
|
|
514
|
+
const handleAddLanguage = t3, {
|
|
515
|
+
isDeleting
|
|
516
|
+
} = useDocumentPane();
|
|
517
|
+
let addedLanguages, t4;
|
|
518
|
+
if ($[15] !== defaultLanguages || $[16] !== languages || $[17] !== members) {
|
|
519
|
+
addedLanguages = members.map(_temp$1);
|
|
520
|
+
let t52;
|
|
521
|
+
$[20] !== languages ? (t52 = (language) => languages.find((l) => l.id === language), $[20] = languages, $[21] = t52) : t52 = $[21], t4 = defaultLanguages.filter(t52).every((language_0) => addedLanguages.includes(language_0)), $[15] = defaultLanguages, $[16] = languages, $[17] = members, $[18] = addedLanguages, $[19] = t4;
|
|
522
|
+
} else
|
|
523
|
+
addedLanguages = $[18], t4 = $[19];
|
|
524
|
+
const hasAddedDefaultLanguages = t4;
|
|
525
|
+
let t5, t6;
|
|
526
|
+
$[22] !== addedLanguages || $[23] !== defaultLanguages || $[24] !== documentReadOnly || $[25] !== handleAddLanguage || $[26] !== hasAddedDefaultLanguages || $[27] !== isDeleting || $[28] !== languages ? (t5 = () => {
|
|
527
|
+
if (!isDeleting && !hasAddedDefaultLanguages) {
|
|
528
|
+
const languagesToAdd = defaultLanguages.filter((language_1) => !addedLanguages.includes(language_1)).filter((language_2) => languages.find((l_0) => l_0.id === language_2)), timeout = setTimeout(() => {
|
|
529
|
+
documentReadOnly || handleAddLanguage(languagesToAdd);
|
|
530
|
+
});
|
|
531
|
+
return () => clearTimeout(timeout);
|
|
532
|
+
}
|
|
533
|
+
}, t6 = [isDeleting, hasAddedDefaultLanguages, handleAddLanguage, defaultLanguages, addedLanguages, languages, documentReadOnly], $[22] = addedLanguages, $[23] = defaultLanguages, $[24] = documentReadOnly, $[25] = handleAddLanguage, $[26] = hasAddedDefaultLanguages, $[27] = isDeleting, $[28] = languages, $[29] = t5, $[30] = t6) : (t5 = $[29], t6 = $[30]), useEffect(t5, t6);
|
|
534
|
+
let t7;
|
|
535
|
+
$[31] !== languages || $[32] !== onChange || $[33] !== toast || $[34] !== value ? (t7 = () => {
|
|
536
|
+
if (!value?.length || !languages?.length)
|
|
537
|
+
return;
|
|
538
|
+
const updatedValue = value.reduce((acc, v) => {
|
|
539
|
+
const newIndex = languages.findIndex((l_1) => l_1.id === v?._key);
|
|
540
|
+
return newIndex > -1 && (acc[newIndex] = v), acc;
|
|
541
|
+
}, []).filter(Boolean);
|
|
542
|
+
value?.length !== updatedValue.length && toast.push({
|
|
543
|
+
title: "There was an error reordering languages",
|
|
544
|
+
status: "warning"
|
|
545
|
+
}), onChange(set(updatedValue));
|
|
546
|
+
}, $[31] = languages, $[32] = onChange, $[33] = toast, $[34] = value, $[35] = t7) : t7 = $[35];
|
|
547
|
+
const handleRestoreOrder = t7;
|
|
548
|
+
let t8;
|
|
549
|
+
bb0: {
|
|
550
|
+
if (!value?.length || !languages?.length) {
|
|
551
|
+
t8 = !0;
|
|
552
|
+
break bb0;
|
|
553
|
+
}
|
|
554
|
+
let t92;
|
|
555
|
+
$[36] !== languages || $[37] !== value ? (t92 = value?.every((v_0) => languages.find((l_2) => l_2?.id === v_0?._key)), $[36] = languages, $[37] = value, $[38] = t92) : t92 = $[38], t8 = t92;
|
|
556
|
+
}
|
|
557
|
+
const allKeysAreLanguages = t8;
|
|
558
|
+
let t9;
|
|
559
|
+
$[39] !== languages || $[40] !== value ? (t9 = languages && languages.length > 1 ? languages.filter((l_3) => value?.find((v_1) => v_1._key === l_3.id)) : [], $[39] = languages, $[40] = value, $[41] = t9) : t9 = $[41];
|
|
560
|
+
const languagesInUse = t9;
|
|
561
|
+
let t10;
|
|
562
|
+
bb1: {
|
|
563
|
+
if (!value?.length || !languagesInUse.length) {
|
|
564
|
+
let t113;
|
|
565
|
+
$[42] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t113 = [], $[42] = t113) : t113 = $[42], t10 = t113;
|
|
566
|
+
break bb1;
|
|
567
|
+
}
|
|
568
|
+
let t112;
|
|
569
|
+
if ($[43] !== languagesInUse || $[44] !== value) {
|
|
570
|
+
let t122;
|
|
571
|
+
$[46] !== languagesInUse ? (t122 = (v_2, vIndex) => vIndex === languagesInUse.findIndex((l_4) => l_4.id === v_2._key) ? null : v_2, $[46] = languagesInUse, $[47] = t122) : t122 = $[47], t112 = value.map(t122).filter(Boolean), $[43] = languagesInUse, $[44] = value, $[45] = t112;
|
|
572
|
+
} else
|
|
573
|
+
t112 = $[45];
|
|
574
|
+
t10 = t112;
|
|
575
|
+
}
|
|
576
|
+
const languagesOutOfOrder = t10, languagesAreValid = !languages?.length || languages?.length && languages.every(_temp2$1);
|
|
577
|
+
let t11;
|
|
578
|
+
$[48] !== allKeysAreLanguages || $[49] !== documentReadOnly || $[50] !== handleRestoreOrder || $[51] !== languagesOutOfOrder.length ? (t11 = () => {
|
|
579
|
+
languagesOutOfOrder.length > 0 && allKeysAreLanguages && !documentReadOnly && handleRestoreOrder();
|
|
580
|
+
}, $[48] = allKeysAreLanguages, $[49] = documentReadOnly, $[50] = handleRestoreOrder, $[51] = languagesOutOfOrder.length, $[52] = t11) : t11 = $[52];
|
|
581
|
+
let t12;
|
|
582
|
+
$[53] !== allKeysAreLanguages || $[54] !== documentReadOnly || $[55] !== handleRestoreOrder || $[56] !== languagesOutOfOrder ? (t12 = [languagesOutOfOrder, allKeysAreLanguages, handleRestoreOrder, documentReadOnly], $[53] = allKeysAreLanguages, $[54] = documentReadOnly, $[55] = handleRestoreOrder, $[56] = languagesOutOfOrder, $[57] = t12) : t12 = $[57], useEffect(t11, t12);
|
|
583
|
+
let t13;
|
|
584
|
+
$[58] !== filteredLanguages || $[59] !== value ? (t13 = checkAllLanguagesArePresent(filteredLanguages, value), $[58] = filteredLanguages, $[59] = value, $[60] = t13) : t13 = $[60];
|
|
585
|
+
const allLanguagesArePresent = t13;
|
|
586
|
+
if (!languagesAreValid) {
|
|
587
|
+
let t142;
|
|
588
|
+
return $[61] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t142 = /* @__PURE__ */ jsx(Feedback, {}), $[61] = t142) : t142 = $[61], t142;
|
|
589
|
+
}
|
|
590
|
+
let t14;
|
|
591
|
+
$[62] !== allLanguagesArePresent || $[63] !== buttonLocations || $[64] !== filteredLanguages?.length ? (t14 = buttonLocations.includes("field") && filteredLanguages?.length > 0 && !allLanguagesArePresent, $[62] = allLanguagesArePresent, $[63] = buttonLocations, $[64] = filteredLanguages?.length, $[65] = t14) : t14 = $[65];
|
|
592
|
+
const addButtonsAreVisible = t14, fieldHasMembers = members?.length > 0;
|
|
593
|
+
let t15;
|
|
594
|
+
$[66] !== fieldHasMembers || $[67] !== filteredMembers || $[68] !== props ? (t15 = fieldHasMembers ? /* @__PURE__ */ jsx(Fragment, { children: filteredMembers.map((member_0) => member_0.kind === "item" ? /* @__PURE__ */ createElement(ArrayOfObjectsItem, { ...props, key: member_0.key, member: member_0 }) : /* @__PURE__ */ jsx(MemberItemError, { member: member_0 }, member_0.key)) }) : null, $[66] = fieldHasMembers, $[67] = filteredMembers, $[68] = props, $[69] = t15) : t15 = $[69];
|
|
595
|
+
let t16;
|
|
596
|
+
$[70] !== addButtonsAreVisible || $[71] !== fieldHasMembers ? (t16 = !addButtonsAreVisible && !fieldHasMembers ? /* @__PURE__ */ jsx(Card, { border: !0, tone: "transparent", padding: 3, radius: 2, children: /* @__PURE__ */ jsx(Text, { size: 1, children: "This internationalized field currently has no translations." }) }) : null, $[70] = addButtonsAreVisible, $[71] = fieldHasMembers, $[72] = t16) : t16 = $[72];
|
|
597
|
+
let t17;
|
|
598
|
+
$[73] !== addButtonsAreVisible || $[74] !== allLanguagesArePresent || $[75] !== buttonAddAll || $[76] !== filteredLanguages || $[77] !== handleAddLanguage || $[78] !== readOnly || $[79] !== value ? (t17 = addButtonsAreVisible ? /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
599
|
+
/* @__PURE__ */ jsx(AddButtons, { languages: filteredLanguages, value, readOnly, onClick: handleAddLanguage }),
|
|
600
|
+
buttonAddAll ? /* @__PURE__ */ jsx(Button, { tone: "primary", mode: "ghost", disabled: readOnly || allLanguagesArePresent, icon: AddIcon, text: createAddAllTitle(value, filteredLanguages), onClick: handleAddLanguage }) : null
|
|
601
|
+
] }) : null, $[73] = addButtonsAreVisible, $[74] = allLanguagesArePresent, $[75] = buttonAddAll, $[76] = filteredLanguages, $[77] = handleAddLanguage, $[78] = readOnly, $[79] = value, $[80] = t17) : t17 = $[80];
|
|
602
|
+
let t18;
|
|
603
|
+
return $[81] !== t15 || $[82] !== t16 || $[83] !== t17 ? (t18 = /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
604
|
+
t15,
|
|
605
|
+
t16,
|
|
606
|
+
t17
|
|
607
|
+
] }), $[81] = t15, $[82] = t16, $[83] = t17, $[84] = t18) : t18 = $[84], t18;
|
|
608
|
+
}
|
|
609
|
+
function _temp2$1(item) {
|
|
610
|
+
return item.id && item.title;
|
|
611
|
+
}
|
|
612
|
+
function _temp$1(t0) {
|
|
613
|
+
const {
|
|
614
|
+
key
|
|
615
|
+
} = t0;
|
|
616
|
+
return key;
|
|
617
|
+
}
|
|
618
|
+
function getLanguagesFieldOption(schemaType) {
|
|
619
|
+
return schemaType ? schemaType.options?.languages || getLanguagesFieldOption(schemaType.type) : void 0;
|
|
620
|
+
}
|
|
621
|
+
var array = (config) => {
|
|
622
|
+
const {
|
|
623
|
+
apiVersion,
|
|
624
|
+
select,
|
|
625
|
+
languages,
|
|
626
|
+
type
|
|
627
|
+
} = config, typeName = typeof type == "string" ? type : type.name, arrayName = createFieldName(typeName), objectName = createFieldName(typeName, !0);
|
|
628
|
+
return defineField({
|
|
629
|
+
name: arrayName,
|
|
630
|
+
title: "Internationalized array",
|
|
631
|
+
type: "array",
|
|
632
|
+
components: {
|
|
633
|
+
input: InternationalizedArray
|
|
634
|
+
},
|
|
635
|
+
options: {
|
|
636
|
+
// @ts-expect-error - these options are required for validation rules – not the custom input component
|
|
637
|
+
apiVersion,
|
|
638
|
+
select,
|
|
639
|
+
languages
|
|
640
|
+
},
|
|
641
|
+
of: [defineField({
|
|
642
|
+
...typeof type == "string" ? {} : type,
|
|
643
|
+
name: objectName,
|
|
644
|
+
type: objectName
|
|
645
|
+
})],
|
|
646
|
+
// @ts-expect-error - fix typings
|
|
647
|
+
validation: (rule) => rule.custom(async (value, context) => {
|
|
648
|
+
if (!value || value.length === 0 || value.length === 1 && !value[0]?._key)
|
|
649
|
+
return !0;
|
|
650
|
+
const selectedValue = getSelectedValue(select, context.document), client = context.getClient({
|
|
651
|
+
apiVersion
|
|
652
|
+
});
|
|
653
|
+
let contextLanguages = [];
|
|
654
|
+
const languagesFieldOption = getLanguagesFieldOption(context?.type);
|
|
655
|
+
if (Array.isArray(languagesFieldOption))
|
|
656
|
+
contextLanguages = languagesFieldOption;
|
|
657
|
+
else if (Array.isArray(peek(selectedValue)))
|
|
658
|
+
contextLanguages = peek(selectedValue) || [];
|
|
659
|
+
else if (typeof languagesFieldOption == "function") {
|
|
660
|
+
const cachedLanguages = getFunctionCache(languagesFieldOption, selectedValue);
|
|
661
|
+
if (Array.isArray(cachedLanguages))
|
|
662
|
+
contextLanguages = cachedLanguages;
|
|
663
|
+
else {
|
|
664
|
+
const suspendCachedLanguages = peek(selectedValue);
|
|
665
|
+
Array.isArray(suspendCachedLanguages) ? contextLanguages = suspendCachedLanguages : (contextLanguages = await languagesFieldOption(client, selectedValue), setFunctionCache(languagesFieldOption, selectedValue, contextLanguages));
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
if (value && value.length > contextLanguages.length)
|
|
669
|
+
return `Cannot be more than ${contextLanguages.length === 1 ? "1 item" : `${contextLanguages.length} items`}`;
|
|
670
|
+
const languageIds = new Set(contextLanguages.map((lang) => lang.id)), nonLanguageKeys = value.filter((item) => item?._key && !languageIds.has(item._key));
|
|
671
|
+
if (nonLanguageKeys.length)
|
|
672
|
+
return {
|
|
673
|
+
message: "Array item keys must be valid languages registered to the field type",
|
|
674
|
+
paths: nonLanguageKeys.map((item) => [{
|
|
675
|
+
_key: item._key
|
|
676
|
+
}])
|
|
677
|
+
};
|
|
678
|
+
const seenKeys = /* @__PURE__ */ new Set(), duplicateValues = [];
|
|
679
|
+
for (const item of value)
|
|
680
|
+
item?._key && (seenKeys.has(item._key) ? duplicateValues.push(item) : seenKeys.add(item._key));
|
|
681
|
+
return duplicateValues.length ? {
|
|
682
|
+
message: "There can only be one field per language",
|
|
683
|
+
paths: duplicateValues.map((item) => [{
|
|
684
|
+
_key: item._key
|
|
685
|
+
}])
|
|
686
|
+
} : !0;
|
|
687
|
+
})
|
|
688
|
+
});
|
|
689
|
+
};
|
|
690
|
+
function getToneFromValidation(validations) {
|
|
691
|
+
if (!validations?.length)
|
|
692
|
+
return;
|
|
693
|
+
const validationLevels = new Set(validations.map((v) => v.level));
|
|
694
|
+
if (validationLevels.has("error"))
|
|
695
|
+
return "critical";
|
|
696
|
+
if (validationLevels.has("warning"))
|
|
697
|
+
return "caution";
|
|
698
|
+
}
|
|
699
|
+
function InternationalizedInput(props) {
|
|
700
|
+
const $ = c(13);
|
|
701
|
+
let t0;
|
|
702
|
+
$[0] !== props.path ? (t0 = props.path.slice(0, -1), $[0] = props.path, $[1] = t0) : t0 = $[1];
|
|
703
|
+
const parentValue = useFormValue(t0), originalOnChange = props.inputProps.onChange;
|
|
704
|
+
let t1;
|
|
705
|
+
$[2] !== originalOnChange || $[3] !== props.value?.value ? (t1 = (patches) => {
|
|
706
|
+
if (!Array.isArray(patches))
|
|
707
|
+
return originalOnChange(patches);
|
|
708
|
+
const valueField = props.value?.value;
|
|
709
|
+
if ((valueField == null || Array.isArray(valueField) && valueField.length === 0) && patches.some(_temp)) {
|
|
710
|
+
const initPatch = valueField === void 0 ? {
|
|
711
|
+
type: "setIfMissing",
|
|
712
|
+
path: ["value"],
|
|
713
|
+
value: []
|
|
714
|
+
} : null, fixedPatches = patches.map(_temp2), allPatches = initPatch ? [initPatch, ...fixedPatches] : fixedPatches;
|
|
715
|
+
return originalOnChange(allPatches);
|
|
716
|
+
}
|
|
717
|
+
return originalOnChange(patches);
|
|
718
|
+
}, $[2] = originalOnChange, $[3] = props.value?.value, $[4] = t1) : t1 = $[4];
|
|
719
|
+
const wrappedOnChange = t1, inlineProps = {
|
|
720
|
+
...props.inputProps,
|
|
721
|
+
members: props.inputProps.members.filter(_temp3),
|
|
722
|
+
value: props.value,
|
|
723
|
+
onChange: wrappedOnChange
|
|
724
|
+
}, {
|
|
725
|
+
validation,
|
|
726
|
+
value,
|
|
727
|
+
onChange,
|
|
728
|
+
readOnly
|
|
729
|
+
} = inlineProps, {
|
|
730
|
+
languages,
|
|
731
|
+
languageDisplay,
|
|
732
|
+
defaultLanguages
|
|
733
|
+
} = useInternationalizedArrayContext();
|
|
734
|
+
let t2;
|
|
735
|
+
$[5] !== parentValue ? (t2 = parentValue?.map(_temp4) ?? [], $[5] = parentValue, $[6] = t2) : t2 = $[6];
|
|
736
|
+
const languageKeysInUse = t2, keyIsValid = languages?.length ? languages.find((l) => l.id === value._key) : !1, handleKeyChange = (event) => {
|
|
737
|
+
const languageId = event?.currentTarget?.value;
|
|
738
|
+
!value || !languages?.length || !languages.find((l_0) => l_0.id === languageId) || onChange([set(languageId, ["_key"])]);
|
|
739
|
+
}, handleUnset = () => {
|
|
740
|
+
onChange(unset());
|
|
741
|
+
};
|
|
742
|
+
if (!languages) {
|
|
743
|
+
let t32;
|
|
744
|
+
return $[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t32 = /* @__PURE__ */ jsx(Spinner, {}), $[7] = t32) : t32 = $[7], t32;
|
|
745
|
+
}
|
|
746
|
+
const language = languages.find((l_1) => l_1.id === value._key), languageTitle = keyIsValid && language ? getLanguageDisplay(languageDisplay, language.title, language.id) : "", isDefault = defaultLanguages.includes(value._key), removeButton = /* @__PURE__ */ jsx(Button, { mode: "bleed", icon: RemoveCircleIcon, tone: "critical", disabled: readOnly || isDefault, onClick: handleUnset }), t3 = getToneFromValidation(validation), t4 = keyIsValid ? /* @__PURE__ */ jsx(Label, { muted: !0, size: 1, children: languageTitle }) : /* @__PURE__ */ jsx(MenuButton, { button: /* @__PURE__ */ jsx(Button, { fontSize: 1, text: `Change "${value._key}"` }), id: `${value._key}-change-key`, menu: /* @__PURE__ */ jsx(Menu, { children: languages.map((lang) => /* @__PURE__ */ jsx(MenuItem, { disabled: languageKeysInUse.includes(lang.id), fontSize: 1, text: lang.id.toLocaleUpperCase(), value: lang.id, onClick: handleKeyChange }, lang.id)) }), popover: {
|
|
747
|
+
portal: !0
|
|
748
|
+
} });
|
|
749
|
+
let t5;
|
|
750
|
+
$[8] !== t4 ? (t5 = /* @__PURE__ */ jsx(Card, { tone: "inherit", children: t4 }), $[8] = t4, $[9] = t5) : t5 = $[9];
|
|
751
|
+
const T0 = Card, t6 = 1, t7 = "inherit", t8 = props.inputProps.renderInput(inlineProps);
|
|
752
|
+
let t9;
|
|
753
|
+
return $[10] !== T0 || $[11] !== t8 ? (t9 = /* @__PURE__ */ jsx(T0, { flex: t6, tone: t7, children: t8 }), $[10] = T0, $[11] = t8, $[12] = t9) : t9 = $[12], /* @__PURE__ */ jsx(Card, { paddingTop: 2, tone: t3, children: /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
754
|
+
t5,
|
|
755
|
+
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
|
|
756
|
+
t9,
|
|
757
|
+
/* @__PURE__ */ jsx(Card, { tone: "inherit", children: isDefault ? /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(Text, { muted: !0, size: 1, children: "Can't remove default language" }), fallbackPlacements: ["right", "left"], placement: "top", portal: !0, children: /* @__PURE__ */ jsx("span", { children: removeButton }) }) : removeButton })
|
|
758
|
+
] })
|
|
759
|
+
] }) });
|
|
760
|
+
}
|
|
761
|
+
function _temp4(v) {
|
|
762
|
+
return v._key;
|
|
763
|
+
}
|
|
764
|
+
function _temp3(m) {
|
|
765
|
+
return m.kind === "field" && m.name === "value";
|
|
766
|
+
}
|
|
767
|
+
function _temp2(patch_0) {
|
|
768
|
+
if (!patch_0 || typeof patch_0 != "object")
|
|
769
|
+
return patch_0;
|
|
770
|
+
if (patch_0.type === "insert" && patch_0.path && Array.isArray(patch_0.path)) {
|
|
771
|
+
const fixedPath = patch_0.path[0] === "value" ? patch_0.path : ["value", ...patch_0.path];
|
|
772
|
+
return {
|
|
773
|
+
...patch_0,
|
|
774
|
+
path: fixedPath
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
return patch_0;
|
|
778
|
+
}
|
|
779
|
+
function _temp(patch) {
|
|
780
|
+
return !patch || typeof patch != "object" ? !1 : patch.type === "insert" && patch.path && Array.isArray(patch.path) && patch.path.length > 0 ? patch.path[0] === "value" || typeof patch.path[0] == "number" : !1;
|
|
781
|
+
}
|
|
782
|
+
var object = (config) => {
|
|
783
|
+
const {
|
|
784
|
+
type
|
|
785
|
+
} = config, typeName = typeof type == "string" ? type : type.name, objectName = createFieldName(typeName, !0);
|
|
786
|
+
return defineField({
|
|
787
|
+
name: objectName,
|
|
788
|
+
title: `Internationalized array ${typeName}`,
|
|
789
|
+
type: "object",
|
|
790
|
+
components: {
|
|
791
|
+
// @ts-expect-error - fix typings
|
|
792
|
+
item: InternationalizedInput
|
|
793
|
+
},
|
|
794
|
+
fields: [defineField({
|
|
795
|
+
...typeof type == "string" ? {
|
|
796
|
+
type
|
|
797
|
+
} : type,
|
|
798
|
+
name: "value"
|
|
799
|
+
})],
|
|
800
|
+
preview: {
|
|
801
|
+
select: {
|
|
802
|
+
title: "value",
|
|
803
|
+
subtitle: "_key"
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
});
|
|
807
|
+
};
|
|
808
|
+
function flattenSchemaType(schemaType) {
|
|
809
|
+
return isDocumentSchemaType(schemaType) ? extractInnerFields(schemaType.fields, [], 3) : (console.error("Schema type is not a document"), []);
|
|
810
|
+
}
|
|
811
|
+
function extractInnerFields(fields, path, maxDepth) {
|
|
812
|
+
return path.length >= maxDepth ? [] : fields.reduce((acc, field) => {
|
|
813
|
+
const thisFieldWithPath = {
|
|
814
|
+
path: [...path, field.name],
|
|
815
|
+
...field
|
|
816
|
+
};
|
|
817
|
+
if (field.type.jsonType === "object") {
|
|
818
|
+
const innerFields = extractInnerFields(field.type.fields, [...path, field.name], maxDepth);
|
|
819
|
+
return acc.push(thisFieldWithPath, ...innerFields), acc;
|
|
820
|
+
} else if (field.type.jsonType === "array" && field.type.of.length && field.type.of.some((item) => "fields" in item)) {
|
|
821
|
+
const innerFields = field.type.of.flatMap((innerField) => extractInnerFields(
|
|
822
|
+
// @ts-expect-error - Fix TS assertion for array fields
|
|
823
|
+
innerField.fields,
|
|
824
|
+
[...path, field.name],
|
|
825
|
+
maxDepth
|
|
826
|
+
));
|
|
827
|
+
return acc.push(thisFieldWithPath, ...innerFields), acc;
|
|
828
|
+
}
|
|
829
|
+
return acc.push(thisFieldWithPath), acc;
|
|
830
|
+
}, []);
|
|
831
|
+
}
|
|
832
|
+
const internationalizedArray = definePlugin((config) => {
|
|
833
|
+
const pluginConfig = {
|
|
834
|
+
...CONFIG_DEFAULT,
|
|
835
|
+
...config
|
|
836
|
+
}, {
|
|
837
|
+
apiVersion = "2025-10-15",
|
|
838
|
+
select,
|
|
839
|
+
languages,
|
|
840
|
+
fieldTypes,
|
|
841
|
+
buttonLocations
|
|
842
|
+
} = pluginConfig;
|
|
843
|
+
return {
|
|
844
|
+
name: "sanity-plugin-internationalized-array",
|
|
845
|
+
// Preload languages for use throughout the Studio
|
|
846
|
+
studio: Array.isArray(languages) ? void 0 : {
|
|
847
|
+
components: {
|
|
848
|
+
layout: (props) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
849
|
+
/* @__PURE__ */ jsx(Preload, { apiVersion, languages }),
|
|
850
|
+
props.renderDefault(props)
|
|
851
|
+
] })
|
|
852
|
+
}
|
|
853
|
+
},
|
|
854
|
+
// Optional: render "add language" buttons as field actions
|
|
855
|
+
document: {
|
|
856
|
+
unstable_fieldActions: buttonLocations.includes("unstable__fieldAction") ? (prev) => [...prev, internationalizedArrayFieldAction] : void 0
|
|
857
|
+
},
|
|
858
|
+
// Wrap document editor with a language provider
|
|
859
|
+
form: {
|
|
860
|
+
components: {
|
|
861
|
+
field: (props) => /* @__PURE__ */ jsx(InternationalizedField, { ...props }),
|
|
862
|
+
input: (props) => !(props.id === "root" && isObjectInputProps(props)) || !flattenSchemaType(props.schemaType).map((field) => field.type.name).some((name) => name.startsWith("internationalizedArray")) ? props.renderDefault(props) : /* @__PURE__ */ jsx(InternationalizedArrayProvider, { ...props, internationalizedArray: pluginConfig })
|
|
863
|
+
}
|
|
864
|
+
},
|
|
865
|
+
// Register custom schema types for the outer array and the inner object
|
|
866
|
+
schema: {
|
|
867
|
+
types: [...fieldTypes.map((type) => array({
|
|
868
|
+
type,
|
|
869
|
+
apiVersion,
|
|
870
|
+
select,
|
|
871
|
+
languages
|
|
872
|
+
})), ...fieldTypes.map((type) => object({
|
|
873
|
+
type
|
|
874
|
+
}))]
|
|
875
|
+
}
|
|
876
|
+
};
|
|
877
|
+
});
|
|
878
|
+
export {
|
|
879
|
+
clear,
|
|
880
|
+
internationalizedArray
|
|
881
|
+
};
|
|
882
|
+
//# sourceMappingURL=index.js.map
|