@riducms/admin 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
"@iconify/json": "^2.2.509",
|
|
22
22
|
"@internationalized/date": "^3.12.3",
|
|
23
23
|
"@lezer/highlight": "^1.2.3",
|
|
24
|
-
"@riducms/plugin": "0.
|
|
25
|
-
"@riducms/protocol": "0.
|
|
26
|
-
"@riducms/sdk": "0.
|
|
27
|
-
"@riducms/translations": "0.
|
|
28
|
-
"@riducms/ui": "0.
|
|
24
|
+
"@riducms/plugin": "0.6.0",
|
|
25
|
+
"@riducms/protocol": "0.6.0",
|
|
26
|
+
"@riducms/sdk": "0.6.0",
|
|
27
|
+
"@riducms/translations": "0.6.0",
|
|
28
|
+
"@riducms/ui": "0.6.0",
|
|
29
29
|
"@twinkleplop/bash": "0.1.5",
|
|
30
30
|
"@twinkleplop/go": "0.1.5",
|
|
31
31
|
"@twinkleplop/typescript": "0.1.5",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"description": "Framework-owned Svelte 5 authoring application embedded by Ridu servers.",
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@hvniel/lexical-svelte": "^0.1.1",
|
|
38
|
-
"@riducms/build": "0.
|
|
38
|
+
"@riducms/build": "0.6.0",
|
|
39
39
|
"svelte": "^5.57.0"
|
|
40
40
|
},
|
|
41
41
|
"exports": {
|
|
@@ -74,5 +74,5 @@
|
|
|
74
74
|
"test:unit": "bun test tests"
|
|
75
75
|
},
|
|
76
76
|
"type": "module",
|
|
77
|
-
"version": "0.
|
|
77
|
+
"version": "0.6.0"
|
|
78
78
|
}
|
|
@@ -66,6 +66,16 @@ export function submissionFormValues(
|
|
|
66
66
|
return submissionRecord(fields, input, "", include);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/** Project an update onto caller edits, retaining row membership and stable identities. */
|
|
70
|
+
export function changedFormValues(
|
|
71
|
+
fields: readonly SchemaField[],
|
|
72
|
+
input: FormValues,
|
|
73
|
+
original: FormValues,
|
|
74
|
+
isInherited?: (path: string) => boolean
|
|
75
|
+
): FormValues {
|
|
76
|
+
return submissionRecord(fields, input, "", () => true, original, isInherited);
|
|
77
|
+
}
|
|
78
|
+
|
|
69
79
|
/** Initialize a new record, retaining supplied values and container metadata. */
|
|
70
80
|
export function initialFormValues(
|
|
71
81
|
fields: readonly SchemaField[],
|
|
@@ -100,9 +110,12 @@ function submissionRecord(
|
|
|
100
110
|
fields: readonly SchemaField[],
|
|
101
111
|
input: unknown,
|
|
102
112
|
prefix: string,
|
|
103
|
-
include: (path: string, canonicalPath: string) => boolean
|
|
113
|
+
include: (path: string, canonicalPath: string) => boolean,
|
|
114
|
+
original?: unknown,
|
|
115
|
+
isInherited?: (path: string) => boolean
|
|
104
116
|
): FormValues {
|
|
105
117
|
const values = isRecord(input) ? input : {};
|
|
118
|
+
const before = isRecord(original) ? original : {};
|
|
106
119
|
const submitted: FormValues = {};
|
|
107
120
|
for (const field of fields) {
|
|
108
121
|
const path = joinFormPath(prefix, field.name);
|
|
@@ -113,23 +126,47 @@ function submissionRecord(
|
|
|
113
126
|
)
|
|
114
127
|
continue;
|
|
115
128
|
const value = values[field.name];
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
129
|
+
const displayedPrevious = before[field.name];
|
|
130
|
+
if (Object.hasOwn(before, field.name) && deepEqual(value, displayedPrevious)) continue;
|
|
131
|
+
// An edited fallback establishes a new locale value, without retained children to merge.
|
|
132
|
+
const previous = isInherited?.(path) === true ? undefined : displayedPrevious;
|
|
133
|
+
|
|
134
|
+
if (field.type === "group" && isRecord(value)) {
|
|
135
|
+
submitted[field.name] = submissionRecord(
|
|
136
|
+
field.nested?.fields ?? [],
|
|
137
|
+
value,
|
|
138
|
+
path,
|
|
139
|
+
include,
|
|
140
|
+
previous,
|
|
141
|
+
isInherited
|
|
121
142
|
);
|
|
122
|
-
} else if (field.type === "blocks" && Array.isArray(value)) {
|
|
143
|
+
} else if ((field.type === "array" || field.type === "blocks") && Array.isArray(value)) {
|
|
144
|
+
const previousRows = new Map(
|
|
145
|
+
(Array.isArray(previous) ? previous : []).flatMap((row) =>
|
|
146
|
+
isRecord(row) && typeof row._key === "string" ? [[row._key, row] as const] : []
|
|
147
|
+
)
|
|
148
|
+
);
|
|
149
|
+
const blocks = resolveBlockTypes(field.blocks);
|
|
123
150
|
submitted[field.name] = value.map((row, index) => {
|
|
124
|
-
if (!isRecord(row)
|
|
125
|
-
const
|
|
126
|
-
|
|
151
|
+
if (!isRecord(row)) return cloneFormValue(row);
|
|
152
|
+
const children =
|
|
153
|
+
field.type === "array"
|
|
154
|
+
? (field.nested?.fields ?? [])
|
|
155
|
+
: blocks.find((block) => block.slug === row.blockType)?.fields;
|
|
156
|
+
if (children === undefined) return cloneFormValue(row);
|
|
157
|
+
|
|
158
|
+
const prior = typeof row._key === "string" ? previousRows.get(row._key) : undefined;
|
|
159
|
+
return submissionRecord(
|
|
160
|
+
children,
|
|
161
|
+
row,
|
|
162
|
+
`${path}.${index}`,
|
|
163
|
+
include,
|
|
164
|
+
field.type === "blocks" && prior?.blockType !== row.blockType ? undefined : prior,
|
|
165
|
+
isInherited
|
|
127
166
|
);
|
|
128
|
-
return block === undefined
|
|
129
|
-
? cloneFormValue(row)
|
|
130
|
-
: submissionRecord(block.fields, row, `${path}.${index}`, include);
|
|
131
167
|
});
|
|
132
168
|
} else if (field.type === "plugin" && field.plugin?.embeddedTrees !== undefined) {
|
|
169
|
+
const priorOccurrences = embeddedOccurrences(field, previous, path).occurrences;
|
|
133
170
|
submitted[field.name] = transformEmbeddedPayloads(
|
|
134
171
|
field,
|
|
135
172
|
cloneFormValue(value),
|
|
@@ -139,7 +176,17 @@ function submissionRecord(
|
|
|
139
176
|
occurrence.block.fields,
|
|
140
177
|
occurrence.payload,
|
|
141
178
|
occurrence.path,
|
|
142
|
-
include
|
|
179
|
+
include,
|
|
180
|
+
occurrence.identity === undefined
|
|
181
|
+
? undefined
|
|
182
|
+
: priorOccurrences.find(
|
|
183
|
+
(prior) =>
|
|
184
|
+
prior.tree.key === occurrence.tree.key &&
|
|
185
|
+
prior.case.tagValue === occurrence.case.tagValue &&
|
|
186
|
+
prior.block.slug === occurrence.block.slug &&
|
|
187
|
+
prior.identity === occurrence.identity
|
|
188
|
+
)?.payload,
|
|
189
|
+
isInherited
|
|
143
190
|
),
|
|
144
191
|
[occurrence.case.discriminator]: occurrence.block.slug,
|
|
145
192
|
...(occurrence.identity === undefined
|
|
@@ -11,7 +11,11 @@ import {
|
|
|
11
11
|
saveFormDraft,
|
|
12
12
|
takeFormDraft,
|
|
13
13
|
} from "@admin/core/forms/form-draft-recovery";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
changedFormValues,
|
|
16
|
+
documentFormValues,
|
|
17
|
+
initialFormValues,
|
|
18
|
+
} from "@admin/core/forms/form-schema";
|
|
15
19
|
import { invalidFieldLabels } from "@admin/core/forms/form-validation";
|
|
16
20
|
import type { NotificationCenter } from "@admin/core/notifications/notification-center.svelte";
|
|
17
21
|
import { samePreparedCreateValues } from "@admin/core/bootstrap/admin-bootstrap";
|
|
@@ -501,6 +505,10 @@ export class DocumentController {
|
|
|
501
505
|
const wasCreating = this.creating;
|
|
502
506
|
try {
|
|
503
507
|
const saved = await this.form.submit(this.validationFields, this.creating, async (values) => {
|
|
508
|
+
if (!wasCreating)
|
|
509
|
+
values = changedFormValues(this.validationFields, values, this.form.original, (path) =>
|
|
510
|
+
this.form.isInherited(path)
|
|
511
|
+
);
|
|
504
512
|
if (this.globalResource) {
|
|
505
513
|
if (publishingChanges) {
|
|
506
514
|
return this.options.runtime.client.publishGlobalChanges(collectionSlug, values, {
|
|
@@ -7,7 +7,11 @@ import { RiduError } from "@riducms/sdk";
|
|
|
7
7
|
|
|
8
8
|
import type { AdminDocument } from "@admin/core/api/admin-client";
|
|
9
9
|
import { FormController, FormValidationError } from "@admin/core/forms/form-controller.svelte";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
changedFormValues,
|
|
12
|
+
documentFormValues,
|
|
13
|
+
initialFormValues,
|
|
14
|
+
} from "@admin/core/forms/form-schema";
|
|
11
15
|
import { invalidFieldLabels } from "@admin/core/forms/form-validation";
|
|
12
16
|
import type { NotificationCenter } from "@admin/core/notifications/notification-center.svelte";
|
|
13
17
|
import type { AdminRuntime } from "@admin/core/runtime/admin-runtime.svelte";
|
|
@@ -450,6 +454,9 @@ export class ReferenceBrowserWorkflow {
|
|
|
450
454
|
const saved = await this.form.submit(this.validationFields, this.creating, async (values) => {
|
|
451
455
|
if (this.options.readOnly) throw new Error("This field is read-only.");
|
|
452
456
|
if (this.editorDocument !== undefined) {
|
|
457
|
+
values = changedFormValues(this.validationFields, values, this.form.original, (path) =>
|
|
458
|
+
this.form.isInherited(path)
|
|
459
|
+
);
|
|
453
460
|
if (this.collection.capabilities.upload) {
|
|
454
461
|
return this.options.runtime.client.updateUpload(
|
|
455
462
|
this.collection.slug,
|