@happyvertical/smrt-svelte 0.55.23 → 0.56.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.
Files changed (108) hide show
  1. package/AGENTS.md +2 -2
  2. package/README.md +2 -2
  3. package/agents/overview-surfaces.md +117 -6
  4. package/agents/screens.md +171 -5
  5. package/dist/components/command-palette/CommandPaletteDialog.svelte +1 -1
  6. package/dist/components/overview/OverviewGrid.svelte +8 -4
  7. package/dist/components/overview/OverviewGrid.svelte.d.ts.map +1 -1
  8. package/dist/components/overview/WidgetOptionsForm.svelte +13 -2
  9. package/dist/components/overview/WidgetOptionsForm.svelte.d.ts.map +1 -1
  10. package/dist/components/overview/format.d.ts +3 -12
  11. package/dist/components/overview/format.d.ts.map +1 -1
  12. package/dist/components/overview/format.js +2 -45
  13. package/dist/components/overview/grid-types.d.ts +6 -11
  14. package/dist/components/overview/grid-types.d.ts.map +1 -1
  15. package/dist/components/overview/index.d.ts +5 -1
  16. package/dist/components/overview/index.d.ts.map +1 -1
  17. package/dist/components/overview/index.js +3 -0
  18. package/dist/components/overview/recipe-widgets.d.ts +6 -3
  19. package/dist/components/overview/recipe-widgets.d.ts.map +1 -1
  20. package/dist/components/overview/recipe-widgets.js +9 -0
  21. package/dist/components/overview/record.d.ts +51 -0
  22. package/dist/components/overview/record.d.ts.map +1 -0
  23. package/dist/components/overview/record.js +146 -0
  24. package/dist/components/overview/registry.d.ts +3 -0
  25. package/dist/components/overview/registry.d.ts.map +1 -1
  26. package/dist/components/overview/registry.js +25 -0
  27. package/dist/components/overview/server.d.ts +5 -1
  28. package/dist/components/overview/server.d.ts.map +1 -1
  29. package/dist/components/overview/server.js +5 -1
  30. package/dist/components/overview/types.d.ts +29 -0
  31. package/dist/components/overview/types.d.ts.map +1 -1
  32. package/dist/components/overview/widgets/ChartWidget.svelte +5 -265
  33. package/dist/components/overview/widgets/ChartWidget.svelte.d.ts +1 -1
  34. package/dist/components/overview/widgets/ChartWidget.svelte.d.ts.map +1 -1
  35. package/dist/components/overview/widgets/LineItemsWidget.svelte +144 -0
  36. package/dist/components/overview/widgets/LineItemsWidget.svelte.d.ts +6 -0
  37. package/dist/components/overview/widgets/LineItemsWidget.svelte.d.ts.map +1 -0
  38. package/dist/components/overview/widgets/RecordListWidget.svelte +67 -3
  39. package/dist/components/overview/widgets/RecordListWidget.svelte.d.ts.map +1 -1
  40. package/dist/components/overview/widgets/RecordTable.svelte +167 -0
  41. package/dist/components/overview/widgets/RecordTable.svelte.d.ts +21 -0
  42. package/dist/components/overview/widgets/RecordTable.svelte.d.ts.map +1 -0
  43. package/dist/components/overview/widgets/RelatedWidget.svelte +117 -0
  44. package/dist/components/overview/widgets/RelatedWidget.svelte.d.ts +6 -0
  45. package/dist/components/overview/widgets/RelatedWidget.svelte.d.ts.map +1 -0
  46. package/dist/components/overview/widgets/core.d.ts +13 -2
  47. package/dist/components/overview/widgets/core.d.ts.map +1 -1
  48. package/dist/components/overview/widgets/core.js +43 -2
  49. package/dist/components/overview/widgets/data.d.ts +97 -8
  50. package/dist/components/overview/widgets/data.d.ts.map +1 -1
  51. package/dist/components/overview/widgets/line-totals.d.ts +48 -0
  52. package/dist/components/overview/widgets/line-totals.d.ts.map +1 -0
  53. package/dist/components/overview/widgets/line-totals.js +91 -0
  54. package/dist/components/overview/widgets/record-loaders.d.ts +63 -0
  55. package/dist/components/overview/widgets/record-loaders.d.ts.map +1 -0
  56. package/dist/components/overview/widgets/record-loaders.js +150 -0
  57. package/dist/components/overview/widgets/record-table.d.ts +45 -0
  58. package/dist/components/overview/widgets/record-table.d.ts.map +1 -0
  59. package/dist/components/overview/widgets/record-table.js +201 -0
  60. package/dist/components/overview/widgets/record-widgets.d.ts +27 -0
  61. package/dist/components/overview/widgets/record-widgets.d.ts.map +1 -0
  62. package/dist/components/overview/widgets/record-widgets.js +100 -0
  63. package/dist/components/screens/DetailScreen.svelte +105 -6
  64. package/dist/components/screens/DetailScreen.svelte.d.ts.map +1 -1
  65. package/dist/components/screens/EditForm.svelte +39 -3
  66. package/dist/components/screens/EditForm.svelte.d.ts.map +1 -1
  67. package/dist/components/screens/RecipeScreens.svelte +18 -18
  68. package/dist/components/screens/RecipeScreens.svelte.d.ts.map +1 -1
  69. package/dist/components/screens/RecordHeader.svelte +238 -0
  70. package/dist/components/screens/RecordHeader.svelte.d.ts +26 -0
  71. package/dist/components/screens/RecordHeader.svelte.d.ts.map +1 -0
  72. package/dist/components/screens/RecordScreen.svelte +511 -0
  73. package/dist/components/screens/RecordScreen.svelte.d.ts +5 -0
  74. package/dist/components/screens/RecordScreen.svelte.d.ts.map +1 -0
  75. package/dist/components/screens/columns.d.ts +29 -0
  76. package/dist/components/screens/columns.d.ts.map +1 -0
  77. package/dist/components/screens/columns.js +115 -0
  78. package/dist/components/screens/fields.d.ts +12 -2
  79. package/dist/components/screens/fields.d.ts.map +1 -1
  80. package/dist/components/screens/fields.js +37 -5
  81. package/dist/components/screens/index.d.ts +7 -2
  82. package/dist/components/screens/index.d.ts.map +1 -1
  83. package/dist/components/screens/index.js +6 -1
  84. package/dist/components/screens/record-header.d.ts +51 -0
  85. package/dist/components/screens/record-header.d.ts.map +1 -0
  86. package/dist/components/screens/record-header.js +118 -0
  87. package/dist/components/screens/relations.d.ts +49 -0
  88. package/dist/components/screens/relations.d.ts.map +1 -0
  89. package/dist/components/screens/relations.js +98 -0
  90. package/dist/components/screens/roles.d.ts +56 -0
  91. package/dist/components/screens/roles.d.ts.map +1 -0
  92. package/dist/components/screens/roles.js +174 -0
  93. package/dist/components/screens/types.d.ts +182 -1
  94. package/dist/components/screens/types.d.ts.map +1 -1
  95. package/dist/components/screens/values.d.ts +23 -1
  96. package/dist/components/screens/values.d.ts.map +1 -1
  97. package/dist/components/screens/values.js +80 -4
  98. package/dist/components/workspace/admin-shell/AdminShell.svelte +4 -4
  99. package/dist/components/workspace/admin-shell/ShellIconButton.svelte +2 -2
  100. package/dist/components/workspace/admin-shell/TenantNav.svelte +8 -8
  101. package/dist/components/workspace/admin-shell/WorkspaceAccountMenu.svelte +3 -3
  102. package/dist/i18n/strings.overview.d.ts +25 -0
  103. package/dist/i18n/strings.overview.d.ts.map +1 -1
  104. package/dist/i18n/strings.overview.js +25 -0
  105. package/dist/i18n/strings.screens.d.ts +8 -0
  106. package/dist/i18n/strings.screens.d.ts.map +1 -1
  107. package/dist/i18n/strings.screens.js +8 -0
  108. package/package.json +16 -16
