@happyvertical/smrt-svelte 0.55.22 → 0.55.24

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 (85) hide show
  1. package/AGENTS.md +2 -2
  2. package/README.md +2 -2
  3. package/agents/overview-surfaces.md +108 -4
  4. package/agents/screens.md +171 -5
  5. package/dist/components/overview/index.d.ts +4 -1
  6. package/dist/components/overview/index.d.ts.map +1 -1
  7. package/dist/components/overview/index.js +3 -0
  8. package/dist/components/overview/record.d.ts +51 -0
  9. package/dist/components/overview/record.d.ts.map +1 -0
  10. package/dist/components/overview/record.js +146 -0
  11. package/dist/components/overview/server.d.ts +4 -0
  12. package/dist/components/overview/server.d.ts.map +1 -1
  13. package/dist/components/overview/server.js +4 -0
  14. package/dist/components/overview/types.d.ts +12 -0
  15. package/dist/components/overview/types.d.ts.map +1 -1
  16. package/dist/components/overview/widgets/LineItemsWidget.svelte +144 -0
  17. package/dist/components/overview/widgets/LineItemsWidget.svelte.d.ts +6 -0
  18. package/dist/components/overview/widgets/LineItemsWidget.svelte.d.ts.map +1 -0
  19. package/dist/components/overview/widgets/RecordListWidget.svelte +67 -3
  20. package/dist/components/overview/widgets/RecordListWidget.svelte.d.ts.map +1 -1
  21. package/dist/components/overview/widgets/RecordTable.svelte +167 -0
  22. package/dist/components/overview/widgets/RecordTable.svelte.d.ts +21 -0
  23. package/dist/components/overview/widgets/RecordTable.svelte.d.ts.map +1 -0
  24. package/dist/components/overview/widgets/RelatedWidget.svelte +117 -0
  25. package/dist/components/overview/widgets/RelatedWidget.svelte.d.ts +6 -0
  26. package/dist/components/overview/widgets/RelatedWidget.svelte.d.ts.map +1 -0
  27. package/dist/components/overview/widgets/core.d.ts +13 -2
  28. package/dist/components/overview/widgets/core.d.ts.map +1 -1
  29. package/dist/components/overview/widgets/core.js +43 -2
  30. package/dist/components/overview/widgets/data.d.ts +97 -8
  31. package/dist/components/overview/widgets/data.d.ts.map +1 -1
  32. package/dist/components/overview/widgets/line-totals.d.ts +48 -0
  33. package/dist/components/overview/widgets/line-totals.d.ts.map +1 -0
  34. package/dist/components/overview/widgets/line-totals.js +91 -0
  35. package/dist/components/overview/widgets/record-loaders.d.ts +63 -0
  36. package/dist/components/overview/widgets/record-loaders.d.ts.map +1 -0
  37. package/dist/components/overview/widgets/record-loaders.js +150 -0
  38. package/dist/components/overview/widgets/record-table.d.ts +45 -0
  39. package/dist/components/overview/widgets/record-table.d.ts.map +1 -0
  40. package/dist/components/overview/widgets/record-table.js +201 -0
  41. package/dist/components/overview/widgets/record-widgets.d.ts +27 -0
  42. package/dist/components/overview/widgets/record-widgets.d.ts.map +1 -0
  43. package/dist/components/overview/widgets/record-widgets.js +100 -0
  44. package/dist/components/screens/DetailScreen.svelte +105 -6
  45. package/dist/components/screens/DetailScreen.svelte.d.ts.map +1 -1
  46. package/dist/components/screens/EditForm.svelte +39 -3
  47. package/dist/components/screens/EditForm.svelte.d.ts.map +1 -1
  48. package/dist/components/screens/RecipeScreens.svelte +18 -18
  49. package/dist/components/screens/RecipeScreens.svelte.d.ts.map +1 -1
  50. package/dist/components/screens/RecordHeader.svelte +238 -0
  51. package/dist/components/screens/RecordHeader.svelte.d.ts +26 -0
  52. package/dist/components/screens/RecordHeader.svelte.d.ts.map +1 -0
  53. package/dist/components/screens/RecordScreen.svelte +511 -0
  54. package/dist/components/screens/RecordScreen.svelte.d.ts +5 -0
  55. package/dist/components/screens/RecordScreen.svelte.d.ts.map +1 -0
  56. package/dist/components/screens/columns.d.ts +29 -0
  57. package/dist/components/screens/columns.d.ts.map +1 -0
  58. package/dist/components/screens/columns.js +115 -0
  59. package/dist/components/screens/fields.d.ts +12 -2
  60. package/dist/components/screens/fields.d.ts.map +1 -1
  61. package/dist/components/screens/fields.js +37 -5
  62. package/dist/components/screens/index.d.ts +7 -2
  63. package/dist/components/screens/index.d.ts.map +1 -1
  64. package/dist/components/screens/index.js +6 -1
  65. package/dist/components/screens/record-header.d.ts +51 -0
  66. package/dist/components/screens/record-header.d.ts.map +1 -0
  67. package/dist/components/screens/record-header.js +118 -0
  68. package/dist/components/screens/relations.d.ts +49 -0
  69. package/dist/components/screens/relations.d.ts.map +1 -0
  70. package/dist/components/screens/relations.js +98 -0
  71. package/dist/components/screens/roles.d.ts +56 -0
  72. package/dist/components/screens/roles.d.ts.map +1 -0
  73. package/dist/components/screens/roles.js +174 -0
  74. package/dist/components/screens/types.d.ts +182 -1
  75. package/dist/components/screens/types.d.ts.map +1 -1
  76. package/dist/components/screens/values.d.ts +23 -1
  77. package/dist/components/screens/values.d.ts.map +1 -1
  78. package/dist/components/screens/values.js +80 -4
  79. package/dist/i18n/strings.overview.d.ts +25 -0
  80. package/dist/i18n/strings.overview.d.ts.map +1 -1
  81. package/dist/i18n/strings.overview.js +25 -0
  82. package/dist/i18n/strings.screens.d.ts +8 -0
  83. package/dist/i18n/strings.screens.d.ts.map +1 -1
  84. package/dist/i18n/strings.screens.js +8 -0
  85. package/package.json +16 -16
