@sanity/document-internationalization 2.0.0-studio-v3-plugin-v2.7 → 2.0.0-studio-v3-plugin-v2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/lib/index.esm.js +407 -156
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +405 -154
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/BulkPublish/DocumentCheck.tsx +39 -16
- package/src/components/BulkPublish/index.tsx +86 -55
- package/src/components/LanguageManage.tsx +1 -2
- package/src/components/LanguageOption.tsx +78 -28
- package/src/components/LanguagePatch.tsx +16 -8
- package/src/components/MenuButton.tsx +76 -43
- package/src/components/OptimisticallyStrengthen/ReferencePatcher.tsx +49 -0
- package/src/components/OptimisticallyStrengthen/index.tsx +34 -0
- package/src/plugin.tsx +195 -147
- package/src/schema/translation/metadata.ts +1 -1
- package/src/types.ts +9 -7
package/lib/index.js
CHANGED
|
@@ -4,71 +4,180 @@ Object.defineProperty(exports, '__esModule', {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
var ui = require('@sanity/ui');
|
|
7
8
|
var sanity = require('sanity');
|
|
8
9
|
var sanityPluginInternationalizedArray = require('sanity-plugin-internationalized-array');
|
|
9
|
-
var ui = require('@sanity/ui');
|
|
10
|
-
var icons = require('@sanity/icons');
|
|
11
10
|
var React = require('react');
|
|
12
|
-
var
|
|
11
|
+
var icons = require('@sanity/icons');
|
|
12
|
+
var sanityPluginUtils = require('sanity-plugin-utils');
|
|
13
13
|
var desk = require('sanity/desk');
|
|
14
14
|
var router = require('sanity/router');
|
|
15
|
-
var
|
|
15
|
+
var uuid = require('@sanity/uuid');
|
|
16
16
|
function _interopDefaultCompat(e) {
|
|
17
17
|
return e && typeof e === 'object' && 'default' in e ? e : {
|
|
18
18
|
default: e
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
var React__default = /*#__PURE__*/_interopDefaultCompat(React);
|
|
22
|
+
function LanguageBadge(props, supportedLanguages, languageField) {
|
|
23
|
+
var _a, _b;
|
|
24
|
+
const source = (props == null ? void 0 : props.draft) || (props == null ? void 0 : props.published);
|
|
25
|
+
const languageId = source == null ? void 0 : source[languageField];
|
|
26
|
+
if (!languageId) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const language = Array.isArray(supportedLanguages) ? supportedLanguages.find(l => l.id === languageId) : null;
|
|
30
|
+
return {
|
|
31
|
+
label: (_a = language == null ? void 0 : language.id) != null ? _a : String(languageId),
|
|
32
|
+
title: (_b = language == null ? void 0 : language.title) != null ? _b : void 0,
|
|
33
|
+
color: "primary"
|
|
34
|
+
};
|
|
35
|
+
}
|
|
22
36
|
const METADATA_SCHEMA_NAME = "translation.metadata";
|
|
23
37
|
const API_VERSION = "2022-11-27";
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
let {
|
|
47
|
-
value
|
|
48
|
-
} = _ref;
|
|
49
|
-
return Boolean(value);
|
|
38
|
+
function DocumentCheck(props) {
|
|
39
|
+
const {
|
|
40
|
+
id,
|
|
41
|
+
addInvalidId,
|
|
42
|
+
removeInvalidId,
|
|
43
|
+
addDraftId,
|
|
44
|
+
removeDraftId
|
|
45
|
+
} = props;
|
|
46
|
+
const editState = sanity.useEditState(id, "");
|
|
47
|
+
const {
|
|
48
|
+
isValidating,
|
|
49
|
+
validation
|
|
50
|
+
} = sanity.useValidationStatus(id, "");
|
|
51
|
+
const schema = sanity.useSchema();
|
|
52
|
+
const validationHasErrors = React__default.default.useMemo(() => {
|
|
53
|
+
return !isValidating && validation.length > 0 && validation.some(item => item.level === "error");
|
|
54
|
+
}, [isValidating, validation]);
|
|
55
|
+
React__default.default.useEffect(() => {
|
|
56
|
+
if (validationHasErrors) {
|
|
57
|
+
addInvalidId(id);
|
|
58
|
+
} else {
|
|
59
|
+
removeInvalidId(id);
|
|
50
60
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
documentSchemaTypes: "schemaTypes"
|
|
56
|
-
},
|
|
57
|
-
prepare(selection) {
|
|
58
|
-
const {
|
|
59
|
-
translations,
|
|
60
|
-
documentSchemaTypes
|
|
61
|
-
} = selection;
|
|
62
|
-
const title = translations.length === 1 ? "1 Translation" : "".concat(translations.length, " Translations");
|
|
63
|
-
const languageKeys = translations.length ? translations.map(t => t._key.toUpperCase()).join(", ") : "";
|
|
64
|
-
const subtitle = [languageKeys ? "(".concat(languageKeys, ")") : null, (documentSchemaTypes == null ? void 0 : documentSchemaTypes.length) ? documentSchemaTypes.map(s => s.toUpperCase()).join(", ") : "No Schemas Defined"].filter(Boolean).join(" ");
|
|
65
|
-
return {
|
|
66
|
-
title,
|
|
67
|
-
subtitle
|
|
68
|
-
};
|
|
61
|
+
if (editState.draft) {
|
|
62
|
+
addDraftId(id);
|
|
63
|
+
} else {
|
|
64
|
+
removeDraftId(id);
|
|
69
65
|
}
|
|
66
|
+
}, [addDraftId, addInvalidId, editState.draft, id, removeDraftId, removeInvalidId, validationHasErrors]);
|
|
67
|
+
if (!editState.draft) {
|
|
68
|
+
return null;
|
|
70
69
|
}
|
|
71
|
-
|
|
70
|
+
const schemaType = schema.get(editState.draft._type);
|
|
71
|
+
return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
72
|
+
border: true,
|
|
73
|
+
padding: 2,
|
|
74
|
+
tone: validationHasErrors ? "critical" : "positive",
|
|
75
|
+
children: editState.draft && schemaType ? /* @__PURE__ */jsxRuntime.jsx(sanity.Preview, {
|
|
76
|
+
layout: "default",
|
|
77
|
+
value: editState.draft,
|
|
78
|
+
schemaType
|
|
79
|
+
}) : /* @__PURE__ */jsxRuntime.jsx(ui.Spinner, {})
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function BulkPublish(props) {
|
|
83
|
+
const {
|
|
84
|
+
translations
|
|
85
|
+
} = props;
|
|
86
|
+
const client = sanity.useClient({
|
|
87
|
+
apiVersion: API_VERSION
|
|
88
|
+
});
|
|
89
|
+
const {
|
|
90
|
+
projectId,
|
|
91
|
+
dataset
|
|
92
|
+
} = sanity.useWorkspace();
|
|
93
|
+
const toast = ui.useToast();
|
|
94
|
+
const [invalidIds, setInvalidIds] = React__default.default.useState(null);
|
|
95
|
+
const addInvalidId = React.useCallback(id => {
|
|
96
|
+
setInvalidIds(ids => ids ? Array.from( /* @__PURE__ */new Set([...ids, id])) : [id]);
|
|
97
|
+
}, []);
|
|
98
|
+
const removeInvalidId = React.useCallback(id => {
|
|
99
|
+
setInvalidIds(ids => ids ? ids.filter(i => i !== id) : []);
|
|
100
|
+
}, []);
|
|
101
|
+
const [draftIds, setDraftIds] = React__default.default.useState([]);
|
|
102
|
+
const addDraftId = React.useCallback(id => {
|
|
103
|
+
setDraftIds(ids => Array.from( /* @__PURE__ */new Set([...ids, id])));
|
|
104
|
+
}, []);
|
|
105
|
+
const removeDraftId = React.useCallback(id => {
|
|
106
|
+
setDraftIds(ids => ids.filter(i => i !== id));
|
|
107
|
+
}, []);
|
|
108
|
+
const handleBulkPublish = React.useCallback(() => {
|
|
109
|
+
const body = translations.map(translation => ({
|
|
110
|
+
documentId: translation.value._ref
|
|
111
|
+
}));
|
|
112
|
+
client.request({
|
|
113
|
+
uri: "/publish/".concat(projectId, "/").concat(dataset),
|
|
114
|
+
method: "POST",
|
|
115
|
+
body
|
|
116
|
+
}).then(res => {
|
|
117
|
+
toast.push({
|
|
118
|
+
status: "success",
|
|
119
|
+
title: "Success",
|
|
120
|
+
description: "Bulk publish complete"
|
|
121
|
+
});
|
|
122
|
+
}).catch(err => {
|
|
123
|
+
console.error(err);
|
|
124
|
+
toast.push({
|
|
125
|
+
status: "error",
|
|
126
|
+
title: "Error",
|
|
127
|
+
description: "Bulk publish failed"
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}, [translations, client, projectId, dataset, toast]);
|
|
131
|
+
return (translations == null ? void 0 : translations.length) > 0 ? /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
132
|
+
padding: 4,
|
|
133
|
+
border: true,
|
|
134
|
+
radius: 2,
|
|
135
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
|
|
136
|
+
space: 3,
|
|
137
|
+
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
138
|
+
weight: "bold",
|
|
139
|
+
size: 1,
|
|
140
|
+
children: "Bulk publishing"
|
|
141
|
+
}), draftIds.length > 0 ? /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
|
|
142
|
+
space: 2,
|
|
143
|
+
children: [/* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
|
|
144
|
+
size: 1,
|
|
145
|
+
children: ["There", " ", draftIds.length === 1 ? "is 1 draft document" : "are ".concat(draftIds.length, " draft documents"), "."]
|
|
146
|
+
}), invalidIds && invalidIds.length > 0 ? /* @__PURE__ */jsxRuntime.jsxs(sanity.TextWithTone, {
|
|
147
|
+
tone: "caution",
|
|
148
|
+
size: 1,
|
|
149
|
+
children: [invalidIds && invalidIds.length === 1 ? "1 draft document has" : "".concat(invalidIds && invalidIds.length, " draft documents have"), " ", "validation issues that must addressed first"]
|
|
150
|
+
}) : /* @__PURE__ */jsxRuntime.jsx(sanity.TextWithTone, {
|
|
151
|
+
tone: "positive",
|
|
152
|
+
size: 1,
|
|
153
|
+
children: "All drafts are valid and can be bulk published"
|
|
154
|
+
})]
|
|
155
|
+
}) : null, /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
|
|
156
|
+
space: 1,
|
|
157
|
+
children: translations.filter(translation => {
|
|
158
|
+
var _a;
|
|
159
|
+
return (_a = translation == null ? void 0 : translation.value) == null ? void 0 : _a._ref;
|
|
160
|
+
}).map(translation => /* @__PURE__ */jsxRuntime.jsx(DocumentCheck, {
|
|
161
|
+
id: translation.value._ref,
|
|
162
|
+
addInvalidId,
|
|
163
|
+
removeInvalidId,
|
|
164
|
+
addDraftId,
|
|
165
|
+
removeDraftId
|
|
166
|
+
}, translation._key))
|
|
167
|
+
}), draftIds.length > 0 ? /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
168
|
+
mode: "ghost",
|
|
169
|
+
tone: invalidIds && (invalidIds == null ? void 0 : invalidIds.length) > 0 ? "caution" : "positive",
|
|
170
|
+
text: draftIds.length === 1 ? "Publish draft document" : "Bulk publish ".concat(draftIds.length, " draft documents"),
|
|
171
|
+
onClick: handleBulkPublish,
|
|
172
|
+
disabled: Boolean(invalidIds && (invalidIds == null ? void 0 : invalidIds.length) > 0) || !draftIds.length
|
|
173
|
+
}) : /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
174
|
+
muted: true,
|
|
175
|
+
size: 1,
|
|
176
|
+
children: "No draft documents to publish"
|
|
177
|
+
})]
|
|
178
|
+
})
|
|
179
|
+
}) : null;
|
|
180
|
+
}
|
|
72
181
|
function shallowEqualArrays(arrA, arrB) {
|
|
73
182
|
let equal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : (a, b) => a === b;
|
|
74
183
|
if (arrA === arrB) return true;
|
|
@@ -120,6 +229,24 @@ function query(fn, keys) {
|
|
|
120
229
|
return undefined;
|
|
121
230
|
}
|
|
122
231
|
const suspend = (fn, keys, config) => query(fn, keys, false, config);
|
|
232
|
+
function useTranslationMetadata(id, schemaType) {
|
|
233
|
+
const query = "*[_type == $translationSchema && $id in translations[].value._ref][0]";
|
|
234
|
+
const {
|
|
235
|
+
data,
|
|
236
|
+
loading,
|
|
237
|
+
error
|
|
238
|
+
} = sanityPluginUtils.useListeningQuery(query, {
|
|
239
|
+
params: {
|
|
240
|
+
id,
|
|
241
|
+
translationSchema: METADATA_SCHEMA_NAME
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
return {
|
|
245
|
+
data,
|
|
246
|
+
loading,
|
|
247
|
+
error
|
|
248
|
+
};
|
|
249
|
+
}
|
|
123
250
|
function useOpenInNewPane(id, type) {
|
|
124
251
|
const routerContext = React__default.default.useContext(router.RouterContext);
|
|
125
252
|
const {
|
|
@@ -146,9 +273,23 @@ function useOpenInNewPane(id, type) {
|
|
|
146
273
|
}, [id, type, routerContext, routerPanesState, groupIndex]);
|
|
147
274
|
return openInNewPane;
|
|
148
275
|
}
|
|
276
|
+
function LanguageManage(props) {
|
|
277
|
+
const {
|
|
278
|
+
id
|
|
279
|
+
} = props;
|
|
280
|
+
const open = useOpenInNewPane(id, METADATA_SCHEMA_NAME);
|
|
281
|
+
return /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
282
|
+
disabled: !id,
|
|
283
|
+
mode: "ghost",
|
|
284
|
+
text: "Manage Translations",
|
|
285
|
+
icon: icons.CogIcon,
|
|
286
|
+
onClick: () => open()
|
|
287
|
+
});
|
|
288
|
+
}
|
|
149
289
|
function createReference(key, ref, type) {
|
|
150
290
|
return {
|
|
151
291
|
_key: key,
|
|
292
|
+
_type: "internationalizedArrayReferenceValue",
|
|
152
293
|
value: {
|
|
153
294
|
_type: "reference",
|
|
154
295
|
_ref: ref,
|
|
@@ -227,59 +368,49 @@ function LanguageOption(props) {
|
|
|
227
368
|
});
|
|
228
369
|
});
|
|
229
370
|
}, [client, documentId, index, language, languageField, metadata == null ? void 0 : metadata._id, schemaType, sourceId, sourceLanguageId, toast]);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
371
|
+
let message;
|
|
372
|
+
if (current) {
|
|
373
|
+
message = "Current document";
|
|
374
|
+
} else if (translation) {
|
|
375
|
+
message = "Open ".concat(language.title, " translation");
|
|
376
|
+
} else if (!translation) {
|
|
377
|
+
message = "Create new ".concat(language.title, " translation");
|
|
378
|
+
}
|
|
379
|
+
return /* @__PURE__ */jsxRuntime.jsx(ui.Tooltip, {
|
|
380
|
+
content: /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
381
|
+
padding: 2,
|
|
382
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
383
|
+
muted: true,
|
|
384
|
+
size: 1,
|
|
385
|
+
children: message
|
|
386
|
+
})
|
|
387
|
+
}),
|
|
388
|
+
fallbackPlacements: ["right", "left"],
|
|
389
|
+
placement: "top",
|
|
390
|
+
portal: true,
|
|
391
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
392
|
+
onClick: translation ? handleOpen : handleCreate,
|
|
393
|
+
mode: current && disabled ? "default" : "bleed",
|
|
394
|
+
disabled: disabled || current,
|
|
395
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
396
|
+
gap: 3,
|
|
397
|
+
align: "center",
|
|
398
|
+
children: [disabled ? /* @__PURE__ */jsxRuntime.jsx(ui.Spinner, {}) : /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
399
|
+
size: 2,
|
|
400
|
+
children: translation ? /* @__PURE__ */jsxRuntime.jsx(icons.SplitVerticalIcon, {}) : current ? /* @__PURE__ */jsxRuntime.jsx(icons.CheckmarkIcon, {}) : /* @__PURE__ */jsxRuntime.jsx(icons.AddIcon, {})
|
|
401
|
+
}), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
402
|
+
flex: 1,
|
|
403
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
404
|
+
children: language.title
|
|
405
|
+
})
|
|
406
|
+
}), /* @__PURE__ */jsxRuntime.jsx(ui.Badge, {
|
|
407
|
+
tone: disabled || current ? "default" : "primary",
|
|
408
|
+
children: language.id
|
|
409
|
+
})]
|
|
410
|
+
})
|
|
249
411
|
})
|
|
250
412
|
});
|
|
251
413
|
}
|
|
252
|
-
function useTranslationMetadata(id, schemaType) {
|
|
253
|
-
const query = "*[_type == $translationSchema && $id in translations[].value._ref][0]";
|
|
254
|
-
const {
|
|
255
|
-
data,
|
|
256
|
-
loading,
|
|
257
|
-
error
|
|
258
|
-
} = sanityPluginUtils.useListeningQuery(query, {
|
|
259
|
-
params: {
|
|
260
|
-
id,
|
|
261
|
-
translationSchema: METADATA_SCHEMA_NAME
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
return {
|
|
265
|
-
data,
|
|
266
|
-
loading,
|
|
267
|
-
error
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
function LanguageManage(props) {
|
|
271
|
-
const {
|
|
272
|
-
id
|
|
273
|
-
} = props;
|
|
274
|
-
const open = useOpenInNewPane(id, METADATA_SCHEMA_NAME);
|
|
275
|
-
return /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
276
|
-
disabled: !id,
|
|
277
|
-
mode: "ghost",
|
|
278
|
-
text: "Manage Translations",
|
|
279
|
-
icon: icons.CogIcon,
|
|
280
|
-
onClick: () => open()
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
414
|
function LanguagePatch(props) {
|
|
284
415
|
const {
|
|
285
416
|
apiVersion = API_VERSION,
|
|
@@ -321,12 +452,25 @@ function LanguagePatch(props) {
|
|
|
321
452
|
});
|
|
322
453
|
}, [source, documentId, client, languageField, language, schemaType, toast]);
|
|
323
454
|
return /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
324
|
-
mode: "
|
|
325
|
-
|
|
326
|
-
icon: icons.ChevronRightIcon,
|
|
327
|
-
onClick: () => handleClick(),
|
|
455
|
+
mode: "bleed",
|
|
456
|
+
onClick: handleClick,
|
|
328
457
|
disabled,
|
|
329
|
-
justify: "flex-start"
|
|
458
|
+
justify: "flex-start",
|
|
459
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
460
|
+
gap: 3,
|
|
461
|
+
align: "center",
|
|
462
|
+
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
463
|
+
size: 2,
|
|
464
|
+
children: /* @__PURE__ */jsxRuntime.jsx(icons.EditIcon, {})
|
|
465
|
+
}), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
466
|
+
flex: 1,
|
|
467
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
468
|
+
children: language.title
|
|
469
|
+
})
|
|
470
|
+
}), /* @__PURE__ */jsxRuntime.jsx(ui.Badge, {
|
|
471
|
+
children: language.id
|
|
472
|
+
})]
|
|
473
|
+
})
|
|
330
474
|
});
|
|
331
475
|
}
|
|
332
476
|
function MenuButton(props) {
|
|
@@ -383,7 +527,34 @@ function MenuButton(props) {
|
|
|
383
527
|
padding: 1,
|
|
384
528
|
space: 1,
|
|
385
529
|
children: [supportedLanguages.length > 0 ? /* @__PURE__ */jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
386
|
-
children: [
|
|
530
|
+
children: [loading ? null : /* @__PURE__ */jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
531
|
+
children: [allLanguagesAreValid ? null : /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
532
|
+
tone: "caution",
|
|
533
|
+
padding: 3,
|
|
534
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
535
|
+
size: 1,
|
|
536
|
+
children: "Not all language objects are valid. See the console."
|
|
537
|
+
})
|
|
538
|
+
}), sourceLanguageId ? null : /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
539
|
+
tone: "caution",
|
|
540
|
+
padding: 3,
|
|
541
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
|
|
542
|
+
size: 1,
|
|
543
|
+
children: ["Choose a language to ", /* @__PURE__ */jsxRuntime.jsx("br", {}), "apply to ", /* @__PURE__ */jsxRuntime.jsx("strong", {
|
|
544
|
+
children: "this Document"
|
|
545
|
+
})]
|
|
546
|
+
})
|
|
547
|
+
}), sourceLanguageId && !sourceLanguageIsValid ? /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
548
|
+
tone: "caution",
|
|
549
|
+
padding: 3,
|
|
550
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
|
|
551
|
+
size: 1,
|
|
552
|
+
children: ["Select a supported language.", /* @__PURE__ */jsxRuntime.jsx("br", {}), "Current language value: ", /* @__PURE__ */jsxRuntime.jsx("code", {
|
|
553
|
+
children: sourceLanguageId
|
|
554
|
+
})]
|
|
555
|
+
})
|
|
556
|
+
}) : null]
|
|
557
|
+
}), supportedLanguages.map((language, langIndex) => {
|
|
387
558
|
var _a;
|
|
388
559
|
return !loading && sourceLanguageId && sourceLanguageIsValid ?
|
|
389
560
|
// Button to duplicate this document to a new translation
|
|
@@ -415,39 +586,13 @@ function MenuButton(props) {
|
|
|
415
586
|
return ((_a2 = t == null ? void 0 : t.value) == null ? void 0 : _a2._ref) !== documentId;
|
|
416
587
|
}).some(t => t._key === language.id))) != null ? _a : false
|
|
417
588
|
}, language.id || language.title || "lang-".concat(langIndex));
|
|
418
|
-
}), loading ? null : /* @__PURE__ */jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
419
|
-
children: [allLanguagesAreValid ? null : /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
420
|
-
tone: "caution",
|
|
421
|
-
padding: 3,
|
|
422
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
423
|
-
size: 1,
|
|
424
|
-
children: "Not all language objects are valid. See the console."
|
|
425
|
-
})
|
|
426
|
-
}), sourceLanguageId ? null : /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
427
|
-
tone: "caution",
|
|
428
|
-
padding: 3,
|
|
429
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
|
|
430
|
-
size: 1,
|
|
431
|
-
children: ["Choose a language to ", /* @__PURE__ */jsxRuntime.jsx("br", {}), "apply to ", /* @__PURE__ */jsxRuntime.jsx("strong", {
|
|
432
|
-
children: "this Document"
|
|
433
|
-
})]
|
|
434
|
-
})
|
|
435
|
-
}), sourceLanguageId && !sourceLanguageIsValid ? /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
436
|
-
tone: "caution",
|
|
437
|
-
padding: 3,
|
|
438
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
|
|
439
|
-
size: 1,
|
|
440
|
-
children: ["Change the current language value ", /* @__PURE__ */jsxRuntime.jsx("code", {
|
|
441
|
-
children: sourceLanguageId
|
|
442
|
-
}), /* @__PURE__ */jsxRuntime.jsx("br", {}), "to one of the supported languages"]
|
|
443
|
-
})
|
|
444
|
-
}) : null]
|
|
445
589
|
})]
|
|
446
590
|
}) : null, /* @__PURE__ */jsxRuntime.jsx(LanguageManage, {
|
|
447
591
|
id: metadata == null ? void 0 : metadata._id
|
|
448
592
|
})]
|
|
449
593
|
})
|
|
450
594
|
});
|
|
595
|
+
const issueWithTranslations = !loading && sourceLanguageId && !sourceLanguageIsValid;
|
|
451
596
|
return /* @__PURE__ */jsxRuntime.jsx(ui.Popover, {
|
|
452
597
|
constrainSize: true,
|
|
453
598
|
content,
|
|
@@ -459,7 +604,7 @@ function MenuButton(props) {
|
|
|
459
604
|
text: "Translations",
|
|
460
605
|
mode: "bleed",
|
|
461
606
|
disabled: !source,
|
|
462
|
-
tone: !source ||
|
|
607
|
+
tone: !source || loading || !issueWithTranslations ? void 0 : "caution",
|
|
463
608
|
icon: icons.TranslateIcon,
|
|
464
609
|
onClick: handleClick,
|
|
465
610
|
ref: setButton,
|
|
@@ -467,20 +612,102 @@ function MenuButton(props) {
|
|
|
467
612
|
})
|
|
468
613
|
});
|
|
469
614
|
}
|
|
470
|
-
function
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
615
|
+
function ReferencePatcher(props) {
|
|
616
|
+
const {
|
|
617
|
+
translation,
|
|
618
|
+
documentType,
|
|
619
|
+
metadataId
|
|
620
|
+
} = props;
|
|
621
|
+
const editState = sanity.useEditState(translation.value._ref, documentType);
|
|
622
|
+
const client = sanity.useClient({
|
|
623
|
+
apiVersion: API_VERSION
|
|
624
|
+
});
|
|
625
|
+
const {
|
|
626
|
+
onChange
|
|
627
|
+
} = desk.useDocumentPane();
|
|
628
|
+
React__default.default.useEffect(() => {
|
|
629
|
+
if (
|
|
630
|
+
// We have a reference
|
|
631
|
+
translation.value._ref &&
|
|
632
|
+
// It's still weak and not-yet-strengthened
|
|
633
|
+
translation.value._weak && translation.value._strengthenOnPublish &&
|
|
634
|
+
// The referenced document has just been published
|
|
635
|
+
!editState.draft && editState.published && editState.ready) {
|
|
636
|
+
const referencePathBase = ["translations", {
|
|
637
|
+
_key: translation._key
|
|
638
|
+
}, "value"];
|
|
639
|
+
onChange(new sanity.PatchEvent([sanity.unset([...referencePathBase, "_weak"]), sanity.unset([...referencePathBase, "_strengthenOnPublish"])]));
|
|
640
|
+
}
|
|
641
|
+
}, [translation, editState, metadataId, client, onChange]);
|
|
642
|
+
return null;
|
|
643
|
+
}
|
|
644
|
+
function OptimisticallyStrengthen(props) {
|
|
645
|
+
const {
|
|
646
|
+
translations = [],
|
|
647
|
+
metadataId
|
|
648
|
+
} = props;
|
|
649
|
+
if (!translations.length) {
|
|
475
650
|
return null;
|
|
476
651
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
652
|
+
return /* @__PURE__ */jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
653
|
+
children: translations.map(translation => {
|
|
654
|
+
var _a;
|
|
655
|
+
return ((_a = translation.value._strengthenOnPublish) == null ? void 0 : _a.type) ? /* @__PURE__ */jsxRuntime.jsx(ReferencePatcher, {
|
|
656
|
+
translation,
|
|
657
|
+
documentType: translation.value._strengthenOnPublish.type,
|
|
658
|
+
metadataId
|
|
659
|
+
}, translation._key) : null;
|
|
660
|
+
})
|
|
661
|
+
});
|
|
483
662
|
}
|
|
663
|
+
var metadata = schemaTypes => sanity.defineType({
|
|
664
|
+
type: "document",
|
|
665
|
+
name: METADATA_SCHEMA_NAME,
|
|
666
|
+
title: "Translation metadata",
|
|
667
|
+
icon: icons.TranslateIcon,
|
|
668
|
+
liveEdit: true,
|
|
669
|
+
fields: [sanity.defineField({
|
|
670
|
+
name: "translations",
|
|
671
|
+
type: "internationalizedArrayReference"
|
|
672
|
+
}), sanity.defineField({
|
|
673
|
+
name: "schemaTypes",
|
|
674
|
+
description: "Optional: Used to filter the reference fields above so all translations share the same types.",
|
|
675
|
+
type: "array",
|
|
676
|
+
// For some reason TS dislikes this line because of the DocumentDefinition return type
|
|
677
|
+
// @ts-expect-error
|
|
678
|
+
of: [{
|
|
679
|
+
type: "string"
|
|
680
|
+
}],
|
|
681
|
+
options: {
|
|
682
|
+
list: schemaTypes
|
|
683
|
+
},
|
|
684
|
+
readOnly: _ref => {
|
|
685
|
+
let {
|
|
686
|
+
value
|
|
687
|
+
} = _ref;
|
|
688
|
+
return Boolean(value);
|
|
689
|
+
}
|
|
690
|
+
})],
|
|
691
|
+
preview: {
|
|
692
|
+
select: {
|
|
693
|
+
translations: "translations",
|
|
694
|
+
documentSchemaTypes: "schemaTypes"
|
|
695
|
+
},
|
|
696
|
+
prepare(selection) {
|
|
697
|
+
const {
|
|
698
|
+
translations,
|
|
699
|
+
documentSchemaTypes
|
|
700
|
+
} = selection;
|
|
701
|
+
const title = translations.length === 1 ? "1 Translation" : "".concat(translations.length, " Translations");
|
|
702
|
+
const languageKeys = translations.length ? translations.map(t => t._key.toUpperCase()).join(", ") : "";
|
|
703
|
+
const subtitle = [languageKeys ? "(".concat(languageKeys, ")") : null, (documentSchemaTypes == null ? void 0 : documentSchemaTypes.length) ? documentSchemaTypes.map(s => s.toUpperCase()).join(", ") : "No Schemas Defined"].filter(Boolean).join(" ");
|
|
704
|
+
return {
|
|
705
|
+
title,
|
|
706
|
+
subtitle
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
});
|
|
484
711
|
const DEFAULT_CONFIG = {
|
|
485
712
|
supportedLanguages: [],
|
|
486
713
|
schemaTypes: [],
|
|
@@ -513,10 +740,22 @@ const documentInternationalization = sanity.definePlugin(config => {
|
|
|
513
740
|
form: {
|
|
514
741
|
components: {
|
|
515
742
|
input: props => {
|
|
516
|
-
|
|
517
|
-
|
|
743
|
+
var _a, _b, _c;
|
|
744
|
+
if (props.id === "root" && props.schemaType.name === METADATA_SCHEMA_NAME && sanity.isSanityDocument(props == null ? void 0 : props.value)) {
|
|
745
|
+
const metadataId = (_a = props == null ? void 0 : props.value) == null ? void 0 : _a._id;
|
|
746
|
+
const translations = (_c = (_b = props == null ? void 0 : props.value) == null ? void 0 : _b.translations) != null ? _c : [];
|
|
747
|
+
const weakAndTypedTranslations = translations.filter(t => {
|
|
748
|
+
var _a2, _b2;
|
|
749
|
+
return ((_a2 = t == null ? void 0 : t.value) == null ? void 0 : _a2._weak) && ((_b2 = t.value) == null ? void 0 : _b2._strengthenOnPublish);
|
|
750
|
+
});
|
|
751
|
+
return /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
|
|
518
752
|
space: 5,
|
|
519
|
-
children:
|
|
753
|
+
children: [bulkPublish ? /* @__PURE__ */jsxRuntime.jsx(BulkPublish, {
|
|
754
|
+
translations
|
|
755
|
+
}) : null, weakAndTypedTranslations.length > 0 ? /* @__PURE__ */jsxRuntime.jsx(OptimisticallyStrengthen, {
|
|
756
|
+
metadataId,
|
|
757
|
+
translations: weakAndTypedTranslations
|
|
758
|
+
}) : null, props.renderDefault(props)]
|
|
520
759
|
});
|
|
521
760
|
}
|
|
522
761
|
return props.renderDefault(props);
|
|
@@ -602,22 +841,34 @@ const documentInternationalization = sanity.definePlugin(config => {
|
|
|
602
841
|
// It cuts down on attribute usage and gives UI conveniences to add new translations
|
|
603
842
|
sanityPluginInternationalizedArray.internationalizedArray({
|
|
604
843
|
languages: supportedLanguages,
|
|
605
|
-
fieldTypes: [
|
|
606
|
-
// TODO: The plugin should allow this kind of input
|
|
607
|
-
// @ts-ignore
|
|
608
|
-
sanity.defineField({
|
|
844
|
+
fieldTypes: [sanity.defineField({
|
|
609
845
|
name: "reference",
|
|
610
846
|
type: "reference",
|
|
611
847
|
to: schemaTypes.map(type => ({
|
|
612
848
|
type
|
|
613
849
|
})),
|
|
614
|
-
// TODO: Add a validation rule to *ensure* the document's language matches the array key
|
|
615
850
|
// Reference filters don't actually enforce validation!
|
|
616
|
-
|
|
851
|
+
validation: Rule => Rule.custom(async (item, context) => {
|
|
852
|
+
var _a;
|
|
853
|
+
if (!((_a = item == null ? void 0 : item.value) == null ? void 0 : _a._ref) || !(item == null ? void 0 : item._key)) {
|
|
854
|
+
return true;
|
|
855
|
+
}
|
|
856
|
+
const client = context.getClient({
|
|
857
|
+
apiVersion: API_VERSION
|
|
858
|
+
});
|
|
859
|
+
const valueLanguage = await client.fetch("*[_id in [$ref, $draftRef]][0].".concat(languageField), {
|
|
860
|
+
ref: item.value._ref,
|
|
861
|
+
draftRef: "drafts.".concat(item.value._ref)
|
|
862
|
+
});
|
|
863
|
+
if (valueLanguage && valueLanguage === item._key) {
|
|
864
|
+
return true;
|
|
865
|
+
}
|
|
866
|
+
return "Referenced document does not have the correct language value";
|
|
867
|
+
}),
|
|
617
868
|
options: {
|
|
618
869
|
collapsed: false,
|
|
619
870
|
// TODO: Update type once it knows the values of this filter
|
|
620
|
-
// @ts-
|
|
871
|
+
// @ts-expect-error
|
|
621
872
|
filter: _ref5 => {
|
|
622
873
|
let {
|
|
623
874
|
parent,
|