@happyvertical/smrt-svelte 0.55.5 → 0.55.7
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.
- package/AGENTS.md +17 -2
- package/README.md +83 -4
- package/agents/workspace.md +202 -5
- package/dist/browser-ai/adapters/stt/dictation-source.d.ts.map +1 -1
- package/dist/browser-ai/adapters/stt/dictation-source.js +8 -2
- package/dist/browser-ai/adapters/stt/factory.d.ts +6 -3
- package/dist/browser-ai/adapters/stt/factory.d.ts.map +1 -1
- package/dist/browser-ai/adapters/stt/factory.js +19 -9
- package/dist/browser-ai/adapters/stt/index.d.ts +3 -1
- package/dist/browser-ai/adapters/stt/index.d.ts.map +1 -1
- package/dist/browser-ai/adapters/stt/index.js +3 -1
- package/dist/browser-ai/adapters/stt/local-speech-model.d.ts +111 -0
- package/dist/browser-ai/adapters/stt/local-speech-model.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/local-speech-model.js +377 -0
- package/dist/browser-ai/adapters/stt/local-speech.d.ts +82 -0
- package/dist/browser-ai/adapters/stt/local-speech.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/local-speech.js +317 -0
- package/dist/browser-ai/adapters/stt/local-speech.worker.d.ts +2 -0
- package/dist/browser-ai/adapters/stt/local-speech.worker.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/local-speech.worker.js +32 -0
- package/dist/browser-ai/adapters/stt/transformers-env.d.ts +8 -0
- package/dist/browser-ai/adapters/stt/transformers-env.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/transformers-env.js +17 -0
- package/dist/browser-ai/adapters/stt/types.d.ts +54 -9
- package/dist/browser-ai/adapters/stt/types.d.ts.map +1 -1
- package/dist/browser-ai/capabilities/speech-probe.d.ts +29 -0
- package/dist/browser-ai/capabilities/speech-probe.d.ts.map +1 -0
- package/dist/browser-ai/capabilities/speech-probe.js +19 -0
- package/dist/browser-ai/core/errors.d.ts +9 -0
- package/dist/browser-ai/core/errors.d.ts.map +1 -1
- package/dist/browser-ai/core/errors.js +12 -0
- package/dist/browser-ai/index.d.ts +1 -0
- package/dist/browser-ai/index.d.ts.map +1 -1
- package/dist/browser-ai/index.js +1 -0
- package/dist/components/app/AppShell.svelte +587 -33
- package/dist/components/app/AppShell.svelte.d.ts +75 -4
- package/dist/components/app/AppShell.svelte.d.ts.map +1 -1
- package/dist/components/app/DockToggles.svelte +0 -1
- package/dist/components/app/dock-toggle.d.ts +7 -1
- package/dist/components/app/dock-toggle.d.ts.map +1 -1
- package/dist/components/app/index.d.ts +2 -1
- package/dist/components/app/index.d.ts.map +1 -1
- package/dist/components/app/slot-item.d.ts +21 -0
- package/dist/components/app/slot-item.d.ts.map +1 -0
- package/dist/components/app/slot-item.js +1 -0
- package/dist/components/audit/AuditList.svelte +51 -10
- package/dist/components/audit/AuditList.svelte.d.ts +13 -1
- package/dist/components/audit/AuditList.svelte.d.ts.map +1 -1
- package/dist/components/audit/RecordHistory.svelte +168 -10
- package/dist/components/audit/RecordHistory.svelte.d.ts +11 -1
- package/dist/components/audit/RecordHistory.svelte.d.ts.map +1 -1
- package/dist/components/audit/index.d.ts +1 -1
- package/dist/components/audit/index.d.ts.map +1 -1
- package/dist/components/audit/types.d.ts +18 -0
- package/dist/components/audit/types.d.ts.map +1 -1
- package/dist/components/forms/AddressInput.svelte +2 -15
- package/dist/components/forms/AddressInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/DateRangeInput.svelte +2 -15
- package/dist/components/forms/DateRangeInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/DateTimeInput.svelte +8 -15
- package/dist/components/forms/DateTimeInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/MeasurementInput.svelte +2 -15
- package/dist/components/forms/MeasurementInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/MoneyInput.svelte +8 -25
- package/dist/components/forms/MoneyInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/NumberInput.svelte +7 -15
- package/dist/components/forms/NumberInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/PhoneInput.svelte +7 -15
- package/dist/components/forms/PhoneInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/SelectInput.svelte +34 -40
- package/dist/components/forms/SelectInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/TextInput.svelte +20 -37
- package/dist/components/forms/TextInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/TextareaInput.svelte +19 -35
- package/dist/components/forms/TextareaInput.svelte.d.ts.map +1 -1
- package/dist/components/sortable/Sortable.svelte +6 -33
- package/dist/components/sortable/Sortable.svelte.d.ts.map +1 -1
- package/dist/components/sortable/announce.d.ts +5 -0
- package/dist/components/sortable/announce.d.ts.map +1 -0
- package/dist/components/sortable/announce.js +33 -0
- package/dist/components/workspace/admin-shell/AdminShell.svelte +424 -58
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts +27 -2
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/ShellBrand.svelte +86 -0
- package/dist/components/workspace/admin-shell/ShellBrand.svelte.d.ts +18 -0
- package/dist/components/workspace/admin-shell/ShellBrand.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellIconButton.svelte +77 -0
- package/dist/components/workspace/admin-shell/ShellIconButton.svelte.d.ts +26 -0
- package/dist/components/workspace/admin-shell/ShellIconButton.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellLayoutEditor.svelte +88 -16
- package/dist/components/workspace/admin-shell/ShellLayoutEditor.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte +531 -0
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte.d.ts +26 -0
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte +57 -0
- package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte.d.ts +22 -0
- package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte +290 -0
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte.d.ts +32 -0
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/TenantNav.svelte +67 -2
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts +8 -0
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/layout-controller.svelte.d.ts +67 -0
- package/dist/components/workspace/admin-shell/layout-controller.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/layout-controller.svelte.js +129 -1
- package/dist/components/workspace/admin-shell/layout.d.ts +122 -0
- package/dist/components/workspace/admin-shell/layout.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/layout.js +410 -10
- package/dist/components/workspace/admin-shell/settings.js +4 -4
- package/dist/components/workspace/admin-shell/shell-icons.d.ts +45 -0
- package/dist/components/workspace/admin-shell/shell-icons.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/shell-icons.js +66 -0
- package/dist/components/workspace/admin-shell/slot-labels.d.ts +33 -0
- package/dist/components/workspace/admin-shell/slot-labels.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/slot-labels.js +33 -0
- package/dist/components/workspace/admin-shell/slots.d.ts +50 -0
- package/dist/components/workspace/admin-shell/slots.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/slots.js +77 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts +35 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/state.svelte.js +111 -0
- package/dist/components/workspace/admin-shell/types.d.ts +101 -1
- package/dist/components/workspace/admin-shell/types.d.ts.map +1 -1
- package/dist/components/workspace/index.d.ts +9 -2
- package/dist/components/workspace/index.d.ts.map +1 -1
- package/dist/components/workspace/index.js +6 -0
- package/dist/i18n/strings.workspace.d.ts +49 -0
- package/dist/i18n/strings.workspace.d.ts.map +1 -1
- package/dist/i18n/strings.workspace.js +49 -0
- package/package.json +30 -19
- package/dist/browser-ai/adapters/stt/whisper-wasm.d.ts +0 -51
- package/dist/browser-ai/adapters/stt/whisper-wasm.d.ts.map +0 -1
- package/dist/browser-ai/adapters/stt/whisper-wasm.js +0 -380
|
@@ -3,17 +3,25 @@ import '@happyvertical/smrt-ui/themes/styles/all.css';
|
|
|
3
3
|
import '@happyvertical/smrt-ui/themes/styles/base.css';
|
|
4
4
|
import '@happyvertical/smrt-ui/themes/styles/fonts.css';
|
|
5
5
|
import type { DataSurfaceRegistry } from '@happyvertical/smrt-ui/data';
|
|
6
|
-
import { type Snippet } from 'svelte';
|
|
6
|
+
import { type Component, type Snippet } from 'svelte';
|
|
7
7
|
import type { User } from '../../state/app-state.js';
|
|
8
8
|
import type { WebMcpProviderConfig } from '../../web/webmcp-provider.js';
|
|
9
9
|
import { type ShellLayout } from '../workspace/admin-shell/layout.js';
|
|
10
|
-
import { type
|
|
10
|
+
import { type ShellSlot } from '../workspace/admin-shell/slots.js';
|
|
11
|
+
import { type AdminShellProps, type ShellNavGroup, type ShellNavItem, type ShellPanelDefaults, type ShellSectionActionsContext } from '../workspace/admin-shell/types.js';
|
|
11
12
|
import type { DockToggle } from './dock-toggle.js';
|
|
13
|
+
import type { ShellSlotItem } from './slot-item.js';
|
|
12
14
|
interface Props {
|
|
13
15
|
/** Application name shown in the shell brand and app panel. */
|
|
14
16
|
title?: string;
|
|
15
17
|
/** Secondary line under the application name in the shell brand. */
|
|
16
18
|
subtitle?: string;
|
|
19
|
+
/** Logo shown before the title in the shell brand (and as the compact rail mark). */
|
|
20
|
+
logoSrc?: string;
|
|
21
|
+
/** Alternative text for the logo (decorative by default: the title names the app). */
|
|
22
|
+
logoAlt?: string;
|
|
23
|
+
/** Where the brand links to (e.g. the app's home); unlinked when omitted. */
|
|
24
|
+
homeHref?: string;
|
|
17
25
|
/** localStorage key for the user's shell layout preferences. */
|
|
18
26
|
storageKey?: string;
|
|
19
27
|
/** Navigation rendered in the tenant (left) panel. */
|
|
@@ -65,7 +73,7 @@ interface Props {
|
|
|
65
73
|
*/
|
|
66
74
|
dock?: Snippet<[DataSurfaceRegistry]>;
|
|
67
75
|
/**
|
|
68
|
-
* Icon buttons
|
|
76
|
+
* Icon buttons, each placed in a shell `slot` (default `header.end`), each toggling
|
|
69
77
|
* the `ShellDockTool` with the same id open and closed. `aria-pressed` and
|
|
70
78
|
* `aria-expanded` follow the dock, focus moves into the dock when it
|
|
71
79
|
* opens and back to the button when it closes (Escape included). The
|
|
@@ -73,9 +81,72 @@ interface Props {
|
|
|
73
81
|
* drive the same dock from code with `useShellDock()`.
|
|
74
82
|
*/
|
|
75
83
|
dockToggles?: DockToggle[];
|
|
84
|
+
/**
|
|
85
|
+
* Host content for any shell slot (`header.start|center|end`,
|
|
86
|
+
* `footer.start|center|end`, `leftSidebar.header|footer`,
|
|
87
|
+
* `rightSidebar.header|footer`). Rendered before dock toggles placed in the
|
|
88
|
+
* same slot. Each snippet is one movable item with id `slot:<slot>`; use
|
|
89
|
+
* `slotItems` for individually movable content.
|
|
90
|
+
*/
|
|
91
|
+
slots?: Partial<Record<ShellSlot, Snippet>>;
|
|
92
|
+
/**
|
|
93
|
+
* Host items with stable ids, each in a default slot. Users can move them
|
|
94
|
+
* between slots in the layout editor (`ShellLayout.placements`). Rendered
|
|
95
|
+
* after `slots` content and before dock toggles in the same slot.
|
|
96
|
+
*/
|
|
97
|
+
slotItems?: ShellSlotItem[];
|
|
98
|
+
/**
|
|
99
|
+
* Opt in to editing the layout in place. Adds the built-in shell item
|
|
100
|
+
* `item:layout-edit` (a pencil toggle, default slot `header.end`, or
|
|
101
|
+
* `{ slot }`); while on, slots render as labelled drop zones, items and
|
|
102
|
+
* navigation get grips, section headings get overlay icons and a floating
|
|
103
|
+
* toolbar, and hidden regions render as strips with a show control. Hosts
|
|
104
|
+
* and assistants drive it with `useShellLayout()` (`editing`,
|
|
105
|
+
* `setEditing`). Off (the default) leaves existing apps unchanged.
|
|
106
|
+
*
|
|
107
|
+
* `{ floating: true }` instead renders the toggle as a fixed round button
|
|
108
|
+
* in the top-right corner of the shell: not a placeable item (no slot, no
|
|
109
|
+
* grip), so hidden regions never displace it. The header and right sidebar
|
|
110
|
+
* reserve room for it so it covers none of their controls.
|
|
111
|
+
*/
|
|
112
|
+
layoutEditing?: boolean | {
|
|
113
|
+
slot?: ShellSlot;
|
|
114
|
+
floating?: boolean;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Host icon buttons for each navigation section while the layout is edited
|
|
118
|
+
* (e.g. an Options gear or Help), rendered in the section's overlay icons
|
|
119
|
+
* and its floating toolbar. Receives the section id, label, whether it is
|
|
120
|
+
* user-created, and `editing`.
|
|
121
|
+
*/
|
|
122
|
+
sectionActions?: Snippet<[ShellSectionActionsContext]>;
|
|
123
|
+
/**
|
|
124
|
+
* `'items'` (default) lists every section's entries in the left sidebar.
|
|
125
|
+
* `'sections'` lists only the sections, one icon link each, to the
|
|
126
|
+
* section's own page (`ShellNavGroup.href`, else `sectionHref`, else its
|
|
127
|
+
* first entry); render the entries there with `ShellSectionMenu`. In edit
|
|
128
|
+
* mode the sidebar edits sections (grip, rename, hide, icon); entries are
|
|
129
|
+
* edited on the section page.
|
|
130
|
+
*/
|
|
131
|
+
navMode?: 'items' | 'sections';
|
|
132
|
+
/** Section page for groups without an `href` (e.g. user-created ones). */
|
|
133
|
+
sectionHref?: (sectionId: string) => string | undefined;
|
|
134
|
+
/** Renders host icon names for sections and entries. */
|
|
135
|
+
iconComponent?: Component<{
|
|
136
|
+
name: string;
|
|
137
|
+
size?: number;
|
|
138
|
+
}>;
|
|
139
|
+
/**
|
|
140
|
+
* Edge toggle buttons and WASD drop-down panels (see `AdminShell`).
|
|
141
|
+
* Default `false`: regions are laid out inline and no toggles or hotkeys
|
|
142
|
+
* exist. Pass `true` (or a per-edge map) for the previous behaviour.
|
|
143
|
+
*/
|
|
144
|
+
edgeToggles?: AdminShellProps['edgeToggles'];
|
|
145
|
+
/** Keyboard shortcuts; default follows `edgeToggles` (see `AdminShell`). */
|
|
146
|
+
hotkeys?: boolean;
|
|
76
147
|
children: Snippet;
|
|
77
148
|
}
|
|
78
|
-
declare const AppShell:
|
|
149
|
+
declare const AppShell: Component<Props, {}, "">;
|
|
79
150
|
type AppShell = ReturnType<typeof AppShell>;
|
|
80
151
|
export default AppShell;
|
|
81
152
|
//# sourceMappingURL=AppShell.svelte.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShell.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/AppShell.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,WAAW,EAEjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,8CAA8C,CAAC;AACtD,OAAO,+CAA+C,CAAC;AACvD,OAAO,gDAAgD,CAAC;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,EAAE,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"AppShell.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/AppShell.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,WAAW,EAEjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,8CAA8C,CAAC;AACtD,OAAO,+CAA+C,CAAC;AACvD,OAAO,gDAAgD,CAAC;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,OAAO,EAAiB,MAAM,QAAQ,CAAC;AAIrE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAKzE,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,oCAAoC,CAAC;AAY5C,OAAO,EAKL,KAAK,SAAS,EAIf,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EACL,KAAK,eAAe,EAGpB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAChC,MAAM,mCAAmC,CAAC;AAG3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,UAAU,KAAK;IACb,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC;IACrB,uEAAuE;IACvE,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;IAC5B,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,OAAO,GAAG,oBAAoB,CAAC;IACxC,yFAAyF;IACzF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,+FAA+F;IAC/F,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,8DAA8D;IAC9D,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,sEAAsE;IACtE,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,gFAAgF;IAChF,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IAC/C,iDAAiD;IACjD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACtC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5C;;;;OAIG;IACH,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;IAC5B;;;;;;;;;;;;;OAaG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,SAAS,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACnE;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACvD;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC/B,0EAA0E;IAC1E,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxD,wDAAwD;IACxD,aAAa,CAAC,EAAE,SAAS,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D;;;;OAIG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC;IAC7C,4EAA4E;IAC5E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AA6iBD,QAAA,MAAM,QAAQ,0BAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import type { ShellSlot } from '../workspace/admin-shell/slots.js';
|
|
2
|
+
/** A button that toggles one dock tool. */
|
|
2
3
|
export interface DockToggle {
|
|
3
4
|
/** Id of the `ShellDockTool` to toggle. */
|
|
4
5
|
tool: string;
|
|
@@ -10,5 +11,10 @@ export interface DockToggle {
|
|
|
10
11
|
* label's first letter stands in.
|
|
11
12
|
*/
|
|
12
13
|
icon?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Shell slot the button renders in. Default `header.end`. If that slot's
|
|
16
|
+
* region is hidden the shell moves it along the slot fallback chain.
|
|
17
|
+
*/
|
|
18
|
+
slot?: ShellSlot;
|
|
13
19
|
}
|
|
14
20
|
//# sourceMappingURL=dock-toggle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dock-toggle.d.ts","sourceRoot":"","sources":["../../../src/components/app/dock-toggle.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"dock-toggle.d.ts","sourceRoot":"","sources":["../../../src/components/app/dock-toggle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAEnE,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* server or `$app/*` imports. Pair with the server `load`/`actions` from
|
|
6
6
|
* `@happyvertical/smrt-app-runtime/sveltekit`.
|
|
7
7
|
*/
|
|
8
|
-
export { type ShellLayout, ShellLayoutController, ShellLayoutEditor, tryUseShellLayout, useShellLayout, } from '../workspace/index.js';
|
|
8
|
+
export { type ShellLayout, ShellLayoutController, ShellLayoutEditor, type ShellSectionActionsContext, tryUseShellLayout, useShellLayout, } from '../workspace/index.js';
|
|
9
9
|
export { default as AppShell } from './AppShell.svelte';
|
|
10
10
|
export type { DockToggle } from './dock-toggle.js';
|
|
11
11
|
export { default as OwnerSetupForm } from './OwnerSetupForm.svelte';
|
|
@@ -13,4 +13,5 @@ export type { OwnerSetupData, OwnerSetupFormResult, } from './owner-setup-types.
|
|
|
13
13
|
export { default as RuntimeDiagnosticsWebMcp } from './RuntimeDiagnosticsWebMcp.svelte';
|
|
14
14
|
export { createRuntimeDiagnosticsWebMcpTool, type RegisterRuntimeDiagnosticsWebMcpOptions, RUNTIME_DIAGNOSTICS_ENDPOINT, RUNTIME_DIAGNOSTICS_WEBMCP_TOOL_NAME, type RuntimeDiagnosticsWebMcpOwner, registerRuntimeDiagnosticsWebMcp, } from './runtime-diagnostics-webmcp.js';
|
|
15
15
|
export { default as ShellSettingsPage } from './ShellSettingsPage.svelte';
|
|
16
|
+
export type { ShellSlotItem } from './slot-item.js';
|
|
16
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/app/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,YAAY,EACV,cAAc,EACd,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AACxF,OAAO,EACL,kCAAkC,EAClC,KAAK,uCAAuC,EAC5C,4BAA4B,EAC5B,oCAAoC,EACpC,KAAK,6BAA6B,EAClC,gCAAgC,GACjC,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/app/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,0BAA0B,EAC/B,iBAAiB,EACjB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,YAAY,EACV,cAAc,EACd,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AACxF,OAAO,EACL,kCAAkC,EAClC,KAAK,uCAAuC,EAC5C,4BAA4B,EAC5B,oCAAoC,EACpC,KAAK,6BAA6B,EAClC,gCAAgC,GACjC,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { ShellSlot } from '../workspace/admin-shell/slots.js';
|
|
3
|
+
/**
|
|
4
|
+
* A host item that lives in a shell slot and that users can move to another
|
|
5
|
+
* slot from the layout editor (`ShellLayout.placements`). Prefer this over the
|
|
6
|
+
* `slots` prop when the content should be individually movable.
|
|
7
|
+
*/
|
|
8
|
+
export interface ShellSlotItem {
|
|
9
|
+
/**
|
|
10
|
+
* Stable id; keep it unchanged across releases because a stored layout
|
|
11
|
+
* refers to it. Must not collide with `dock:` or `slot:` ids.
|
|
12
|
+
*/
|
|
13
|
+
id: string;
|
|
14
|
+
/** Accessible, user-facing name shown in the layout editor. */
|
|
15
|
+
label: string;
|
|
16
|
+
/** Default slot; a user's layout can move it elsewhere. */
|
|
17
|
+
slot: ShellSlot;
|
|
18
|
+
/** The content. */
|
|
19
|
+
render: Snippet;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=slot-item.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slot-item.d.ts","sourceRoot":"","sources":["../../../src/components/app/slot-item.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAEnE;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,IAAI,EAAE,SAAS,CAAC;IAChB,mBAAmB;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -4,7 +4,14 @@ import { useI18n } from '@happyvertical/smrt-ui/i18n';
|
|
|
4
4
|
import { Button } from '@happyvertical/smrt-ui/ui';
|
|
5
5
|
import { M } from '../../i18n/strings.audit.js';
|
|
6
6
|
import RecordHistory from './RecordHistory.svelte';
|
|
7
|
-
import type {
|
|
7
|
+
import type {
|
|
8
|
+
AuditEntryLabel,
|
|
9
|
+
AuditFieldLabel,
|
|
10
|
+
AuditHistoryEntry,
|
|
11
|
+
AuditListFilter,
|
|
12
|
+
AuditResourceHref,
|
|
13
|
+
AuditValueFormatter,
|
|
14
|
+
} from './types.js';
|
|
8
15
|
|
|
9
16
|
interface Props {
|
|
10
17
|
/** Authorized data only. For server paging use onfilter to reload the authorized page. */
|
|
@@ -15,8 +22,31 @@ interface Props {
|
|
|
15
22
|
error?: string | null;
|
|
16
23
|
/** Requests an authorized server page for the submitted filters instead of filtering locally. */
|
|
17
24
|
onfilter?: (filter: AuditListFilter) => void;
|
|
25
|
+
/** Shows the built-in person, record and date filters. */
|
|
26
|
+
showFilters?: boolean;
|
|
27
|
+
/** Resolves friendly resource text for each authorized entry. */
|
|
28
|
+
resourceLabel?: AuditEntryLabel;
|
|
29
|
+
/** Resolves an already-authorized local or HTTP(S) destination for each entry. */
|
|
30
|
+
resourceHref?: AuditResourceHref;
|
|
31
|
+
/** Resolves friendly action text for each authorized entry. */
|
|
32
|
+
actionLabel?: AuditEntryLabel;
|
|
33
|
+
/** Resolves friendly field text for each authorized entry change. */
|
|
34
|
+
fieldLabel?: AuditFieldLabel;
|
|
35
|
+
/** Formats before/after values as escaped text. */
|
|
36
|
+
formatValue?: AuditValueFormatter;
|
|
18
37
|
}
|
|
19
|
-
let {
|
|
38
|
+
let {
|
|
39
|
+
entries,
|
|
40
|
+
loading = false,
|
|
41
|
+
error = null,
|
|
42
|
+
onfilter,
|
|
43
|
+
showFilters = true,
|
|
44
|
+
resourceLabel,
|
|
45
|
+
resourceHref,
|
|
46
|
+
actionLabel,
|
|
47
|
+
fieldLabel,
|
|
48
|
+
formatValue,
|
|
49
|
+
}: Props = $props();
|
|
20
50
|
const { t } = useI18n();
|
|
21
51
|
let profileId = $state('');
|
|
22
52
|
let resourceId = $state('');
|
|
@@ -51,14 +81,25 @@ function apply() {
|
|
|
51
81
|
</script>
|
|
52
82
|
|
|
53
83
|
<section aria-label={t(M['ui.audit.list'])}>
|
|
54
|
-
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
84
|
+
{#if showFilters}
|
|
85
|
+
<Form onsubmit={apply} class="smrt-audit-filters">
|
|
86
|
+
<FormGroup label={t(M['ui.audit.person'])}><Input bind:value={profileId} /></FormGroup>
|
|
87
|
+
<FormGroup label={t(M['ui.audit.record'])}><Input bind:value={resourceId} /></FormGroup>
|
|
88
|
+
<FormGroup label={t(M['ui.audit.from'])}><Input type="date" bind:value={from} max={to || undefined} /></FormGroup>
|
|
89
|
+
<FormGroup label={t(M['ui.audit.to'])}><Input type="date" bind:value={to} min={from || undefined} /></FormGroup>
|
|
90
|
+
<Button type="submit" disabled={loading}>{t(M['ui.audit.filter'])}</Button>
|
|
91
|
+
</Form>
|
|
92
|
+
{/if}
|
|
93
|
+
<RecordHistory
|
|
94
|
+
entries={visible}
|
|
95
|
+
{loading}
|
|
96
|
+
{error}
|
|
97
|
+
{resourceLabel}
|
|
98
|
+
{resourceHref}
|
|
99
|
+
{actionLabel}
|
|
100
|
+
{fieldLabel}
|
|
101
|
+
{formatValue}
|
|
102
|
+
/>
|
|
62
103
|
</section>
|
|
63
104
|
|
|
64
105
|
<style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuditHistoryEntry, AuditListFilter } from './types.js';
|
|
1
|
+
import type { AuditEntryLabel, AuditFieldLabel, AuditHistoryEntry, AuditListFilter, AuditResourceHref, AuditValueFormatter } from './types.js';
|
|
2
2
|
interface Props {
|
|
3
3
|
/** Authorized data only. For server paging use onfilter to reload the authorized page. */
|
|
4
4
|
entries: AuditHistoryEntry[];
|
|
@@ -8,6 +8,18 @@ interface Props {
|
|
|
8
8
|
error?: string | null;
|
|
9
9
|
/** Requests an authorized server page for the submitted filters instead of filtering locally. */
|
|
10
10
|
onfilter?: (filter: AuditListFilter) => void;
|
|
11
|
+
/** Shows the built-in person, record and date filters. */
|
|
12
|
+
showFilters?: boolean;
|
|
13
|
+
/** Resolves friendly resource text for each authorized entry. */
|
|
14
|
+
resourceLabel?: AuditEntryLabel;
|
|
15
|
+
/** Resolves an already-authorized local or HTTP(S) destination for each entry. */
|
|
16
|
+
resourceHref?: AuditResourceHref;
|
|
17
|
+
/** Resolves friendly action text for each authorized entry. */
|
|
18
|
+
actionLabel?: AuditEntryLabel;
|
|
19
|
+
/** Resolves friendly field text for each authorized entry change. */
|
|
20
|
+
fieldLabel?: AuditFieldLabel;
|
|
21
|
+
/** Formats before/after values as escaped text. */
|
|
22
|
+
formatValue?: AuditValueFormatter;
|
|
11
23
|
}
|
|
12
24
|
declare const AuditList: import("svelte").Component<Props, {}, "">;
|
|
13
25
|
type AuditList = ReturnType<typeof AuditList>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuditList.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/audit/AuditList.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"AuditList.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/audit/AuditList.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAGpB,UAAU,KAAK;IACb,0FAA0F;IAC1F,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,sFAAsF;IACtF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,iGAAiG;IACjG,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAC7C,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iEAAiE;IACjE,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,kFAAkF;IAClF,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,+DAA+D;IAC/D,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,mDAAmD;IACnD,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACnC;AAuED,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { useI18n } from '@happyvertical/smrt-ui/i18n';
|
|
3
3
|
import { M } from '../../i18n/strings.audit.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
AuditEntryLabel,
|
|
6
|
+
AuditFieldLabel,
|
|
7
|
+
AuditHistoryEntry,
|
|
8
|
+
AuditResourceHref,
|
|
9
|
+
AuditValueFormatter,
|
|
10
|
+
} from './types.js';
|
|
5
11
|
|
|
6
12
|
interface Props {
|
|
7
13
|
/** Authorized entries. This component never fetches or authorizes records. */
|
|
@@ -16,6 +22,16 @@ interface Props {
|
|
|
16
22
|
error?: string | null;
|
|
17
23
|
/** Overrides the translated accessible label for the history section. */
|
|
18
24
|
label?: string;
|
|
25
|
+
/** Resolves friendly resource text for each authorized entry. */
|
|
26
|
+
resourceLabel?: AuditEntryLabel;
|
|
27
|
+
/** Resolves an already-authorized local or HTTP(S) destination for each entry. */
|
|
28
|
+
resourceHref?: AuditResourceHref;
|
|
29
|
+
/** Resolves friendly action text for each authorized entry. */
|
|
30
|
+
actionLabel?: AuditEntryLabel;
|
|
31
|
+
/** Resolves friendly field text for each authorized entry change. */
|
|
32
|
+
fieldLabel?: AuditFieldLabel;
|
|
33
|
+
/** Formats before/after values as escaped text. */
|
|
34
|
+
formatValue?: AuditValueFormatter;
|
|
19
35
|
}
|
|
20
36
|
let {
|
|
21
37
|
entries,
|
|
@@ -24,6 +40,11 @@ let {
|
|
|
24
40
|
loading = false,
|
|
25
41
|
error = null,
|
|
26
42
|
label,
|
|
43
|
+
resourceLabel,
|
|
44
|
+
resourceHref,
|
|
45
|
+
actionLabel,
|
|
46
|
+
fieldLabel,
|
|
47
|
+
formatValue,
|
|
27
48
|
}: Props = $props();
|
|
28
49
|
const { locale, t } = useI18n();
|
|
29
50
|
const visible = $derived(
|
|
@@ -35,8 +56,87 @@ const visible = $derived(
|
|
|
35
56
|
)
|
|
36
57
|
.toSorted((a, b) => Date.parse(b.occurredAt) - Date.parse(a.occurredAt)),
|
|
37
58
|
);
|
|
38
|
-
function
|
|
39
|
-
|
|
59
|
+
function defaultDisplay(value: unknown): string {
|
|
60
|
+
if (typeof value === 'string') return value;
|
|
61
|
+
try {
|
|
62
|
+
return JSON.stringify(value) ?? '';
|
|
63
|
+
} catch {
|
|
64
|
+
try {
|
|
65
|
+
return String(value);
|
|
66
|
+
} catch {
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function entryLabel(
|
|
72
|
+
resolver: AuditEntryLabel | undefined,
|
|
73
|
+
entry: AuditHistoryEntry,
|
|
74
|
+
fallback: string,
|
|
75
|
+
): string {
|
|
76
|
+
if (!resolver) return fallback;
|
|
77
|
+
try {
|
|
78
|
+
const resolved = resolver(entry);
|
|
79
|
+
return typeof resolved === 'string' && resolved.trim()
|
|
80
|
+
? resolved
|
|
81
|
+
: fallback;
|
|
82
|
+
} catch {
|
|
83
|
+
return fallback;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function changedFieldLabel(field: string, entry: AuditHistoryEntry): string {
|
|
87
|
+
if (!fieldLabel) return field;
|
|
88
|
+
try {
|
|
89
|
+
const resolved = fieldLabel(field, entry);
|
|
90
|
+
return typeof resolved === 'string' && resolved.trim() ? resolved : field;
|
|
91
|
+
} catch {
|
|
92
|
+
return field;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function display(
|
|
96
|
+
value: unknown,
|
|
97
|
+
entry: AuditHistoryEntry,
|
|
98
|
+
field: string,
|
|
99
|
+
side: 'before' | 'after',
|
|
100
|
+
): string {
|
|
101
|
+
if (formatValue) {
|
|
102
|
+
try {
|
|
103
|
+
const resolved = formatValue(value, { entry, field, side });
|
|
104
|
+
if (typeof resolved === 'string') return resolved;
|
|
105
|
+
} catch {
|
|
106
|
+
// Presentation callbacks cannot make an authorized history list fail.
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return defaultDisplay(value);
|
|
110
|
+
}
|
|
111
|
+
function hasUrlControlCharacter(value: string): boolean {
|
|
112
|
+
return Array.from(value).some((character) => {
|
|
113
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
114
|
+
return codePoint <= 0x1f || codePoint === 0x7f;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function safeResourceHref(entry: AuditHistoryEntry): string | null {
|
|
118
|
+
if (!resourceHref) return null;
|
|
119
|
+
let resolved: unknown;
|
|
120
|
+
try {
|
|
121
|
+
resolved = resourceHref(entry);
|
|
122
|
+
} catch {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
if (typeof resolved !== 'string') return null;
|
|
126
|
+
const href = resolved.trim();
|
|
127
|
+
if (
|
|
128
|
+
!href ||
|
|
129
|
+
href.startsWith('//') ||
|
|
130
|
+
href.includes('\\') ||
|
|
131
|
+
hasUrlControlCharacter(href)
|
|
132
|
+
)
|
|
133
|
+
return null;
|
|
134
|
+
try {
|
|
135
|
+
const url = new URL(href, 'https://smrt.invalid');
|
|
136
|
+
return url.protocol === 'http:' || url.protocol === 'https:' ? href : null;
|
|
137
|
+
} catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
40
140
|
}
|
|
41
141
|
function date(value: string): string {
|
|
42
142
|
const parsed = new Date(value);
|
|
@@ -50,17 +150,27 @@ function date(value: string): string {
|
|
|
50
150
|
{#if error}<p role="alert">{error}</p>{/if}
|
|
51
151
|
{#if loading}<p role="status">{t(M['ui.audit.loading'])}</p>{/if}
|
|
52
152
|
{#if !loading && visible.length === 0}<p>{t(M['ui.audit.empty'])}</p>{/if}
|
|
53
|
-
<ol>
|
|
153
|
+
<ol role="list">
|
|
54
154
|
{#each visible as entry (entry.id)}
|
|
155
|
+
{@const resolvedResourceLabel = entryLabel(resourceLabel, entry, `${entry.resourceType} / ${entry.resourceId}`)}
|
|
156
|
+
{@const resolvedResourceHref = safeResourceHref(entry)}
|
|
55
157
|
<li>
|
|
56
|
-
<p
|
|
158
|
+
<p>
|
|
159
|
+
<strong>{entry.actorLabel ?? entry.profileId}</strong>
|
|
160
|
+
· {entryLabel(actionLabel, entry, entry.action)} ·
|
|
161
|
+
{#if resolvedResourceHref}<a href={resolvedResourceHref}>{resolvedResourceLabel}</a>{:else}{resolvedResourceLabel}{/if}
|
|
162
|
+
</p>
|
|
57
163
|
<time datetime={entry.occurredAt}>{date(entry.occurredAt)}</time>
|
|
58
164
|
{#if entry.onBehalfOfId}<p>{t(M['ui.audit.behalf'], { actor: entry.onBehalfOfId })}</p>{/if}
|
|
59
165
|
{#if entry.reason}<p>{t(M['ui.audit.reason'], { reason: entry.reason })}</p>{/if}
|
|
60
166
|
{#if entry.changes && Object.keys(entry.changes).length}
|
|
61
|
-
<ul>
|
|
167
|
+
<ul role="list">
|
|
62
168
|
{#each Object.entries(entry.changes) as [field, change] (field)}
|
|
63
|
-
<li>{t(M['ui.audit.change'], {
|
|
169
|
+
<li>{t(M['ui.audit.change'], {
|
|
170
|
+
field: changedFieldLabel(field, entry),
|
|
171
|
+
before: display(change.before, entry, field, 'before'),
|
|
172
|
+
after: display(change.after, entry, field, 'after'),
|
|
173
|
+
})}</li>
|
|
64
174
|
{/each}
|
|
65
175
|
</ul>
|
|
66
176
|
{/if}
|
|
@@ -70,7 +180,55 @@ function date(value: string): string {
|
|
|
70
180
|
</section>
|
|
71
181
|
|
|
72
182
|
<style>
|
|
73
|
-
.smrt-record-history ol {
|
|
74
|
-
|
|
75
|
-
|
|
183
|
+
.smrt-record-history > ol {
|
|
184
|
+
display: grid;
|
|
185
|
+
margin: 0;
|
|
186
|
+
padding: 0;
|
|
187
|
+
list-style: none;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.smrt-record-history > ol > li {
|
|
191
|
+
min-inline-size: 0;
|
|
192
|
+
padding-block: var(--smrt-spacing-3);
|
|
193
|
+
border-block-end: 1px solid var(--smrt-color-outline-variant);
|
|
194
|
+
overflow-wrap: anywhere;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.smrt-record-history > ol > li:first-child { padding-block-start: 0; }
|
|
198
|
+
.smrt-record-history > ol > li:last-child {
|
|
199
|
+
padding-block-end: 0;
|
|
200
|
+
border-block-end: 0;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.smrt-record-history p { margin-block: var(--smrt-spacing-1); }
|
|
204
|
+
.smrt-record-history time {
|
|
205
|
+
display: block;
|
|
206
|
+
color: var(--smrt-color-on-surface-variant);
|
|
207
|
+
font: var(--smrt-typography-label-medium-font);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.smrt-record-history a {
|
|
211
|
+
color: var(--smrt-color-on-surface);
|
|
212
|
+
text-decoration-color: var(--smrt-color-primary);
|
|
213
|
+
text-decoration-thickness: .08em;
|
|
214
|
+
text-underline-offset: .18em;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.smrt-record-history a:hover { text-decoration-thickness: .14em; }
|
|
218
|
+
.smrt-record-history a:focus-visible {
|
|
219
|
+
border-radius: var(--smrt-radius-extra-small, .25rem);
|
|
220
|
+
outline: 2px solid var(--smrt-color-primary);
|
|
221
|
+
outline-offset: 2px;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.smrt-record-history ul {
|
|
225
|
+
display: grid;
|
|
226
|
+
gap: var(--smrt-spacing-1);
|
|
227
|
+
margin-block: var(--smrt-spacing-2) 0;
|
|
228
|
+
padding: var(--smrt-spacing-2) var(--smrt-spacing-3);
|
|
229
|
+
border-inline-start: 2px solid var(--smrt-color-outline);
|
|
230
|
+
border-radius: var(--smrt-radius-small, .375rem);
|
|
231
|
+
background: var(--smrt-color-surface-container-low);
|
|
232
|
+
list-style: none;
|
|
233
|
+
}
|
|
76
234
|
</style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuditHistoryEntry } from './types.js';
|
|
1
|
+
import type { AuditEntryLabel, AuditFieldLabel, AuditHistoryEntry, AuditResourceHref, AuditValueFormatter } from './types.js';
|
|
2
2
|
interface Props {
|
|
3
3
|
/** Authorized entries. This component never fetches or authorizes records. */
|
|
4
4
|
entries: AuditHistoryEntry[];
|
|
@@ -12,6 +12,16 @@ interface Props {
|
|
|
12
12
|
error?: string | null;
|
|
13
13
|
/** Overrides the translated accessible label for the history section. */
|
|
14
14
|
label?: string;
|
|
15
|
+
/** Resolves friendly resource text for each authorized entry. */
|
|
16
|
+
resourceLabel?: AuditEntryLabel;
|
|
17
|
+
/** Resolves an already-authorized local or HTTP(S) destination for each entry. */
|
|
18
|
+
resourceHref?: AuditResourceHref;
|
|
19
|
+
/** Resolves friendly action text for each authorized entry. */
|
|
20
|
+
actionLabel?: AuditEntryLabel;
|
|
21
|
+
/** Resolves friendly field text for each authorized entry change. */
|
|
22
|
+
fieldLabel?: AuditFieldLabel;
|
|
23
|
+
/** Formats before/after values as escaped text. */
|
|
24
|
+
formatValue?: AuditValueFormatter;
|
|
15
25
|
}
|
|
16
26
|
declare const RecordHistory: import("svelte").Component<Props, {}, "">;
|
|
17
27
|
type RecordHistory = ReturnType<typeof RecordHistory>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecordHistory.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/audit/RecordHistory.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"RecordHistory.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/audit/RecordHistory.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAGpB,UAAU,KAAK;IACb,8EAA8E;IAC9E,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,wFAAwF;IACxF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,kFAAkF;IAClF,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,+DAA+D;IAC/D,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,mDAAmD;IACnD,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACnC;AA4JD,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default as AuditList } from './AuditList.svelte';
|
|
2
2
|
export { default as RecordHistory } from './RecordHistory.svelte';
|
|
3
|
-
export type { AuditHistoryEntry, AuditListFilter } from './types.js';
|
|
3
|
+
export type { AuditEntryLabel, AuditFieldLabel, AuditHistoryEntry, AuditListFilter, AuditResourceHref, AuditValueFormatContext, AuditValueFormatter, } from './types.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/audit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/audit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,YAAY,EACV,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
|
|
@@ -20,4 +20,22 @@ export interface AuditListFilter {
|
|
|
20
20
|
from: string;
|
|
21
21
|
to: string;
|
|
22
22
|
}
|
|
23
|
+
/** Resolves presentation text for one already-authorized audit entry. */
|
|
24
|
+
export type AuditEntryLabel = (entry: AuditHistoryEntry) => string;
|
|
25
|
+
/**
|
|
26
|
+
* Resolves an already-authorized destination for an audit entry.
|
|
27
|
+
*
|
|
28
|
+
* The component accepts local paths and explicit HTTP(S) URLs only. Consumers
|
|
29
|
+
* must still authorize the referenced resource before exposing its href.
|
|
30
|
+
*/
|
|
31
|
+
export type AuditResourceHref = (entry: AuditHistoryEntry) => string | null | undefined;
|
|
32
|
+
/** Resolves a presentation label for one changed field. */
|
|
33
|
+
export type AuditFieldLabel = (field: string, entry: AuditHistoryEntry) => string;
|
|
34
|
+
export interface AuditValueFormatContext {
|
|
35
|
+
entry: AuditHistoryEntry;
|
|
36
|
+
field: string;
|
|
37
|
+
side: 'before' | 'after';
|
|
38
|
+
}
|
|
39
|
+
/** Formats an audit value as text. Formatter output is never rendered as HTML. */
|
|
40
|
+
export type AuditValueFormatter = (value: unknown, context: AuditValueFormatContext) => string;
|
|
23
41
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/audit/types.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/audit/types.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,MAAM,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAC9B,KAAK,EAAE,iBAAiB,KACrB,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAE/B,2DAA2D;AAC3D,MAAM,MAAM,eAAe,GAAG,CAC5B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,iBAAiB,KACrB,MAAM,CAAC;AAEZ,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC1B;AAED,kFAAkF;AAClF,MAAM,MAAM,mBAAmB,GAAG,CAChC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,uBAAuB,KAC7B,MAAM,CAAC"}
|