@@ -0,0 +1,146 @@
1
+ import { relationKey } from '../screens/relations.js';
2
+ import { defineOverview } from './model.js';
3
+ import { formatColumnsOption } from './widgets/record-table.js';
4
+ /** Widget types a record overview offers by default. */
5
+ export const RECORD_OVERVIEW_ALLOWED = [
6
+ 'related',
7
+ 'line-items',
8
+ 'records',
9
+ 'metric',
10
+ 'chart',
11
+ 'note',
12
+ ];
13
+ /** Tiles in the default summary strip. */
14
+ export const RECORD_OVERVIEW_MAX_METRICS = 4;
15
+ /** Rows a default `records` panel shows. */
16
+ export const RECORD_OVERVIEW_LIMIT = 5;
17
+ /**
18
+ * `detail:<model>` as an overview id. A qualified model id
19
+ * (`@acme/shop:Customer`) carries characters an overview id cannot
20
+ * (`OVERVIEW_PAGE_ID_PATTERN`), so `@`, `/` and `:` fold to dots:
21
+ * `detail:acme.shop.Customer`. Stable per model kind.
22
+ */
23
+ export function recordOverviewId(model) {
24
+ const folded = model
25
+ .replace(/^@/, '')
26
+ .replace(/[/:]+/g, '.')
27
+ .replace(/[^A-Za-z0-9_.-]/g, '-')
28
+ .replace(/^[^A-Za-z0-9]+/, '');
29
+ return `detail:${folded || 'record'}`;
30
+ }
31
+ /**
32
+ * A default widget's id, from its relation rather than its position:
33
+ * `<prefix>-<Class>-<field>` (`records-Order-customerId`). The same relation
34
+ * keeps its id whichever other relations a host shows (a host may narrow the
35
+ * defaults to the models one app has), and never collides with the `w<n>`
36
+ * ids `nextWidgetId` gives added widgets, so a stored override stays valid
37
+ * against the full and the narrowed definition alike.
38
+ */
39
+ function relationWidgetId(prefix, relation, taken) {
40
+ const base = `${prefix}-${relationKey(relation)}`
41
+ .replace(/[^A-Za-z0-9_-]+/g, '-')
42
+ .slice(0, 60);
43
+ let id = base;
44
+ for (let n = 2; taken.has(id); n += 1)
45
+ id = `${base}-${n}`;
46
+ taken.add(id);
47
+ return id;
48
+ }
49
+ /** Span of a default `records` panel: two side by side on a wide page. */
50
+ export const RECORD_OVERVIEW_PANEL_SPAN = 2;
51
+ /** The default record overview of `definition` for its relations. */
52
+ export function recordOverview(definition, relations, options = {}) {
53
+ const children = relations.filter((r) => r.kind === 'children');
54
+ const items = relations.filter((r) => r.kind === 'items');
55
+ const defaults = [];
56
+ const models = [];
57
+ const taken = new Set();
58
+ for (const relation of [...items, ...children]) {
59
+ if (!models.includes(relation.model))
60
+ models.push(relation.model);
61
+ }
62
+ if (options.metrics !== false) {
63
+ const max = options.maxMetrics ?? RECORD_OVERVIEW_MAX_METRICS;
64
+ const strip = [];
65
+ for (const relation of children) {
66
+ if (strip.length >= max)
67
+ break;
68
+ strip.push({
69
+ id: relationWidgetId('count', relation, taken),
70
+ type: 'metric',
71
+ span: 1,
72
+ options: {
73
+ title: relation.label,
74
+ model: relation.model,
75
+ measure: 'count',
76
+ field: relation.field,
77
+ filter: 'parent',
78
+ },
79
+ });
80
+ const money = (relation.columns ?? []).find((c) => c.role === 'money');
81
+ if (!money || strip.length >= max)
82
+ continue;
83
+ strip.push({
84
+ id: relationWidgetId('sum', relation, taken),
85
+ type: 'metric',
86
+ span: 1,
87
+ options: {
88
+ title: `${relation.label} · ${money.label}`,
89
+ model: relation.model,
90
+ measure: 'sum',
91
+ field: money.key,
92
+ filter: 'parent',
93
+ parentField: relation.field,
94
+ },
95
+ });
96
+ }
97
+ defaults.push(...strip);
98
+ }
99
+ const lines = items[0];
100
+ if (lines) {
101
+ defaults.push({
102
+ id: relationWidgetId('items', lines, taken),
103
+ type: 'line-items',
104
+ span: 4,
105
+ options: { title: lines.label, relation: relationKey(lines) },
106
+ });
107
+ }
108
+ if (options.related === 'panels') {
109
+ for (const relation of children) {
110
+ defaults.push({
111
+ id: relationWidgetId('records', relation, taken),
112
+ type: 'records',
113
+ span: RECORD_OVERVIEW_PANEL_SPAN,
114
+ options: {
115
+ title: relation.label,
116
+ model: relation.model,
117
+ field: relation.field,
118
+ filter: 'parent',
119
+ sort: 'createdAt',
120
+ direction: 'desc',
121
+ limit: RECORD_OVERVIEW_LIMIT,
122
+ ...((relation.columns ?? []).length > 0
123
+ ? {
124
+ columns: formatColumnsOption((relation.columns ?? []).map((c) => c.key)),
125
+ }
126
+ : {}),
127
+ },
128
+ });
129
+ }
130
+ }
131
+ else if (children.length > 0) {
132
+ taken.add('related');
133
+ defaults.push({
134
+ id: 'related',
135
+ type: 'related',
136
+ span: 4,
137
+ options: { limit: RECORD_OVERVIEW_LIMIT },
138
+ });
139
+ }
140
+ return defineOverview({
141
+ id: options.id ?? recordOverviewId(definition.objectRef),
142
+ allowed: RECORD_OVERVIEW_ALLOWED,
143
+ models: models.length > 0 ? models : undefined,
144
+ defaults,
145
+ });
146
+ }
@@ -10,7 +10,11 @@ export { type LoadOverviewOptions, loadOverview, type WidgetLoadInput, } from '.
10
10
  export { applyOverviewOverride, checkOverviewOverride, defineOverview, diffOverview, isEmptyOverride, nextWidgetId, type OverviewOverrideCheck, parseOverviewDocument, parseOverviewOverride, type ResolvedOverview, resolveOverview, type SanitizeOptions, sanitizeOverview, } from './model.js';
