@kyro-cms/admin 0.10.12 → 0.10.14
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/dist/index.cjs +15 -15
- package/dist/index.js +15 -15
- package/package.json +1 -1
- package/src/components/AutoForm.tsx +4 -1
- package/src/components/blocks/BlockEditModal.tsx +0 -11
- package/src/components/fields/BlocksField.tsx +22 -4
- package/src/components/fields/RelationshipField.tsx +1 -1
- package/src/lib/config.ts +48 -0
package/package.json
CHANGED
|
@@ -540,6 +540,8 @@ export function AutoForm({
|
|
|
540
540
|
setLocalSaveStatus("saving");
|
|
541
541
|
|
|
542
542
|
try {
|
|
543
|
+
let dataToPublish = { ...formData };
|
|
544
|
+
|
|
543
545
|
if (isNewDoc && !globalSlug) {
|
|
544
546
|
// Create then immediately publish
|
|
545
547
|
const data = normalizeUploadFields({ ...formData }) as Record<string, unknown>;
|
|
@@ -560,10 +562,11 @@ export function AutoForm({
|
|
|
560
562
|
const savedData = result.data || data;
|
|
561
563
|
setFormData({ ...formData, ...savedData });
|
|
562
564
|
setLastSavedData({ ...formData, ...savedData });
|
|
565
|
+
dataToPublish = { ...formData, ...savedData };
|
|
563
566
|
}
|
|
564
567
|
|
|
565
568
|
// Save and publish (X-Draft: false writes to main doc + versions table)
|
|
566
|
-
const data = normalizeUploadFields(
|
|
569
|
+
const data = normalizeUploadFields(dataToPublish) as Record<string, unknown>;
|
|
567
570
|
const response = await saveDocument(data, false);
|
|
568
571
|
|
|
569
572
|
if (response?.ok) {
|
|
@@ -107,17 +107,6 @@ export const BlockEditModal: React.FC<BlockEditModalProps> = ({
|
|
|
107
107
|
accentClass={theme.border}
|
|
108
108
|
>
|
|
109
109
|
<div className="space-y-4">
|
|
110
|
-
<div>
|
|
111
|
-
<label className="text-[10px] font-medium text-[var(--kyro-text-muted)] mb-1 block">
|
|
112
|
-
Block Name
|
|
113
|
-
</label>
|
|
114
|
-
<input
|
|
115
|
-
value={(blockData?.name as string) || ""}
|
|
116
|
-
onChange={(e) => updateBlock(block.id, { name: e.target.value })}
|
|
117
|
-
placeholder={blockSchema?.label || (block.type as string)}
|
|
118
|
-
className="w-full bg-[var(--kyro-bg-primary)] border border-[var(--kyro-border)] rounded-lg px-3 py-2 text-sm text-[var(--kyro-text-primary)] outline-none focus:border-[var(--kyro-primary)] transition-colors"
|
|
119
|
-
/>
|
|
120
|
-
</div>
|
|
121
110
|
|
|
122
111
|
{renderFields()}
|
|
123
112
|
|
|
@@ -257,12 +257,18 @@ const SortableBlockComponent = ({
|
|
|
257
257
|
onKeyDown={(e) => { if (e.key === "Enter") commitName(); if (e.key === "Escape") { setNameDraft((block.name as string) || ""); setEditingName(false); } }}
|
|
258
258
|
onClick={(e) => e.stopPropagation()}
|
|
259
259
|
placeholder={getBlockLabel(block.type as string)}
|
|
260
|
-
className="w-full bg-[var(--kyro-surface-accent)] border border-[var(--kyro-primary)] rounded px-2 py-0.5 text-xs font-semibold text-[var(--kyro-text-primary)] outline-none"
|
|
260
|
+
className="w-full max-w-[150px] sm:max-w-[250px] md:max-w-[400px] bg-[var(--kyro-surface-accent)] border border-[var(--kyro-primary)] rounded px-2 py-0.5 text-xs font-semibold text-[var(--kyro-text-primary)] outline-none"
|
|
261
261
|
/>
|
|
262
262
|
) : (
|
|
263
263
|
<div
|
|
264
|
-
onClick={(e) => {
|
|
265
|
-
|
|
264
|
+
onClick={(e) => {
|
|
265
|
+
if (window.innerWidth >= 768) {
|
|
266
|
+
e.stopPropagation();
|
|
267
|
+
setNameDraft((block.name as string) || "");
|
|
268
|
+
setEditingName(true);
|
|
269
|
+
}
|
|
270
|
+
}}
|
|
271
|
+
className="text-xs font-semibold text-[var(--kyro-text-secondary)] truncate md:cursor-text hover:text-[var(--kyro-text-primary)] transition-colors"
|
|
266
272
|
title="Click to rename"
|
|
267
273
|
>
|
|
268
274
|
{itemLabel}
|
|
@@ -310,7 +316,19 @@ const SortableBlockComponent = ({
|
|
|
310
316
|
</button>
|
|
311
317
|
</div>
|
|
312
318
|
) : (
|
|
313
|
-
<div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
319
|
+
<div className="flex items-center gap-1 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-opacity">
|
|
320
|
+
<button
|
|
321
|
+
type="button"
|
|
322
|
+
onClick={(e) => {
|
|
323
|
+
e.stopPropagation();
|
|
324
|
+
setNameDraft((block.name as string) || "");
|
|
325
|
+
setEditingName(true);
|
|
326
|
+
}}
|
|
327
|
+
className="md:hidden p-1 hover:bg-[var(--kyro-surface-accent)] rounded text-[var(--kyro-text-secondary)] transition-colors"
|
|
328
|
+
title="Rename Block"
|
|
329
|
+
>
|
|
330
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"/><path d="m15 5 4 4"/></svg>
|
|
331
|
+
</button>
|
|
314
332
|
<button
|
|
315
333
|
type="button"
|
|
316
334
|
onClick={(e) => {
|
|
@@ -65,7 +65,7 @@ export function RelationshipField({
|
|
|
65
65
|
? field.relationTo
|
|
66
66
|
: [field.relationTo];
|
|
67
67
|
const isPolymorphic = relationTo.length > 1;
|
|
68
|
-
const [activeRelation, setActiveRelation] = useState(relationTo[0]);
|
|
68
|
+
const [activeRelation, setActiveRelation] = useState(relationTo[0] || "");
|
|
69
69
|
|
|
70
70
|
const extractIds = useCallback((): string[] => {
|
|
71
71
|
if (!value) return [];
|
package/src/lib/config.ts
CHANGED
|
@@ -101,6 +101,33 @@ function updateFieldByPath(
|
|
|
101
101
|
if (field.fields && Array.isArray(field.fields)) {
|
|
102
102
|
return updateFieldByPath(field.fields, remainingPath, updates);
|
|
103
103
|
}
|
|
104
|
+
|
|
105
|
+
// For tabs fields, traverse into all tabs
|
|
106
|
+
if (field.type === "tabs" && field.tabs && Array.isArray(field.tabs)) {
|
|
107
|
+
for (const tab of field.tabs) {
|
|
108
|
+
if (tab.fields && Array.isArray(tab.fields)) {
|
|
109
|
+
if (updateFieldByPath(tab.fields, remainingPath, updates)) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// For blocks fields, the next path segment is the block slug
|
|
118
|
+
if (field.type === "blocks" && field.blocks && Array.isArray(field.blocks)) {
|
|
119
|
+
const blockSlug = remainingPath.split(".")[0];
|
|
120
|
+
const restOfPath = remainingPath.split(".").slice(1).join(".");
|
|
121
|
+
if (!restOfPath) return false;
|
|
122
|
+
|
|
123
|
+
for (const block of field.blocks) {
|
|
124
|
+
if (block.slug === blockSlug && block.fields && Array.isArray(block.fields)) {
|
|
125
|
+
return updateFieldByPath(block.fields, restOfPath, updates);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
104
131
|
// For array fields, look in the nested fields
|
|
105
132
|
if (field.type === "array" && field.fields && Array.isArray(field.fields)) {
|
|
106
133
|
return updateFieldByPath(field.fields, remainingPath, updates);
|
|
@@ -112,6 +139,27 @@ function updateFieldByPath(
|
|
|
112
139
|
return true;
|
|
113
140
|
}
|
|
114
141
|
}
|
|
142
|
+
|
|
143
|
+
// If it's a structural field (like tabs, row, or collapsible) that we should pass through implicitly,
|
|
144
|
+
// we must traverse it even if it has a name, because these fields do not create nested data objects.
|
|
145
|
+
const isFlatStructuralField =
|
|
146
|
+
!field.name ||
|
|
147
|
+
field.type === "tabs" ||
|
|
148
|
+
field.type === "row" ||
|
|
149
|
+
field.type === "collapsible";
|
|
150
|
+
|
|
151
|
+
if (isFlatStructuralField) {
|
|
152
|
+
if (field.fields && Array.isArray(field.fields)) {
|
|
153
|
+
if (updateFieldByPath(field.fields, path, updates)) return true;
|
|
154
|
+
}
|
|
155
|
+
if (field.type === "tabs" && field.tabs && Array.isArray(field.tabs)) {
|
|
156
|
+
for (const tab of field.tabs) {
|
|
157
|
+
if (tab.fields && Array.isArray(tab.fields)) {
|
|
158
|
+
if (updateFieldByPath(tab.fields, path, updates)) return true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
115
163
|
}
|
|
116
164
|
return false;
|
|
117
165
|
}
|