@declarion/react 0.38.5 → 0.40.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-lib/{DraggableChildrenTable-DvJO6-m0.js → DraggableChildrenTable-Ctmn0liO.js} +27 -27
- package/dist-lib/{Grid-D2ArPFCz.js → Grid-BsIkTp3u.js} +42 -42
- package/dist-lib/{LayoutRenderer-C8DQ61Vo.js → LayoutRenderer-D4oTfZhV.js} +833 -731
- package/dist-lib/{MarkdownRenderer-CSuODN70.js → MarkdownRenderer-B-2CrtjU.js} +1 -1
- package/dist-lib/{RefreshControl-CHvOUn0o.js → RefreshControl-VQf34HKZ.js} +302 -220
- package/dist-lib/SmartDetailPage.impl-HMaLVDlV.js +1802 -0
- package/dist-lib/SmartRecordListPage.impl-Cxm7qvlZ.js +763 -0
- package/dist-lib/api/params.d.ts +12 -11
- package/dist-lib/components/columns/ColumnPicker.d.ts +11 -1
- package/dist-lib/components/detail-layout/EvidenceBlock.d.ts +6 -0
- package/dist-lib/components/detail-layout/useManualColumnResize.d.ts +25 -0
- package/dist-lib/components/list/QuickPeek.d.ts +11 -2
- package/dist-lib/components/pages/list/{ListBulkBar.d.ts → ListFloatbar.d.ts} +3 -3
- package/dist-lib/components/pages/list/RowActionsCell.d.ts +8 -10
- package/dist-lib/components/pages/list/RowContextMenu.d.ts +29 -0
- package/dist-lib/components/pages/list/SaveViewDialog.d.ts +5 -1
- package/dist-lib/components/pages/list/cardProjection.d.ts +1 -1
- package/dist-lib/components/pages/list/column-sizing.d.ts +15 -0
- package/dist-lib/components/pages/list/columns.d.ts +3 -0
- package/dist-lib/components/pages/list/useHeaderReorder.d.ts +26 -0
- package/dist-lib/components/pages/list/useRowMenu.d.ts +47 -0
- package/dist-lib/components/pages/profile/Profile.d.ts +3 -0
- package/dist-lib/components/pages/tenant-params/TenantParamsPage.d.ts +2 -0
- package/dist-lib/components/params/ParamsBlock.d.ts +25 -0
- package/dist-lib/components/params/param-editors.d.ts +28 -0
- package/dist-lib/components/primitives/Dropdown.d.ts +10 -1
- package/dist-lib/components/shared/ActionButton.d.ts +1 -7
- package/dist-lib/components/shared/ActionDialog.d.ts +2 -2
- package/dist-lib/components/shared/ResponsiveActionBar.d.ts +45 -23
- package/dist-lib/declarion-react.css +1 -1
- package/dist-lib/hooks/useParams.d.ts +45 -1
- package/dist-lib/index.d.ts +0 -2
- package/dist-lib/index.js +3561 -2570
- package/dist-lib/lib/actions.d.ts +44 -3
- package/dist-lib/lib/evidence-verdict.d.ts +11 -0
- package/dist-lib/lib/rowClickGesture.d.ts +14 -0
- package/dist-lib/registry-DFtAh6zc.js +4991 -0
- package/dist-lib/stores/list-layout.d.ts +86 -0
- package/dist-lib/testing.js +27 -27
- package/dist-lib/types/api.d.ts +29 -1
- package/dist-lib/types/schema.d.ts +12 -0
- package/dist-lib/{useCurrentScreen-DD3KdlMj.js → useCurrentScreen-mw8TfE8q.js} +596 -382
- package/dist-lib/{useProperties-CliP5qvg.js → useProperties-gMdnhdhO.js} +117 -117
- package/dist-lib/{value-CNy3_xCA.js → value-t9ETvWIJ.js} +4 -4
- package/package.json +1 -1
- package/dist-lib/SmartDetailPage.impl-Cl306lX3.js +0 -1768
- package/dist-lib/SmartRecordListPage.impl-j8bhyL4e.js +0 -763
- package/dist-lib/components/list/RowMenu.d.ts +0 -23
- package/dist-lib/components/shared/ActionConfirmDialog.d.ts +0 -10
- package/dist-lib/registry-C3hbFTDQ.js +0 -5400
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-device list-table WIDTH store (plan 2026-07-18 "Adjustable table
|
|
3
|
+
* columns", rev 2). Holds ONE thing: column pixel widths, device-local in
|
|
4
|
+
* localStorage, per (tenant, user, SCREEN) by column id. Screen-keyed, so
|
|
5
|
+
* widening a column once holds across EVERY view of that screen on this device.
|
|
6
|
+
* Absent entry = the YAML default (`field.display.width ?? 150`), resolved by
|
|
7
|
+
* TanStack when `header.getSize()` reads `columnSizing[id] ?? columnDef.size`.
|
|
8
|
+
*
|
|
9
|
+
* Why widths are the ONLY thing here: order/visibility/sort/filters already
|
|
10
|
+
* live in the URL and are persisted per device per tab by the `tabs` store -
|
|
11
|
+
* that is the single source of truth for the logical layout (a second store
|
|
12
|
+
* mirroring them caused a cold-open seed to clobber `?sort`; removed in rev 2).
|
|
13
|
+
* Width is the one column setting that must NOT ride a shareable URL: it is
|
|
14
|
+
* physical fit (a width tuned for a 27"/4K monitor would corrupt the same view
|
|
15
|
+
* for a teammate on a laptop), so it is device-local and never in a saved view.
|
|
16
|
+
*
|
|
17
|
+
* This does NOT violate the "browser stores nothing" appearance-preferences
|
|
18
|
+
* rule (Decision 33, `preferences.ts`): that governs deployment BRANDING
|
|
19
|
+
* (theme/accent/density). Widths are device state of the same class as the
|
|
20
|
+
* `tabs` store, which already uses localStorage. Keying + persistence mirror
|
|
21
|
+
* `stores/tabs.ts`: a module-level (tenant,user) scope set via `setScope`, the
|
|
22
|
+
* whole snapshot under one key `declarion::${tenantId}::${userId}::listlayout`,
|
|
23
|
+
* hydrated on tenant switch. `childKey` callers pass a composite screenKey
|
|
24
|
+
* `${screenCode}::child::${childKey}`; the store is agnostic to it.
|
|
25
|
+
*/
|
|
26
|
+
/** Minimum resizable column width in px. Exported so the resize handler and
|
|
27
|
+
* the store's defensive clamp share ONE floor (no magic number). */
|
|
28
|
+
export declare const MIN_COL_WIDTH = 60;
|
|
29
|
+
/** Maximum resizable column width in px (a sane cap so a column can never
|
|
30
|
+
* become absurdly wide). Shared by the TanStack per-column `maxSize` and the
|
|
31
|
+
* store's defensive clamp. */
|
|
32
|
+
export declare const MAX_COL_WIDTH = 1200;
|
|
33
|
+
/** Snapshot schema version. A snapshot with a different `v` is discarded on
|
|
34
|
+
* read (future migrations plug in here). */
|
|
35
|
+
export declare const LIST_LAYOUT_VERSION = 2;
|
|
36
|
+
/** A screen's width overrides: colId -> pixel width. */
|
|
37
|
+
export type WidthMap = Record<string, number>;
|
|
38
|
+
interface LayoutSnapshot {
|
|
39
|
+
v: number;
|
|
40
|
+
/** screenKey -> (colId -> width). */
|
|
41
|
+
widths: Record<string, WidthMap>;
|
|
42
|
+
/** True once this user has resized any column on this device - gates the
|
|
43
|
+
* one-time "widths are personal per device" education toast. */
|
|
44
|
+
resizeEduShown?: boolean;
|
|
45
|
+
}
|
|
46
|
+
interface LayoutState extends LayoutSnapshot {
|
|
47
|
+
setScope: (tenantId: string | null, userId: string | null) => void;
|
|
48
|
+
hydrate: () => void;
|
|
49
|
+
/** Set one column's width (clamped). */
|
|
50
|
+
setWidth: (screenKey: string, colId: string, width: number) => void;
|
|
51
|
+
/** Merge a batch of column widths (clamped). */
|
|
52
|
+
setWidths: (screenKey: string, widths: WidthMap) => void;
|
|
53
|
+
/** Drop all width overrides for a screen (back to YAML defaults). Stored as
|
|
54
|
+
* an empty map, not a deleted key, so the reset propagates across tabs. */
|
|
55
|
+
resetWidths: (screenKey: string) => void;
|
|
56
|
+
/** Drop width entries for colIds no longer in the screen schema. */
|
|
57
|
+
prune: (screenKey: string, validColIds: string[]) => void;
|
|
58
|
+
/** Record that the one-time resize-education toast has been shown. */
|
|
59
|
+
markResizeEduShown: () => void;
|
|
60
|
+
}
|
|
61
|
+
/** Narrow an untrusted persisted snapshot (localStorage is hostile) to
|
|
62
|
+
* LayoutSnapshot, discarding anything malformed or of a foreign version. */
|
|
63
|
+
export declare function parseLayoutSnapshot(raw: string): LayoutSnapshot | null;
|
|
64
|
+
/**
|
|
65
|
+
* Merge an incoming cross-tab snapshot into the local one, last-writer-wins per
|
|
66
|
+
* screenKey (a screenKey present in `incoming` replaces the local value
|
|
67
|
+
* wholesale, so a prune / reset-to-`{}` / edit all propagate; screenKeys only
|
|
68
|
+
* the local tab touched survive).
|
|
69
|
+
*/
|
|
70
|
+
export declare function mergeSnapshot(local: LayoutSnapshot, incoming: LayoutSnapshot): LayoutSnapshot;
|
|
71
|
+
export declare const useListLayoutStore: import("zustand").UseBoundStore<import("zustand").StoreApi<LayoutState>>;
|
|
72
|
+
/** Subscribe to the window `storage` event for the layout key and merge an
|
|
73
|
+
* incoming snapshot (last-writer-wins per screenKey). Idempotent. */
|
|
74
|
+
export declare function startListLayoutCrossTabSync(): void;
|
|
75
|
+
export interface ScopedListLayout {
|
|
76
|
+
widths: WidthMap;
|
|
77
|
+
/** Whether the one-time resize-education toast has already been shown. */
|
|
78
|
+
resizeEduShown: boolean;
|
|
79
|
+
setWidth: (colId: string, width: number) => void;
|
|
80
|
+
setWidths: (widths: WidthMap) => void;
|
|
81
|
+
resetWidths: () => void;
|
|
82
|
+
prune: (validColIds: string[]) => void;
|
|
83
|
+
markResizeEduShown: () => void;
|
|
84
|
+
}
|
|
85
|
+
export declare function useListLayout(screenKey: string | null | undefined): ScopedListLayout;
|
|
86
|
+
export {};
|
package/dist-lib/testing.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Dt as e, Mt as t, Ot as n, Qn as r, bt as i, kt as a, r as o, t as s } from "./useCurrentScreen-mw8TfE8q.js";
|
|
2
2
|
import { useState as c } from "react";
|
|
3
3
|
import { MemoryRouter as l } from "react-router-dom";
|
|
4
4
|
import { QueryClient as u, QueryClientProvider as d } from "@tanstack/react-query";
|
|
@@ -85,11 +85,11 @@ function C(e) {
|
|
|
85
85
|
}
|
|
86
86
|
return e;
|
|
87
87
|
}
|
|
88
|
-
function w(
|
|
89
|
-
let
|
|
90
|
-
|
|
91
|
-
let
|
|
92
|
-
return
|
|
88
|
+
function w(t) {
|
|
89
|
+
let r = t.entityData ?? {};
|
|
90
|
+
a((e, t) => {
|
|
91
|
+
let n = r[e], i = C(n), a = i.meta?.per_page ?? 50, o = i.meta?.total ?? i.rows.length;
|
|
92
|
+
return t.count === "only" ? {
|
|
93
93
|
data: [],
|
|
94
94
|
meta: {
|
|
95
95
|
page: 1,
|
|
@@ -108,50 +108,50 @@ function w(e) {
|
|
|
108
108
|
...i.refs === void 0 ? {} : { $refs: i.refs }
|
|
109
109
|
};
|
|
110
110
|
});
|
|
111
|
-
let o =
|
|
112
|
-
|
|
113
|
-
let
|
|
114
|
-
if (
|
|
115
|
-
if (
|
|
116
|
-
let a = o[e]?.[
|
|
111
|
+
let o = t.entityItems ?? {}, s = t.entityItemResponses ?? {};
|
|
112
|
+
n((e, t) => {
|
|
113
|
+
let n = typeof t == "string" ? t : i(t), r = s[e]?.[n];
|
|
114
|
+
if (r instanceof Error) throw r;
|
|
115
|
+
if (r !== void 0) return r;
|
|
116
|
+
let a = o[e]?.[n];
|
|
117
117
|
if (a instanceof Error) throw a;
|
|
118
118
|
return { data: a };
|
|
119
119
|
});
|
|
120
|
-
let c =
|
|
121
|
-
|
|
120
|
+
let c = t.actionResults ?? {};
|
|
121
|
+
e(async (e, t) => {
|
|
122
122
|
if (!(e in c)) throw Error(`renderWithDeclarion: no action result registered for "${e}" (seed it via actionResults)`);
|
|
123
123
|
let n = c[e];
|
|
124
124
|
return x(typeof n == "function" ? await n(t) : n);
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
127
|
function T() {
|
|
128
|
-
|
|
128
|
+
a(null), n(null), e(null), t.setState({
|
|
129
129
|
user: null,
|
|
130
130
|
isAuthenticated: !1,
|
|
131
131
|
activeTenant: null,
|
|
132
132
|
tenants: []
|
|
133
133
|
});
|
|
134
134
|
}
|
|
135
|
-
function E(
|
|
136
|
-
let
|
|
135
|
+
function E(e, t = {}) {
|
|
136
|
+
let n = new u({ defaultOptions: { queries: {
|
|
137
137
|
retry: !1,
|
|
138
138
|
gcTime: Infinity
|
|
139
139
|
} } });
|
|
140
|
-
S(),
|
|
141
|
-
let i =
|
|
142
|
-
code:
|
|
143
|
-
children:
|
|
144
|
-
}) :
|
|
145
|
-
client:
|
|
140
|
+
S(), n.setQueryData(["schema", !0], t.schema ?? g()), w(t);
|
|
141
|
+
let i = t.screenCode ? /* @__PURE__ */ p(s, {
|
|
142
|
+
code: t.screenCode,
|
|
143
|
+
children: e
|
|
144
|
+
}) : e, a = /* @__PURE__ */ m(d, {
|
|
145
|
+
client: n,
|
|
146
146
|
children: [/* @__PURE__ */ p(l, {
|
|
147
|
-
initialEntries: [
|
|
147
|
+
initialEntries: [t.route ?? "/"],
|
|
148
148
|
children: /* @__PURE__ */ p(o, { children: i })
|
|
149
149
|
}), /* @__PURE__ */ p(f, {})]
|
|
150
|
-
}), c = h(
|
|
151
|
-
viewportOverride:
|
|
150
|
+
}), c = h(t.viewport ? /* @__PURE__ */ p(r, {
|
|
151
|
+
viewportOverride: t.viewport,
|
|
152
152
|
children: a
|
|
153
153
|
}) : a);
|
|
154
|
-
return Object.assign(c, { queryClient:
|
|
154
|
+
return Object.assign(c, { queryClient: n });
|
|
155
155
|
}
|
|
156
156
|
function D({ children: e, authenticated: n = !0, ...r }) {
|
|
157
157
|
let [i] = c(() => {
|
package/dist-lib/types/api.d.ts
CHANGED
|
@@ -355,7 +355,12 @@ export interface ParamLookup {
|
|
|
355
355
|
source?: "object" | "user" | "role" | "tenant" | "env" | "yaml";
|
|
356
356
|
type?: string;
|
|
357
357
|
}
|
|
358
|
-
/**
|
|
358
|
+
/**
|
|
359
|
+
* One entry of the bulk `GET /api/params` response (and per-code resolution).
|
|
360
|
+
* Carries the declaration facets the admin UIs need to compute attachment,
|
|
361
|
+
* render structure editors, and render choice selects, so the bulk endpoint is
|
|
362
|
+
* self-sufficient without a second schema fetch.
|
|
363
|
+
*/
|
|
359
364
|
export interface ResolvedParam {
|
|
360
365
|
code: string;
|
|
361
366
|
name: LocalizedString;
|
|
@@ -364,6 +369,12 @@ export interface ResolvedParam {
|
|
|
364
369
|
description?: LocalizedString;
|
|
365
370
|
value: unknown;
|
|
366
371
|
source: "object" | "user" | "role" | "tenant" | "env" | "yaml" | "none";
|
|
372
|
+
/** Override levels the param accepts (reserved words or entity codes). */
|
|
373
|
+
scopes?: string[];
|
|
374
|
+
/** Structure code when `type === "structure"`. */
|
|
375
|
+
structure?: string;
|
|
376
|
+
/** Closed value set for a choices-constrained string param. */
|
|
377
|
+
choices?: string[];
|
|
367
378
|
}
|
|
368
379
|
export interface ParamOverride {
|
|
369
380
|
param_code: string;
|
|
@@ -449,6 +460,22 @@ export interface V2PropertyInstance {
|
|
|
449
460
|
updated_by?: string;
|
|
450
461
|
}
|
|
451
462
|
/** Per-row parameter override. */
|
|
463
|
+
/**
|
|
464
|
+
* The last verification verdict of an evidence-covered row, shipped under the
|
|
465
|
+
* row's `$evidence` key (the evidence satellite, mirroring `$statuses`). Read
|
|
466
|
+
* cheaply from the stored verification result - never a live re-verify. Mirrors
|
|
467
|
+
* the Go `evidence.RowVerdict`. `verdict` is one of: `verified`, `unverified`,
|
|
468
|
+
* `tampered`, `erased`, `indeterminate`, `outside_coverage`.
|
|
469
|
+
*/
|
|
470
|
+
export interface EvidenceVerdict {
|
|
471
|
+
verdict: string;
|
|
472
|
+
verified_at?: string;
|
|
473
|
+
reason?: string;
|
|
474
|
+
seq?: number;
|
|
475
|
+
generation?: number;
|
|
476
|
+
checkpoint_number?: number;
|
|
477
|
+
covered: boolean;
|
|
478
|
+
}
|
|
452
479
|
export interface V2ParamInstance {
|
|
453
480
|
param_code: string;
|
|
454
481
|
value: unknown;
|
|
@@ -498,4 +525,5 @@ export interface EnrichedRow extends RowData {
|
|
|
498
525
|
$params?: V2ParamInstance[];
|
|
499
526
|
$children?: Record<string, Record<string, unknown>[]>;
|
|
500
527
|
$units?: Units;
|
|
528
|
+
$evidence?: EvidenceVerdict;
|
|
501
529
|
}
|
|
@@ -360,6 +360,11 @@ export interface Entity {
|
|
|
360
360
|
tenant_key?: string;
|
|
361
361
|
children?: ChildRelation[];
|
|
362
362
|
status_groups?: Record<string, StatusGroupDef>;
|
|
363
|
+
/** Computed by the server: this entity's rows are evidence-covered (an
|
|
364
|
+
* `evidence:` block, or an audit table the core audit source covers). Drives
|
|
365
|
+
* the evidence panel / `?expand=evidence` the same way `status_groups` drives
|
|
366
|
+
* the statuses surface. Absent for uncovered entities. */
|
|
367
|
+
evidence_covered?: boolean;
|
|
363
368
|
properties?: Record<string, PropertyDef>;
|
|
364
369
|
search_fields?: string[];
|
|
365
370
|
actions?: Record<string, Action>;
|
|
@@ -377,6 +382,10 @@ export interface Entity {
|
|
|
377
382
|
* routes a singleton entity's detail screen at the screen's declared
|
|
378
383
|
* `route:` without a `:id` segment, and skips list-route registration. */
|
|
379
384
|
singleton?: boolean;
|
|
385
|
+
/** Carrier scope its `$params` writes land under (e.g. my_tenant -> "tenant",
|
|
386
|
+
* profile -> "user"). Absent = writes land under the entity's own code. Used
|
|
387
|
+
* by ParamsBlock to compute the attachable parameter set. */
|
|
388
|
+
params_scope?: string;
|
|
380
389
|
/** Server-enforced WHERE applied unconditionally on every read/write
|
|
381
390
|
* via server/handlers/data_prefilter.go. Values may be literal scalars
|
|
382
391
|
* OR `$caller.*` expressions (`$caller.user_id`, `$caller.tenant_id`)
|
|
@@ -759,6 +768,9 @@ export interface HandlerParam {
|
|
|
759
768
|
description?: LocalizedString;
|
|
760
769
|
color?: string;
|
|
761
770
|
}>;
|
|
771
|
+
/** `type: structure` (or structure-shaped json) param target: the top-level
|
|
772
|
+
* structure code whose fields the dialog renders as a nested form. */
|
|
773
|
+
structure?: string;
|
|
762
774
|
/** `type: ref` param target. Scalar entity-code string (shorthand) OR a
|
|
763
775
|
* structured RefConfig (non-id lookup / display). Normalize via
|
|
764
776
|
* normalizeRefConfig before use. */
|