11
11
  export { allowedWidgetTypes, type DescribeOverviewInput, describeOverview, OVERVIEW_MAX_OPERATIONS, OVERVIEW_OPERATION_KINDS, OVERVIEW_OPERATION_SCHEMA, type OverviewAddOperation, type OverviewConfigureOperation, type OverviewDescription, type OverviewMoveOperation, type OverviewOperation, type OverviewOperationIssue, type OverviewOperationIssueCode, type OverviewOperationKind, type OverviewOperationResult, type OverviewOptionDescription, type OverviewPlan, type OverviewRemoveOperation, type OverviewResizeOperation, type OverviewWidgetTypeDescription, type PlanOverviewOperationsInput, planOverviewOperations, } from './operations.js';
12
12
  export { parseRecipeExportRef, type RecipeExportResolver, type RecipeWidgetRegistration, type RecipeWidgetSkip, type RecipeWidgetSkipReason, type RecipeWidgetSource, type RegisterRecipeWidgetsOptions, registerRecipeWidgets, } from './recipe-widgets.js';
13
+ export { RECORD_OVERVIEW_ALLOWED, RECORD_OVERVIEW_LIMIT, RECORD_OVERVIEW_MAX_METRICS, RECORD_OVERVIEW_PANEL_SPAN, type RecordOverviewOptions, recordOverview, recordOverviewId, } from './record.js';
13
14
  export { createWidgetRegistry, defaultWidgetRegistry, registerWidget, resolveWidgetComponents, type WidgetComponents, WidgetRegistry, } from './registry.js';
