@cosmicdrift/kumiko-types 0.332.0 → 0.334.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/dist/config.d.ts +8 -4
- package/dist/extension-options-map.d.ts +2 -2
- package/dist/fields.d.ts +28 -4
- package/dist/fields.js +8 -0
- package/dist/screen.d.ts +157 -3
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { ZodType } from "zod";
|
|
|
2
2
|
import type { ConcurrencyMode } from "./concurrency-mode.js";
|
|
3
3
|
import type { ConfigScope } from "./config-scope.js";
|
|
4
4
|
import type { DbConnection } from "./db-connection.js";
|
|
5
|
-
import type { FieldDefinition } from "./fields.js";
|
|
5
|
+
import type { FieldDefinition, OptionsQueryPayload } from "./fields.js";
|
|
6
6
|
import type { EscapeHatchDeclaration, JobContext } from "./handlers.js";
|
|
7
7
|
import type { PostDeleteHookFn, PostSaveHookFn, PreDeleteHookFn, PreQueryHookFn, PreSaveHookFn } from "./hooks.js";
|
|
8
8
|
import type { TenantId } from "./identifiers.js";
|
|
@@ -46,12 +46,14 @@ export type ConfigKeyDefinition<T extends ConfigKeyType = ConfigKeyType> = {
|
|
|
46
46
|
readonly piiEncrypted?: boolean;
|
|
47
47
|
readonly options?: readonly string[];
|
|
48
48
|
/** Only on `type: "select"`: loads the options from this query (QN), contract
|
|
49
|
-
* `{ rows: { value, label }[] }`, labels shown verbatim. Mutually exclusive with
|
|
49
|
+
* `{ rows: { value, label, description?, group? }[] }`, labels shown verbatim. Mutually exclusive with
|
|
50
50
|
* `options` and `allowPerRequest`. The write side does not check the value against
|
|
51
51
|
* the query result; the consuming feature validates it where it uses it. */
|
|
52
52
|
readonly optionsQuery?: string;
|
|
53
|
-
/**
|
|
54
|
-
|
|
53
|
+
/** Payload sent with every `optionsQuery` call. Requires `optionsQuery`. `{ field }`
|
|
54
|
+
* names another config key (short name) of the owner feature, resolved on the
|
|
55
|
+
* generated settings screen. */
|
|
56
|
+
readonly optionsQueryPayload?: OptionsQueryPayload;
|
|
55
57
|
readonly bounds?: ConfigBounds;
|
|
56
58
|
readonly pattern?: {
|
|
57
59
|
readonly regex: string;
|
|
@@ -68,6 +70,8 @@ export type ConfigKeyDefinition<T extends ConfigKeyType = ConfigKeyType> = {
|
|
|
68
70
|
};
|
|
69
71
|
export type ConfigMask = {
|
|
70
72
|
readonly title: string;
|
|
73
|
+
/** i18n key for help text shown under the field label. */
|
|
74
|
+
readonly description?: string;
|
|
71
75
|
readonly icon?: NavIconKey;
|
|
72
76
|
readonly order?: number;
|
|
73
77
|
};
|
|
@@ -5,5 +5,5 @@ export interface KumikoExtensionOptionsMap {
|
|
|
5
5
|
export type ExtensionOptionsFor<N extends string> = N extends keyof KumikoExtensionOptionsMap ? KumikoExtensionOptionsMap[N] & {
|
|
6
6
|
readonly escapeHatch?: EscapeHatchDeclaration;
|
|
7
7
|
} : Record<string, unknown>;
|
|
8
|
-
/** Rest-tuple for useExtension's positional options arg: required for an augmented name, optional otherwise. */
|
|
9
|
-
export type ExtensionOptionsArgs<N extends string> = N extends keyof KumikoExtensionOptionsMap ? [options: ExtensionOptionsFor<N>] : [options?: Record<string, unknown>];
|
|
8
|
+
/** Rest-tuple for useExtension's positional options arg: required for an augmented name with required keys, optional otherwise. */
|
|
9
|
+
export type ExtensionOptionsArgs<N extends string> = N extends keyof KumikoExtensionOptionsMap ? Record<never, never> extends KumikoExtensionOptionsMap[N] ? [options?: ExtensionOptionsFor<N>] : [options: ExtensionOptionsFor<N>] : [options?: Record<string, unknown>];
|
package/dist/fields.d.ts
CHANGED
|
@@ -89,6 +89,18 @@ export type TextFieldDef = {
|
|
|
89
89
|
readonly filterable?: boolean;
|
|
90
90
|
readonly encrypted?: boolean;
|
|
91
91
|
readonly sensitive?: boolean;
|
|
92
|
+
/** Write-only secret (API key): the value is never returned to clients. Reads
|
|
93
|
+
* (list/detail/write responses) show `true` = set, `null` = empty. Writes:
|
|
94
|
+
* `""` or omitted = unchanged, `null` = clear, string = new value.
|
|
95
|
+
* Server-side: executor reads (detail/list in server handlers) and
|
|
96
|
+
* postSave/postQuery hooks see the plaintext; ctx.query, dispatcher.query,
|
|
97
|
+
* agent tools and `_refs` see true/null; ctx.db sees the ciphertext.
|
|
98
|
+
* Known limit: masking runs for entity-bound query handlers with array /
|
|
99
|
+
* {rows} / flat results; an unbound custom query handler that returns
|
|
100
|
+
* executor rows must call maskWriteOnlyFields itself (same scope limit as
|
|
101
|
+
* access.read). Requires `sensitive` (via `find: "secret"`); forbidden with
|
|
102
|
+
* default/searchable/sortable/filterable/lookupable and on screen/form fields. */
|
|
103
|
+
readonly writeOnly?: boolean;
|
|
92
104
|
/** A later run reads this field's value as an instruction — prompt, rule,
|
|
93
105
|
* template. Every create/update whose payload writes it requires agent.risk
|
|
94
106
|
* "high" on the directly-dispatched entry handler; a revert doesn't undo a
|
|
@@ -158,6 +170,16 @@ export type BooleanFieldDef = {
|
|
|
158
170
|
readonly access?: FieldAccess;
|
|
159
171
|
};
|
|
160
172
|
export type SelectOptionTone = "ok" | "warn" | "bad" | "neutral";
|
|
173
|
+
/** One `optionsQueryPayload` entry: a literal, or `{ field }` = the current value of
|
|
174
|
+
* a sibling field of the same form (config keys: another key of the owner feature). */
|
|
175
|
+
export type OptionsQueryPayloadValue = string | number | boolean | {
|
|
176
|
+
readonly field: string;
|
|
177
|
+
};
|
|
178
|
+
export type OptionsQueryPayload = Readonly<Record<string, OptionsQueryPayloadValue>>;
|
|
179
|
+
export declare function isOptionsQueryFieldRef(value: OptionsQueryPayloadValue): value is {
|
|
180
|
+
readonly field: string;
|
|
181
|
+
};
|
|
182
|
+
export declare function optionsQueryFieldRefs(payload: OptionsQueryPayload | undefined): string[];
|
|
161
183
|
export type SelectFieldDef<TOptions extends readonly string[] = readonly string[]> = {
|
|
162
184
|
readonly type: "select";
|
|
163
185
|
readonly description?: string;
|
|
@@ -180,13 +202,15 @@ export type SelectFieldDef<TOptions extends readonly string[] = readonly string[
|
|
|
180
202
|
readonly optionTones?: {
|
|
181
203
|
readonly [K in TOptions[number]]?: SelectOptionTone;
|
|
182
204
|
};
|
|
183
|
-
/** Loads the options from this query (QN). Contract:
|
|
184
|
-
*
|
|
205
|
+
/** Loads the options from this query (QN). Contract:
|
|
206
|
+
* `{ rows: { value, label, description?, group? }[] }`, labels are shown verbatim
|
|
207
|
+
* (not translated); description is a muted second line, group a heading. `options` must be empty when set.
|
|
185
208
|
* Only valid on configEdit/actionForm screen fields and config keys, not on entity
|
|
186
209
|
* fields: the stored value would not be checked against the query result. */
|
|
187
210
|
readonly optionsQuery?: string;
|
|
188
|
-
/**
|
|
189
|
-
|
|
211
|
+
/** Payload sent with every `optionsQuery` call. `{ field }` entries re-load the
|
|
212
|
+
* options when that sibling field changes. */
|
|
213
|
+
readonly optionsQueryPayload?: OptionsQueryPayload;
|
|
190
214
|
} & ResolvedPiiFlags;
|
|
191
215
|
export type MultiSelectFieldDef<TOptions extends readonly string[] = readonly string[]> = {
|
|
192
216
|
readonly type: "multiSelect";
|
package/dist/fields.js
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
// --- Field Types ---
|
|
2
|
+
export function isOptionsQueryFieldRef(value) {
|
|
3
|
+
return typeof value === "object" && value !== null;
|
|
4
|
+
}
|
|
5
|
+
export function optionsQueryFieldRefs(payload) {
|
|
6
|
+
return Object.values(payload ?? {})
|
|
7
|
+
.filter(isOptionsQueryFieldRef)
|
|
8
|
+
.map((ref) => ref.field);
|
|
9
|
+
}
|
|
2
10
|
/** Qualified config key a `{ kind: "tenant" }` MoneyCurrencySource resolves
|
|
3
11
|
* against — the tenant-settings bundle's per-tenant currency. Lives here
|
|
4
12
|
* (client-safe) rather than framework/engine so renderer code can read it
|
package/dist/screen.d.ts
CHANGED
|
@@ -147,6 +147,16 @@ export type RowFieldExtractor = {
|
|
|
147
147
|
} | {
|
|
148
148
|
readonly map: Readonly<Record<string, string>>;
|
|
149
149
|
};
|
|
150
|
+
/** How a row action renders inline in the row-action column. `"button"` is a
|
|
151
|
+
* bordered button (its colour follows the action's `style`), `"link"` a text
|
|
152
|
+
* link, `"icon"` an icon-only button (needs a resolved icon, falls back to
|
|
153
|
+
* `"link"` without one). Unset: the renderer decides (primary action as link,
|
|
154
|
+
* the rest in the kebab menu). */
|
|
155
|
+
export type RowActionDisplay = "button" | "link" | "icon";
|
|
156
|
+
/** Row-action column layout. `"adaptive"` (default): primary action as link,
|
|
157
|
+
* the rest in a kebab menu — except actions with an explicit `display`, which
|
|
158
|
+
* stay inline. `"inline"`: every action inline, no kebab. */
|
|
159
|
+
export type RowActionMode = "adaptive" | "inline";
|
|
150
160
|
export type RowAction = RowActionWriteHandler | RowActionNavigate | RowActionDrawer;
|
|
151
161
|
export type RowActionWriteHandler = {
|
|
152
162
|
/** Default für RowActions ohne explizit gesetzten `kind` —
|
|
@@ -182,6 +192,8 @@ export type RowActionWriteHandler = {
|
|
|
182
192
|
* kumiko-renderer) — closed IconKey vocabulary into the ICONS registry
|
|
183
193
|
* (renderer-web), analogous to EditFieldSpec.icon. */
|
|
184
194
|
readonly icon?: IconKey;
|
|
195
|
+
/** Inline render form in the row-action column — see `RowActionDisplay`. */
|
|
196
|
+
readonly display?: RowActionDisplay;
|
|
185
197
|
};
|
|
186
198
|
export type RowActionNavigateBase = {
|
|
187
199
|
readonly kind: "navigate";
|
|
@@ -216,6 +228,8 @@ export type RowActionNavigateBase = {
|
|
|
216
228
|
* kumiko-renderer) — closed IconKey vocabulary into the ICONS registry
|
|
217
229
|
* (renderer-web), analogous to EditFieldSpec.icon. */
|
|
218
230
|
readonly icon?: IconKey;
|
|
231
|
+
/** Inline render form in the row-action column — see `RowActionDisplay`. */
|
|
232
|
+
readonly display?: RowActionDisplay;
|
|
219
233
|
};
|
|
220
234
|
/** Exactly one of `screen` / `entity` — mutual exclusivity is type-enforced
|
|
221
235
|
* (boot validator still rejects both/neither for untyped schemas). */
|
|
@@ -252,6 +266,15 @@ export type RowActionDrawer = {
|
|
|
252
266
|
* kumiko-renderer) — closed IconKey vocabulary into the ICONS registry
|
|
253
267
|
* (renderer-web), analogous to EditFieldSpec.icon. */
|
|
254
268
|
readonly icon?: IconKey;
|
|
269
|
+
/** Inline render form in the row-action column — see `RowActionDisplay`. */
|
|
270
|
+
readonly display?: RowActionDisplay;
|
|
271
|
+
/** Drawer heading (i18n key) instead of the action `label`. `{name}`
|
|
272
|
+
* placeholders resolve from the drawer prefill (`params`), formatted for
|
|
273
|
+
* display like `ActionFormScreenDefinition.summary`. */
|
|
274
|
+
readonly title?: string;
|
|
275
|
+
/** Line under the drawer heading (i18n key or a bare `{name}` template),
|
|
276
|
+
* resolved like `title`. */
|
|
277
|
+
readonly subtitle?: string;
|
|
255
278
|
};
|
|
256
279
|
export type ToolbarAction = {
|
|
257
280
|
readonly kind: "navigate";
|
|
@@ -294,6 +317,10 @@ export type ToolbarAction = {
|
|
|
294
317
|
* not force a confirm dialog here: the target form is the
|
|
295
318
|
* confirmation. */
|
|
296
319
|
readonly style?: "primary" | "secondary" | "danger";
|
|
320
|
+
/** Drawer heading (i18n key) instead of `label`. */
|
|
321
|
+
readonly title?: string;
|
|
322
|
+
/** Line under the drawer heading (i18n key). */
|
|
323
|
+
readonly subtitle?: string;
|
|
297
324
|
};
|
|
298
325
|
export type RelatedListToolbarAction = (Extract<ToolbarAction, {
|
|
299
326
|
readonly kind: "navigate";
|
|
@@ -319,6 +346,31 @@ export type RelatedListToolbarAction = (Extract<ToolbarAction, {
|
|
|
319
346
|
* layout and are therefore omitted. `kind` stays the discriminator so further
|
|
320
347
|
* expansion kinds can be added without a breaking change. */
|
|
321
348
|
export type EntityListExpandableRow = Omit<EditRelatedListSection, "id" | "countField">;
|
|
349
|
+
/** An extra choice on a facet next to the field's own options: a named
|
|
350
|
+
* bundle of values ("Running" = several statuses) or "no filter" (`values:
|
|
351
|
+
* []`, e.g. "All"). Chips only. */
|
|
352
|
+
export type EntityListFacetExtraOption = {
|
|
353
|
+
readonly id: string;
|
|
354
|
+
/** i18n key. */
|
|
355
|
+
readonly label: string;
|
|
356
|
+
/** Option values this choice selects; `[]` selects nothing, i.e. no filter. */
|
|
357
|
+
readonly values: readonly string[];
|
|
358
|
+
/** Where the chip sits relative to the field's own options. Default "start". */
|
|
359
|
+
readonly position?: "start" | "end";
|
|
360
|
+
};
|
|
361
|
+
export type EntityListFacetConfig = {
|
|
362
|
+
/** `"select"` (default): dropdown with checkboxes. `"chips"`: one toggle
|
|
363
|
+
* chip per option, single choice. */
|
|
364
|
+
readonly display?: "select" | "chips";
|
|
365
|
+
/** Chips show how many rows each option matches (other facets and the
|
|
366
|
+
* search apply). Counts come from the list query itself, one `limit: 1`
|
|
367
|
+
* count request per chip. */
|
|
368
|
+
readonly showCounts?: boolean;
|
|
369
|
+
/** Chips with zero matching rows are not shown. Needs counts; implies
|
|
370
|
+
* `showCounts`'s requests even when the number itself is not shown. */
|
|
371
|
+
readonly hideEmpty?: boolean;
|
|
372
|
+
readonly extraOptions?: readonly EntityListFacetExtraOption[];
|
|
373
|
+
};
|
|
322
374
|
export type EntityListScreenDefinition = {
|
|
323
375
|
readonly id: string;
|
|
324
376
|
readonly type: "entityList";
|
|
@@ -340,10 +392,13 @@ export type EntityListScreenDefinition = {
|
|
|
340
392
|
readonly columns: readonly ListColumnSpec[];
|
|
341
393
|
readonly rowRenderer?: PlatformComponent;
|
|
342
394
|
readonly cardRenderer?: PlatformComponent;
|
|
343
|
-
/** Per-
|
|
344
|
-
*
|
|
345
|
-
*
|
|
395
|
+
/** Per-row actions, rendered as an actions column on the right.
|
|
396
|
+
* Adaptive (default, see `rowActionMode`): the primary action as a link,
|
|
397
|
+
* the rest in the kebab menu; actions with an explicit `display` stay
|
|
398
|
+
* inline. Array order is UI order. */
|
|
346
399
|
readonly rowActions?: readonly RowAction[];
|
|
400
|
+
/** Layout of the row-action column — see `RowActionMode`. */
|
|
401
|
+
readonly rowActionMode?: RowActionMode;
|
|
347
402
|
/** Toolbar-Aktionen (List-Header). "Open Incident", "Schedule Maintenance"
|
|
348
403
|
* etc. — neben "+ Neu" wenn vorhanden. Reihenfolge im Array = UI-
|
|
349
404
|
* Reihenfolge, primary-style links. */
|
|
@@ -361,6 +416,17 @@ export type EntityListScreenDefinition = {
|
|
|
361
416
|
readonly pagination?: ListPaginationMode;
|
|
362
417
|
readonly pageSize?: number;
|
|
363
418
|
readonly defaultSort?: ListSortSpec;
|
|
419
|
+
/** Initial facet selection, per filterable field: option values (string
|
|
420
|
+
* facets) or a boolean. Applies only while the URL carries no value for
|
|
421
|
+
* that field, so a link or the user's own choice wins; picking "no filter"
|
|
422
|
+
* (an `extraOptions` entry with `values: []`, or clearing the facet) is
|
|
423
|
+
* remembered in the URL and is not overridden again. */
|
|
424
|
+
readonly defaultFilters?: Readonly<Record<string, readonly string[] | boolean>>;
|
|
425
|
+
/** Per-facet display options for the entity's `filterable` fields, keyed by
|
|
426
|
+
* field name. `false` hides the facet's control (its filter stays usable
|
|
427
|
+
* through `defaultFilters` and the URL). Fields without an entry keep the
|
|
428
|
+
* default dropdown. */
|
|
429
|
+
readonly facets?: Readonly<Record<string, EntityListFacetConfig | false>>;
|
|
364
430
|
/** i18n key for the primary create button label (default `kumiko.actions.create`). */
|
|
365
431
|
readonly createLabel?: string;
|
|
366
432
|
/** i18n key for the search field placeholder (default `kumiko.list.search-placeholder`). */
|
|
@@ -430,6 +496,8 @@ export type ProjectionListScreenDefinition = {
|
|
|
430
496
|
readonly rowRenderer?: PlatformComponent;
|
|
431
497
|
readonly cardRenderer?: PlatformComponent;
|
|
432
498
|
readonly rowActions?: readonly RowAction[];
|
|
499
|
+
/** Layout of the row-action column — see `RowActionMode`. */
|
|
500
|
+
readonly rowActionMode?: RowActionMode;
|
|
433
501
|
readonly toolbarActions?: readonly ToolbarAction[];
|
|
434
502
|
readonly pagination?: ListPaginationMode;
|
|
435
503
|
readonly pageSize?: number;
|
|
@@ -667,6 +735,11 @@ export type DashboardScreenPanel = {
|
|
|
667
735
|
readonly screen: string;
|
|
668
736
|
readonly label?: string;
|
|
669
737
|
readonly visibleWhen?: DashboardPanelVisibility;
|
|
738
|
+
/** Render the embedded form without its own card frame and padding, aligned to
|
|
739
|
+
* the dashboard's page grid like a standalone settings screen. Default false
|
|
740
|
+
* (framed card); set for panels whose body is a settings-list form, where a
|
|
741
|
+
* card inside the page would double the inset. */
|
|
742
|
+
readonly chromeless?: boolean;
|
|
670
743
|
};
|
|
671
744
|
export type DashboardPanelDefinition = DashboardStatPanel | DashboardStatGroupPanel | DashboardChartPanel | DashboardListPanel | DashboardFeedPanel | DashboardProgressListPanel | DashboardCustomPanel | DashboardScreenPanel;
|
|
672
745
|
export type DashboardFilterDefinition = {
|
|
@@ -713,6 +786,10 @@ export type DashboardScreenDefinition = {
|
|
|
713
786
|
readonly timeRange?: DashboardTimeRangeDefinition;
|
|
714
787
|
/** Marks the screen as spanning more than the caller's own scope. */
|
|
715
788
|
readonly scope?: DashboardScopeDefinition;
|
|
789
|
+
/** Show the "Updated at" timestamp in the toolbar. Default true; turn off for
|
|
790
|
+
* dashboards that host forms rather than live metrics, where a load time
|
|
791
|
+
* next to the form reads as stale data. */
|
|
792
|
+
readonly showUpdatedAt?: boolean;
|
|
716
793
|
readonly slots?: ScreenSlots;
|
|
717
794
|
readonly access?: AccessRule;
|
|
718
795
|
};
|
|
@@ -723,6 +800,11 @@ export type EditFieldSpec = string | {
|
|
|
723
800
|
readonly readOnly?: FieldCondition;
|
|
724
801
|
readonly required?: FieldCondition;
|
|
725
802
|
readonly renderer?: FieldRenderer;
|
|
803
|
+
/** `false` keeps the field out of the submitted payload — for values
|
|
804
|
+
* that are shown or prefilled for display only (a label, a counter)
|
|
805
|
+
* and that the write handler's schema does not accept. Validation and
|
|
806
|
+
* rendering are unchanged. */
|
|
807
|
+
readonly submit?: false;
|
|
726
808
|
/** Prefix icon on the input — closed FieldIconKey vocabulary into
|
|
727
809
|
* the FIELD_ICONS registry (renderer-web), analogous to
|
|
728
810
|
* `ScreenNavSugar.icon` / NavIconKey. Only takes effect for
|
|
@@ -780,6 +862,10 @@ export type EditFieldsSection = {
|
|
|
780
862
|
* Ignored outside tabs mode or when the field's value is not a finite
|
|
781
863
|
* number. */
|
|
782
864
|
readonly countField?: string;
|
|
865
|
+
/** Short line (i18n key) under this step's title in the wizard step rail
|
|
866
|
+
* and in the "up next" box. Wizard layouts only; unlike `description` it
|
|
867
|
+
* is not shown inside the step. */
|
|
868
|
+
readonly subtitle?: string;
|
|
783
869
|
/** Rendered top-right in the section's Card title row — same
|
|
784
870
|
* navigate/drawer/writeHandler dispatch as `ProjectionDetailScreenDefinition.actions`,
|
|
785
871
|
* evaluated against the same record. Every action must resolve an icon
|
|
@@ -816,6 +902,26 @@ export type EditExtensionSection = {
|
|
|
816
902
|
* (declared or id-derived); the boot-validator rejects one that doesn't. */
|
|
817
903
|
readonly actions?: readonly RowAction[];
|
|
818
904
|
};
|
|
905
|
+
/** Rows are grouped by `field` in order of first appearance. Every group gets
|
|
906
|
+
* a collapsible header. */
|
|
907
|
+
export type RelatedListGroupBy = {
|
|
908
|
+
readonly field: string;
|
|
909
|
+
/** Groups whose field value equals this start collapsed; the others start open. */
|
|
910
|
+
readonly collapsedWhen?: string | number | boolean | null;
|
|
911
|
+
/** i18n key of the group header. Placeholders: `{count}` rows in the group,
|
|
912
|
+
* `{value}` the group's field value, `{lastDate}` the group's latest
|
|
913
|
+
* `dateField` value as a locale date. */
|
|
914
|
+
readonly label: string;
|
|
915
|
+
/** Header i18n key per group value (as string), overriding `label`. */
|
|
916
|
+
readonly labels?: Readonly<Record<string, string>>;
|
|
917
|
+
/** Row field (ISO date or timestamp) behind `{lastDate}`. */
|
|
918
|
+
readonly dateField?: string;
|
|
919
|
+
};
|
|
920
|
+
/** Row tint rule: rows where the `FieldCondition` (`{ field, eq }`, `{ field,
|
|
921
|
+
* in }` …) holds get the tone. `bad` renders red. */
|
|
922
|
+
export type RelatedListRowTone = Exclude<FieldCondition, boolean> & {
|
|
923
|
+
readonly tone: SelectOptionTone;
|
|
924
|
+
};
|
|
819
925
|
export type EditRelatedListSection = {
|
|
820
926
|
/** Kebab-case tab id, used as the `?tab=` value. Required by the
|
|
821
927
|
* boot-validator when the enclosing `EditLayout.mode` is "tabs". */
|
|
@@ -885,6 +991,13 @@ export type EditRelatedListSection = {
|
|
|
885
991
|
* writeHandler action re-runs this section's own query, same as a
|
|
886
992
|
* projectionList row action re-running its list query. */
|
|
887
993
|
readonly rowActions?: readonly RowAction[];
|
|
994
|
+
/** Layout of the row-action column — see `RowActionMode`. */
|
|
995
|
+
readonly rowActionMode?: RowActionMode;
|
|
996
|
+
/** Groups rows by the value of a field under collapsible group headers. */
|
|
997
|
+
readonly groupBy?: RelatedListGroupBy;
|
|
998
|
+
/** Tints rows whose field matches — a declarative rule, not a function, so
|
|
999
|
+
* the screen definition stays serializable. */
|
|
1000
|
+
readonly rowTone?: RelatedListRowTone;
|
|
888
1001
|
/** Toolbar actions above the table — same type and dispatch semantics as
|
|
889
1002
|
* `entityList`/`projectionList`'s `toolbarActions` ("+ Anlegen" etc.),
|
|
890
1003
|
* plus `visible`/`params` evaluated against the parent record (see
|
|
@@ -958,9 +1071,23 @@ export type EditLayout = {
|
|
|
958
1071
|
* boot-validator rejects it on entityEdit, see the check for the reason);
|
|
959
1072
|
* requires >= 2 sections, each with a title and an `id`. */
|
|
960
1073
|
readonly mode?: "single" | "wizard" | "tabs";
|
|
1074
|
+
/** "settings-list" lays each section out as a band with a title column on
|
|
1075
|
+
* the left and one hairline-separated row per field (label + help left,
|
|
1076
|
+
* control right) — the familiar settings pattern, for screens that are a
|
|
1077
|
+
* list of independent preferences rather than one record form. Default
|
|
1078
|
+
* "form" keeps the grid of cells. */
|
|
1079
|
+
readonly variant?: "form" | "settings-list";
|
|
961
1080
|
/** Persists in-progress wizard state as a resumable draft instead of
|
|
962
1081
|
* discarding it on navigation away. */
|
|
963
1082
|
readonly draft?: boolean;
|
|
1083
|
+
/** Wizard layouts only. `upNext: true` adds an "up next" box to the step
|
|
1084
|
+
* rail with the following step's title and `subtitle`; the last step
|
|
1085
|
+
* shows none. */
|
|
1086
|
+
readonly wizard?: {
|
|
1087
|
+
readonly aside?: {
|
|
1088
|
+
readonly upNext: true;
|
|
1089
|
+
};
|
|
1090
|
+
};
|
|
964
1091
|
};
|
|
965
1092
|
export type EntityEditScreenDefinition = {
|
|
966
1093
|
readonly id: string;
|
|
@@ -984,6 +1111,11 @@ export type EntityEditScreenDefinition = {
|
|
|
984
1111
|
readonly entity: string;
|
|
985
1112
|
/** Entity field whose value names the loaded record in the header breadcrumb (edit mode only). */
|
|
986
1113
|
readonly recordTitleField?: string;
|
|
1114
|
+
/** Screen title (i18n key) with `{field}` placeholders filled from the
|
|
1115
|
+
* current form values, so the title follows what the user types (create
|
|
1116
|
+
* wizard: "Add {make} {model}"). Falls back to the plain title while the
|
|
1117
|
+
* placeholders are still empty. */
|
|
1118
|
+
readonly titleTemplate?: string;
|
|
987
1119
|
readonly layout: EditLayout;
|
|
988
1120
|
/** Optionaler i18n-Key (oder Roh-String) für den Submit-Button. Default
|
|
989
1121
|
* `kumiko.actions.save`. Lässt den Auto-Edit-Screen domain-spezifische
|
|
@@ -1085,6 +1217,12 @@ export type ActionFormScreenDefinition = {
|
|
|
1085
1217
|
/** i18n-key für den Submit-Button. Default: i18n-Default des
|
|
1086
1218
|
* Renderers (typischerweise "actions.submit"). */
|
|
1087
1219
|
readonly submitLabel?: string;
|
|
1220
|
+
/** Extra buttons in the form footer next to the submit button. A click
|
|
1221
|
+
* applies `patch` to the form values, then submits the form (same
|
|
1222
|
+
* validation, same handler) — e.g. a "Mark as posted" button that sets
|
|
1223
|
+
* `posted: true`. The patched field need not be rendered by the layout.
|
|
1224
|
+
* Order in the array = order in the footer, before the submit button. */
|
|
1225
|
+
readonly footerActions?: readonly ActionFormFooterAction[];
|
|
1088
1226
|
/** Context box above the fields (i18n keys). `{name}` placeholders resolve from the
|
|
1089
1227
|
* drawer prefill (`params` of the opening row action), formatted for display. */
|
|
1090
1228
|
readonly summary?: {
|
|
@@ -1131,6 +1269,17 @@ export type ActionFormScreenDefinition = {
|
|
|
1131
1269
|
readonly slots?: ScreenSlots;
|
|
1132
1270
|
readonly access?: AccessRule;
|
|
1133
1271
|
};
|
|
1272
|
+
export type ActionFormFooterAction = {
|
|
1273
|
+
/** Stable id (kebab-case), used for the test id. */
|
|
1274
|
+
readonly id: string;
|
|
1275
|
+
/** i18n key. */
|
|
1276
|
+
readonly label: string;
|
|
1277
|
+
readonly icon?: IconKey;
|
|
1278
|
+
/** Button style. Default "secondary". */
|
|
1279
|
+
readonly variant?: "primary" | "secondary" | "danger";
|
|
1280
|
+
/** Form values set before the submit. JSON-safe literals only. */
|
|
1281
|
+
readonly patch: Readonly<Record<string, string | number | boolean | null>>;
|
|
1282
|
+
};
|
|
1134
1283
|
/** Redirect target plus the success-payload field carrying the navigation
|
|
1135
1284
|
* id. The write-handler reports the id of what it wrote (`data.id`); when
|
|
1136
1285
|
* that record is a child and the target screen shows its parent, the
|
|
@@ -1290,6 +1439,11 @@ export type ConfigEditScreenDefinition = {
|
|
|
1290
1439
|
* ohne es unter der `__config-edit__`-Konvention zu duplizieren.
|
|
1291
1440
|
* Fehlt ein Eintrag, gilt die Konvention. */
|
|
1292
1441
|
readonly fieldLabels?: Readonly<Record<string, string>>;
|
|
1442
|
+
/** Per-field help text i18n key (Field-Name → Key), from `mask.description`. */
|
|
1443
|
+
readonly fieldDescriptions?: Readonly<Record<string, string>>;
|
|
1444
|
+
/** Field names whose config key declares `required: true` — drives the
|
|
1445
|
+
* "Not set. Required." origin line, not form validation. */
|
|
1446
|
+
readonly requiredFields?: readonly string[];
|
|
1293
1447
|
/** i18n-key für den Submit-Button. Default: "kumiko.actions.save". */
|
|
1294
1448
|
readonly submitLabel?: string;
|
|
1295
1449
|
readonly slots?: ScreenSlots;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.334.0",
|
|
4
4
|
"description": "Framework-Type-Definitions für Kumiko — FeatureDefinition, BootCheck-Types und die reinen Engine-Types. Erlaubt Downstream-Konsumenten, gegen die Type-Contracts zu bauen, ohne das ganze Framework-Package zu importieren. Enthaelt keine identitaets-sensitiven Runtime-Werte mehr (Error-Klassen leben seit #1629 in kumiko-framework, Brand-Symbole nutzen Symbol.for) und ist deshalb eine plain dependency, keine peerDependency.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|