@happyvertical/smrt-svelte 0.55.7 → 0.55.8

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 (197) hide show
  1. package/AGENTS.md +7 -44
  2. package/README.md +112 -1
  3. package/agents/browser-ai.md +47 -0
  4. package/agents/command-palette.md +85 -0
  5. package/agents/import-export.md +62 -0
  6. package/agents/overview-surfaces.md +255 -0
  7. package/agents/screens.md +57 -0
  8. package/dist/browser-ai/adapters/tts/browser-synthesis.d.ts +5 -0
  9. package/dist/browser-ai/adapters/tts/browser-synthesis.d.ts.map +1 -1
  10. package/dist/browser-ai/adapters/tts/browser-synthesis.js +83 -55
  11. package/dist/components/command-palette/CommandPalette.svelte +75 -0
  12. package/dist/components/command-palette/CommandPalette.svelte.d.ts +22 -0
  13. package/dist/components/command-palette/CommandPalette.svelte.d.ts.map +1 -0
  14. package/dist/components/command-palette/CommandPaletteDialog.svelte +406 -0
  15. package/dist/components/command-palette/CommandPaletteDialog.svelte.d.ts +18 -0
  16. package/dist/components/command-palette/CommandPaletteDialog.svelte.d.ts.map +1 -0
  17. package/dist/components/command-palette/CommandPaletteTrigger.svelte +91 -0
  18. package/dist/components/command-palette/CommandPaletteTrigger.svelte.d.ts +17 -0
  19. package/dist/components/command-palette/CommandPaletteTrigger.svelte.d.ts.map +1 -0
  20. package/dist/components/command-palette/context.d.ts +18 -0
  21. package/dist/components/command-palette/context.d.ts.map +1 -0
  22. package/dist/components/command-palette/context.js +38 -0
  23. package/dist/components/command-palette/controller.svelte.d.ts +70 -0
  24. package/dist/components/command-palette/controller.svelte.d.ts.map +1 -0
  25. package/dist/components/command-palette/controller.svelte.js +379 -0
  26. package/dist/components/command-palette/hotkeys.d.ts +30 -0
  27. package/dist/components/command-palette/hotkeys.d.ts.map +1 -0
  28. package/dist/components/command-palette/hotkeys.js +161 -0
  29. package/dist/components/command-palette/index.d.ts +19 -0
  30. package/dist/components/command-palette/index.d.ts.map +1 -0
  31. package/dist/components/command-palette/index.js +17 -0
  32. package/dist/components/command-palette/match.d.ts +38 -0
  33. package/dist/components/command-palette/match.d.ts.map +1 -0
  34. package/dist/components/command-palette/match.js +172 -0
  35. package/dist/components/command-palette/providers.d.ts +159 -0
  36. package/dist/components/command-palette/providers.d.ts.map +1 -0
  37. package/dist/components/command-palette/providers.js +345 -0
  38. package/dist/components/command-palette/rank.d.ts +20 -0
  39. package/dist/components/command-palette/rank.d.ts.map +1 -0
  40. package/dist/components/command-palette/rank.js +74 -0
  41. package/dist/components/command-palette/types.d.ts +119 -0
  42. package/dist/components/command-palette/types.d.ts.map +1 -0
  43. package/dist/components/command-palette/types.js +10 -0
  44. package/dist/components/command-palette/use-provider.svelte.d.ts +14 -0
  45. package/dist/components/command-palette/use-provider.svelte.d.ts.map +1 -0
  46. package/dist/components/command-palette/use-provider.svelte.js +23 -0
  47. package/dist/components/import-export/ImportExport.svelte +678 -0
  48. package/dist/components/import-export/ImportExport.svelte.d.ts +5 -0
  49. package/dist/components/import-export/ImportExport.svelte.d.ts.map +1 -0
  50. package/dist/components/import-export/collection-adapter.d.ts +35 -0
  51. package/dist/components/import-export/collection-adapter.d.ts.map +1 -0
  52. package/dist/components/import-export/collection-adapter.js +42 -0
  53. package/dist/components/import-export/csv.d.ts +60 -0
  54. package/dist/components/import-export/csv.d.ts.map +1 -0
  55. package/dist/components/import-export/csv.js +192 -0
  56. package/dist/components/import-export/download.d.ts +4 -0
  57. package/dist/components/import-export/download.d.ts.map +1 -0
  58. package/dist/components/import-export/download.js +17 -0
  59. package/dist/components/import-export/export.d.ts +25 -0
  60. package/dist/components/import-export/export.d.ts.map +1 -0
  61. package/dist/components/import-export/export.js +68 -0
  62. package/dist/components/import-export/fields.d.ts +48 -0
  63. package/dist/components/import-export/fields.d.ts.map +1 -0
  64. package/dist/components/import-export/fields.js +103 -0
  65. package/dist/components/import-export/index.d.ts +12 -0
  66. package/dist/components/import-export/index.d.ts.map +1 -0
  67. package/dist/components/import-export/index.js +9 -0
  68. package/dist/components/import-export/mapping.d.ts +12 -0
  69. package/dist/components/import-export/mapping.d.ts.map +1 -0
  70. package/dist/components/import-export/mapping.js +38 -0
  71. package/dist/components/import-export/props.d.ts +34 -0
  72. package/dist/components/import-export/props.d.ts.map +1 -0
  73. package/dist/components/import-export/props.js +1 -0
  74. package/dist/components/import-export/report.d.ts +13 -0
  75. package/dist/components/import-export/report.d.ts.map +1 -0
  76. package/dist/components/import-export/report.js +50 -0
  77. package/dist/components/import-export/runner.d.ts +17 -0
  78. package/dist/components/import-export/runner.d.ts.map +1 -0
  79. package/dist/components/import-export/runner.js +39 -0
  80. package/dist/components/import-export/types.d.ts +100 -0
  81. package/dist/components/import-export/types.d.ts.map +1 -0
  82. package/dist/components/import-export/types.js +6 -0
  83. package/dist/components/import-export/validate.d.ts +39 -0
  84. package/dist/components/import-export/validate.d.ts.map +1 -0
  85. package/dist/components/import-export/validate.js +268 -0
  86. package/dist/components/overview/OverviewGrid.svelte +579 -0
  87. package/dist/components/overview/OverviewGrid.svelte.d.ts +5 -0
  88. package/dist/components/overview/OverviewGrid.svelte.d.ts.map +1 -0
  89. package/dist/components/overview/WidgetOptionsForm.svelte +193 -0
  90. package/dist/components/overview/WidgetOptionsForm.svelte.d.ts +5 -0
  91. package/dist/components/overview/WidgetOptionsForm.svelte.d.ts.map +1 -0
  92. package/dist/components/overview/controller.svelte.d.ts +92 -0
  93. package/dist/components/overview/controller.svelte.d.ts.map +1 -0
  94. package/dist/components/overview/controller.svelte.js +336 -0
  95. package/dist/components/overview/format.d.ts +13 -0
  96. package/dist/components/overview/format.d.ts.map +1 -0
  97. package/dist/components/overview/format.js +45 -0
  98. package/dist/components/overview/grid-types.d.ts +52 -0
  99. package/dist/components/overview/grid-types.d.ts.map +1 -0
  100. package/dist/components/overview/grid-types.js +1 -0
  101. package/dist/components/overview/index.d.ts +24 -0
  102. package/dist/components/overview/index.d.ts.map +1 -0
  103. package/dist/components/overview/index.js +22 -0
  104. package/dist/components/overview/load.d.ts +30 -0
  105. package/dist/components/overview/load.d.ts.map +1 -0
  106. package/dist/components/overview/load.js +92 -0
  107. package/dist/components/overview/markdown.d.ts +53 -0
  108. package/dist/components/overview/markdown.d.ts.map +1 -0
  109. package/dist/components/overview/markdown.js +203 -0
  110. package/dist/components/overview/model.d.ts +100 -0
  111. package/dist/components/overview/model.d.ts.map +1 -0
  112. package/dist/components/overview/model.js +460 -0
  113. package/dist/components/overview/recipe-widgets.d.ts +77 -0
  114. package/dist/components/overview/recipe-widgets.d.ts.map +1 -0
  115. package/dist/components/overview/recipe-widgets.js +151 -0
  116. package/dist/components/overview/registry.d.ts +45 -0
  117. package/dist/components/overview/registry.d.ts.map +1 -0
  118. package/dist/components/overview/registry.js +112 -0
  119. package/dist/components/overview/resize.d.ts +25 -0
  120. package/dist/components/overview/resize.d.ts.map +1 -0
  121. package/dist/components/overview/resize.js +41 -0
  122. package/dist/components/overview/schema.d.ts +34 -0
  123. package/dist/components/overview/schema.d.ts.map +1 -0
  124. package/dist/components/overview/schema.js +180 -0
  125. package/dist/components/overview/server.d.ts +14 -0
  126. package/dist/components/overview/server.d.ts.map +1 -0
  127. package/dist/components/overview/server.js +13 -0
  128. package/dist/components/overview/types.d.ts +235 -0
  129. package/dist/components/overview/types.d.ts.map +1 -0
  130. package/dist/components/overview/types.js +17 -0
  131. package/dist/components/overview/widgets/ChartWidget.svelte +111 -0
  132. package/dist/components/overview/widgets/ChartWidget.svelte.d.ts +6 -0
  133. package/dist/components/overview/widgets/ChartWidget.svelte.d.ts.map +1 -0
  134. package/dist/components/overview/widgets/MetricWidget.svelte +86 -0
  135. package/dist/components/overview/widgets/MetricWidget.svelte.d.ts +6 -0
  136. package/dist/components/overview/widgets/MetricWidget.svelte.d.ts.map +1 -0
  137. package/dist/components/overview/widgets/NoteWidget.svelte +61 -0
  138. package/dist/components/overview/widgets/NoteWidget.svelte.d.ts +5 -0
  139. package/dist/components/overview/widgets/NoteWidget.svelte.d.ts.map +1 -0
  140. package/dist/components/overview/widgets/RecordListWidget.svelte +91 -0
  141. package/dist/components/overview/widgets/RecordListWidget.svelte.d.ts +6 -0
  142. package/dist/components/overview/widgets/RecordListWidget.svelte.d.ts.map +1 -0
  143. package/dist/components/overview/widgets/ShortcutsWidget.svelte +80 -0
  144. package/dist/components/overview/widgets/ShortcutsWidget.svelte.d.ts +6 -0
  145. package/dist/components/overview/widgets/ShortcutsWidget.svelte.d.ts.map +1 -0
  146. package/dist/components/overview/widgets/core.d.ts +44 -0
  147. package/dist/components/overview/widgets/core.d.ts.map +1 -0
  148. package/dist/components/overview/widgets/core.js +222 -0
  149. package/dist/components/overview/widgets/data.d.ts +76 -0
  150. package/dist/components/overview/widgets/data.d.ts.map +1 -0
  151. package/dist/components/overview/widgets/data.js +40 -0
  152. package/dist/components/screens/DetailScreen.svelte +220 -0
  153. package/dist/components/screens/DetailScreen.svelte.d.ts +5 -0
  154. package/dist/components/screens/DetailScreen.svelte.d.ts.map +1 -0
  155. package/dist/components/screens/EditForm.svelte +313 -0
  156. package/dist/components/screens/EditForm.svelte.d.ts +5 -0
  157. package/dist/components/screens/EditForm.svelte.d.ts.map +1 -0
  158. package/dist/components/screens/ListScreen.svelte +191 -0
  159. package/dist/components/screens/ListScreen.svelte.d.ts +5 -0
  160. package/dist/components/screens/ListScreen.svelte.d.ts.map +1 -0
  161. package/dist/components/screens/RecipeScreens.svelte +237 -0
  162. package/dist/components/screens/RecipeScreens.svelte.d.ts +5 -0
  163. package/dist/components/screens/RecipeScreens.svelte.d.ts.map +1 -0
  164. package/dist/components/screens/fields.d.ts +54 -0
  165. package/dist/components/screens/fields.d.ts.map +1 -0
  166. package/dist/components/screens/fields.js +229 -0
  167. package/dist/components/screens/index.d.ts +8 -0
  168. package/dist/components/screens/index.d.ts.map +1 -0
  169. package/dist/components/screens/index.js +6 -0
  170. package/dist/components/screens/types.d.ts +215 -0
  171. package/dist/components/screens/types.d.ts.map +1 -0
  172. package/dist/components/screens/types.js +1 -0
  173. package/dist/components/screens/values.d.ts +62 -0
  174. package/dist/components/screens/values.d.ts.map +1 -0
  175. package/dist/components/screens/values.js +289 -0
  176. package/dist/components/sortable/controller.svelte.d.ts +10 -0
  177. package/dist/components/sortable/controller.svelte.d.ts.map +1 -1
  178. package/dist/components/sortable/controller.svelte.js +29 -7
  179. package/dist/components/workspace/manifest-nav.d.ts +20 -0
  180. package/dist/components/workspace/manifest-nav.d.ts.map +1 -1
  181. package/dist/components/workspace/manifest-nav.js +42 -13
  182. package/dist/i18n/server.d.ts +6 -0
  183. package/dist/i18n/server.d.ts.map +1 -1
  184. package/dist/i18n/server.js +6 -0
  185. package/dist/i18n/strings.import-export.d.ts +88 -0
  186. package/dist/i18n/strings.import-export.d.ts.map +1 -0
  187. package/dist/i18n/strings.import-export.js +88 -0
  188. package/dist/i18n/strings.overview.d.ts +100 -0
  189. package/dist/i18n/strings.overview.d.ts.map +1 -0
  190. package/dist/i18n/strings.overview.js +107 -0
  191. package/dist/i18n/strings.palette.d.ts +18 -0
  192. package/dist/i18n/strings.palette.d.ts.map +1 -0
  193. package/dist/i18n/strings.palette.js +18 -0
  194. package/dist/i18n/strings.screens.d.ts +31 -0
  195. package/dist/i18n/strings.screens.d.ts.map +1 -0
  196. package/dist/i18n/strings.screens.js +31 -0
  197. package/package.json +45 -16