14
15
  export { assertWidgetOptionFields, defaultWidgetOptions, IDENTIFIER_PATTERN, MODEL_PATTERN, optionsEqual, validateWidgetOptions, } from './schema.js';
15
16
  export * from './types.js';
17
+ export { type LineItemsTotals, type LineTotalKey, type LineTotalLine, type LineTotalsMismatch, type LineTotalsResult, lineItemTotals, sumLineAmounts, } from './widgets/line-totals.js';
18
+ export { createLineItemsLoader, createRelatedLoader, LINE_ITEMS_LIMIT, lineItemsOptions, lineItemsRelation, RELATED_WIDGET_LIMIT, RELATED_WIDGET_MAX_TABS, type RecordWidgetsOptions, relatedRelations, relatedTabOptions, } from './widgets/record-loaders.js';
19
+ export { DEFAULT_STATUS_TONES, formatColumnsOption, formatRecordCell, lineItemColumns, parseColumnsOption, RECORD_TABLE_MAX_COLUMNS, RECORD_TABLE_MAX_ROWS, type RecordCellContext, relatedColumns, statusLabel, statusTone, } from './widgets/record-table.js';
16
20
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/components/overview/server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,8BAA8B,EAC9B,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAC7B,KAAK,+BAA+B,GACrC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,mBAAmB,EACxB,YAAY,EACZ,KAAK,eAAe,GACrB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,eAAe,EACf,KAAK,eAAe,EACpB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,EAChC,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,4BAA4B,EACjC,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/components/overview/server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,8BAA8B,EAC9B,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAC7B,KAAK,+BAA+B,GACrC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,mBAAmB,EACxB,YAAY,EACZ,KAAK,eAAe,GACrB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,eAAe,EACf,KAAK,eAAe,EACpB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,EAChC,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,4BAA4B,EACjC,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,cAAc,EACd,cAAc,GACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,KAAK,oBAAoB,EACzB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,iBAAiB,EACtB,cAAc,EACd,WAAW,EACX,UAAU,GACX,MAAM,2BAA2B,CAAC"}
@@ -10,6 +10,10 @@ export { loadOverview, } from './load.js';
10
10
  export { applyOverviewOverride, checkOverviewOverride, defineOverview, diffOverview, isEmptyOverride, nextWidgetId, parseOverviewDocument, parseOverviewOverride, resolveOverview, sanitizeOverview, } from './model.js';