@@ -0,0 +1,174 @@
1
+ /** Every role, in the order a role list is reported. */
2
+ export const FIELD_ROLES = [
3
+ 'title',
4
+ 'identifier',
5
+ 'status',
6
+ 'money',
7
+ 'quantity',
8
+ 'date',
9
+ 'party',
10
+ 'subtotal',
11
+ 'tax',
12
+ 'discount',
13
+ 'total',
14
+ ];
15
+ const NUMERIC = new Set(['integer', 'decimal']);
16
+ const REFERENCE = new Set(['foreignKey', 'crossPackageRef']);
17
+ /** `*Amount`, `*Total`, `price`, `cost` (and the totals roles' own names). */
18
+ const MONEY_NAME = /(?:^|[a-z])(?:amount|total|price|cost)$|^(?:subtotal|tax|discount)$/i;
19
+ const SUBTOTAL_NAME = /^subtotal(?:Amount)?$|[a-z]Subtotal(?:Amount)?$/;
20
+ const TAX_NAME = /^tax(?:Amount|Total)?$|[a-z]Tax(?:Amount|Total)?$/;
21
+ const DISCOUNT_NAME = /^discount(?:Amount|Total)?$|[a-z]Discount(?:Amount|Total)?$/;
22
+ const TOTAL_NAME = /^(?:total|grandTotal)(?:Amount)?$|^amountTotal$/;
23
+ const RATE_NAME = /(?:rate|percent|percentage|pct|ratio)$/i;
24
+ const STATUS_NAME = /^(?:status|state)$|[a-z](?:Status|State)$/;
25
+ const IDENTIFIER_NAME = /^(?:number|reference|code|ref)$|[a-z](?:Number|Reference|Code)$/;
26
+ /** `phoneNumber`, `postalCode`, `currencyCode`, ... are not the record's identifier. */
27
+ const NOT_IDENTIFIER = /^(?:phone|mobile|fax|postal|zip|country|currency|language|locale|tax|vat|account|routing|card|area|promo|coupon|discount|sort|tracking|billing|shipping|iban|swift|bank|unit|line|street|house|building)/i;
28
+ const DATE_NAME = /^date$|[a-z](?:At|Date|On|Until)$/;
29
+ const QUANTITY_NAME = /^(?:quantity|qty)|(?:Quantity|Qty)$/;
30
+ const TITLE_NAMES = ['name', 'title', 'label', 'displayName'];
31
+ /** A party: who a record is with. Matched against the FK name and its target. */
32
+ const PARTY_NAME = /customer|vendor|supplier|client|party|profile|contact|person|people|member|company|organi[sz]ation|payer|payee|buyer|seller|licensee|lessee/i;
33
+ function explicitRoles(definition) {
34
+ const role = definition.role;
35
+ if (role === undefined)
36
+ return null;
37
+ const list = (Array.isArray(role) ? role : [role]);
38
+ return list.filter((r) => FIELD_ROLES.includes(r));
39
+ }
40
+ function formatOf(definition) {
41
+ return definition.format ?? definition.ui?.format;
42
+ }
43
+ /** True when a field declares money through metadata or a manifest hint. */
44
+ function hintedMoney(definition) {
45
+ if (formatOf(definition) === 'money')
46
+ return true;
47
+ return definition.type === 'integer' && definition.ui?.widget === 'currency';
48
+ }
49
+ function hasEnum(definition) {
50
+ return Array.isArray(definition.enum) && definition.enum.length > 0;
51
+ }
52
+ function relationshipFor(relationships, field) {
53
+ return relationships?.find((edge) => edge.field === field);
54
+ }
55
+ function heuristicRoles(name, definition, relationship) {
56
+ const roles = [];
57
+ const { type } = definition;
58
+ const numeric = NUMERIC.has(type);
59
+ const rate = RATE_NAME.test(name);
60
+ if (type === 'text') {
61
+ if (hasEnum(definition) && STATUS_NAME.test(name))
62
+ roles.push('status');
63
+ if (IDENTIFIER_NAME.test(name) &&
64
+ !NOT_IDENTIFIER.test(name) &&
65
+ definition.ui?.widget !== 'phone') {
66
+ roles.push('identifier');
67
+ }
68
+ }
69
+ if (type === 'integer' && !rate && MONEY_NAME.test(name))
70
+ roles.push('money');
71
+ if (numeric && QUANTITY_NAME.test(name))
72
+ roles.push('quantity');
73
+ if (type === 'datetime' && DATE_NAME.test(name))
74
+ roles.push('date');
75
+ if (REFERENCE.has(type)) {
76
+ const target = relationship?.relatedCollection ?? '';
77
+ const base = name.replace(/Id$/, '');
78
+ if (base !== 'tenant' && (PARTY_NAME.test(base) || PARTY_NAME.test(target)))
79
+ roles.push('party');
80
+ }
81
+ if (numeric && !rate) {
82
+ if (SUBTOTAL_NAME.test(name))
83
+ roles.push('subtotal');
84
+ else if (TAX_NAME.test(name))
85
+ roles.push('tax');
86
+ else if (DISCOUNT_NAME.test(name))
87
+ roles.push('discount');
88
+ else if (TOTAL_NAME.test(name))
89
+ roles.push('total');
90
+ }
91
+ return roles;
92
+ }
93
+ function ordered(roles) {
94
+ const set = new Set(roles);
95
+ return FIELD_ROLES.filter((r) => set.has(r));
96
+ }
97
+ /**
98
+ * Roles of every declared field of `definition` (a key per field, possibly
99
+ * an empty list). Without an explicit `display` field, the first text field
100
+ * named `name` / `title` / `label` / `displayName` takes the `title` role.
101
+ */
102
+ export function deriveFieldRoles(definition) {
103
+ const out = {};
104
+ const entries = Object.entries(definition.fields).filter(([name]) => !name.startsWith('_') && !name.startsWith('$'));
105
+ const hasDisplay = entries.some(([, d]) => d.display === true);
106
+ for (const [name, fieldDefinition] of entries) {
107
+ const roles = new Set();
108
+ const explicit = explicitRoles(fieldDefinition);
109
+ if (explicit)
110
+ for (const r of explicit)
111
+ roles.add(r);
112
+ else {
113
+ for (const r of heuristicRoles(name, fieldDefinition, relationshipFor(definition.relationships, name)))
114
+ roles.add(r);
115
+ }
116
+ if (hintedMoney(fieldDefinition))
117
+ roles.add('money');
118
+ const format = formatOf(fieldDefinition);
119
+ if ((format === 'date' || format === 'datetime') &&
120
+ fieldDefinition.type === 'datetime') {
121
+ roles.add('date');
122
+ }
123
+ if (fieldDefinition.display === true)
124
+ roles.add('title');
125
+ out[name] = ordered(roles);
126
+ }
127
+ if (!hasDisplay && !Object.values(out).some((r) => r.includes('title'))) {
128
+ for (const candidate of TITLE_NAMES) {
129
+ const fieldDefinition = definition.fields[candidate];
130
+ if (fieldDefinition?.type === 'text' &&
131
+ explicitRoles(fieldDefinition) === null) {
132
+ out[candidate] = ordered([...(out[candidate] ?? []), 'title']);
133
+ break;
134
+ }
135
+ }
136
+ }
137
+ return out;
138
+ }
139
+ /** Fields holding `role`, in declaration order. */
140
+ export function fieldsWithRole(roles, role) {
141
+ return Object.keys(roles).filter((name) => roles[name]?.includes(role));
142
+ }
143
+ /** The first field holding `role`, or `undefined`. */
144
+ export function fieldWithRole(roles, role) {
145
+ return Object.keys(roles).find((name) => roles[name]?.includes(role));
146
+ }
147
+ /**
148
+ * The field naming a record's currency: a text field hinted
149
+ * `ui.widget: 'currency'` (the manifest's currency-code picker), else a text
150
+ * field named `currency` / `currencyCode`.
151
+ */
152
+ export function currencyCodeField(definition) {
153
+ const entries = Object.entries(definition.fields);
154
+ return (entries.find(([, d]) => d.type === 'text' && d.ui?.widget === 'currency')?.[0] ??
155
+ entries.find(([name, d]) => d.type === 'text' && /^currency(?:Code)?$/.test(name))?.[0]);
156
+ }
157
+ /**
158
+ * Whether records of this definition read like documents (an order, an
159
+ * invoice): an identifier plus a party or a total. Their header leads with
160
+ * the identifier ("Order GRA-3159") rather than a name.
161
+ */
162
+ export function isDocumentLike(roles) {
163
+ return (fieldWithRole(roles, 'identifier') !== undefined &&
164
+ (fieldWithRole(roles, 'party') !== undefined ||
165
+ fieldWithRole(roles, 'total') !== undefined));
166
+ }
167
+ /**
168
+ * Whether a child definition has line-item roles: a quantity and a money
169
+ * field (`deriveScreenRelations` classifies such a child relation `items`).
170
+ */
171
+ export function hasLineItemRoles(roles) {
172
+ return (fieldWithRole(roles, 'quantity') !== undefined &&
173
+ fieldWithRole(roles, 'money') !== undefined);
174
+ }
@@ -1,4 +1,10 @@
1
1
  import type { Snippet } from 'svelte';
