@cosmicdrift/kumiko-renderer 0.34.0 → 0.34.2

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-renderer",
3
- "version": "0.34.0",
3
+ "version": "0.34.2",
4
4
  "description": "Platform-agnostic React renderer for Kumiko screens. Contains the shared logic — primitives-contract, hooks, KumikoScreen, navigation & SSE abstractions — that any platform-specific renderer (web, native) composes. No DOM, no EventSource, no react-dom.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -29,6 +29,11 @@ export function extensionSectionName(component: PlatformComponent): string | und
29
29
  export type ExtensionSectionProps = {
30
30
  readonly entityName: string;
31
31
  readonly entityId: string | null;
32
+ /** Bereits gespeicherte Extension-Werte der Entity (aus der geladenen
33
+ * detail-row durchgereicht). `undefined` im Create-Mode oder wenn der
34
+ * Host-Screen keine Werte liefert. Erlaubt der Section, den Bestand
35
+ * beim Edit anzuzeigen statt write-only zu sein. */
36
+ readonly initialValues?: Readonly<Record<string, unknown>>;
32
37
  };
33
38
 
34
39
  export type ExtensionSectionComponent = ComponentType<ExtensionSectionProps>;
@@ -421,6 +421,15 @@ function EntityEditUpdateForm({
421
421
  return out as FormValues;
422
422
  }, [entity.fields, record]);
423
423
 
424
+ // Extension-Werte (z.B. customFields-jsonb) an extension-sections geben,
425
+ // damit sie beim Edit den Bestand zeigen statt write-only zu sein.
426
+ const extensionInitialValues = useMemo((): Readonly<Record<string, unknown>> | undefined => {
427
+ const cf = record["customFields"];
428
+ return cf !== null && typeof cf === "object" && !Array.isArray(cf)
429
+ ? (cf as Record<string, unknown>)
430
+ : undefined;
431
+ }, [record]);
432
+
424
433
  const writeCommand = entityWriteCommand(schema.featureName, screen.entity, "update");
425
434
  const deleteCommand = entityWriteCommand(schema.featureName, screen.entity, "delete");
426
435
  const buildPayload = useMemo(
@@ -452,6 +461,13 @@ function EntityEditUpdateForm({
452
461
  entity={entity}
453
462
  featureName={schema.featureName}
454
463
  initial={initial}
464
+ // Echte route-id an die extension-section (Set-Value-UI): das
465
+ // Update-Form lässt `id` bewusst aus den Form-values, daher braucht
466
+ // die Section die id explizit — sonst create-mode trotz Edit.
467
+ entityId={entityId}
468
+ // customFields-Bestand an die extension-section, damit sie beim Edit
469
+ // die gespeicherten Werte zeigt (nicht write-only).
470
+ extensionInitialValues={extensionInitialValues}
455
471
  writeCommand={writeCommand}
456
472
  payloadMode="changes"
457
473
  buildPayload={buildPayload}
@@ -35,6 +35,17 @@ export type RenderEditProps<TValues extends FormValues, TCtx = unknown> = {
35
35
  readonly entity: EntityDefinition;
36
36
  readonly featureName: string;
37
37
  readonly initial: TValues;
38
+ /** Echte entity-id für extension-section-Mounts (Set-Value-UI). Der
39
+ * Update-Body kennt sie aus der Route; ohne sie fiele die Section auf
40
+ * `vm.id` (= values["id"]) zurück, das im Update-Form immer fehlt
41
+ * (id ist keine deklarierte Form-Field, siehe EntityEditUpdateForm) —
42
+ * die Section bliebe dann fälschlich im create-mode. Weglassen
43
+ * (undefined) = create-mode / kein extension-Kontext (vm.id-Fallback). */
44
+ readonly entityId?: string | null;
45
+ /** Bereits gespeicherte Extension-Werte (z.B. `record.customFields`) für
46
+ * extension-section-Mounts. Erlaubt der Section, den Bestand beim Edit
47
+ * anzuzeigen. Nur der Update-Body liefert das. */
48
+ readonly extensionInitialValues?: Readonly<Record<string, unknown>>;
38
49
  /** Standard single-write Submit-Pfad. Ignoriert wenn `customSubmit`
39
50
  * gesetzt ist (configEdit-Screens dispatchen mehrere Writes pro
40
51
  * Submit, da macht writeCommand keinen Sinn). */
@@ -111,10 +122,12 @@ function ExtensionSectionMount({
111
122
  section,
112
123
  entityName,
113
124
  entityId,
125
+ initialValues,
114
126
  }: {
115
127
  readonly section: EditExtensionSectionViewModel;
116
128
  readonly entityName: string;
117
129
  readonly entityId: string | null;
130
+ readonly initialValues?: Readonly<Record<string, unknown>>;
118
131
  }): ReactNode {
119
132
  const { Banner, Section, Text } = usePrimitives();
120
133
  const name = extensionSectionName(section.component);
@@ -138,7 +151,7 @@ function ExtensionSectionMount({
138
151
  }
139
152
  return (
140
153
  <Section title={section.title} testId={`section-extension-${section.title}`}>
141
- <Component entityName={entityName} entityId={entityId} />
154
+ <Component entityName={entityName} entityId={entityId} initialValues={initialValues} />
142
155
  </Section>
143
156
  );
144
157
  }
@@ -163,6 +176,8 @@ export function RenderEdit<TValues extends FormValues, TCtx = unknown>(
163
176
  onReload,
164
177
  submitLabel,
165
178
  fieldAppendix,
179
+ entityId: entityIdProp,
180
+ extensionInitialValues,
166
181
  } = props;
167
182
  const { customSubmit } = props;
168
183
  // Translate-Fallback: wenn der Caller keine Translate-Fn übergibt,
@@ -322,7 +337,8 @@ export function RenderEdit<TValues extends FormValues, TCtx = unknown>(
322
337
  key={section.title}
323
338
  section={section}
324
339
  entityName={vm.entityName}
325
- entityId={vm.id}
340
+ entityId={entityIdProp !== undefined ? entityIdProp : vm.id}
341
+ initialValues={extensionInitialValues}
326
342
  />
327
343
  );
328
344
  }