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