@declarion/react 0.23.0 → 0.24.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.
@@ -11,6 +11,25 @@ export interface FilterNode {
11
11
  }
12
12
  /** All supported filter operator codes. */
13
13
  export type FilterOp = "eq" | "not_eq" | "gt" | "gte" | "lt" | "lte" | "in" | "not_in" | "between" | "contains" | "starts_with" | "is_empty" | "is_not_empty" | "today" | "this_week" | "this_month" | "last_7_days" | "last_30_days" | "last_hour" | "last_24_hours";
14
+ /**
15
+ * Resolution status of one filter value, produced by the filter-value label
16
+ * resolver (`useFilterValueLabels`). `special` / `resolved` carry a `label`
17
+ * and are terminal-synchronous (no flicker); `loading` is a ref fetch in
18
+ * flight (render a skeleton, never the raw uuid); `unresolved` is a ref that
19
+ * could not be labeled (deleted / no access); `plain` is a literal/number/date
20
+ * (rendered raw, as before).
21
+ */
22
+ export type FilterValueStatus = "special" | "resolved" | "loading" | "unresolved" | "plain";
23
+ /** Resolver result for one `(field, value)`: a label when known, the raw
24
+ * coerced value always (the terminal fallback). */
25
+ export interface FilterValueLabel {
26
+ status: FilterValueStatus;
27
+ label?: string;
28
+ raw: string;
29
+ }
30
+ /** Maps one stored filter `(field, value)` to its human label. The single
31
+ * source of chip + drawer value labels; see `useFilterValueLabels`. */
32
+ export type FilterValueResolver = (field: string, value: unknown) => FilterValueLabel;
14
33
  /** Operators that don't take a value. */
15
34
  export declare const NO_VALUE_OPS: Set<FilterOp>;
16
35
  /** Human-friendly display names for operators. */
@@ -30,8 +49,17 @@ export declare function hasOrGroups(nodes: FilterNode[]): boolean;
30
49
  export declare function flatFieldConditions(nodes: FilterNode[]): FilterNode[];
31
50
  /** Count active field conditions in the filter tree. */
32
51
  export declare function countActiveFilters(nodes: FilterNode[]): number;
33
- /** Format a filter node for chip display. */
34
- export declare function formatFilterChip(node: FilterNode): string;
52
+ /**
53
+ * Format a filter node for chip display as a string (op label + value).
54
+ *
55
+ * When a `resolveValue` resolver is passed, each value is humanized to its
56
+ * label for the synchronous statuses (`special` / `resolved`) and falls back
57
+ * to the raw value otherwise. Without a resolver, values render raw exactly as
58
+ * before. This string form is used in OR-group joins and as a fallback; the
59
+ * single-chip renderer (`FilterChips`) uses a richer per-value renderer that
60
+ * also shows a skeleton while a ref label loads.
61
+ */
62
+ export declare function formatFilterChip(node: FilterNode, resolveValue?: FilterValueResolver): string;
35
63
  /** Create a simple equality filter node. */
36
64
  export declare function eqFilter(field: string, value: string): FilterNode;
37
65
  /** Remove a filter node by field name, recursing into OR/AND groups. */
@@ -1,4 +1,4 @@
1
- import { Pt as e, ct as t, lt as n, t as r, tt as i, ut as a } from "./ActionRunner-C2A73D9b.js";
1
+ import { It as e, dt as t, ft as n, rt as r, t as i, ut as a } from "./ActionRunner-eixtbT5K.js";
2
2
  import { useState as o } from "react";
3
3
  import { MemoryRouter as s } from "react-router-dom";
4
4
  import { QueryClient as c, QueryClientProvider as l } from "@tanstack/react-query";
@@ -86,42 +86,42 @@ function x(e) {
86
86
  return e;
87
87
  }