2
+ import type { WidgetRegistry } from '../overview/registry.js';
3
+ import type { OverviewDefinition, OverviewOverride, WidgetLoadContext } from '../overview/types.js';
4
+ import type { CoreWidgetLoaders } from '../overview/widgets/core.js';
5
+ import type { RecordStatusTone } from '../overview/widgets/data.js';
6
+ import type { ScreenRelation } from './relations.js';
7
+ import type { FieldRole } from './roles.js';
2
8
  /**
3
9
  * Structural types for the manifest-derived record screens (#3718).
4
10
  *
@@ -10,13 +16,25 @@ import type { Snippet } from 'svelte';
10
16
  */
11
17
  /** Persisted public wire types emitted by generated web collections. */
12
18
  export type ScreenFieldType = 'text' | 'integer' | 'decimal' | 'boolean' | 'datetime' | 'json' | 'foreignKey' | 'crossPackageRef';
19
+ /**
20
+ * How a value is presented: `money` (integer minor units), `date` (a
21
+ * business date, shown without a time), `datetime`, `percent` (a rate, `0.08`
22
+ * shows as `8%`).
23
+ */
24
+ export type ScreenFieldFormat = 'money' | 'date' | 'datetime' | 'percent';
13
25
  /** Static `@field({ ui })` presentation hints from the manifest. */