11
11
  export { allowedWidgetTypes, describeOverview, OVERVIEW_MAX_OPERATIONS, OVERVIEW_OPERATION_KINDS, OVERVIEW_OPERATION_SCHEMA, planOverviewOperations, } from './operations.js';
12
12
  export { parseRecipeExportRef, registerRecipeWidgets, } from './recipe-widgets.js';
13
+ export { RECORD_OVERVIEW_ALLOWED, RECORD_OVERVIEW_LIMIT, RECORD_OVERVIEW_MAX_METRICS, RECORD_OVERVIEW_PANEL_SPAN, recordOverview, recordOverviewId, } from './record.js';
13
14
  export { createWidgetRegistry, defaultWidgetRegistry, registerWidget, resolveWidgetComponents, WidgetRegistry, } from './registry.js';
14
15
  export { assertWidgetOptionFields, defaultWidgetOptions, IDENTIFIER_PATTERN, MODEL_PATTERN, optionsEqual, validateWidgetOptions, } from './schema.js';
15
16
  export * from './types.js';
17
+ export { lineItemTotals, sumLineAmounts, } from './widgets/line-totals.js';
18
+ export { createLineItemsLoader, createRelatedLoader, LINE_ITEMS_LIMIT, lineItemsOptions, lineItemsRelation, RELATED_WIDGET_LIMIT, RELATED_WIDGET_MAX_TABS, relatedRelations, relatedTabOptions, } from './widgets/record-loaders.js';
19
+ export { DEFAULT_STATUS_TONES, formatColumnsOption, formatRecordCell, lineItemColumns, parseColumnsOption, RECORD_TABLE_MAX_COLUMNS, RECORD_TABLE_MAX_ROWS, relatedColumns, statusLabel, statusTone, } from './widgets/record-table.js';
@@ -158,6 +158,12 @@ export interface WidgetComponentProps<Data = unknown> {
158
158
  */
159
159
  presentation?: 'card' | 'plain';
160
160
  }
161
+ /** The record an overview is rendered on (a record view, `RecordScreen`). */
162
+ export interface WidgetRecordContext {
163
+ /** Qualified model id (`objectRef`) of the record. */
164
+ model: string;
165
+ id: string;
166
+ }
161
167
  /**
162
168
  * Context a widget `load` runs with. The host builds it inside the page's
163
169
  * server load from the request principal: the user's permissions, the
@@ -170,6 +176,12 @@ export interface WidgetLoadContext {
170
176
  /** Aborts when the load times out or the request ends. */
171
177
  signal?: AbortSignal;
172
178
  locale?: string;
179
+ /**
180
+ * The record a record overview is rendered on. A `records` / `metric`
181
+ * loader honours `options.filter === 'parent'` by confining its query to
182
+ * rows whose `options.field` equals `record.id`.
183
+ */
184
+ record?: WidgetRecordContext;
173
185
  [capability: string]: unknown;
174
186
  }
