@revenexx/studio-shared 0.3.2 → 0.3.3

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/dist/module.d.mts +4 -0
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +9 -0
  4. package/dist/runtime/components/Dashboard/DashboardConfirmDialog.d.vue.ts +15 -0
  5. package/dist/runtime/components/Dashboard/DashboardConfirmDialog.vue +39 -0
  6. package/dist/runtime/components/Dashboard/DashboardConfirmDialog.vue.d.ts +15 -0
  7. package/dist/runtime/components/Dashboard/DashboardControls.d.vue.ts +57 -0
  8. package/dist/runtime/components/Dashboard/DashboardControls.vue +209 -0
  9. package/dist/runtime/components/Dashboard/DashboardControls.vue.d.ts +57 -0
  10. package/dist/runtime/components/Dashboard/DashboardGrid.d.vue.ts +16 -0
  11. package/dist/runtime/components/Dashboard/DashboardGrid.vue +87 -0
  12. package/dist/runtime/components/Dashboard/DashboardGrid.vue.d.ts +16 -0
  13. package/dist/runtime/components/Dashboard/DashboardNameDialog.d.vue.ts +18 -0
  14. package/dist/runtime/components/Dashboard/DashboardNameDialog.vue +61 -0
  15. package/dist/runtime/components/Dashboard/DashboardNameDialog.vue.d.ts +18 -0
  16. package/dist/runtime/components/Dashboard/DashboardPickerDialog.d.vue.ts +14 -0
  17. package/dist/runtime/components/Dashboard/DashboardPickerDialog.vue +100 -0
  18. package/dist/runtime/components/Dashboard/DashboardPickerDialog.vue.d.ts +14 -0
  19. package/dist/runtime/components/Dashboard/DashboardShareDialog.d.vue.ts +27 -0
  20. package/dist/runtime/components/Dashboard/DashboardShareDialog.vue +155 -0
  21. package/dist/runtime/components/Dashboard/DashboardShareDialog.vue.d.ts +27 -0
  22. package/dist/runtime/components/Dashboard/DashboardTopBar.d.vue.ts +59 -0
  23. package/dist/runtime/components/Dashboard/DashboardTopBar.vue +79 -0
  24. package/dist/runtime/components/Dashboard/DashboardTopBar.vue.d.ts +59 -0
  25. package/dist/runtime/components/Dashboard/DashboardWidgetConfigDialog.d.vue.ts +42 -0
  26. package/dist/runtime/components/Dashboard/DashboardWidgetConfigDialog.vue +153 -0
  27. package/dist/runtime/components/Dashboard/DashboardWidgetConfigDialog.vue.d.ts +42 -0
  28. package/dist/runtime/components/Dashboard/DashboardWidgetFrame.d.vue.ts +27 -0
  29. package/dist/runtime/components/Dashboard/DashboardWidgetFrame.vue +80 -0
  30. package/dist/runtime/components/Dashboard/DashboardWidgetFrame.vue.d.ts +27 -0
  31. package/dist/runtime/components/Dashboard/DashboardWidgetHost.d.vue.ts +6 -0
  32. package/dist/runtime/components/Dashboard/DashboardWidgetHost.vue +30 -0
  33. package/dist/runtime/components/Dashboard/DashboardWidgetHost.vue.d.ts +6 -0
  34. package/dist/runtime/components/Dashboard/DashboardWidgetIcon.d.vue.ts +8 -0
  35. package/dist/runtime/components/Dashboard/DashboardWidgetIcon.vue +13 -0
  36. package/dist/runtime/components/Dashboard/DashboardWidgetIcon.vue.d.ts +8 -0
  37. package/dist/runtime/components/Dashboard/DashboardWidgetLibrary.d.vue.ts +23 -0
  38. package/dist/runtime/components/Dashboard/DashboardWidgetLibrary.vue +140 -0
  39. package/dist/runtime/components/Dashboard/DashboardWidgetLibrary.vue.d.ts +23 -0
  40. package/dist/runtime/components/Dashboard/DashboardWidgetPreview.d.vue.ts +22 -0
  41. package/dist/runtime/components/Dashboard/DashboardWidgetPreview.vue +124 -0
  42. package/dist/runtime/components/Dashboard/DashboardWidgetPreview.vue.d.ts +22 -0
  43. package/dist/runtime/components/DataTable/DataTable.d.vue.ts +36 -3
  44. package/dist/runtime/components/DataTable/DataTable.vue +252 -27
  45. package/dist/runtime/components/DataTable/DataTable.vue.d.ts +36 -3
  46. package/dist/runtime/components/DataTable/FacetChips.d.vue.ts +16 -0
  47. package/dist/runtime/components/DataTable/FacetChips.vue +72 -0
  48. package/dist/runtime/components/DataTable/FacetChips.vue.d.ts +16 -0
  49. package/dist/runtime/components/DataTable/FacetPanel.d.vue.ts +20 -0
  50. package/dist/runtime/components/DataTable/FacetPanel.vue +359 -0
  51. package/dist/runtime/components/DataTable/FacetPanel.vue.d.ts +20 -0
  52. package/dist/runtime/components/DataTable/SavedViewsMenu.d.vue.ts +5 -1
  53. package/dist/runtime/components/DataTable/SavedViewsMenu.vue +83 -63
  54. package/dist/runtime/components/DataTable/SavedViewsMenu.vue.d.ts +5 -1
  55. package/dist/runtime/components/DataTable/SortMenu.d.vue.ts +5 -1
  56. package/dist/runtime/components/DataTable/SortMenu.vue +40 -12
  57. package/dist/runtime/components/DataTable/SortMenu.vue.d.ts +5 -1
  58. package/dist/runtime/components/Media/MediaPickerDialog.d.vue.ts +2 -2
  59. package/dist/runtime/components/Media/MediaPickerDialog.vue.d.ts +2 -2
  60. package/dist/runtime/components/Media/MediaUploader.d.vue.ts +2 -2
  61. package/dist/runtime/components/Media/MediaUploader.vue.d.ts +2 -2
  62. package/dist/runtime/components/Shared/SortHeader.vue +6 -2
  63. package/dist/runtime/components/Shared/TabBar.d.vue.ts +23 -7
  64. package/dist/runtime/components/Shared/TabBar.vue +3 -2
  65. package/dist/runtime/components/Shared/TabBar.vue.d.ts +23 -7
  66. package/dist/runtime/composables/useDashboards.d.ts +27 -0
  67. package/dist/runtime/composables/useDashboards.js +143 -0
  68. package/dist/runtime/composables/useSavedViews.d.ts +44 -0
  69. package/dist/runtime/composables/useSavedViews.js +44 -0
  70. package/dist/runtime/composables/useStickyListView.d.ts +60 -0
  71. package/dist/runtime/composables/useStickyListView.js +32 -0
  72. package/dist/runtime/lib/canonicalJson.d.ts +43 -0
  73. package/dist/runtime/lib/canonicalJson.js +38 -0
  74. package/dist/runtime/lib/dashboardIcons.d.ts +4 -0
  75. package/dist/runtime/lib/dashboardIcons.js +50 -0
  76. package/dist/runtime/lib/facets.d.ts +200 -0
  77. package/dist/runtime/lib/facets.js +171 -0
  78. package/dist/runtime/lib/gridTracks.d.ts +55 -0
  79. package/dist/runtime/lib/gridTracks.js +29 -0
  80. package/dist/runtime/lib/widgetRegistry.d.ts +124 -0
  81. package/dist/runtime/lib/widgetRegistry.js +66 -0
  82. package/dist/runtime/types/dashboard.d.ts +95 -0
  83. package/dist/runtime/types/dashboard.js +2 -0
  84. package/dist/types.d.mts +8 -0
  85. package/package.json +3 -2