14
26
  export interface ScreenFieldUIHints {
15
27
  basic?: boolean;
16
28
  group?: string;
17
29
  order?: number;
18
30
  locked?: boolean;
31
+ /**
32
+ * `currency` on a TEXT field is the currency-code picker (the manifest
33
+ * meaning); on an INTEGER field it is read as the legacy money hint.
34
+ */
19
35
  widget?: 'textarea' | 'currency' | 'email' | 'url' | 'phone';
36
+ /** Manifest presentation format (`@field({ ui: { format } })`). */
37
+ format?: ScreenFieldFormat;
20
38
  }
21
39
  /** Browser-safe subset of one generated web field definition. */
22
40
  export interface ScreenFieldDefinition {
@@ -27,9 +45,40 @@ export interface ScreenFieldDefinition {
27
45
  /** Developer-authored `@field({ description })`; the code-seed help text. */
28
46
  description?: string;
29
47
  ui?: ScreenFieldUIHints;
48
+ /**
49
+ * What the field means on a record page (`deriveFieldRoles`). Explicit
50
+ * roles are authoritative: name heuristics never add to them.
51
+ */
52
+ role?: FieldRole | readonly FieldRole[];
53
+ /** Allowed values; a text field with an enum edits as a select. */
54
+ enum?: readonly string[];
55
+ /** Presentation format; wins over `ui.format`. */
56
+ format?: ScreenFieldFormat;
57
+ /** This field is the record's display label (the `title` role). */
58
+ display?: boolean;
59
+ }
60
+ export type ScreenRelationshipKind = 'foreignKey' | 'crossPackageRef' | 'oneToMany' | 'manyToMany';
61
+ /**
62
+ * One manifest-derived relationship edge, structurally the generated
63
+ * `SmrtWebRelationship`: `field` is the FK field on this model and
64
+ * `relatedCollection` the sibling collection's name (the key in
65
+ * `collectionDefinitions`), not a qualified model id.
66
+ */
67
+ export interface ScreenRelationshipDefinition {
68
+ field: string;
69
+ kind: ScreenRelationshipKind;
70
+ relatedCollection: string;
71
+ /**
72
+ * `items`: the declaring (child) model is the line items of the target
73
+ * (`@foreignKey(Order, { role: 'items' })`); `deriveScreenRelations`
74
+ * classifies the relation `items`.
75
+ */
76
+ role?: 'items';
30
77
  }
31
78
  /** Structural subset of a generated `SmrtWebCollectionDefinition`. */
32
79
  export interface ScreenCollectionDefinition {
80
+ /** Collection name (the key in `collectionDefinitions`); used to resolve relationships. */
81
+ name?: string;
33
82
  /** Canonical qualified model identity (`@package/name:ClassName`). */
34
83
  objectRef: string;
35
84
  /** Simple class name, used to derive default titles. */
@@ -37,6 +86,8 @@ export interface ScreenCollectionDefinition {
37
86
  /** Primary-key field name. Defaults to `id`. */
38
87
  idField?: string;
39
88
  fields: Readonly<Record<string, ScreenFieldDefinition>>;
89
+ /** Manifest-derived relationship edges; the source of `deriveScreenRelations`. */
90
+ relationships?: readonly ScreenRelationshipDefinition[];
40
91
  }
41
92
  export type ScreenFieldVisibility = 'basic' | 'advanced' | 'hidden';
42
93
  /**
@@ -61,7 +112,7 @@ export interface ScreenPolicy {
61
112
  }
62
113
  export type ScreenMode = 'list' | 'view' | 'edit';
63
114
  /** How a field is rendered and edited. */
64
- export type ScreenInputKind = 'text' | 'textarea' | 'email' | 'url' | 'tel' | 'integer' | 'decimal' | 'money' | 'boolean' | 'datetime' | 'json' | 'reference';
115
+ export type ScreenInputKind = 'text' | 'textarea' | 'email' | 'url' | 'tel' | 'integer' | 'decimal' | 'money' | 'boolean' | 'datetime' | 'json' | 'reference' | 'select';
65
116
  /** A field selected and decorated for one screen. */
66
117
  export interface ScreenField {
67
118
  name: string;
@@ -76,6 +127,10 @@ export interface ScreenField {
76
127
  group: string | null;
77
128
  order: number | null;
78
129
  definition: ScreenFieldDefinition;
130
+ /** The field's roles (`deriveFieldRoles`); set by `deriveScreenFields`. */
131
+ roles?: readonly FieldRole[];
132
+ /** Choices of a `select` field (the definition's `enum`). */
133
+ options?: readonly string[];
79
134
  }
80
135
  /** Why a draft value could not become a payload value. */
81
136
  export type ScreenFieldErrorCode = 'required' | 'invalid_integer' | 'invalid_decimal' | 'invalid_money' | 'invalid_datetime' | 'invalid_json';
@@ -156,6 +211,27 @@ export interface DetailScreenProps {
156
211
  extraActions?: Snippet;
157
212
  /** Extra content under the fields. */
158
213
  children?: Snippet;
214
+ /**
215
+ * Relations of this model (`deriveScreenRelations`). The `reference` ones
216
+ * map a FK field to its target model, which `labels` is keyed by.
217
+ */
218
+ relations?: readonly ScreenRelation[];
219
+ /** Link for a reference field's value; `undefined` renders no link. */
220
+ hrefFor?: (field: ScreenField, id: string) => string | undefined;
221
+ /**
222
+ * Display label for a referenced record, keyed by target model id
223
+ * (`relation.model`); `undefined` falls back to the raw id.
224
+ */
225
+ labels?: Readonly<Record<string, (id: string) => string | undefined>>;
226
+ /** Field names to leave out (the record header shows them). */
227
+ exclude?: readonly string[];
228
+ /**
229
+ * Move fields with no value behind a "Show empty fields" disclosure
230
+ * instead of listing "Not set" cells.
231
+ */
232
+ hideEmpty?: boolean;
233
+ /** `card`: the fields sit in a bordered card (the record page's details card). */
234
+ variant?: 'plain' | 'card';
159
235
  }
160
236
  /** What a submit handler may return to report server-side field problems. */
161
237
  export interface EditFormSubmitResult {
@@ -180,12 +256,110 @@ export interface EditFormProps {
180
256
  fieldErrors?: Readonly<Record<string, string>>;
181
257
  /** A form-level failure message from the host. */
182
258
  error?: string | null;
259
+ /**
260
+ * Fields computed elsewhere (a subtotal / tax / total worked out from the
261
+ * line items): shown read-only with a hint and never part of the payload.
262
+ */
263
+ derivedFields?: readonly string[];
183
264
  /** Receives wire-ready values for the displayed fields. */
184
265
  onsubmit: (values: Record<string, unknown>, context: {
185
266
  isNew: boolean;
186
267
  }) => void | EditFormSubmitResult | Promise<void | EditFormSubmitResult>;
187
268
  oncancel?: () => void;
188
269
  }
270
+ export type RecordScreenMode = 'view' | 'edit';
271
+ /**
272
+ * Props of `RecordScreen`: the record view (#3718 record view). The detail
273
+ * header and fields sit at the top, a customizable overview of related
274
+ * records below; `mode: 'edit'` opens the edit form beside the header on
275
+ * desktop and in a full-screen sheet on phones.
276
+ */
277
+ export interface RecordScreenProps {
278
+ definition: ScreenCollectionDefinition;
279
+ /** Resolved field policy for the same object; omit for the code seed. */
280
+ policy?: ScreenPolicy | null;
281
+ record: ScreenRecord;
282
+ /** Relations of this model (`deriveScreenRelations`). */
283
+ relations?: readonly ScreenRelation[];
284
+ mode: RecordScreenMode;
285
+ /**
286
+ * Loaders of the core widgets; the shell registers them on a registry of
287
+ * its own and runs them in the browser with the record context. A widget
288
+ * without a loader is not offered (and a default using it is dropped).
289
+ */
290
+ loaders?: CoreWidgetLoaders;
291
+ /** An explicit registry (recipe widgets included) instead of one built from `loaders`. */
292
+ registry?: WidgetRegistry;
293
+ /**
294
+ * Host capabilities for the widget loads (a `fetch`, a client, the
295
+ * locale). `overviewId` and `record` are set by the screen.
296
+ */
297
+ widgetContext?: Omit<WidgetLoadContext, 'overviewId' | 'record'>;
298
+ /** The overview to render; defaults to `recordOverview(definition, relations)`. */
299
+ overview?: OverviewDefinition;
300
+ /** The stored layout override for this model kind (host-owned when given). */
301
+ override?: OverviewOverride | null;
302
+ /** Receives the override after each layout edit (`null` = defaults). */
303
+ onoverviewchange?: (override: OverviewOverride | null) => void | Promise<void>;
304
+ /** Layout edit mode; omit to follow the shell's layout editor. */
305
+ layoutEditing?: boolean;
306
+ /** Whether the viewer may customize the layout (default true). */
307
+ canCustomize?: boolean;
308
+ /** Link for a reference field's value. */
309
+ hrefFor?: (field: ScreenField, id: string) => string | undefined;
310
+ /** Display labels for referenced records, keyed by target model id. */
311
+ labels?: Readonly<Record<string, (id: string) => string | undefined>>;
312
+ /** "View all" link of a related-records panel; `undefined` renders none. */
313
+ viewAllHref?: (relation: ScreenRelation) => string | undefined;
314
+ /** Page title. Defaults to the first basic text field, else the class name. */
315
+ title?: string;
316
+ /** Explicit field names, in order (overrides the derived set). */
317
+ fields?: readonly string[];
318
+ /** ISO 4217 code used by money fields. */
319
+ currency?: string;
320
+ /** BCP-47 locale for number and date formatting. */
321
+ locale?: string;
322
+ /** Label for the back action; defaults to the pluralized class name. */
323
+ backLabel?: string;
324
+ /** Mutation in flight; locks the delete confirmation. */
325
+ deleting?: boolean;
326
+ /** True while the host is persisting the edit; locks the form. */
327
+ submitting?: boolean;
328
+ /** Server-reported field messages for the edit form, keyed by field name. */
329
+ fieldErrors?: Readonly<Record<string, string>>;
330
+ /** A form-level failure message from the host. */
331
+ error?: string | null;
332
+ onback?: () => void;
333
+ /** When set, an Edit action is offered (the host switches `mode`). */
334
+ onedit?: () => void;
335
+ /** Closes the edit form (Cancel, the sheet's close button, Escape). */
336
+ oncancel?: () => void;
337
+ /** Receives the edit form's wire-ready values; `EditFormProps['onsubmit']`. */
338
+ onsave?: EditFormProps['onsubmit'];
339
+ /** When set, Delete (with a confirmation) is offered in the overflow menu. */
340
+ ondelete?: () => void | Promise<void>;
341
+ /** Extra actions, rendered in the header's overflow menu before Delete. */
342
+ extraActions?: Snippet;
343
+ /**
344
+ * Badge tone per status value (`paid: 'success'`); unmapped values use
345
+ * `DEFAULT_STATUS_TONES`, else neutral.
346
+ */
347
+ statusTones?: Readonly<Record<string, RecordStatusTone>>;
348
+ /** Extra content under the fields, inside the details card. */
349
+ children?: Snippet;
350
+ /**
351
+ * The edit form's derived (read-only, never submitted) fields. Defaults
352
+ * to the subtotal / discount / tax / total role fields when the model has
353
+ * an `items` relation, else none.
354
+ */
355
+ derivedFields?: readonly string[];
356
+ /**
357
+ * Editable line items (the host's own editor), rendered under the edit
358
+ * form: in the edit column on desktop and inside the edit sheet on
359
+ * phones, so lines are editable on a phone too.
360
+ */
361
+ items?: Snippet;
362
+ }
189
363
  export interface RecipeScreensProps {
190
364
  definition: ScreenCollectionDefinition;
191
365
  /** Resolved field policy for the same object; omit for the code seed. */
@@ -211,5 +385,12 @@ export interface RecipeScreensProps {
211
385
  };
212
386
  /** Called on every user navigation, for router synchronization. */
213
387
  onnavigate?: (view: RecipeScreenView, recordId: string | null) => void;
388
+ /**
389
+ * Every exposed collection definition, keyed by collection name; the
390
+ * record view derives this model's relations from it. Omit for none.
391
+ */
392
+ definitions?: Readonly<Record<string, ScreenCollectionDefinition>>;
393
+ /** Passed to `RecordScreen` for the record view and edit. */
394
+ record?: Pick<RecordScreenProps, 'loaders' | 'registry' | 'widgetContext' | 'overview' | 'override' | 'onoverviewchange' | 'layoutEditing' | 'canCustomize' | 'hrefFor' | 'labels' | 'viewAllHref' | 'statusTones'>;
214
395
  }
215
396
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/screens/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/screens/types.ts"],"names":[],"mappings":"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"}
@@ -53,7 +53,29 @@ export interface FormatValueContext extends ScreenValueContext {
53
53
  no?: string;
54
54
  }
55
55
  /** A record value as display text for a list cell or a view row. */
56
- export declare function formatScreenValue(field: Pick<ScreenField, 'kind'>, value: unknown, context?: FormatValueContext): string;
56
+ export declare function formatScreenValue(field: Pick<ScreenField, 'kind'> & {
57
+ definition?: Pick<ScreenField['definition'], 'format' | 'ui'>;
58
+ }, value: unknown, context?: FormatValueContext): string;
59
+ /** One row of a JSON object shown as a key/value list. */
60
+ export interface ScreenJsonEntry {
61
+ key: string;
62
+ value: string;
63
+ }
64
+ /**
65
+ * A JSON object field as key/value rows for a record view (an address reads
66
+ * `Line1: 12 Main St`, not `{"line1":...}`): its non-blank top-level entries,
67
+ * nested values as compact JSON. `null` for anything that is not a non-empty
68
+ * plain object (an array, a scalar, stored text that is not an object), which
69
+ * the view shows through {@link formatScreenValue} instead; an empty object
70
+ * formats as `''`, the view's empty placeholder.
71
+ */
72
+ export declare function jsonScreenEntries(value: unknown): ScreenJsonEntry[] | null;
73
+ /**
74
+ * A record id short enough to read where no label names the record: the
75
+ * first eight characters of a long id (a UUID's first group) and an
76
+ * ellipsis; a short id as is. Views keep the full id in a tooltip.
77
+ */
78
+ export declare function shortScreenId(id: string): string;
57
79
  /**
58
80
  * Order two record values for a list column: empty values last (whichever
59
81
  * way the column sorts), numbers numerically, everything else as text.
@@ -1 +1 @@
1
- {"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../../src/components/screens/values.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,QAAQ,CAAC;AAE7C,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,yEAAyE;AACzE,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAYf;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAUf;AAMD,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMtD;AAED,MAAM,WAAW,kBAAkB;IACjC,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAC1B,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAChC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,kBAAuB,GAC/B,gBAAgB,CAkBlB;AAED,4CAA4C;AAC5C,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAMb;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,EAC5B,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAWb;AAED,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D;;;;;OAKG;IACH,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,iBAAsB,GAC9B,WAAW,CA8Fb;AAED,MAAM,WAAW,kBAAmB,SAAQ,kBAAkB;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,oEAAoE;AACpE,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAChC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CAsDR;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,GAC/B,MAAM,CAgBR"}
1
+ {"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../../src/components/screens/values.ts"],"names":[],"mappings":"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"}
@@ -126,7 +126,8 @@ export function parseDraft(fields, draft, context = {}) {
126
126
  field.kind === 'textarea' ||
127
127
  field.kind === 'email' ||
128
128
  field.kind === 'url' ||
129
- field.kind === 'tel') &&
129
+ field.kind === 'tel' ||
130
+ field.kind === 'select') &&
130
131
  field.definition.nullable !== true) {
131
132
  values[field.name] = '';
132
133
  }
@@ -203,6 +204,7 @@ export function parseDraft(fields, draft, context = {}) {
203
204
  }
204
205
  /** A record value as display text for a list cell or a view row. */
205
206
  export function formatScreenValue(field, value, context = {}) {
207
+ const format = field.definition?.format ?? field.definition?.ui?.format;
206
208
  if (field.kind === 'boolean') {
207
209
  if (value === null || value === undefined)
208
210
  return '';
@@ -221,6 +223,12 @@ export function formatScreenValue(field, value, context = {}) {
221
223
  }).format(value)
222
224
  : String(value);
223
225
  case 'decimal':
226
+ if (format === 'percent' && typeof value === 'number') {
227
+ return new Intl.NumberFormat(context.locale, {
228
+ style: 'percent',
229
+ maximumFractionDigits: 4,
230
+ }).format(value);
231
+ }
224
232
  return typeof value === 'number'
225
233
  ? new Intl.NumberFormat(context.locale, {
226
234
  maximumFractionDigits: 6,
@@ -243,14 +251,19 @@ export function formatScreenValue(field, value, context = {}) {
243
251
  const date = value instanceof Date ? value : new Date(value);
244
252
  if (Number.isNaN(date.getTime()))
245
253
  return String(value);
254
+ // A business date (`format: 'date'`) shows no time of day.
246
255
  return new Intl.DateTimeFormat(context.locale, {
247
256
  dateStyle: 'medium',
248
- timeStyle: 'short',
257
+ ...(format === 'date' ? {} : { timeStyle: 'short' }),
249
258
  ...(context.timeZone ? { timeZone: context.timeZone } : {}),
250
259
  }).format(date);
251
260
  }
252
- case 'json':
253
- return typeof value === 'string' ? value : JSON.stringify(value);
261
+ case 'json': {
262
+ const parsed = parseJsonValue(value);
263
+ if (isEmptyJsonValue(parsed))
264
+ return '';
265
+ return typeof parsed === 'string' ? parsed : JSON.stringify(parsed);
266
+ }
254
267
  default:
255
268
  return String(value);
256
269
  }
@@ -260,6 +273,69 @@ export function formatScreenValue(field, value, context = {}) {
260
273
  return String(value);
261
274
  }
262
275
  }
276
+ /** A JSON field's value: stored JSON text parsed, anything else as given. */
277
+ function parseJsonValue(value) {
278
+ if (typeof value !== 'string')
279
+ return value;
280
+ const text = value.trim();
281
+ if (!text.startsWith('{') && !text.startsWith('['))
282
+ return value;
283
+ try {
284
+ return JSON.parse(text);
285
+ }
286
+ catch {
287
+ return value;
288
+ }
289
+ }
290
+ function isPlainObject(value) {
291
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
292
+ }
293
+ function isBlank(value) {
294
+ return value === null || value === undefined || value === '';
295
+ }
296
+ /** `{}`, `[]`, or an object whose every value is blank: nothing to show. */
297
+ function isEmptyJsonValue(value) {
298
+ if (isBlank(value))
299
+ return true;
300
+ if (Array.isArray(value))
301
+ return value.length === 0;
302
+ if (isPlainObject(value))
303
+ return Object.values(value).every(isBlank);
304
+ return false;
305
+ }
306
+ /**
307
+ * A JSON object field as key/value rows for a record view (an address reads
308
+ * `Line1: 12 Main St`, not `{"line1":...}`): its non-blank top-level entries,
309
+ * nested values as compact JSON. `null` for anything that is not a non-empty
310
+ * plain object (an array, a scalar, stored text that is not an object), which
311
+ * the view shows through {@link formatScreenValue} instead; an empty object
312
+ * formats as `''`, the view's empty placeholder.
313
+ */
314
+ export function jsonScreenEntries(value) {
315
+ const parsed = parseJsonValue(value);
316
+ if (!isPlainObject(parsed))
317
+ return null;
318
+ const entries = [];
319
+ for (const [key, entry] of Object.entries(parsed)) {
320
+ if (isBlank(entry))
321
+ continue;
322
+ entries.push({
323
+ key,
324
+ value: entry !== null && typeof entry === 'object'
325
+ ? JSON.stringify(entry)
326
+ : String(entry),
327
+ });
328
+ }
329
+ return entries.length > 0 ? entries : null;
330
+ }
331
+ /**
332
+ * A record id short enough to read where no label names the record: the
333
+ * first eight characters of a long id (a UUID's first group) and an
334
+ * ellipsis; a short id as is. Views keep the full id in a tooltip.
335
+ */
336
+ export function shortScreenId(id) {
337
+ return id.length > 12 ? `${id.slice(0, 8)}…` : id;
338
+ }
263
339
  /**
264
340
  * Order two record values for a list column: empty values last (whichever
265
341
  * way the column sorts), numbers numerically, everything else as text.
@@ -2306,8 +2306,8 @@ function buildLayoutStyle(shell: ModuleShellState): string {
2306
2306
  flex: 0 0 auto;
2307
2307
  margin-block-start: auto;
2308
2308
  align-self: flex-end;
2309
- inline-size: max(2rem, var(--smrt-control-target-min, 0px));
2310
- block-size: max(2rem, var(--smrt-control-target-min, 0px));
2309
+ inline-size: max(2rem, var(--smrt-control-target-min));
2310
+ block-size: max(2rem, var(--smrt-control-target-min));
2311
2311
  padding: 0;
2312
2312
  border-radius: var(--smrt-control-radius);
2313
2313
  color: var(--smrt-color-on-surface-variant);
@@ -2332,8 +2332,8 @@ function buildLayoutStyle(shell: ModuleShellState): string {
2332
2332
 
2333
2333
  :global(.smrt-admin-shell__edge-toggle--left[data-smrt-component="Button"]) {
2334
2334
  flex: 0 0 auto;
2335
- inline-size: max(2.75rem, var(--smrt-control-target-min, 0px));
2336
- block-size: max(2.75rem, var(--smrt-control-target-min, 0px));
2335
+ inline-size: max(2.75rem, var(--smrt-control-target-min));
2336
+ block-size: max(2.75rem, var(--smrt-control-target-min));
2337
2337
  padding: 0;
2338
2338
  color: var(--smrt-color-on-surface-variant);
2339
2339
  }