88
88
  function S(e) {
89
- let r = e.entityData ?? {};
90
- a((e, t) => {
91
- let n = r[e], i = x(n), a = i.meta?.per_page ?? 50, o = i.meta?.total ?? i.rows.length;
89
+ let i = e.entityData ?? {};
90
+ n((e, t) => {
91
+ let n = i[e], r = x(n), a = r.meta?.per_page ?? 50, o = r.meta?.total ?? r.rows.length;
92
92
  return t.count === "only" ? {
93
93
  data: [],
94
94
  meta: {
95
95
  page: 1,
96
96
  per_page: a,
97
97
  total: o,
98
- total_pages: i.meta?.total_pages ?? Math.max(1, Math.ceil(o / a)),
99
- count_mode: i.meta?.count_mode ?? "exact"
98
+ total_pages: r.meta?.total_pages ?? Math.max(1, Math.ceil(o / a)),
99
+ count_mode: r.meta?.count_mode ?? "exact"
100
100
  }
101
101
  } : {
102
- data: i.rows,
102
+ data: r.rows,
103
103
  meta: {
104
- page: i.meta?.page ?? 1,
104
+ page: r.meta?.page ?? 1,
105
105
  per_page: a,
106
- has_more: i.meta?.has_more ?? !1
106
+ has_more: r.meta?.has_more ?? !1
107
107
  },
108
- ...i.refs === void 0 ? {} : { $refs: i.refs }
108
+ ...r.refs === void 0 ? {} : { $refs: r.refs }
109
109
  };
110
110
  });
111
111
  let o = e.entityItems ?? {};
112
- n((e, t) => {
113
- let n = typeof t == "string" ? t : i(t);
112
+ t((e, t) => {
113
+ let n = typeof t == "string" ? t : r(t);
114
114
  return { data: o[e]?.[n] };
115
115
  });
116
116
  let s = e.actionResults ?? {};
117
- t(async (e, t) => {
117
+ a(async (e, t) => {
118
118
  if (!(e in s)) throw Error(`renderWithDeclarion: no action result registered for "${e}" (seed it via actionResults)`);
119
119
  let n = s[e];
120
120
  return y(typeof n == "function" ? await n(t) : n);
121
121
  });
122
122
  }
123
123
  function C() {
124
- a(null), n(null), t(null), e.setState({
124
+ n(null), t(null), a(null), e.setState({
125
125
  user: null,
126
126
  isAuthenticated: !1,
127
127
  activeTenant: null,
@@ -134,33 +134,33 @@ function w(e, t = {}) {
134
134
  gcTime: Infinity
135
135
  } } });
136
136
  b(), n.setQueryData(["schema", !0], t.schema ?? m()), S(t);
137
- let i = p(/* @__PURE__ */ f(l, {
137
+ let r = p(/* @__PURE__ */ f(l, {
138
138
  client: n,
139
139
  children: [/* @__PURE__ */ d(s, {
140
140
  initialEntries: [t.route ?? "/"],
141
- children: /* @__PURE__ */ d(r, { children: e })
141
+ children: /* @__PURE__ */ d(i, { children: e })
142
142
  }), /* @__PURE__ */ d(u, {})]
143
143
  }));
144
- return Object.assign(i, { queryClient: n });
144
+ return Object.assign(r, { queryClient: n });
145
145
  }
146
- function T({ children: t, authenticated: n = !0, ...i }) {
146
+ function T({ children: t, authenticated: n = !0, ...r }) {
147
147
  let [a] = o(() => {
148
148
  let t = new c({ defaultOptions: { queries: {
149
149
  retry: !1,
150
150
  gcTime: Infinity
151
151
  } } });
152
- return n ? (b(), t.setQueryData(["schema", !0], i.schema ?? m())) : e.setState({
152
+ return n ? (b(), t.setQueryData(["schema", !0], r.schema ?? m())) : e.setState({
153
153
  user: null,
154
154
  isAuthenticated: !1,
155
155
  activeTenant: null,
156
156
  tenants: []
157
- }), S(i), t;
157
+ }), S(r), t;
158
158
  });
159
159
  return /* @__PURE__ */ f(l, {
160
160
  client: a,
161
161
  children: [/* @__PURE__ */ d(s, {
162
- initialEntries: [i.route ?? "/"],
163
- children: /* @__PURE__ */ d(r, { children: t })
162
+ initialEntries: [r.route ?? "/"],
163
+ children: /* @__PURE__ */ d(i, { children: t })
164
164
  }), /* @__PURE__ */ d(u, {})]
165
165
  });
166
166
  }
@@ -44,6 +44,29 @@ export interface RefConfig {
44
44
  display?: RefDisplay;
45
45
  fields?: string[];
46
46
  }
47
+ /** One declared filter-only option ({code, label}). `code` is stored into the
48
+ * filter when chosen (a literal or a `$user.*` token resolved server-side);
49
+ * `label` is the localized display string. Mirrors engine.FilterSpecialValue. */
50
+ export interface FilterSpecialValue {
51
+ code: string;
52
+ label: LocalizedString;
53
+ }
54
+ /** Per-screen override of a field's filter_special_values, keyed in
55
+ * Screen.filter_special_values by the filter field code. */
56
+ export interface ScreenFilterSpecialValues {
57
+ mode?: "append" | "replace" | "clear";
58
+ values?: FilterSpecialValue[];
59
+ }
60
+ /** Normalizes a handler-param ref (scalar entity-code string OR structured
61
+ * object) into a RefConfig. One helper shared by filters, SmartDetailPage
62
+ * fields, and ActionDialog params so the scalar shorthand and structured form
63
+ * reach the relation combobox identically. */
64
+ export declare function normalizeRefConfig(ref: string | RefConfig | undefined): RefConfig | undefined;
65
+ /** Computes the effective filter_special_values for a field on a screen by
66
+ * merging the field-level list with an optional screen override per its mode
67
+ * (append [default] / replace / clear). Pure; mirrors the engine's
68
+ * EffectiveFilterSpecialValues so the SDK and loader agree. */
69
+ export declare function effectiveFilterSpecialValues(fieldValues: FilterSpecialValue[] | undefined, override: ScreenFilterSpecialValues | undefined): FilterSpecialValue[];
47
70
  export interface UnitConfig {
48
71
  storage: string;
49
72
  display?: string;
@@ -98,6 +121,10 @@ export interface EntityField {
98
121
  enum?: string;
99
122
  files?: FileFieldDef;
100
123
  ref?: RefConfig;
124
+ /** Filter-only declared options (e.g. "Myself" -> $user.id) surfaced in this
125
+ * field's filter control. Inert everywhere else. A screen MAY override these
126
+ * per-screen via Screen.filter_special_values. */
127
+ filter_special_values?: FilterSpecialValue[];
101
128
  structure?: string;
102
129
  array?: boolean;
103
130
  copyable?: boolean;
@@ -529,6 +556,10 @@ export interface Screen {
529
556
  list_resizable?: boolean;
530
557
  detail_screen?: string;
531
558
  fixed_filters?: Record<string, unknown>;
559
+ /** Per-screen override of field-level filter_special_values, keyed by filter
560
+ * field code. Append/replace/clear the entity field's declared values for
561
+ * just this screen. Mirrors engine.Screen.FilterSpecialValues. */
562
+ filter_special_values?: Record<string, ScreenFilterSpecialValues>;
532
563
  views?: ViewDefinition[];
533
564
  /** Action slot promotion for list screens (rule-of-2). UI honors first 2.
534
565
  * Note: primary_record_actions (detail header) was removed in Task 5 of plan
@@ -639,7 +670,10 @@ export interface HandlerParam {
639
670
  description?: LocalizedString;
640
671
  color?: string;
641
672
  }>;
642
- ref?: string;
673
+ /** `type: ref` param target. Scalar entity-code string (shorthand) OR a
674
+ * structured RefConfig (non-id lookup / display). Normalize via
675
+ * normalizeRefConfig before use. */
676
+ ref?: string | RefConfig;
643
677
  display?: HandlerParamDisplay;
644
678
  /**
645
679
  * Narrows the param's option set. Values may be literals or templates
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@declarion/react",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "description": "React SDK for Declarion, the schema-driven business apps platform.",