sanity-plugin-internationalized-array 0.0.4 → 0.0.5
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 +41 -9
- package/lib/LanguageArray/Table.js +72 -0
- package/lib/LanguageArray/Table.js.map +1 -0
- package/lib/LanguageArray/index.js +35 -47
- package/lib/LanguageArray/index.js.map +1 -1
- package/migrations/transformObjectToArray.js +94 -0
- package/package.json +3 -2
- package/src/LanguageArray/Table.tsx +73 -0
- package/src/LanguageArray/index.tsx +49 -41
package/README.md
CHANGED
|
@@ -25,13 +25,18 @@ export default {
|
|
|
25
25
|
fields: [
|
|
26
26
|
// ...all your other fields
|
|
27
27
|
internationalizedArray({
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
// Required, the `name` of the outer array
|
|
29
|
+
name: "greeting",
|
|
30
|
+
// Required, the `type` of the inner field
|
|
31
|
+
// One of: string | text | number | boolean
|
|
32
|
+
type: "string",
|
|
33
|
+
// Required, must be an array of objects
|
|
30
34
|
languages: [
|
|
31
35
|
{ id: "en", title: "English" },
|
|
32
36
|
{ id: "fr", title: "French" },
|
|
33
|
-
],
|
|
34
|
-
|
|
37
|
+
],
|
|
38
|
+
// Optional: just for debugging
|
|
39
|
+
showNativeInput: false,
|
|
35
40
|
}),
|
|
36
41
|
],
|
|
37
42
|
};
|
|
@@ -54,24 +59,51 @@ Using GROQ filters you can query for a specific language key like so:
|
|
|
54
59
|
}
|
|
55
60
|
```
|
|
56
61
|
|
|
62
|
+
## Migrate from objects to arrays
|
|
63
|
+
|
|
64
|
+
[See the migration script](https://github.com/SimeonGriggs/sanity-plugin-internationalized-array/blob/main/migrations/transformObjectToArray.js) inside `./migrations/transformObjectToArray.js` of this Repo.
|
|
65
|
+
|
|
66
|
+
Follow the instructions inside the script and set the `_type` and field name you wish to target.
|
|
67
|
+
|
|
68
|
+
Please take a backup first!
|
|
69
|
+
|
|
57
70
|
### Why store localised field data like this?
|
|
58
71
|
|
|
59
72
|
The most popular way to store field-level translated content is in an object using the method prescribed in [@sanity/language-filter](https://www.npmjs.com/package/@sanity/language-filter). This works well and creates tidy object structures, but also create a unique field path for every unique field name, multiplied by the number of languages in your dataset.
|
|
60
73
|
|
|
61
|
-
For most people, this won't become an issue. On a very large dataset with a lot of languages, the [Attribute Limit](https://www.sanity.io/docs/attribute-limit) can become a concern.
|
|
74
|
+
For most people, this won't become an issue. On a very large dataset with a lot of languages, the [Attribute Limit](https://www.sanity.io/docs/attribute-limit) can become a concern. This plugin's arrays will use less attributes than an object once you have more than three languages.
|
|
62
75
|
|
|
63
|
-
|
|
76
|
+
The same content as above, plus a third language, structed as an `object` of `string` fields looks like this:
|
|
64
77
|
|
|
65
78
|
```json
|
|
66
79
|
"greeting" {
|
|
67
80
|
"en": "hello",
|
|
68
|
-
"fr": "bonjour"
|
|
81
|
+
"fr": "bonjour",
|
|
82
|
+
"es": "hola"
|
|
69
83
|
}
|
|
70
84
|
```
|
|
71
85
|
|
|
72
|
-
|
|
86
|
+
Which creates four unique query paths, one for the object and one for each language.
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
greeting
|
|
90
|
+
greeting.en
|
|
91
|
+
greeting.fr
|
|
92
|
+
greeting.es
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Every language you add to every object that uses this structure will add to the number of unique query paths.
|
|
96
|
+
|
|
97
|
+
The array created by this plugin creates four query paths by default, but is not effected by the number of languages:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
greeting
|
|
101
|
+
greeting[]
|
|
102
|
+
greeting[]._key
|
|
103
|
+
greeting[].value
|
|
104
|
+
```
|
|
73
105
|
|
|
74
|
-
|
|
106
|
+
By using this plugin you can safely extend the number of languages without adding any additional query paths.
|
|
75
107
|
|
|
76
108
|
## License
|
|
77
109
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Row = exports.Cell = void 0;
|
|
7
|
+
exports.Table = Table;
|
|
8
|
+
exports.TableCell = TableCell;
|
|
9
|
+
exports.TableRow = TableRow;
|
|
10
|
+
exports.TableWrapper = void 0;
|
|
11
|
+
|
|
12
|
+
var _react = _interopRequireDefault(require("react"));
|
|
13
|
+
|
|
14
|
+
var _styledComponents = _interopRequireWildcard(require("styled-components"));
|
|
15
|
+
|
|
16
|
+
var _ui = require("@sanity/ui");
|
|
17
|
+
|
|
18
|
+
var _excluded = ["children"],
|
|
19
|
+
_excluded2 = ["children"];
|
|
20
|
+
|
|
21
|
+
var _templateObject, _templateObject2, _templateObject3;
|
|
22
|
+
|
|
23
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
24
|
+
|
|
25
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
26
|
+
|
|
27
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
28
|
+
|
|
29
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
30
|
+
|
|
31
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
32
|
+
|
|
33
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
34
|
+
|
|
35
|
+
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
|
36
|
+
|
|
37
|
+
var TableWrapper = (0, _styledComponents.default)(_ui.Box)(() => (0, _styledComponents.css)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: table;\n "]))));
|
|
38
|
+
exports.TableWrapper = TableWrapper;
|
|
39
|
+
|
|
40
|
+
function Table(props) {
|
|
41
|
+
var children = props.children,
|
|
42
|
+
rest = _objectWithoutProperties(props, _excluded);
|
|
43
|
+
|
|
44
|
+
return /*#__PURE__*/_react.default.createElement(TableWrapper, _extends({
|
|
45
|
+
as: "table"
|
|
46
|
+
}, rest), children);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
var Row = (0, _styledComponents.default)(_ui.Card)(() => (0, _styledComponents.css)(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n display: table-row;\n\n &:not([hidden]) {\n display: table-row;\n }\n "]))));
|
|
50
|
+
exports.Row = Row;
|
|
51
|
+
|
|
52
|
+
function TableRow(props) {
|
|
53
|
+
var children = props.children,
|
|
54
|
+
rest = _objectWithoutProperties(props, _excluded2);
|
|
55
|
+
|
|
56
|
+
return /*#__PURE__*/_react.default.createElement(Row, _extends({
|
|
57
|
+
as: "tr"
|
|
58
|
+
}, rest), children);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var Cell = (0, _styledComponents.default)(_ui.Box)(() => (0, _styledComponents.css)(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n display: table-cell;\n "]))));
|
|
62
|
+
exports.Cell = Cell;
|
|
63
|
+
|
|
64
|
+
function TableCell(props) {
|
|
65
|
+
var children = props.children,
|
|
66
|
+
style = props.style;
|
|
67
|
+
return /*#__PURE__*/_react.default.createElement(Cell, {
|
|
68
|
+
as: "td",
|
|
69
|
+
style: style
|
|
70
|
+
}, children);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=Table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Table.js","names":["TableWrapper","styled","Box","css","Table","props","children","rest","Row","Card","TableRow","Cell","TableCell","style"],"sources":["../../src/LanguageArray/Table.tsx"],"sourcesContent":["import React from 'react'\nimport styled, {css} from 'styled-components'\nimport {Box, Card} from '@sanity/ui'\n\nexport const TableWrapper = styled(Box)(\n () =>\n css`\n display: table;\n `\n)\n\ntype TableProps = {\n children: React.ReactNode\n [key: string]: unknown\n}\n\nexport function Table(props: TableProps) {\n const {children, ...rest} = props\n\n return (\n <TableWrapper as=\"table\" {...rest}>\n {children}\n </TableWrapper>\n )\n}\n\nexport const Row = styled(Card)(\n () =>\n css`\n display: table-row;\n\n &:not([hidden]) {\n display: table-row;\n }\n `\n)\n\ntype TableRowProps = {\n children: React.ReactNode\n [key: string]: unknown\n}\n\nexport function TableRow(props: TableRowProps) {\n const {children, ...rest} = props\n\n return (\n <Row as=\"tr\" {...rest}>\n {children}\n </Row>\n )\n}\n\nexport const Cell = styled(Box)(\n () =>\n css`\n display: table-cell;\n `\n)\n\ntype TableCellProps = {\n children: React.ReactNode\n style?: React.CSSProperties\n}\n\nexport function TableCell(props: TableCellProps) {\n const {children, style} = props\n\n return (\n <Cell as=\"td\" style={style}>\n {children}\n </Cell>\n )\n}\n"],"mappings":";;;;;;;;;;;AAAA;;AACA;;AACA;;;;;;;;;;;;;;;;;;;;;AAEO,IAAMA,YAAY,GAAG,IAAAC,yBAAA,EAAOC,OAAP,EAC1B,UACEC,qBADF,mGAD0B,CAArB;;;AAYA,SAASC,KAAT,CAAeC,KAAf,EAAkC;EACvC,IAAOC,QAAP,GAA4BD,KAA5B,CAAOC,QAAP;EAAA,IAAoBC,IAApB,4BAA4BF,KAA5B;;EAEA,oBACE,6BAAC,YAAD;IAAc,EAAE,EAAC;EAAjB,GAA6BE,IAA7B,GACGD,QADH,CADF;AAKD;;AAEM,IAAME,GAAG,GAAG,IAAAP,yBAAA,EAAOQ,QAAP,EACjB,UACEN,qBADF,0KADiB,CAAZ;;;AAgBA,SAASO,QAAT,CAAkBL,KAAlB,EAAwC;EAC7C,IAAOC,QAAP,GAA4BD,KAA5B,CAAOC,QAAP;EAAA,IAAoBC,IAApB,4BAA4BF,KAA5B;;EAEA,oBACE,6BAAC,GAAD;IAAK,EAAE,EAAC;EAAR,GAAiBE,IAAjB,GACGD,QADH,CADF;AAKD;;AAEM,IAAMK,IAAI,GAAG,IAAAV,yBAAA,EAAOC,OAAP,EAClB,UACEC,qBADF,0GADkB,CAAb;;;AAYA,SAASS,SAAT,CAAmBP,KAAnB,EAA0C;EAC/C,IAAOC,QAAP,GAA0BD,KAA1B,CAAOC,QAAP;EAAA,IAAiBO,KAAjB,GAA0BR,KAA1B,CAAiBQ,KAAjB;EAEA,oBACE,6BAAC,IAAD;IAAM,EAAE,EAAC,IAAT;IAAc,KAAK,EAAEA;EAArB,GACGP,QADH,CADF;AAKD"}
|
|
@@ -25,6 +25,8 @@ var _ValueInput = _interopRequireDefault(require("./ValueInput"));
|
|
|
25
25
|
|
|
26
26
|
var _useUnsetInputComponent = require("./useUnsetInputComponent");
|
|
27
27
|
|
|
28
|
+
var _Table = require("./Table");
|
|
29
|
+
|
|
28
30
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
29
31
|
|
|
30
32
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -151,76 +153,62 @@ var LanguageArrayWrapper = /*#__PURE__*/(0, _react.forwardRef)(function CustomCo
|
|
|
151
153
|
|
|
152
154
|
var validationMarkers = markers !== null && markers !== void 0 && markers.length ? markers.filter(mark => mark.type === "validation") : [];
|
|
153
155
|
var invalidKeys = validationMarkers.map(mark => mark.path).flat().map(item => item._key);
|
|
154
|
-
console.log(props);
|
|
155
156
|
return /*#__PURE__*/_react.default.createElement(_ui.Stack, {
|
|
156
157
|
space: 3
|
|
157
158
|
}, /*#__PURE__*/_react.default.createElement(_ui.Box, null, /*#__PURE__*/_react.default.createElement(_ui.Text, {
|
|
158
159
|
size: 1,
|
|
159
160
|
weight: "bold"
|
|
160
|
-
}, (_type$title = type === null || type === void 0 ? void 0 : type.title) !== null && _type$title !== void 0 ? _type$title : type.name)), (value === null || value === void 0 ? void 0 : value.length) > 0 ? /*#__PURE__*/_react.default.createElement(_ui.Card, {
|
|
161
|
-
padding: 1,
|
|
162
|
-
border: true,
|
|
163
|
-
radius: 1
|
|
164
|
-
}, /*#__PURE__*/_react.default.createElement(_ui.Stack, {
|
|
165
|
-
space: 1
|
|
166
|
-
}, value.map(item => {
|
|
161
|
+
}, (_type$title = type === null || type === void 0 ? void 0 : type.title) !== null && _type$title !== void 0 ? _type$title : type.name)), (value === null || value === void 0 ? void 0 : value.length) > 0 ? /*#__PURE__*/_react.default.createElement(_ui.Card, null, /*#__PURE__*/_react.default.createElement(_Table.Table, null, /*#__PURE__*/_react.default.createElement("tbody", null, value.map(item => {
|
|
167
162
|
var _type$of;
|
|
168
163
|
|
|
169
|
-
return /*#__PURE__*/_react.default.createElement(
|
|
164
|
+
return /*#__PURE__*/_react.default.createElement(_Table.TableRow, {
|
|
170
165
|
paddingY: 1,
|
|
171
166
|
paddingX: 2,
|
|
172
167
|
key: item._key,
|
|
173
168
|
tone: // TODO: Move this logic somewhere else
|
|
174
169
|
invalidKeys.includes(item._key) ? "critical" : undefined || languagesOutOfOrder.find(l => l._key === item._key) ? "caution" : undefined
|
|
175
|
-
}, /*#__PURE__*/_react.default.createElement(_ui.Flex, {
|
|
176
|
-
gap: 3,
|
|
177
|
-
align: "center"
|
|
178
170
|
}, (type === null || type === void 0 ? void 0 : (_type$of = type.of) === null || _type$of === void 0 ? void 0 : _type$of.length) > 0 && (type === null || type === void 0 ? void 0 : type.of.map(subType => {
|
|
179
171
|
var _subType$fields;
|
|
180
172
|
|
|
181
|
-
return /*#__PURE__*/_react.default.createElement(_ui.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
},
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
compareValue: props === null || props === void 0 ? void 0 : (_props$compareValue = props.compareValue) === null || _props$compareValue === void 0 ? void 0 : (_props$compareValue$f = _props$compareValue.find(c => c._key === item._key)) === null || _props$compareValue$f === void 0 ? void 0 : _props$compareValue$f.value
|
|
210
|
-
});
|
|
211
|
-
}))) : null);
|
|
212
|
-
})), (presence === null || presence === void 0 ? void 0 : presence.length) > 0 ? /*#__PURE__*/_react.default.createElement(_presence.FieldPresence, {
|
|
173
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, (subType === null || subType === void 0 ? void 0 : (_subType$fields = subType.fields) === null || _subType$fields === void 0 ? void 0 : _subType$fields.length) > 0 ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Table.TableCell, null, /*#__PURE__*/_react.default.createElement(_ui.Box, {
|
|
174
|
+
paddingRight: 2
|
|
175
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Label, {
|
|
176
|
+
muted: true,
|
|
177
|
+
size: 1
|
|
178
|
+
}, item._key))), /*#__PURE__*/_react.default.createElement(_Table.TableCell, {
|
|
179
|
+
style: {
|
|
180
|
+
width: "100%"
|
|
181
|
+
}
|
|
182
|
+
}, subType.fields.map((subTypeField, subTypeFieldIndex) => /*#__PURE__*/_react.default.createElement(_ValueInput.default, {
|
|
183
|
+
key: subTypeField.name,
|
|
184
|
+
onChange: patchEvent => handleInnerValueChange(patchEvent, item._key),
|
|
185
|
+
onBlur: onBlur // We don't want the array item to open onFocus
|
|
186
|
+
,
|
|
187
|
+
onFocus: () => null,
|
|
188
|
+
path: [{
|
|
189
|
+
_key: item._key
|
|
190
|
+
}, subTypeField.name] // focusPath={[{_key: item._key}, subTypeField.name]}
|
|
191
|
+
,
|
|
192
|
+
parent: item,
|
|
193
|
+
readOnly: readOnly,
|
|
194
|
+
type: subTypeField,
|
|
195
|
+
value: item.value,
|
|
196
|
+
level: props.level + 1,
|
|
197
|
+
markers: [],
|
|
198
|
+
compareValue: props.compareValue
|
|
199
|
+
})))) : null);
|
|
200
|
+
})), (presence === null || presence === void 0 ? void 0 : presence.length) > 0 ? /*#__PURE__*/_react.default.createElement(_Table.TableCell, null, /*#__PURE__*/_react.default.createElement(_presence.FieldPresence, {
|
|
213
201
|
maxAvatars: 1,
|
|
214
202
|
presence: presence
|
|
215
|
-
}) : null, invalidKeys.includes(item._key) ? /*#__PURE__*/_react.default.createElement(_components.FormFieldValidationStatus, {
|
|
203
|
+
})) : null, invalidKeys.includes(item._key) ? /*#__PURE__*/_react.default.createElement(_Table.TableCell, null, /*#__PURE__*/_react.default.createElement(_components.FormFieldValidationStatus, {
|
|
216
204
|
__unstable_markers: validationMarkers
|
|
217
|
-
}) : null, /*#__PURE__*/_react.default.createElement(_ui.Button, {
|
|
205
|
+
})) : null, /*#__PURE__*/_react.default.createElement(_Table.TableCell, null, /*#__PURE__*/_react.default.createElement(_ui.Button, {
|
|
218
206
|
mode: "ghost",
|
|
219
207
|
icon: _icons.RemoveIcon,
|
|
220
208
|
tone: "critical",
|
|
221
209
|
onClick: () => handleUnsetByKey(item._key)
|
|
222
210
|
})));
|
|
223
|
-
}))) : null, languagesOutOfOrder.length > 0 ? /*#__PURE__*/_react.default.createElement(_ui.Button, {
|
|
211
|
+
})))) : null, languagesOutOfOrder.length > 0 ? /*#__PURE__*/_react.default.createElement(_ui.Button, {
|
|
224
212
|
tone: "caution",
|
|
225
213
|
disabled: languagesOutOfOrder.length > languages.length,
|
|
226
214
|
icon: _icons.RestoreIcon,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["schemaExample","name","type","options","languages","id","title","DEFAULT_OPTIONS","showNativeInput","LanguageArrayWrapper","forwardRef","CustomComponent","props","ref","onChange","onBlur","readOnly","presence","markers","value","useUnsetInputComponent","handleAddLanguage","useCallback","languageId","newItems","_key","filter","language","length","find","v","map","languagesInUse","insertions","item","languageIndex","findIndex","l","remainingLanguages","slice","nextLanguageIndex","r","push","splice","insert","PatchEvent","from","setIfMissing","handleUnsetByKey","unset","handleInnerValueChange","patchEvent","inputValue","patches","inputPath","set","handleRestoreOrder","updatedValue","reduce","acc","newIndex","languagesOutOfOrder","useMemo","vIndex","Boolean","languagesAreValid","every","JSON","stringify","validationMarkers","mark","invalidKeys","path","flat","console","log","includes","undefined","of","subType","fields","subTypeField","subTypeFieldIndex","level","compareValue","c","RemoveIcon","RestoreIcon","Math","min","toUpperCase","AddIcon","withDocument"],"sources":["../../src/LanguageArray/index.tsx"],"sourcesContent":["import React, {forwardRef, useCallback, useMemo} from 'react'\nimport {Code, Text, Card, Label, Flex, Box, Stack, Button, Grid} from '@sanity/ui'\nimport {withDocument} from 'part:@sanity/form-builder'\nimport {PatchEvent, setIfMissing, insert, unset, set} from '@sanity/form-builder/PatchEvent'\nimport {AddIcon, RemoveIcon, RestoreIcon} from '@sanity/icons'\nimport {FormFieldValidationStatus} from '@sanity/base/components'\nimport {FieldPresence} from '@sanity/base/presence'\nimport {FormBuilderInput} from '@sanity/form-builder/lib/FormBuilderInput'\n\nimport ValueInput from './ValueInput'\nimport {useUnsetInputComponent} from './useUnsetInputComponent'\n\nconst schemaExample = {\n name: 'title',\n type: 'localisedArray',\n options: {\n languages: [\n {id: 'en', title: 'English'},\n {id: 'no', title: 'Norsk'},\n ],\n },\n}\n\ntype Value = {\n _key: string\n value?: string\n}\n\ntype Language = {\n id: string\n title: string\n}\n\ntype Options = {\n languages: Language[]\n showNativeInput: boolean\n}\n\nconst DEFAULT_OPTIONS = {\n languages: [],\n showNativeInput: false,\n}\n\nconst LanguageArrayWrapper = forwardRef(function CustomComponent(props, ref) {\n const {onChange, onBlur, readOnly, presence, markers} = props\n const value: Value[] = props?.value\n\n // IMPORTANT: leaving out will cause the browser to lock up in an infinite loop\n const type = useUnsetInputComponent(props.type)\n const options: Options = type?.options ?? DEFAULT_OPTIONS\n const {languages, showNativeInput} = options\n\n const handleAddLanguage = useCallback(\n (languageId?: string) => {\n // Create new items\n const newItems = languageId\n ? // Just one for this language\n [{_key: languageId}]\n : // Or one for every missing language\n languages\n .filter((language) =>\n value?.length ? !value.find((v) => v._key === language.id) : true\n )\n .map((language) => ({_key: language.id}))\n\n // Insert new items in the correct order\n const languagesInUse = value?.length ? value.map((v) => v) : []\n\n const insertions = newItems.map((item) => {\n // What's the original index of this language?\n const languageIndex = languages.findIndex((l) => item._key === l.id)\n\n // What languages are there beyond that index?\n const remainingLanguages = languages.slice(languageIndex + 1)\n\n // So what is the index in the current value array of the next language in the language array?\n const nextLanguageIndex = languagesInUse.findIndex((l) =>\n remainingLanguages.find((r) => r.id === l._key)\n )\n\n // Keep local state up to date incase multiple insertions are being made\n if (nextLanguageIndex < 0) {\n languagesInUse.push(item)\n } else {\n languagesInUse.splice(nextLanguageIndex, 0, item)\n }\n\n return nextLanguageIndex < 0\n ? // No next language (-1), add to end of array\n insert([item], 'after', [nextLanguageIndex])\n : // Next language found, insert before that\n insert([item], 'before', [nextLanguageIndex])\n })\n\n onChange(PatchEvent.from(setIfMissing([]), ...insertions))\n },\n [languages, onChange, value]\n )\n\n const handleUnsetByKey = useCallback(\n (_key) => {\n onChange(PatchEvent.from(unset([{_key}])))\n },\n [onChange]\n )\n\n const handleInnerValueChange = useCallback(\n (patchEvent: PatchEvent, _key: string) => {\n const inputValue = patchEvent.patches[0]?.value\n const inputPath = [{_key}, `value`]\n\n onChange(PatchEvent.from(inputValue ? set(inputValue, inputPath) : unset(inputPath)))\n },\n [onChange]\n )\n\n // TODO: This is lazy, reordering and re-setting the whole array – it should be surgical\n const handleRestoreOrder = useCallback(() => {\n // Create a new value array in the correct order\n const updatedValue = value.reduce((acc, v) => {\n const newIndex = languages.findIndex((l) => l.id === v._key)\n\n acc[newIndex] = v\n\n return acc\n }, [])\n\n onChange(PatchEvent.from(unset(), set(updatedValue)))\n }, [languages, onChange, value])\n\n // Check languages are in the correct order\n const languagesOutOfOrder = useMemo(() => {\n if (!value?.length) {\n return []\n }\n\n const languagesInUse = languages.filter((l) => value.find((v) => v._key === l.id))\n\n return value\n .map((v, vIndex) => (vIndex === languagesInUse.findIndex((l) => l.id === v._key) ? null : v))\n .filter(Boolean)\n }, [value, languages])\n\n // Check options are supplied and valid\n const languagesAreValid = useMemo(\n () => languages?.length && languages.every((item) => item.id && item.title),\n [languages]\n )\n\n if (!languagesAreValid) {\n return (\n <Card tone=\"caution\" border radius={2} padding={3}>\n <Stack space={4}>\n <Text>\n An array of language objects must be passed into the <code>{type.name}</code> field as\n options, each with an <code>id</code> and <code>title</code> field. Example:\n </Text>\n <Card padding={2} border radius={2}>\n <Code size={1} language=\"javascript\">\n {JSON.stringify(schemaExample, null, 2)}\n </Code>\n </Card>\n </Stack>\n </Card>\n )\n }\n\n const validationMarkers = markers?.length\n ? markers.filter((mark) => mark.type === `validation`)\n : []\n const invalidKeys = validationMarkers\n .map((mark) => mark.path)\n .flat()\n .map((item) => item._key)\n console.log(props)\n\n return (\n <Stack space={3}>\n <Box>\n <Text size={1} weight=\"bold\">\n {type?.title ?? type.name}\n </Text>\n </Box>\n {/* Loop over the values */}\n {value?.length > 0 ? (\n <Card padding={1} border radius={1}>\n <Stack space={1}>\n {value.map((item) => (\n <Card\n paddingY={1}\n paddingX={2}\n key={item._key}\n tone={\n // TODO: Move this logic somewhere else\n invalidKeys.includes(item._key)\n ? `critical`\n : undefined || languagesOutOfOrder.find((l) => l._key === item._key)\n ? `caution`\n : undefined\n }\n >\n <Flex gap={3} align=\"center\">\n {/* To render each individual field in this type */}\n {type?.of?.length > 0 &&\n type?.of.map((subType) => (\n <Flex key={subType.name} flex={1} align=\"center\" gap={2}>\n {subType?.fields?.length > 0 ? (\n <>\n <Box>\n <Label>{item._key}</Label>\n </Box>\n <Box flex={1}>\n {/* There _should_ only be one field */}\n {subType.fields.map((subTypeField, subTypeFieldIndex) => (\n <ValueInput\n key={subTypeField.name}\n onChange={(patchEvent) =>\n handleInnerValueChange(patchEvent, item._key)\n }\n onBlur={onBlur}\n // We don't want the array item to open onFocus\n onFocus={() => null}\n path={[{_key: item._key}, subTypeField.name]}\n focusPath={[{_key: item._key}, subTypeField.name]}\n parent={item}\n readOnly={readOnly}\n type={subTypeField}\n value={item.value}\n level={props.level + 1}\n markers={[]}\n compareValue={\n props?.compareValue?.find((c) => c._key === item._key)?.value\n }\n />\n ))}\n </Box>\n </>\n ) : null}\n </Flex>\n ))}\n {presence?.length > 0 ? (\n <FieldPresence maxAvatars={1} presence={presence} />\n ) : null}\n {invalidKeys.includes(item._key) ? (\n <FormFieldValidationStatus __unstable_markers={validationMarkers} />\n ) : null}\n <Button\n mode=\"ghost\"\n icon={RemoveIcon}\n tone=\"critical\"\n onClick={() => handleUnsetByKey(item._key)}\n />\n </Flex>\n </Card>\n ))}\n </Stack>\n </Card>\n ) : null}\n\n {languagesOutOfOrder.length > 0 ? (\n <Button\n tone=\"caution\"\n disabled={languagesOutOfOrder.length > languages.length}\n icon={RestoreIcon}\n onClick={() => handleRestoreOrder()}\n text=\"Restore order of languages\"\n />\n ) : null}\n\n {languages.length > 0 ? (\n <Stack space={2}>\n {/* No more than 5 columns */}\n <Grid columns={Math.min(languages.length, 5)} gap={2}>\n {languages.map((language) => (\n <Button\n key={language.id}\n tone=\"primary\"\n mode=\"ghost\"\n fontSize={1}\n disabled={readOnly || value?.find((item) => item._key === language.id)}\n text={language.id.toUpperCase()}\n icon={AddIcon}\n onClick={() => handleAddLanguage(language.id)}\n />\n ))}\n </Grid>\n <Button\n tone=\"primary\"\n mode=\"ghost\"\n disabled={readOnly || value?.length >= languages?.length}\n icon={AddIcon}\n text={value?.length ? `Add missing languages` : `Add all languages`}\n onClick={() => handleAddLanguage()}\n />\n </Stack>\n ) : null}\n\n {showNativeInput ? <FormBuilderInput {...props} type={type} ref={ref} /> : null}\n </Stack>\n )\n})\n\nexport default withDocument(LanguageArrayWrapper)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["schemaExample","name","type","options","languages","id","title","DEFAULT_OPTIONS","showNativeInput","LanguageArrayWrapper","forwardRef","CustomComponent","props","ref","onChange","onBlur","readOnly","presence","markers","value","useUnsetInputComponent","handleAddLanguage","useCallback","languageId","newItems","_key","filter","language","length","find","v","map","languagesInUse","insertions","item","languageIndex","findIndex","l","remainingLanguages","slice","nextLanguageIndex","r","push","splice","insert","PatchEvent","from","setIfMissing","handleUnsetByKey","unset","handleInnerValueChange","patchEvent","inputValue","patches","inputPath","set","handleRestoreOrder","updatedValue","reduce","acc","newIndex","languagesOutOfOrder","useMemo","vIndex","Boolean","languagesAreValid","every","JSON","stringify","validationMarkers","mark","invalidKeys","path","flat","includes","undefined","of","subType","fields","width","subTypeField","subTypeFieldIndex","level","compareValue","RemoveIcon","RestoreIcon","Math","min","toUpperCase","AddIcon","withDocument"],"sources":["../../src/LanguageArray/index.tsx"],"sourcesContent":["import React, {forwardRef, useCallback, useMemo} from 'react'\nimport {Code, Text, Card, Label, Flex, Box, Stack, Button, Grid} from '@sanity/ui'\nimport {withDocument} from 'part:@sanity/form-builder'\nimport {PatchEvent, setIfMissing, insert, unset, set} from '@sanity/form-builder/PatchEvent'\nimport {AddIcon, RemoveIcon, RestoreIcon} from '@sanity/icons'\nimport {FormFieldValidationStatus} from '@sanity/base/components'\nimport {FieldPresence} from '@sanity/base/presence'\nimport {FormBuilderInput} from '@sanity/form-builder/lib/FormBuilderInput'\n\nimport ValueInput from './ValueInput'\nimport {useUnsetInputComponent} from './useUnsetInputComponent'\nimport {Table, TableCell, TableRow} from './Table'\n\nconst schemaExample = {\n name: 'title',\n type: 'localisedArray',\n options: {\n languages: [\n {id: 'en', title: 'English'},\n {id: 'no', title: 'Norsk'},\n ],\n },\n}\n\ntype Value = {\n _key: string\n value?: string\n}\n\ntype Language = {\n id: string\n title: string\n}\n\ntype Options = {\n languages: Language[]\n showNativeInput: boolean\n}\n\nconst DEFAULT_OPTIONS = {\n languages: [],\n showNativeInput: false,\n}\n\nconst LanguageArrayWrapper = forwardRef(function CustomComponent(props, ref) {\n const {onChange, onBlur, readOnly, presence, markers} = props\n const value: Value[] = props?.value\n\n // IMPORTANT: leaving out will cause the browser to lock up in an infinite loop\n const type = useUnsetInputComponent(props.type)\n const options: Options = type?.options ?? DEFAULT_OPTIONS\n const {languages, showNativeInput} = options\n\n const handleAddLanguage = useCallback(\n (languageId?: string) => {\n // Create new items\n const newItems = languageId\n ? // Just one for this language\n [{_key: languageId}]\n : // Or one for every missing language\n languages\n .filter((language) =>\n value?.length ? !value.find((v) => v._key === language.id) : true\n )\n .map((language) => ({_key: language.id}))\n\n // Insert new items in the correct order\n const languagesInUse = value?.length ? value.map((v) => v) : []\n\n const insertions = newItems.map((item) => {\n // What's the original index of this language?\n const languageIndex = languages.findIndex((l) => item._key === l.id)\n\n // What languages are there beyond that index?\n const remainingLanguages = languages.slice(languageIndex + 1)\n\n // So what is the index in the current value array of the next language in the language array?\n const nextLanguageIndex = languagesInUse.findIndex((l) =>\n remainingLanguages.find((r) => r.id === l._key)\n )\n\n // Keep local state up to date incase multiple insertions are being made\n if (nextLanguageIndex < 0) {\n languagesInUse.push(item)\n } else {\n languagesInUse.splice(nextLanguageIndex, 0, item)\n }\n\n return nextLanguageIndex < 0\n ? // No next language (-1), add to end of array\n insert([item], 'after', [nextLanguageIndex])\n : // Next language found, insert before that\n insert([item], 'before', [nextLanguageIndex])\n })\n\n onChange(PatchEvent.from(setIfMissing([]), ...insertions))\n },\n [languages, onChange, value]\n )\n\n const handleUnsetByKey = useCallback(\n (_key) => {\n onChange(PatchEvent.from(unset([{_key}])))\n },\n [onChange]\n )\n\n const handleInnerValueChange = useCallback(\n (patchEvent: PatchEvent, _key: string) => {\n const inputValue = patchEvent.patches[0]?.value\n const inputPath = [{_key}, `value`]\n\n onChange(PatchEvent.from(inputValue ? set(inputValue, inputPath) : unset(inputPath)))\n },\n [onChange]\n )\n\n // TODO: This is lazy, reordering and re-setting the whole array – it should be surgical\n const handleRestoreOrder = useCallback(() => {\n // Create a new value array in the correct order\n const updatedValue = value.reduce((acc, v) => {\n const newIndex = languages.findIndex((l) => l.id === v._key)\n\n acc[newIndex] = v\n\n return acc\n }, [])\n\n onChange(PatchEvent.from(unset(), set(updatedValue)))\n }, [languages, onChange, value])\n\n // Check languages are in the correct order\n const languagesOutOfOrder = useMemo(() => {\n if (!value?.length) {\n return []\n }\n\n const languagesInUse = languages.filter((l) => value.find((v) => v._key === l.id))\n\n return value\n .map((v, vIndex) => (vIndex === languagesInUse.findIndex((l) => l.id === v._key) ? null : v))\n .filter(Boolean)\n }, [value, languages])\n\n // Check options are supplied and valid\n const languagesAreValid = useMemo(\n () => languages?.length && languages.every((item) => item.id && item.title),\n [languages]\n )\n\n if (!languagesAreValid) {\n return (\n <Card tone=\"caution\" border radius={2} padding={3}>\n <Stack space={4}>\n <Text>\n An array of language objects must be passed into the <code>{type.name}</code> field as\n options, each with an <code>id</code> and <code>title</code> field. Example:\n </Text>\n <Card padding={2} border radius={2}>\n <Code size={1} language=\"javascript\">\n {JSON.stringify(schemaExample, null, 2)}\n </Code>\n </Card>\n </Stack>\n </Card>\n )\n }\n\n const validationMarkers = markers?.length\n ? markers.filter((mark) => mark.type === `validation`)\n : []\n const invalidKeys = validationMarkers\n .map((mark) => mark.path)\n .flat()\n .map((item) => item._key)\n\n return (\n <Stack space={3}>\n <Box>\n <Text size={1} weight=\"bold\">\n {type?.title ?? type.name}\n </Text>\n </Box>\n {/* Loop over the values */}\n {value?.length > 0 ? (\n <Card>\n <Table>\n <tbody>\n {value.map((item) => (\n <TableRow\n paddingY={1}\n paddingX={2}\n key={item._key}\n tone={\n // TODO: Move this logic somewhere else\n invalidKeys.includes(item._key)\n ? `critical`\n : undefined || languagesOutOfOrder.find((l) => l._key === item._key)\n ? `caution`\n : undefined\n }\n >\n {/* To render each individual field in this type */}\n {type?.of?.length > 0 &&\n type?.of.map((subType) => (\n <>\n {subType?.fields?.length > 0 ? (\n <>\n <TableCell>\n <Box paddingRight={2}>\n <Label muted size={1}>\n {item._key}\n </Label>\n </Box>\n </TableCell>\n <TableCell style={{width: `100%`}}>\n {/* There _should_ only be one field */}\n {subType.fields.map((subTypeField, subTypeFieldIndex) => (\n <ValueInput\n key={subTypeField.name}\n onChange={(patchEvent) =>\n handleInnerValueChange(patchEvent, item._key)\n }\n onBlur={onBlur}\n // We don't want the array item to open onFocus\n onFocus={() => null}\n path={[{_key: item._key}, subTypeField.name]}\n // focusPath={[{_key: item._key}, subTypeField.name]}\n parent={item}\n readOnly={readOnly}\n type={subTypeField}\n value={item.value}\n level={props.level + 1}\n markers={[]}\n compareValue={props.compareValue}\n />\n ))}\n </TableCell>\n </>\n ) : null}\n </>\n ))}\n {presence?.length > 0 ? (\n <TableCell>\n <FieldPresence maxAvatars={1} presence={presence} />\n </TableCell>\n ) : null}\n {invalidKeys.includes(item._key) ? (\n <TableCell>\n <FormFieldValidationStatus __unstable_markers={validationMarkers} />\n </TableCell>\n ) : null}\n <TableCell>\n <Button\n mode=\"ghost\"\n icon={RemoveIcon}\n tone=\"critical\"\n onClick={() => handleUnsetByKey(item._key)}\n />\n </TableCell>\n </TableRow>\n ))}\n </tbody>\n </Table>\n </Card>\n ) : null}\n\n {languagesOutOfOrder.length > 0 ? (\n <Button\n tone=\"caution\"\n disabled={languagesOutOfOrder.length > languages.length}\n icon={RestoreIcon}\n onClick={() => handleRestoreOrder()}\n text=\"Restore order of languages\"\n />\n ) : null}\n\n {languages.length > 0 ? (\n <Stack space={2}>\n {/* No more than 5 columns */}\n <Grid columns={Math.min(languages.length, 5)} gap={2}>\n {languages.map((language) => (\n <Button\n key={language.id}\n tone=\"primary\"\n mode=\"ghost\"\n fontSize={1}\n disabled={readOnly || value?.find((item) => item._key === language.id)}\n text={language.id.toUpperCase()}\n icon={AddIcon}\n onClick={() => handleAddLanguage(language.id)}\n />\n ))}\n </Grid>\n <Button\n tone=\"primary\"\n mode=\"ghost\"\n disabled={readOnly || value?.length >= languages?.length}\n icon={AddIcon}\n text={value?.length ? `Add missing languages` : `Add all languages`}\n onClick={() => handleAddLanguage()}\n />\n </Stack>\n ) : null}\n\n {showNativeInput ? <FormBuilderInput {...props} type={type} ref={ref} /> : null}\n </Stack>\n )\n})\n\nexport default withDocument(LanguageArrayWrapper)\n"],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import sanityClient from 'part:@sanity/base/client'
|
|
3
|
+
|
|
4
|
+
const client = sanityClient.withConfig({apiVersion: `2022-07-14`})
|
|
5
|
+
|
|
6
|
+
// Run this script with: `sanity exec --with-user-token migrations/transformObjectToArray.js`
|
|
7
|
+
|
|
8
|
+
// This example shows how you may write a migration script that migrates an internationalized object
|
|
9
|
+
// To an internationalized array
|
|
10
|
+
|
|
11
|
+
// Transforms fields from:
|
|
12
|
+
// "greeting" {
|
|
13
|
+
// "en": "hello",
|
|
14
|
+
// "fr": "bonjour"
|
|
15
|
+
// }
|
|
16
|
+
|
|
17
|
+
// To:
|
|
18
|
+
// "greeting": [
|
|
19
|
+
// { "_key": "en", "value": "hello" },
|
|
20
|
+
// { "_key": "fr", "value": "bonjour" },
|
|
21
|
+
// ]
|
|
22
|
+
|
|
23
|
+
// This will migrate documents in batches of 100 and continue patching until no more documents are
|
|
24
|
+
// returned from the query.
|
|
25
|
+
//
|
|
26
|
+
// This script can safely be run, even if documents are being concurrently modified by others.
|
|
27
|
+
// If a document gets modified in the time between fetch => submit patch, this script will fail,
|
|
28
|
+
// but can safely be re-run multiple times until it eventually runs out of documents to migrate.
|
|
29
|
+
|
|
30
|
+
// A few things to note:
|
|
31
|
+
// - This script will exit if any of the mutations fail due to a revision mismatch (which means the
|
|
32
|
+
// document was edited between fetch => update)
|
|
33
|
+
// - The query must eventually return an empty set, or else this script will continue indefinitely
|
|
34
|
+
|
|
35
|
+
// Fetching documents that matches the precondition for the migration.
|
|
36
|
+
// NOTE: This query should eventually return an empty set of documents to mark the migration
|
|
37
|
+
// as complete
|
|
38
|
+
|
|
39
|
+
const TYPE = `presenter`
|
|
40
|
+
const FIELD_NAME = `title`
|
|
41
|
+
|
|
42
|
+
const fetchDocuments = () =>
|
|
43
|
+
client.fetch(
|
|
44
|
+
`*[_type == $type
|
|
45
|
+
&& defined(${FIELD_NAME})
|
|
46
|
+
&& count(${FIELD_NAME}) == null
|
|
47
|
+
][0...100] {_id, _rev, ${FIELD_NAME}}`,
|
|
48
|
+
{type: TYPE}
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
const buildPatches = (docs) =>
|
|
52
|
+
docs.map((doc) => ({
|
|
53
|
+
id: doc._id,
|
|
54
|
+
patch: {
|
|
55
|
+
set: {
|
|
56
|
+
// Convert existing object to array
|
|
57
|
+
[FIELD_NAME]: Object.keys(doc[FIELD_NAME])
|
|
58
|
+
.filter((key) => key !== '_type')
|
|
59
|
+
.map((key) => ({
|
|
60
|
+
_key: key,
|
|
61
|
+
value: doc[FIELD_NAME][key],
|
|
62
|
+
})),
|
|
63
|
+
},
|
|
64
|
+
// this will cause the migration to fail if any of the documents has been
|
|
65
|
+
// modified since it was fetched.
|
|
66
|
+
ifRevisionID: doc._rev,
|
|
67
|
+
},
|
|
68
|
+
}))
|
|
69
|
+
|
|
70
|
+
const createTransaction = (patches) =>
|
|
71
|
+
patches.reduce((tx, patch) => tx.patch(patch.id, patch.patch), client.transaction())
|
|
72
|
+
|
|
73
|
+
const commitTransaction = (tx) => tx.commit()
|
|
74
|
+
|
|
75
|
+
const migrateNextBatch = async () => {
|
|
76
|
+
const documents = await fetchDocuments()
|
|
77
|
+
const patches = buildPatches(documents)
|
|
78
|
+
if (patches.length === 0) {
|
|
79
|
+
console.log('No more documents to migrate!')
|
|
80
|
+
return null
|
|
81
|
+
}
|
|
82
|
+
console.log(
|
|
83
|
+
`Migrating batch:\n %s`,
|
|
84
|
+
patches.map((patch) => `${patch.id} => ${JSON.stringify(patch.patch)}`).join('\n')
|
|
85
|
+
)
|
|
86
|
+
const transaction = createTransaction(patches)
|
|
87
|
+
await commitTransaction(transaction)
|
|
88
|
+
return migrateNextBatch()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
migrateNextBatch().catch((err) => {
|
|
92
|
+
console.error(err)
|
|
93
|
+
process.exit(1)
|
|
94
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sanity-plugin-internationalized-array",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Store localised fields in an array to save on attributes",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@sanity/icons": "^1.3.1",
|
|
33
|
-
"@sanity/ui": "^0.37.9"
|
|
33
|
+
"@sanity/ui": "^0.37.9",
|
|
34
|
+
"styled-components": "^5.3.5"
|
|
34
35
|
},
|
|
35
36
|
"peerDependencies": {
|
|
36
37
|
"@sanity/base": "^2.30.1",
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import styled, {css} from 'styled-components'
|
|
3
|
+
import {Box, Card} from '@sanity/ui'
|
|
4
|
+
|
|
5
|
+
export const TableWrapper = styled(Box)(
|
|
6
|
+
() =>
|
|
7
|
+
css`
|
|
8
|
+
display: table;
|
|
9
|
+
`
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
type TableProps = {
|
|
13
|
+
children: React.ReactNode
|
|
14
|
+
[key: string]: unknown
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function Table(props: TableProps) {
|
|
18
|
+
const {children, ...rest} = props
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<TableWrapper as="table" {...rest}>
|
|
22
|
+
{children}
|
|
23
|
+
</TableWrapper>
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const Row = styled(Card)(
|
|
28
|
+
() =>
|
|
29
|
+
css`
|
|
30
|
+
display: table-row;
|
|
31
|
+
|
|
32
|
+
&:not([hidden]) {
|
|
33
|
+
display: table-row;
|
|
34
|
+
}
|
|
35
|
+
`
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
type TableRowProps = {
|
|
39
|
+
children: React.ReactNode
|
|
40
|
+
[key: string]: unknown
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function TableRow(props: TableRowProps) {
|
|
44
|
+
const {children, ...rest} = props
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<Row as="tr" {...rest}>
|
|
48
|
+
{children}
|
|
49
|
+
</Row>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const Cell = styled(Box)(
|
|
54
|
+
() =>
|
|
55
|
+
css`
|
|
56
|
+
display: table-cell;
|
|
57
|
+
`
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
type TableCellProps = {
|
|
61
|
+
children: React.ReactNode
|
|
62
|
+
style?: React.CSSProperties
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function TableCell(props: TableCellProps) {
|
|
66
|
+
const {children, style} = props
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<Cell as="td" style={style}>
|
|
70
|
+
{children}
|
|
71
|
+
</Cell>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
@@ -9,6 +9,7 @@ import {FormBuilderInput} from '@sanity/form-builder/lib/FormBuilderInput'
|
|
|
9
9
|
|
|
10
10
|
import ValueInput from './ValueInput'
|
|
11
11
|
import {useUnsetInputComponent} from './useUnsetInputComponent'
|
|
12
|
+
import {Table, TableCell, TableRow} from './Table'
|
|
12
13
|
|
|
13
14
|
const schemaExample = {
|
|
14
15
|
name: 'title',
|
|
@@ -172,7 +173,6 @@ const LanguageArrayWrapper = forwardRef(function CustomComponent(props, ref) {
|
|
|
172
173
|
.map((mark) => mark.path)
|
|
173
174
|
.flat()
|
|
174
175
|
.map((item) => item._key)
|
|
175
|
-
console.log(props)
|
|
176
176
|
|
|
177
177
|
return (
|
|
178
178
|
<Stack space={3}>
|
|
@@ -183,33 +183,37 @@ const LanguageArrayWrapper = forwardRef(function CustomComponent(props, ref) {
|
|
|
183
183
|
</Box>
|
|
184
184
|
{/* Loop over the values */}
|
|
185
185
|
{value?.length > 0 ? (
|
|
186
|
-
<Card
|
|
187
|
-
<
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
186
|
+
<Card>
|
|
187
|
+
<Table>
|
|
188
|
+
<tbody>
|
|
189
|
+
{value.map((item) => (
|
|
190
|
+
<TableRow
|
|
191
|
+
paddingY={1}
|
|
192
|
+
paddingX={2}
|
|
193
|
+
key={item._key}
|
|
194
|
+
tone={
|
|
195
|
+
// TODO: Move this logic somewhere else
|
|
196
|
+
invalidKeys.includes(item._key)
|
|
197
|
+
? `critical`
|
|
198
|
+
: undefined || languagesOutOfOrder.find((l) => l._key === item._key)
|
|
199
|
+
? `caution`
|
|
200
|
+
: undefined
|
|
201
|
+
}
|
|
202
|
+
>
|
|
203
203
|
{/* To render each individual field in this type */}
|
|
204
204
|
{type?.of?.length > 0 &&
|
|
205
205
|
type?.of.map((subType) => (
|
|
206
|
-
|
|
206
|
+
<>
|
|
207
207
|
{subType?.fields?.length > 0 ? (
|
|
208
208
|
<>
|
|
209
|
-
<
|
|
210
|
-
<
|
|
211
|
-
|
|
212
|
-
|
|
209
|
+
<TableCell>
|
|
210
|
+
<Box paddingRight={2}>
|
|
211
|
+
<Label muted size={1}>
|
|
212
|
+
{item._key}
|
|
213
|
+
</Label>
|
|
214
|
+
</Box>
|
|
215
|
+
</TableCell>
|
|
216
|
+
<TableCell style={{width: `100%`}}>
|
|
213
217
|
{/* There _should_ only be one field */}
|
|
214
218
|
{subType.fields.map((subTypeField, subTypeFieldIndex) => (
|
|
215
219
|
<ValueInput
|
|
@@ -221,39 +225,43 @@ const LanguageArrayWrapper = forwardRef(function CustomComponent(props, ref) {
|
|
|
221
225
|
// We don't want the array item to open onFocus
|
|
222
226
|
onFocus={() => null}
|
|
223
227
|
path={[{_key: item._key}, subTypeField.name]}
|
|
224
|
-
focusPath={[{_key: item._key}, subTypeField.name]}
|
|
228
|
+
// focusPath={[{_key: item._key}, subTypeField.name]}
|
|
225
229
|
parent={item}
|
|
226
230
|
readOnly={readOnly}
|
|
227
231
|
type={subTypeField}
|
|
228
232
|
value={item.value}
|
|
229
233
|
level={props.level + 1}
|
|
230
234
|
markers={[]}
|
|
231
|
-
compareValue={
|
|
232
|
-
props?.compareValue?.find((c) => c._key === item._key)?.value
|
|
233
|
-
}
|
|
235
|
+
compareValue={props.compareValue}
|
|
234
236
|
/>
|
|
235
237
|
))}
|
|
236
|
-
</
|
|
238
|
+
</TableCell>
|
|
237
239
|
</>
|
|
238
240
|
) : null}
|
|
239
|
-
|
|
241
|
+
</>
|
|
240
242
|
))}
|
|
241
243
|
{presence?.length > 0 ? (
|
|
242
|
-
<
|
|
244
|
+
<TableCell>
|
|
245
|
+
<FieldPresence maxAvatars={1} presence={presence} />
|
|
246
|
+
</TableCell>
|
|
243
247
|
) : null}
|
|
244
248
|
{invalidKeys.includes(item._key) ? (
|
|
245
|
-
<
|
|
249
|
+
<TableCell>
|
|
250
|
+
<FormFieldValidationStatus __unstable_markers={validationMarkers} />
|
|
251
|
+
</TableCell>
|
|
246
252
|
) : null}
|
|
247
|
-
<
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
253
|
+
<TableCell>
|
|
254
|
+
<Button
|
|
255
|
+
mode="ghost"
|
|
256
|
+
icon={RemoveIcon}
|
|
257
|
+
tone="critical"
|
|
258
|
+
onClick={() => handleUnsetByKey(item._key)}
|
|
259
|
+
/>
|
|
260
|
+
</TableCell>
|
|
261
|
+
</TableRow>
|
|
262
|
+
))}
|
|
263
|
+
</tbody>
|
|
264
|
+
</Table>
|
|
257
265
|
</Card>
|
|
258
266
|
) : null}
|
|
259
267
|
|