@byline/admin 3.19.0 → 3.20.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.
|
@@ -24,6 +24,13 @@ const ArrayField = ({ field, defaultValue, path, disableSorting = false, collect
|
|
|
24
24
|
getFieldValue,
|
|
25
25
|
path
|
|
26
26
|
]);
|
|
27
|
+
const patchItemId = (item, index)=>{
|
|
28
|
+
if (item && 'object' == typeof item) {
|
|
29
|
+
if ('_id' in item) return String(item._id);
|
|
30
|
+
if ('id' in item) return String(item.id);
|
|
31
|
+
}
|
|
32
|
+
return String(index);
|
|
33
|
+
};
|
|
27
34
|
const handleDragEnd = ({ moveFromIndex, moveToIndex })=>{
|
|
28
35
|
setItems((prev)=>moveItem(prev, moveFromIndex, moveToIndex));
|
|
29
36
|
const currentArray = getFieldValue(path) ?? defaultValue;
|
|
@@ -32,11 +39,10 @@ const ArrayField = ({ field, defaultValue, path, disableSorting = false, collect
|
|
|
32
39
|
const clampedTo = Math.max(0, Math.min(moveToIndex, currentArray.length - 1));
|
|
33
40
|
if (clampedFrom === clampedTo) return;
|
|
34
41
|
const item = currentArray[clampedFrom];
|
|
35
|
-
const itemId = item && 'object' == typeof item && 'id' in item ? String(item.id) : String(clampedFrom);
|
|
36
42
|
appendPatch({
|
|
37
43
|
kind: 'array.move',
|
|
38
44
|
path: path,
|
|
39
|
-
itemId,
|
|
45
|
+
itemId: patchItemId(item, clampedFrom),
|
|
40
46
|
toIndex: clampedTo
|
|
41
47
|
});
|
|
42
48
|
}
|
|
@@ -45,7 +51,9 @@ const ArrayField = ({ field, defaultValue, path, disableSorting = false, collect
|
|
|
45
51
|
const childFields = field.fields ?? [];
|
|
46
52
|
if (0 === childFields.length) return;
|
|
47
53
|
const newId = crypto.randomUUID();
|
|
48
|
-
const newItem = {
|
|
54
|
+
const newItem = {
|
|
55
|
+
_id: newId
|
|
56
|
+
};
|
|
49
57
|
for (const childField of childFields)if ('group' === childField.type && childField.fields && childField.fields.length > 0) {
|
|
50
58
|
const groupObj = {};
|
|
51
59
|
for (const innerField of childField.fields)groupObj[innerField.name] = await defaultScalarForField(innerField, getFieldValues);
|
|
@@ -80,12 +88,11 @@ const ArrayField = ({ field, defaultValue, path, disableSorting = false, collect
|
|
|
80
88
|
const currentArray = getFieldValue(path) ?? defaultValue;
|
|
81
89
|
if (!Array.isArray(currentArray) || index < 0 || index >= currentArray.length) return;
|
|
82
90
|
const item = currentArray[index];
|
|
83
|
-
const itemId = item && 'object' == typeof item && 'id' in item ? String(item.id) : String(index);
|
|
84
91
|
setItems((prev)=>prev.filter((_, i)=>i !== index));
|
|
85
92
|
appendPatch({
|
|
86
93
|
kind: 'array.remove',
|
|
87
94
|
path: path,
|
|
88
|
-
itemId
|
|
95
|
+
itemId: patchItemId(item, index)
|
|
89
96
|
});
|
|
90
97
|
const newArrayValue = [
|
|
91
98
|
...currentArray
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@byline/admin",
|
|
3
3
|
"private": false,
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.20.1",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=20.9.0"
|
|
8
8
|
},
|
|
@@ -155,10 +155,10 @@
|
|
|
155
155
|
"react-diff-viewer-continued": "^4.2.2",
|
|
156
156
|
"uuid": "^14.0.1",
|
|
157
157
|
"zod": "^4.4.3",
|
|
158
|
-
"@byline/auth": "3.
|
|
159
|
-
"@byline/
|
|
160
|
-
"@byline/
|
|
161
|
-
"@byline/
|
|
158
|
+
"@byline/auth": "3.20.1",
|
|
159
|
+
"@byline/i18n": "3.20.1",
|
|
160
|
+
"@byline/ui": "3.20.1",
|
|
161
|
+
"@byline/core": "3.20.1"
|
|
162
162
|
},
|
|
163
163
|
"peerDependencies": {
|
|
164
164
|
"react": "^19.0.0",
|
|
@@ -80,6 +80,23 @@ export const ArrayField = ({
|
|
|
80
80
|
}
|
|
81
81
|
}, [defaultValue, getFieldValue, path])
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Stable patch identity for an array item. Persisted items carry `_id`
|
|
85
|
+
* (the array-item identity from `store_meta`) — that is what the server's
|
|
86
|
+
* patch engine matches on (`applyArrayPatch`: `item._id === patch.itemId`),
|
|
87
|
+
* so it MUST be preferred here. `id` is accepted as a legacy/seed-data
|
|
88
|
+
* alias. Items added this session have neither (the storage layer assigns
|
|
89
|
+
* `_id` at write time), so fall back to the item's current index — the
|
|
90
|
+
* patch engine resolves a pure-integer itemId as an index fallback.
|
|
91
|
+
*/
|
|
92
|
+
const patchItemId = (item: unknown, index: number): string => {
|
|
93
|
+
if (item && typeof item === 'object') {
|
|
94
|
+
if ('_id' in item) return String((item as { _id: string })._id)
|
|
95
|
+
if ('id' in item) return String((item as { id: string }).id)
|
|
96
|
+
}
|
|
97
|
+
return String(index)
|
|
98
|
+
}
|
|
99
|
+
|
|
83
100
|
const handleDragEnd = ({
|
|
84
101
|
moveFromIndex,
|
|
85
102
|
moveToIndex,
|
|
@@ -96,15 +113,11 @@ export const ArrayField = ({
|
|
|
96
113
|
if (clampedFrom === clampedTo) return
|
|
97
114
|
|
|
98
115
|
const item = currentArray[clampedFrom]
|
|
99
|
-
const itemId =
|
|
100
|
-
item && typeof item === 'object' && 'id' in item
|
|
101
|
-
? String((item as { id: string }).id)
|
|
102
|
-
: String(clampedFrom)
|
|
103
116
|
|
|
104
117
|
appendPatch({
|
|
105
118
|
kind: 'array.move',
|
|
106
119
|
path: path,
|
|
107
|
-
itemId,
|
|
120
|
+
itemId: patchItemId(item, clampedFrom),
|
|
108
121
|
toIndex: clampedTo,
|
|
109
122
|
})
|
|
110
123
|
}
|
|
@@ -116,8 +129,12 @@ export const ArrayField = ({
|
|
|
116
129
|
|
|
117
130
|
const newId = crypto.randomUUID()
|
|
118
131
|
|
|
119
|
-
// Build a new item with default values for ALL child fields
|
|
120
|
-
|
|
132
|
+
// Build a new item with default values for ALL child fields.
|
|
133
|
+
// Assign the stable `_id` client-side — exactly like BlocksField's
|
|
134
|
+
// handleAddItem — so the item is patch-addressable (move / remove by
|
|
135
|
+
// `_id`) within the same editing session, before any server write has
|
|
136
|
+
// assigned identity. The storage layer persists `_id` via store_meta.
|
|
137
|
+
const newItem: Record<string, any> = { _id: newId }
|
|
121
138
|
for (const childField of childFields) {
|
|
122
139
|
if (childField.type === 'group' && childField.fields && childField.fields.length > 0) {
|
|
123
140
|
// Group child — build a nested object with defaults for each inner field
|
|
@@ -158,17 +175,13 @@ export const ArrayField = ({
|
|
|
158
175
|
if (!Array.isArray(currentArray) || index < 0 || index >= currentArray.length) return
|
|
159
176
|
|
|
160
177
|
const item = currentArray[index]
|
|
161
|
-
const itemId =
|
|
162
|
-
item && typeof item === 'object' && 'id' in item
|
|
163
|
-
? String((item as { id: string }).id)
|
|
164
|
-
: String(index)
|
|
165
178
|
|
|
166
179
|
setItems((prev) => prev.filter((_, i) => i !== index))
|
|
167
180
|
|
|
168
181
|
appendPatch({
|
|
169
182
|
kind: 'array.remove',
|
|
170
183
|
path: path,
|
|
171
|
-
itemId,
|
|
184
|
+
itemId: patchItemId(item, index),
|
|
172
185
|
})
|
|
173
186
|
|
|
174
187
|
const newArrayValue = [...currentArray]
|