@@ -0,0 +1,80 @@
1
+ <script lang="ts">
2
+ /**
3
+ * Shortcuts widget (#3727): the section-overview cards as a widget. It draws
4
+ * the cards a loader produced (see `shortcutsFromNav`), with the same look as
5
+ * `ShellSectionMenu layout="cards"`, so a section's default overview is just
6
+ * this widget.
7
+ */
8
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
9
+ import { M } from '../../../i18n/strings.overview.js';
10
+ import ShellSectionIcon from '../../workspace/admin-shell/ShellSectionIcon.svelte';
11
+ import { SHELL_DEFAULT_SECTION_ICON } from '../../workspace/admin-shell/shell-icons.js';
12
+ import { safeHref } from '../markdown.js';
13
+ import type { WidgetComponentProps } from '../types.js';
14
+ import { isRecord, type ShortcutsWidgetData } from './data.js';
15
+
16
+ let { data, iconComponent }: WidgetComponentProps<ShortcutsWidgetData> =
17
+ $props();
18
+
19
+ const { t } = useI18n();
20
+ const MAX_ITEMS = 48;
21
+
22
+ interface Card {
23
+ id: string;
24
+ label: string;
25
+ href: string;
26
+ icon: string;
27
+ description?: string;
28
+ }
29
+
30
+ const cards = $derived.by((): Card[] => {
31
+ if (!isRecord(data) || !Array.isArray(data.items)) return [];
32
+ const out: Card[] = [];
33
+ for (const item of data.items.slice(0, MAX_ITEMS)) {
34
+ if (!isRecord(item) || typeof item.label !== 'string') continue;
35
+ const href = typeof item.href === 'string' ? safeHref(item.href) : null;
36
+ if (!href) continue;
37
+ out.push({
38
+ id: typeof item.id === 'string' ? item.id : href,
39
+ label: item.label,
40
+ href,
41
+ icon:
42
+ typeof item.icon === 'string' ? item.icon : SHELL_DEFAULT_SECTION_ICON,
43
+ description:
44
+ typeof item.description === 'string' ? item.description : undefined,
45
+ });
46
+ }
47
+ return out;
48
+ });
49
+ </script>
50
+
51
+ {#if cards.length === 0}
52
+ <p class="smrt-shortcuts__empty">{t(M['ui.overview.shortcuts.empty'])}</p>
53
+ {:else}
54
+ <ul class="smrt-shortcuts">
55
+ {#each cards as card (card.id)}
56
+ <li class="smrt-shortcuts__card">
57
+ <a class="smrt-shortcuts__link" href={card.href}>
58
+ <span class="smrt-shortcuts__icon">
59
+ <ShellSectionIcon name={card.icon} size={28} {iconComponent} />
60
+ </span>
61
+ <span class="smrt-shortcuts__title">{card.label}</span>
62
+ {#if card.description}<span class="smrt-shortcuts__desc">{card.description}</span>{/if}
63
+ </a>
64
+ </li>
65
+ {/each}
66
+ </ul>
67
+ {/if}
68
+
69
+ <style>
70
+ .smrt-shortcuts { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(12rem, 100%), 1fr)); gap: var(--smrt-spacing-3); margin: 0; padding: 0; list-style: none; }
71
+ .smrt-shortcuts__card { position: relative; display: flex; min-inline-size: 0; border: 1px solid var(--smrt-color-outline-variant); border-radius: var(--smrt-radius-large, var(--smrt-radius-medium)); background: var(--smrt-color-surface); transition: background-color 120ms, border-color 120ms; }
72
+ .smrt-shortcuts__card:hover { background: var(--smrt-color-surface-container-high); border-color: var(--smrt-color-outline); }
73
+ .smrt-shortcuts__link { flex: 1 1 auto; display: flex; flex-direction: column; gap: var(--smrt-spacing-2); padding: var(--smrt-spacing-3); color: var(--smrt-color-on-surface); text-decoration: none; }
74
+ .smrt-shortcuts__link:focus-visible { outline: 2px solid var(--smrt-color-primary); outline-offset: 2px; border-radius: inherit; }
75
+ .smrt-shortcuts__icon { display: inline-grid; place-items: center; inline-size: 3rem; block-size: 3rem; border-radius: var(--smrt-radius-full, 9999px); background: var(--smrt-color-primary-container); color: var(--smrt-color-on-primary-container); }
76
+ .smrt-shortcuts__icon :global(.smrt-shell-section-icon) { inline-size: 28px; block-size: 28px; }
77
+ .smrt-shortcuts__title { font-weight: var(--smrt-typography-weight-medium, 500); overflow-wrap: anywhere; }
78
+ .smrt-shortcuts__desc { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; color: var(--smrt-color-on-surface-variant); font-size: var(--smrt-typography-body-medium-size, 0.875rem); }
79
+ .smrt-shortcuts__empty { margin: 0; color: var(--smrt-color-on-surface-variant); }
80
+ </style>
@@ -0,0 +1,6 @@
1
+ import type { WidgetComponentProps } from '../types.js';
2
+ import { type ShortcutsWidgetData } from './data.js';
3
+ declare const ShortcutsWidget: import("svelte").Component<WidgetComponentProps<ShortcutsWidgetData>, {}, "">;
4
+ type ShortcutsWidget = ReturnType<typeof ShortcutsWidget>;
5
+ export default ShortcutsWidget;
6
+ //# sourceMappingURL=ShortcutsWidget.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShortcutsWidget.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/ShortcutsWidget.svelte.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAY,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAqE/D,QAAA,MAAM,eAAe,+EAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The core widget definitions (#3727): metric, chart, record list, shortcuts
3
+ * and note. Data-backed widgets take their loader by structural injection, so
4
+ * this package depends on no data package: an app wires `load` to runtime
5
+ * reports, a collection query, or the planner's in-browser source.
6
+ *
7
+ * ```ts
8
+ * registerCoreWidgets(defaultWidgetRegistry, {
9
+ * metric: (options, ctx) => countRecords(ctx, options),
10
+ * chart: (options, ctx) => runReportChart(ctx, options),
11
+ * });
12
+ * ```
13
+ */
14
+ import { type WidgetRegistry } from '../registry.js';
15
+ import type { WidgetDefinition, WidgetLoad } from '../types.js';
16
+ import type { ChartWidgetData, MetricWidgetData, RecordListWidgetData, ShortcutsWidgetData } from './data.js';
17
+ /** Metric: one number from a model. Options: model, measure, field, filter. */
18
+ export declare function createMetricWidget(load: WidgetLoad<MetricWidgetData>): WidgetDefinition<MetricWidgetData>;
19
+ /** Chart: values grouped by a field over a period. */
20
+ export declare function createChartWidget(load: WidgetLoad<ChartWidgetData>): WidgetDefinition<ChartWidgetData>;
21
+ /** Record list: the latest or top records of a model. */
22
+ export declare function createRecordListWidget(load: WidgetLoad<RecordListWidgetData>): WidgetDefinition<RecordListWidgetData>;
23
+ /**
24
+ * Shortcuts: the section-overview cards. The default widget of a section
25
+ * overview; its loader typically wraps `shortcutsFromNav`.
26
+ */
27
+ export declare function createShortcutsWidget(load: WidgetLoad<ShortcutsWidgetData>): WidgetDefinition<ShortcutsWidgetData>;
28
+ /** Note: sanitized Markdown text. Needs no loader. */
29
+ export declare function createNoteWidget(): WidgetDefinition;
30
+ /** The loaders an app supplies; a widget without one is not registered. */
31
+ export interface CoreWidgetLoaders {
32
+ metric?: WidgetLoad<MetricWidgetData>;
33
+ chart?: WidgetLoad<ChartWidgetData>;
34
+ records?: WidgetLoad<RecordListWidgetData>;
35
+ shortcuts?: WidgetLoad<ShortcutsWidgetData>;
36
+ }
37
+ /**
38
+ * Register the core widgets on `registry`: `note` always, each data-backed
39
+ * widget only when its loader is given. Returns a disposer for all of them.
40
+ */
41
+ export declare function registerCoreWidgets(registry?: WidgetRegistry, loaders?: CoreWidgetLoaders, options?: {
42
+ replace?: boolean;
43
+ }): () => void;
44
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,KAAK,EACV,gBAAgB,EAChB,UAAU,EAEX,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,WAAW,CAAC;AA2CnB,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,CAAC,gBAAgB,CAAC,GACjC,gBAAgB,CAAC,gBAAgB,CAAC,CAgBpC;AAED,sDAAsD;AACtD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,UAAU,CAAC,eAAe,CAAC,GAChC,gBAAgB,CAAC,eAAe,CAAC,CA0CnC;AAED,yDAAyD;AACzD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,UAAU,CAAC,oBAAoB,CAAC,GACrC,gBAAgB,CAAC,oBAAoB,CAAC,CAkCxC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,UAAU,CAAC,mBAAmB,CAAC,GACpC,gBAAgB,CAAC,mBAAmB,CAAC,CAmBvC;AAED,sDAAsD;AACtD,wBAAgB,gBAAgB,IAAI,gBAAgB,CAoBnD;AAED,2EAA2E;AAC3E,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAC3C,SAAS,CAAC,EAAE,UAAU,CAAC,mBAAmB,CAAC,CAAC;CAC7C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,GAAE,cAAsC,EAChD,OAAO,GAAE,iBAAsB,EAC/B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,MAAM,IAAI,CAyBZ"}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * The core widget definitions (#3727): metric, chart, record list, shortcuts
3
+ * and note. Data-backed widgets take their loader by structural injection, so
4
+ * this package depends on no data package: an app wires `load` to runtime
5
+ * reports, a collection query, or the planner's in-browser source.
6
+ *
7
+ * ```ts
8
+ * registerCoreWidgets(defaultWidgetRegistry, {
9
+ * metric: (options, ctx) => countRecords(ctx, options),
10
+ * chart: (options, ctx) => runReportChart(ctx, options),
11
+ * });
12
+ * ```
13
+ */
14
+ import { defaultWidgetRegistry } from '../registry.js';
15
+ import ChartWidget from './ChartWidget.svelte';
16
+ import MetricWidget from './MetricWidget.svelte';
17
+ import NoteWidget from './NoteWidget.svelte';
18
+ import RecordListWidget from './RecordListWidget.svelte';
19
+ import ShortcutsWidget from './ShortcutsWidget.svelte';
20
+ const titleField = {
21
+ key: 'title',
22
+ type: 'text',
23
+ label: 'ui.overview.opt.title',
24
+ help: 'ui.overview.opt.title_help',
25
+ maxLength: 80,
26
+ };
27
+ const modelField = {
28
+ key: 'model',
29
+ type: 'model',
30
+ label: 'ui.overview.opt.model',
31
+ help: 'ui.overview.opt.model_help',
32
+ required: true,
33
+ };
34
+ const filterField = {
35
+ key: 'filter',
36
+ type: 'identifier',
37
+ label: 'ui.overview.opt.filter',
38
+ help: 'ui.overview.opt.filter_help',
39
+ };
40
+ const fieldField = {
41
+ key: 'field',
42
+ type: 'identifier',
43
+ label: 'ui.overview.opt.field',
44
+ help: 'ui.overview.opt.field_help',
45
+ };
46
+ const measureField = (choices) => ({
47
+ key: 'measure',
48
+ type: 'enum',
49
+ label: 'ui.overview.opt.measure',
50
+ default: 'count',
51
+ choices: choices.map((value) => ({
52
+ value,
53
+ label: `ui.overview.opt.measure_${value}`,
54
+ })),
55
+ });
56
+ /** Metric: one number from a model. Options: model, measure, field, filter. */
57
+ export function createMetricWidget(load) {
58
+ return {
59
+ type: 'metric',
60
+ title: 'ui.overview.widget.metric.title',
61
+ description: 'ui.overview.widget.metric.description',
62
+ icon: 'layers',
63
+ options: [
64
+ titleField,
65
+ modelField,
66
+ measureField(['count', 'sum', 'avg', 'min', 'max']),
67
+ fieldField,
68
+ filterField,
69
+ ],
70
+ component: MetricWidget,
71
+ load,
72
+ };
73
+ }
74
+ /** Chart: values grouped by a field over a period. */
75
+ export function createChartWidget(load) {
76
+ return {
77
+ type: 'chart',
78
+ title: 'ui.overview.widget.chart.title',
79
+ description: 'ui.overview.widget.chart.description',
80
+ icon: 'repeat',
81
+ options: [
82
+ titleField,
83
+ modelField,
84
+ {
85
+ key: 'groupBy',
86
+ type: 'identifier',
87
+ label: 'ui.overview.opt.group_by',
88
+ },
89
+ measureField(['count', 'sum', 'avg']),
90
+ fieldField,
91
+ {
92
+ key: 'period',
93
+ type: 'enum',
94
+ label: 'ui.overview.opt.period',
95
+ default: '30d',
96
+ choices: ['7d', '30d', '90d', '12m', 'all'].map((value) => ({
97
+ value,
98
+ label: `ui.overview.opt.period_${value}`,
99
+ })),
100
+ },
101
+ {
102
+ key: 'style',
103
+ type: 'enum',
104
+ label: 'ui.overview.opt.style',
105
+ default: 'bar',
106
+ choices: [
107
+ { value: 'bar', label: 'ui.overview.opt.style_bar' },
108
+ { value: 'line', label: 'ui.overview.opt.style_line' },
109
+ ],
110
+ },
111
+ filterField,
112
+ ],
113
+ component: ChartWidget,
114
+ load,
115
+ defaultSpan: 2,
116
+ };
117
+ }
118
+ /** Record list: the latest or top records of a model. */
119
+ export function createRecordListWidget(load) {
120
+ return {
121
+ type: 'records',
122
+ title: 'ui.overview.widget.records.title',
123
+ description: 'ui.overview.widget.records.description',
124
+ icon: 'fileText',
125
+ options: [
126
+ titleField,
127
+ modelField,
128
+ { key: 'sort', type: 'identifier', label: 'ui.overview.opt.sort' },
129
+ {
130
+ key: 'direction',
131
+ type: 'enum',
132
+ label: 'ui.overview.opt.direction',
133
+ default: 'desc',
134
+ choices: [
135
+ { value: 'desc', label: 'ui.overview.opt.direction_desc' },
136
+ { value: 'asc', label: 'ui.overview.opt.direction_asc' },
137
+ ],
138
+ },
139
+ {
140
+ key: 'limit',
141
+ type: 'integer',
142
+ label: 'ui.overview.opt.limit',
143
+ default: 5,
144
+ min: 1,
145
+ max: 20,
146
+ },
147
+ filterField,
148
+ ],
149
+ component: RecordListWidget,
150
+ load,
151
+ defaultSpan: 2,
152
+ };
153
+ }
154
+ /**
155
+ * Shortcuts: the section-overview cards. The default widget of a section
156
+ * overview; its loader typically wraps `shortcutsFromNav`.
157
+ */
158
+ export function createShortcutsWidget(load) {
159
+ return {
160
+ type: 'shortcuts',
161
+ title: 'ui.overview.widget.shortcuts.title',
162
+ description: 'ui.overview.widget.shortcuts.description',
163
+ icon: 'home',
164
+ options: [
165
+ titleField,
166
+ {
167
+ key: 'section',
168
+ type: 'identifier',
169
+ label: 'ui.overview.opt.section',
170
+ help: 'ui.overview.opt.section_help',
171
+ },
172
+ ],
173
+ component: ShortcutsWidget,
174
+ load,
175
+ defaultSpan: 4,
176
+ };
177
+ }
178
+ /** Note: sanitized Markdown text. Needs no loader. */
179
+ export function createNoteWidget() {
180
+ return {
181
+ type: 'note',
182
+ title: 'ui.overview.widget.note.title',
183
+ description: 'ui.overview.widget.note.description',
184
+ icon: 'fileText',
185
+ options: [
186
+ titleField,
187
+ {
188
+ key: 'body',
189
+ type: 'markdown',
190
+ label: 'ui.overview.opt.body',
191
+ help: 'ui.overview.opt.body_help',
192
+ default: '',
193
+ maxLength: 4000,
194
+ },
195
+ ],
196
+ component: NoteWidget,
197
+ defaultSpan: 2,
198
+ };
199
+ }
200
+ /**
201
+ * Register the core widgets on `registry`: `note` always, each data-backed
202
+ * widget only when its loader is given. Returns a disposer for all of them.
203
+ */
204
+ export function registerCoreWidgets(registry = defaultWidgetRegistry, loaders = {}, options = {}) {
205
+ const disposers = [registry.register(createNoteWidget(), options)];
206
+ if (loaders.metric) {
207
+ disposers.push(registry.register(createMetricWidget(loaders.metric), options));
208
+ }
209
+ if (loaders.chart) {
210
+ disposers.push(registry.register(createChartWidget(loaders.chart), options));
211
+ }
212
+ if (loaders.records) {
213
+ disposers.push(registry.register(createRecordListWidget(loaders.records), options));
214
+ }
215
+ if (loaders.shortcuts) {
216
+ disposers.push(registry.register(createShortcutsWidget(loaders.shortcuts), options));
217
+ }
218
+ return () => {
219
+ for (const dispose of disposers)
220
+ dispose();
221
+ };
222
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The data each core widget renders (#3727), and the pure helpers a loader
3
+ * uses to produce it. The shapes are structural on purpose: a loader can be
4
+ * backed by runtime reports, a collection query or the planner's in-browser
5
+ * source without this package depending on any of them.
6
+ */
7
+ import type { WidgetValueFormat } from '../format.js';
8
+ /** `metric`: one number. `money` values are integer minor units. */
9
+ export interface MetricWidgetData {
10
+ value: number;
11
+ format?: WidgetValueFormat;
12
+ /** ISO 4217 code for `money`. */
13
+ currency?: string;
14
+ /** Caption under the number (default: the widget title only). */
15
+ label?: string;
16
+ /** Percent change against the previous period (12.5 means +12.5%). */
17
+ change?: number | null;
18
+ href?: string;
19
+ }
20
+ /** `chart`: values grouped by label. Shaped like one measure of a runtime report. */
21
+ export interface ChartWidgetData {
22
+ points: {
23
+ label: string;
24
+ value: number;
25
+ }[];
26
+ format?: WidgetValueFormat;
27
+ currency?: string;
28
+ href?: string;
29
+ }
30
+ /** `records`: the rows to list. The loader chooses the title field. */
31
+ export interface RecordListWidgetData {
32
+ rows: {
33
+ id: string;
34
+ title: string;
35
+ subtitle?: string;
36
+ meta?: string;
37
+ href?: string;
38
+ }[];
39
+ /** Total matching records, when more than `rows`. */
40
+ total?: number;
41
+ /** Link to the full list. */
42
+ href?: string;
43
+ }
44
+ /** `shortcuts`: cards that link to pages. */
45
+ export interface ShortcutsWidgetData {
46
+ items: {
47
+ id: string;
48
+ label: string;
49
+ href: string;
50
+ icon?: string;
51
+ description?: string;
52
+ }[];
53
+ }
54
+ /** The part of a shell nav model section `shortcutsFromNav` reads. */
55
+ export interface ShortcutNavSection {
56
+ id: string;
57
+ items: readonly {
58
+ id: string;
59
+ label: string;
60
+ hidden?: boolean;
61
+ item: {
62
+ href: string;
63
+ icon?: string;
64
+ description?: string;
65
+ };
66
+ }[];
67
+ }
68
+ /**
69
+ * Cards for one navigation section: its visible entries with the user's
70
+ * renames, as `resolveShellNavModel(...)` (or `useShellLayout().sections`)
71
+ * reports them. Entries with an unsafe href are skipped. With no
72
+ * `sectionId`, every section's entries are listed.
73
+ */
74
+ export declare function shortcutsFromNav(sections: readonly ShortcutNavSection[], sectionId?: string): ShortcutsWidgetData;
75
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
76
+ //# sourceMappingURL=data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/data.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtD,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,uEAAuE;AACvE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;IACJ,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,EAAE,CAAC;CACL;AAED,sEAAsE;AACtE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS;QACd,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,IAAI,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC7D,EAAE,CAAC;CACL;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,SAAS,kBAAkB,EAAE,EACvC,SAAS,CAAC,EAAE,MAAM,GACjB,mBAAmB,CAoBrB;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The data each core widget renders (#3727), and the pure helpers a loader
3
+ * uses to produce it. The shapes are structural on purpose: a loader can be
4
+ * backed by runtime reports, a collection query or the planner's in-browser
5
+ * source without this package depending on any of them.
6
+ */
7
+ import { safeHref } from '../markdown.js';
8
+ /**
9
+ * Cards for one navigation section: its visible entries with the user's
10
+ * renames, as `resolveShellNavModel(...)` (or `useShellLayout().sections`)
11
+ * reports them. Entries with an unsafe href are skipped. With no
12
+ * `sectionId`, every section's entries are listed.
13
+ */
14
+ export function shortcutsFromNav(sections, sectionId) {
15
+ const items = [];
16
+ for (const section of sections) {
17
+ if (sectionId && section.id !== sectionId)
18
+ continue;
19
+ for (const entry of section.items) {
20
+ if (entry.hidden)
21
+ continue;
22
+ const href = safeHref(entry.item.href);
23
+ if (!href)
24
+ continue;
25
+ items.push({
26
+ id: entry.id,
27
+ label: entry.label,
28
+ href,
29
+ ...(entry.item.icon ? { icon: entry.item.icon } : {}),
30
+ ...(entry.item.description
31
+ ? { description: entry.item.description }
32
+ : {}),
33
+ });
34
+ }
35
+ }
36
+ return { items };
37
+ }
38
+ export function isRecord(value) {
39
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
40
+ }