@@ -0,0 +1,124 @@
1
+ import type { Component, InjectionKey, MaybeRef } from 'vue';
2
+ export type WidgetCategory = 'commerce' | 'operations' | 'ai' | 'workspace' | 'apps';
3
+ /**
4
+ * The schematic the library draws for a widget. Not a screenshot and not the
5
+ * live widget: a shape, so the picture cannot go stale and costs no query.
6
+ */
7
+ export type WidgetPreviewShape = 'kpi-row' | 'bar-chart' | 'ranked-list' | 'funnel' | 'stat-split' | 'feed' | 'status-grid' | 'text' | 'links' | 'greeting' | 'sparkline-grid' | 'count';
8
+ export interface WidgetConfigField {
9
+ key: string;
10
+ /** Catalogue key for the field label. */
11
+ labelKey?: string;
12
+ /** Ready-made label — a field a manifest named, which arrives translated. */
13
+ label?: string;
14
+ type: 'text' | 'textarea' | 'number' | 'boolean' | 'select' | 'links' | 'filters' | 'sort';
15
+ /** Catalogue keys for the help line and the placeholder. */
16
+ helpKey?: string;
17
+ placeholderKey?: string;
18
+ help?: string;
19
+ options?: {
20
+ value: string;
21
+ labelKey?: string;
22
+ label?: string;
23
+ }[];
24
+ default?: unknown;
25
+ }
26
+ export interface WidgetDefinition {
27
+ /** Stable id persisted in `dashboards.widgets[].type`. Never rename in place. */
28
+ type: string;
29
+ /**
30
+ * Catalogue key for the title. A surface whose widgets are declared in code
31
+ * uses this; one whose widgets come from a manifest already has the operator's
32
+ * language and passes `title` instead.
33
+ */
34
+ titleKey?: string;
35
+ title?: string;
36
+ descriptionKey?: string;
37
+ description?: string;
38
+ /** Solar icon name — must also exist in WidgetIcon's map. */
39
+ icon: string;
40
+ category: WidgetCategory;
41
+ /** The schematic the library draws. */
42
+ preview: WidgetPreviewShape;
43
+ defaultSize: {
44
+ w: number;
45
+ h: number;
46
+ };
47
+ minSize?: {
48
+ w: number;
49
+ h: number;
50
+ };
51
+ /**
52
+ * The component, always as a loader, always memoised per type. An adapter
53
+ * that renders many types through ONE component hands in a loader that
54
+ * resolves immediately (`() => Promise.resolve(Adapter)`) rather than the
55
+ * component itself — a Vue component can be a function too, and telling the
56
+ * two apart by inspection is how a functional component ends up being awaited.
57
+ */
58
+ component: () => Promise<Component | {
59
+ default: Component;
60
+ }>;
61
+ /** Rendered by the generic config form; omit for a widget with no options. */
62
+ configFields?: WidgetConfigField[];
63
+ /** Installed apps this widget reads from. Empty = works for every tenant. */
64
+ requiresApps?: string[];
65
+ /**
66
+ * Announced but not built. It appears in the library so people can see what
67
+ * is coming, and cannot be placed — a card that adds an empty promise to a
68
+ * dashboard is worse than one that says "not yet".
69
+ */
70
+ comingSoon?: boolean;
71
+ /** Widget draws its own header/card; the frame then renders body-only. */
72
+ bare?: boolean;
73
+ /**
74
+ * Config the widget always carries, merged under the operator's own. The
75
+ * adapter for manifest widgets uses it to say WHICH manifest widget a type
76
+ * stands for, without that ending up in the config form.
77
+ */
78
+ fixedConfig?: Record<string, unknown>;
79
+ }
80
+ export interface WidgetCategoryGroup {
81
+ category: WidgetCategory;
82
+ labelKey: string;
83
+ widgets: WidgetDefinition[];
84
+ }
85
+ /** Catalogue keys for the library's group headings. */
86
+ export declare const WIDGET_CATEGORY_KEYS: Record<WidgetCategory, string>;
87
+ export interface WidgetRegistry {
88
+ all: () => WidgetDefinition[];
89
+ get: (type: string) => WidgetDefinition | undefined;
90
+ byCategory: () => WidgetCategoryGroup[];
91
+ /** The component for a type, memoised. Null when the type is unknown. */
92
+ componentFor: (type: string) => Component | null;
93
+ /** Defaults from `configFields`, plus whatever the definition fixes. */
94
+ defaultConfigFor: (type: string) => Record<string, unknown>;
95
+ }
96
+ /**
97
+ * Build a registry over a fixed list or a reactive one.
98
+ *
99
+ * Reactive is the interesting case: Commerce derives its definitions from the
100
+ * installed apps' manifests, which resolve after mount. A registry built over
101
+ * the computed sees them arrive without the surface re-providing anything.
102
+ */
103
+ export declare function createWidgetRegistry(source: MaybeRef<WidgetDefinition[]>): WidgetRegistry;
104
+ export declare const WIDGET_REGISTRY: InjectionKey<WidgetRegistry>;
105
+ /** Called once by the surface that owns the dashboard. */
106
+ export declare function provideWidgetRegistry(registry: WidgetRegistry): void;
107
+ /**
108
+ * The registry of the surface this component is rendering on.
109
+ *
110
+ * An empty registry rather than a throw when nothing is provided: a dashboard
111
+ * component mounted outside a surface should render the same "unknown widget"
112
+ * placeholder it renders for a retired type, not take the page down.
113
+ */
114
+ export declare function useWidgetRegistry(): WidgetRegistry;
115
+ /** Apps a widget needs that are not in the given installed set. */
116
+ export declare function missingAppsFor(definition: WidgetDefinition, installed: Set<string>): string[];
117
+ /**
118
+ * A definition's heading, with the translator the host registered. Written
119
+ * once because four components need it and each got it subtly wrong on its own:
120
+ * an operator's own title wins, then the definition's text, then its key.
121
+ */
122
+ export declare function widgetTitle(definition: WidgetDefinition | undefined, t: (key: string) => string, operatorTitle?: string): string;
123
+ /** Same rule for the library's second line. */
124
+ export declare function widgetDescription(definition: WidgetDefinition, t: (key: string) => string): string;
@@ -0,0 +1,66 @@
1
+ import { computed, defineAsyncComponent, inject, isRef, provide } from "vue";
2
+ export const WIDGET_CATEGORY_KEYS = {
3
+ commerce: "dashboard.category.commerce",
4
+ operations: "dashboard.category.operations",
5
+ ai: "dashboard.category.ai",
6
+ workspace: "dashboard.category.workspace",
7
+ apps: "dashboard.category.apps"
8
+ };
9
+ const CATEGORY_ORDER = ["commerce", "apps", "operations", "ai", "workspace"];
10
+ export function createWidgetRegistry(source) {
11
+ const definitions = computed(() => isRef(source) ? source.value : source);
12
+ const byType = computed(() => new Map(definitions.value.map((d) => [d.type, d])));
13
+ const components = /* @__PURE__ */ new Map();
14
+ function get(type) {
15
+ return byType.value.get(type);
16
+ }
17
+ return {
18
+ all: () => definitions.value,
19
+ get,
20
+ byCategory() {
21
+ return CATEGORY_ORDER.map((category) => ({
22
+ category,
23
+ labelKey: WIDGET_CATEGORY_KEYS[category],
24
+ widgets: definitions.value.filter((d) => d.category === category)
25
+ })).filter((group) => group.widgets.length > 0);
26
+ },
27
+ componentFor(type) {
28
+ const cached = components.get(type);
29
+ if (cached) return cached;
30
+ const definition = get(type);
31
+ if (!definition) return null;
32
+ const component = defineAsyncComponent(definition.component);
33
+ components.set(type, component);
34
+ return component;
35
+ },
36
+ defaultConfigFor(type) {
37
+ const definition = get(type);
38
+ if (!definition) return {};
39
+ const out = {};
40
+ for (const field of definition.configFields ?? []) {
41
+ if (field.default !== void 0) out[field.key] = field.default;
42
+ }
43
+ return { ...out, ...definition.fixedConfig ?? {} };
44
+ }
45
+ };
46
+ }
47
+ export const WIDGET_REGISTRY = Symbol("studio-widget-registry");
48
+ export function provideWidgetRegistry(registry) {
49
+ provide(WIDGET_REGISTRY, registry);
50
+ }
51
+ export function useWidgetRegistry() {
52
+ return inject(WIDGET_REGISTRY, null) ?? createWidgetRegistry([]);
53
+ }
54
+ export function missingAppsFor(definition, installed) {
55
+ return (definition.requiresApps ?? []).filter((app) => !installed.has(app));
56
+ }
57
+ export function widgetTitle(definition, t, operatorTitle) {
58
+ if (operatorTitle) return operatorTitle;
59
+ if (!definition) return "";
60
+ if (definition.title) return definition.title;
61
+ return definition.titleKey ? t(definition.titleKey) : "";
62
+ }
63
+ export function widgetDescription(definition, t) {
64
+ if (definition.description) return definition.description;
65
+ return definition.descriptionKey ? t(definition.descriptionKey) : "";
66
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * The dashboard contract, shared by every surface that has one (PE-618).
3
+ *
4
+ * It started in the cockpit's `shared/dashboards/types.ts`, where the home
5
+ * screen and its Nitro routes were the only readers. The Commerce Studio now
6
+ * renders the same dashboards from a published module that cannot see the
7
+ * host's `#shared` alias — so the shape moves here, and the cockpit's file
8
+ * re-exports it. One declaration, two consumers, no drift between the rows
9
+ * Nitro writes and the layout the grid reads.
10
+ *
11
+ * The layout vocabulary is deliberately identical to `shared/analytics/types`:
12
+ * two dashboard surfaces in one product must not grow two models of a grid.
13
+ */
14
+ /** Grid placement on a twelve-column grid. `i` is the widget instance id. */
15
+ export interface DashboardLayoutItem {
16
+ i: string;
17
+ x: number;
18
+ y: number;
19
+ w: number;
20
+ h: number;
21
+ }
22
+ /** One placed widget. `type` resolves against the surface's widget registry. */
23
+ export interface DashboardWidget {
24
+ id: string;
25
+ type: string;
26
+ /** Operator-set title; falls back to the registry entry's title when unset. */
27
+ title?: string;
28
+ config?: Record<string, unknown>;
29
+ }
30
+ /**
31
+ * Which surface a dashboard belongs to.
32
+ *
33
+ * A dashboard is made of the widgets available where it is edited, so it is
34
+ * only meaningful on its own surface: a Commerce dashboard listed in the
35
+ * cockpit's home switcher would open as a grid of widgets that screen cannot
36
+ * render. Stored on the row rather than encoded in the slug, because a
37
+ * convention nothing enforces is one typo away from the wrong surface.
38
+ */
39
+ export type DashboardScope = 'home' | 'commerce';
40
+ export declare const DASHBOARD_SCOPES: readonly DashboardScope[];
41
+ /** `private` — owner only. `tenant` — anyone in the tenant may see it. */
42
+ export type DashboardVisibility = 'private' | 'tenant';
43
+ /**
44
+ * What a tenant-wide share grants. `view` is the default and the safe one; a
45
+ * dashboard several people can change becomes whatever the last one left
46
+ * behind, so `edit` is a decision the owner makes explicitly.
47
+ */
48
+ export type DashboardTenantPermission = 'view' | 'edit';
49
+ export interface Dashboard {
50
+ id: string;
51
+ slug: string;
52
+ name: string;
53
+ description?: string | null;
54
+ icon?: string | null;
55
+ /** The surface this dashboard belongs to. Older rows read as `home`. */
56
+ scope: DashboardScope;
57
+ ownerUserId: string;
58
+ /** Display name captured when the dashboard was created. */
59
+ ownerName?: string | null;
60
+ /** Who last saved it, and under what name at that moment. */
61
+ updatedByUserId?: string | null;
62
+ updatedByName?: string | null;
63
+ visibility: DashboardVisibility;
64
+ tenantPermission: DashboardTenantPermission;
65
+ layout: DashboardLayoutItem[];
66
+ widgets: DashboardWidget[];
67
+ version: number;
68
+ createdAt: string;
69
+ updatedAt: string;
70
+ /**
71
+ * Server-derived, per caller. True for the owner, and for anyone in the
72
+ * tenant when the dashboard is shared with `edit`.
73
+ */
74
+ canEdit: boolean;
75
+ /** Server-derived: this caller created it. Only the owner may share or delete. */
76
+ isOwner: boolean;
77
+ /** Server-derived: true when this is the caller's landing dashboard. */
78
+ isDefault: boolean;
79
+ }
80
+ export interface DashboardListResponse {
81
+ dashboards: Dashboard[];
82
+ defaultDashboardId: string | null;
83
+ }
84
+ export interface DashboardWritePayload {
85
+ name?: string;
86
+ description?: string | null;
87
+ icon?: string | null;
88
+ visibility?: DashboardVisibility;
89
+ tenantPermission?: DashboardTenantPermission;
90
+ layout?: DashboardLayoutItem[];
91
+ widgets?: DashboardWidget[];
92
+ /** Required on update — a stale value is answered with 409, not an overwrite. */
93
+ version?: number;
94
+ }
95
+ export declare const MAX_DASHBOARD_COLUMNS = 12;
@@ -0,0 +1,2 @@
1
+ export const DASHBOARD_SCOPES = ["home", "commerce"];
2
+ export const MAX_DASHBOARD_COLUMNS = 12;
package/dist/types.d.mts CHANGED
@@ -16,6 +16,12 @@ export { type TalkbackChannel, type TalkbackChannelOptions, type TalkbackMaybeRe
16
16
 
17
17
  export { type MediaLibraryClient } from '../dist/runtime/composables/useMediaLibrary.js'
18
18
 
19
+ export { type SavedViewsStore, type StoredSavedView } from '../dist/runtime/composables/useSavedViews.js'
20
+
21
+ export { type WidgetCategory, type WidgetCategoryGroup, type WidgetConfigField, type WidgetDefinition, type WidgetPreviewShape, type WidgetRegistry } from '../dist/runtime/lib/widgetRegistry.js'
22
+
23
+ export { type StickyListView } from '../dist/runtime/composables/useStickyListView.js'
24
+
19
25
  export { type FloatingPanelDock, type FloatingPanelMode, type FloatingPanelOptions } from '../dist/runtime/composables/useFloatingPanel.js'
20
26
 
21
27
  export { type IsoOption } from '../dist/runtime/lib/isoLists.js'
@@ -27,3 +33,5 @@ export { default } from './module.mjs'
27
33
  export * from '../dist/runtime/components/DataTable/types.js'
28
34
 
29
35
  export * from '../dist/runtime/types/storage.js'
36
+
37
+ export * from '../dist/runtime/types/dashboard.js'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revenexx/studio-shared",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "description": "Shared revenexx Studio shell primitives (PageHeader, SidebarNav, StateCard, DataTable, …) + the platform provider contract (usePlatformAuth/usePlatformTenant). A Nuxt module — add it to `modules`.",
6
6
  "main": "./dist/module.mjs",
@@ -25,7 +25,8 @@
25
25
  "access": "public"
26
26
  },
27
27
  "dependencies": {
28
- "@nuxt/kit": "^4.0.0"
28
+ "@nuxt/kit": "^4.0.0",
29
+ "grid-layout-plus": "^1.1.1"
29
30
  },
30
31
  "peerDependencies": {
31
32
  "@revenexx/studio": "^0.2.3",