175
187
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/overview/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/overview/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ <script lang="ts">
2
+ /**
3
+ * Line items widget (#3718 record page): a document's lines as a table
4
+ * (item, quantity, unit price, amount) with a footer, then the totals block
5
+ * aligned under the amounts: subtotal, discount and tax when present, total.
6
+ * The record's own figures are shown as they are; a missing one is computed
7
+ * from the lines and says so; when the record and the lines disagree, a
8
+ * visible flag says what the lines add up to (`lineItemTotals`).
9
+ */
10
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
11
+ import { M } from '../../../i18n/strings.overview.js';
12
+ import { safeHref } from '../markdown.js';
13
+ import type { WidgetComponentProps } from '../types.js';
14
+ import { isRecord, type LineItemsWidgetData } from './data.js';
15
+ import { lineItemTotals, sumLineAmounts } from './line-totals.js';
16
+ import RecordTable from './RecordTable.svelte';
17
+ import {
18
+ formatRecordCell,
19
+ readRecordRows,
20
+ resolveRecordColumns,
21
+ } from './record-table.js';
22
+
23
+ let { data, locale, title }: WidgetComponentProps<LineItemsWidgetData> =
24
+ $props();
25
+
26
+ const { t } = useI18n();
27
+
28
+ const rows = $derived(readRecordRows(data));
29
+ const columns = $derived(
30
+ resolveRecordColumns([], isRecord(data) ? data.columns : undefined),
31
+ );
32
+ const total = $derived(
33
+ isRecord(data) &&
34
+ typeof data.total === 'number' &&
35
+ Number.isFinite(data.total)
36
+ ? data.total
37
+ : rows.length,
38
+ );
39
+ const currency = $derived(
40
+ isRecord(data) && typeof data.currency === 'string'
41
+ ? data.currency
42
+ : undefined,
43
+ );
44
+ const summaryValues = $derived.by(() => {
45
+ if (!isRecord(data) || !isRecord(data.summaries)) return undefined;
46
+ const out: Record<string, number> = {};
47
+ for (const [key, value] of Object.entries(data.summaries)) {
48
+ if (typeof value === 'number' && Number.isFinite(value)) out[key] = value;
49
+ }
50
+ return out;
51
+ });
52
+ /** The line amount column: the last money column that is summed. */
53
+ const amountKey = $derived(
54
+ [...columns]
55
+ .reverse()
56
+ .find((c) => c.role === 'money' && c.summarize !== false)?.key,
57
+ );
58
+ const lineSum = $derived.by((): number | null => {
59
+ if (!amountKey) return null;
60
+ const hosted = summaryValues?.[amountKey];
61
+ if (typeof hosted === 'number') return hosted;
62
+ if (total > rows.length) return null;
63
+ return sumLineAmounts(rows.map((row) => row.cells?.[amountKey]));
64
+ });
65
+ const result = $derived(
66
+ lineItemTotals(
67
+ isRecord(data) && isRecord(data.totals)
68
+ ? (data.totals as LineItemsWidgetData['totals'])
69
+ : undefined,
70
+ lineSum,
71
+ ),
72
+ );
73
+ const viewAll = $derived(
74
+ isRecord(data) && typeof data.href === 'string' ? safeHref(data.href) : null,
75
+ );
76
+
77
+ function money(value: number): string {
78
+ return formatRecordCell({ role: 'money' }, value, { currency, locale });
79
+ }
80
+
81
+ const LABELS = {
82
+ subtotal: M['ui.overview.line_items.subtotal'],
83
+ discount: M['ui.overview.line_items.discount'],
84
+ tax: M['ui.overview.line_items.tax'],
85
+ total: M['ui.overview.line_items.total'],
86
+ } as const;
87
+ </script>
88
+
89
+ <div class="smrt-line-items" data-smrt-component="LineItemsWidget">
90
+ {#if rows.length > 0 && columns.length > 0}
91
+ <RecordTable
92
+ {rows}
93
+ {columns}
94
+ {locale}
95
+ label={title}
96
+ {currency}
97
+ summaries
98
+ {summaryValues}
99
+ {total}
100
+ />
101
+ {:else}
102
+ <p class="smrt-line-items__empty">{t(M['ui.overview.line_items.empty'])}</p>
103
+ {/if}
104
+ {#if result.lines.length > 0}
105
+ <dl class="smrt-line-items__totals">
106
+ {#each result.lines as line (line.key)}
107
+ <div class="smrt-line-items__total" class:smrt-line-items__total--grand={line.key === 'total'}>
108
+ <dt>
109
+ {t(LABELS[line.key])}
110
+ {#if line.computed}<span class="smrt-line-items__computed">{t(M['ui.overview.line_items.computed'])}</span>{/if}
111
+ </dt>
112
+ <dd>{line.key === 'discount' ? `−${money(line.value)}` : money(line.value)}</dd>
113
+ </div>
114
+ {/each}
115
+ </dl>
116
+ {/if}
117
+ {#if result.mismatch}
118
+ <p class="smrt-line-items__flag">
119
+ <strong>{t(M['ui.overview.line_items.mismatch'], { amount: money(result.mismatch.lines) })}</strong>
120
+ {t(M[result.mismatch.field === 'subtotal' ? 'ui.overview.line_items.mismatch_subtotal' : 'ui.overview.line_items.mismatch_total'], { amount: money(result.mismatch.recorded) })}
121
+ </p>
122
+ {/if}
123
+ {#if viewAll}
124
+ <p class="smrt-line-items__foot"><a href={viewAll}>{t(M['ui.overview.records.view_all'])}</a></p>
125
+ {/if}
126
+ </div>
127
+
128
+ <style>
129
+ @layer smrt.reset, smrt.structure, smrt.theme;
130
+ @layer smrt.theme {
131
+ .smrt-line-items { display: grid; gap: var(--smrt-spacing-3); min-inline-size: 0; }
132
+ .smrt-line-items__empty { margin: 0; color: var(--smrt-color-on-surface-variant); }
133
+ .smrt-line-items__totals { display: grid; justify-self: end; gap: var(--smrt-spacing-1); min-inline-size: min(100%, 18rem); margin: 0; font-variant-numeric: tabular-nums; }
134
+ .smrt-line-items__total { display: flex; justify-content: space-between; gap: var(--smrt-spacing-4); }
135
+ .smrt-line-items__total dt { color: var(--smrt-color-on-surface-variant); }
136
+ .smrt-line-items__total dd { margin: 0; text-align: end; }
137
+ .smrt-line-items__total--grand { padding-block-start: var(--smrt-spacing-2); border-block-start: var(--smrt-hairline); font-weight: var(--smrt-typography-weight-semibold); }
138
+ .smrt-line-items__total--grand dt { color: var(--smrt-color-on-surface); }
139
+ .smrt-line-items__computed { margin-inline-start: var(--smrt-spacing-1); font-size: var(--smrt-typography-body-small-size, 0.75rem); }
140
+ .smrt-line-items__flag { margin: 0; padding: var(--smrt-spacing-2) var(--smrt-spacing-3); border-inline-start: var(--smrt-spacing-1) solid var(--smrt-color-warning); border-radius: var(--smrt-radius-sm); background: var(--smrt-color-warning-container); color: var(--smrt-color-on-warning-container); }
141
+ .smrt-line-items__foot { display: flex; justify-content: flex-end; margin: 0; }
142
+ .smrt-line-items__foot a { color: var(--smrt-color-primary); }
143
+ }
144
+ </style>
@@ -0,0 +1,6 @@
1
+ import type { WidgetComponentProps } from '../types.js';
2
+ import { type LineItemsWidgetData } from './data.js';
3
+ declare const LineItemsWidget: import("svelte").Component<WidgetComponentProps<LineItemsWidgetData>, {}, "">;
4
+ type LineItemsWidget = ReturnType<typeof LineItemsWidget>;
5
+ export default LineItemsWidget;
6
+ //# sourceMappingURL=LineItemsWidget.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LineItemsWidget.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/LineItemsWidget.svelte.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAY,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAwH/D,QAAA,MAAM,eAAe,+EAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
@@ -3,14 +3,32 @@
3
3
  * Record list widget (#3727): the rows a loader chose, each optionally a
4
4
  * link. The loader owns which field is the title and which records the viewer
5
5
  * may see; the widget only draws what it is given.
6
+ *
7
+ * With columns (the `columns` option, else the data's `columns`) the rows
8
+ * render as a compact table of their `cells` (`RecordTable`): identifier,
9
+ * status badge, date and amount by role, with a totals footer (on by
10
+ * default when a money or quantity column exists; the `summaries` option
11
+ * overrides). Without columns, the title list.
6
12
  */
7
13
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
8
14
  import { M } from '../../../i18n/strings.overview.js';
9
15
  import { safeHref } from '../markdown.js';
10
16
  import type { WidgetComponentProps } from '../types.js';
11
17
  import { isRecord, type RecordListWidgetData } from './data.js';
18
+ import RecordTable from './RecordTable.svelte';
19
+ import {
20
+ isSummedColumn,
21
+ parseColumnsOption,
22
+ readRecordRows,
23
+ resolveRecordColumns,
24
+ } from './record-table.js';
12
25
 
13
- let { data, locale }: WidgetComponentProps<RecordListWidgetData> = $props();
26
+ let {
27
+ data,
28
+ locale,
29
+ options,
30
+ title,
31
+ }: WidgetComponentProps<RecordListWidgetData> = $props();
14
32
 
15
33
  const { t } = useI18n();
16
34
  const MAX_ROWS = 50;
@@ -46,9 +64,54 @@ const total = $derived(
46
64
  const viewAll = $derived(
47
65
  isRecord(data) && typeof data.href === 'string' ? safeHref(data.href) : null,
48
66
  );
67
+
68
+ const columns = $derived(
69
+ resolveRecordColumns(
70
+ parseColumnsOption(options?.columns),
71
+ isRecord(data) ? data.columns : undefined,
72
+ ),
73
+ );
74
+ const tableRows = $derived(readRecordRows(data));
75
+ const showSummaries = $derived(
76
+ typeof options?.summaries === 'boolean'
77
+ ? options.summaries
78
+ : columns.some((c) => isSummedColumn(c)),
79
+ );
80
+ const dataTotal = $derived(
81
+ isRecord(data) &&
82
+ typeof data.total === 'number' &&
83
+ Number.isFinite(data.total)
84
+ ? data.total
85
+ : null,
86
+ );
87
+ const summaryValues = $derived.by(() => {
88
+ if (!isRecord(data) || !isRecord(data.summaries)) return undefined;
89
+ const out: Record<string, number> = {};
90
+ for (const [key, value] of Object.entries(data.summaries)) {
91
+ if (typeof value === 'number' && Number.isFinite(value)) out[key] = value;
92
+ }
93
+ return out;
94
+ });
49
95
  </script>
50
96
 
51
- {#if rows.length === 0}
97
+ {#if columns.length > 0 && tableRows.length > 0}
98
+ <RecordTable
99
+ rows={tableRows}
100
+ {columns}
101
+ {locale}
102
+ label={title}
103
+ currency={isRecord(data) && typeof data.currency === 'string' ? data.currency : undefined}
104
+ timeZone={isRecord(data) && typeof data.timeZone === 'string' ? data.timeZone : undefined}
105
+ summaries={showSummaries}
106
+ {summaryValues}
107
+ total={dataTotal}
108
+ />
109
+ {#if viewAll}
110
+ <p class="smrt-records__foot smrt-records__foot--end" data-smrt-component="RecordListWidget">
111
+ <a href={viewAll}>{t(M['ui.overview.records.view_all'])}</a>
112
+ </p>
113
+ {/if}
114
+ {:else if rows.length === 0}
52
115
  <p class="smrt-records__empty" data-smrt-component="RecordListWidget">{t(M['ui.overview.records.empty'])}</p>
53
116
  {:else}
54
117
  <ul class="smrt-records" data-smrt-component="RecordListWidget">
@@ -67,7 +130,7 @@ const viewAll = $derived(
67
130
  {/each}
68
131
  </ul>
69
132
  {/if}
70
- {#if total !== null || viewAll}
133
+ {#if columns.length === 0 && (total !== null || viewAll)}
71
134
  <p class="smrt-records__foot" data-smrt-component="RecordListWidget">
72
135
  {#if total !== null}
73
136
  <span>{t(M['ui.overview.records.total'], { count: new Intl.NumberFormat(locale).format(total) })}</span>
@@ -88,6 +151,7 @@ const viewAll = $derived(
88
151
  .smrt-records__sub, .smrt-records__meta { color: var(--smrt-color-on-surface-variant); font-size: var(--smrt-typography-body-medium-size, 0.875rem); }
89
152
  .smrt-records__meta { flex: 0 0 auto; font-variant-numeric: tabular-nums; }
90
153
  .smrt-records__foot { display: flex; justify-content: space-between; gap: var(--smrt-spacing-3); margin: var(--smrt-spacing-2) 0 0; color: var(--smrt-color-on-surface-variant); font-size: var(--smrt-typography-body-medium-size, 0.875rem); }
154
+ .smrt-records__foot--end { justify-content: flex-end; }
91
155
  .smrt-records__foot a { color: var(--smrt-color-primary); }
92
156
  .smrt-records__empty { margin: 0; color: var(--smrt-color-on-surface-variant); }
93
157
  }
@@ -1 +1 @@
1
- {"version":3,"file":"RecordListWidget.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/RecordListWidget.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAgFhE,QAAA,MAAM,gBAAgB,gFAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"RecordListWidget.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/RecordListWidget.svelte.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAiIhE,QAAA,MAAM,gBAAgB,gFAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}