@vuu-ui/vuu-shell 4.0.0-alpha.25 → 4.0.0-alpha.26

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 (77) hide show
  1. package/package.json +15 -15
  2. package/src/persistence-manager/PersistenceProvider.js +5 -7
  3. package/src/persistence-manager/index.js +1 -3
  4. package/src/workspace-management/LayoutList.js +1 -1
  5. package/src/workspace-management/index.js +1 -8
  6. package/src/workspace-management/useWorkspaceContextMenuItems.js +1 -2
  7. package/types/feature/FeatureErrorBoundary.d.ts +13 -0
  8. package/types/persistence-manager/PersistenceProvider.d.ts +2 -3
  9. package/types/persistence-manager/index.d.ts +1 -3
  10. package/types/src/ShellContextProvider.d.ts +7 -0
  11. package/types/src/app-header/AppHeader.d.ts +6 -0
  12. package/types/src/app-header/index.d.ts +1 -0
  13. package/types/src/application-provider/ApplicationContext.d.ts +11 -0
  14. package/types/src/application-provider/ApplicationProvider.d.ts +17 -0
  15. package/types/src/application-provider/index.d.ts +1 -0
  16. package/types/src/feature/Feature.d.ts +10 -0
  17. package/types/src/feature/FeatureErrorBoundary.d.ts +13 -0
  18. package/types/src/feature/Loader.d.ts +1 -0
  19. package/types/src/feature/index.d.ts +1 -0
  20. package/types/src/feature-and-layout-provider/FeatureAndLayoutProvider.d.ts +19 -0
  21. package/types/src/feature-and-layout-provider/index.d.ts +1 -0
  22. package/types/src/feature-list/FeatureList.d.ts +7 -0
  23. package/types/src/feature-list/index.d.ts +1 -0
  24. package/types/src/get-layout-history.d.ts +8 -0
  25. package/types/src/index.d.ts +14 -0
  26. package/types/src/left-nav/LeftNav.d.ts +14 -0
  27. package/types/src/left-nav/index.d.ts +1 -0
  28. package/types/src/login/LoginPanel.d.ts +6 -0
  29. package/types/src/login/VuuLogo.d.ts +1 -0
  30. package/types/src/persistence-manager/LocalPersistenceManager.d.ts +20 -0
  31. package/types/src/persistence-manager/PersistenceManager.d.ts +71 -0
  32. package/types/src/persistence-manager/PersistenceProvider.d.ts +11 -0
  33. package/types/src/persistence-manager/RemotePersistenceManager.d.ts +25 -0
  34. package/types/src/persistence-manager/StaticPersistenceManager.d.ts +25 -0
  35. package/types/src/persistence-manager/index.d.ts +5 -0
  36. package/types/src/shell-layout-templates/context-panel/ContextPanel.d.ts +13 -0
  37. package/types/src/shell-layout-templates/context-panel/index.d.ts +1 -0
  38. package/types/src/shell-layout-templates/full-height-left-panel/useFullHeightLeftPanel.d.ts +2 -0
  39. package/types/src/shell-layout-templates/index.d.ts +3 -0
  40. package/types/src/shell-layout-templates/inlay-left-panel/useInlayLeftPanel.d.ts +2 -0
  41. package/types/src/shell-layout-templates/left-main-tabs/useLeftMainTabs.d.ts +2 -0
  42. package/types/src/shell-layout-templates/side-panel/SidePanel.d.ts +8 -0
  43. package/types/src/shell-layout-templates/side-panel/index.d.ts +1 -0
  44. package/types/src/shell-layout-templates/simple-content-pane/useSimpleContentPane.d.ts +2 -0
  45. package/types/src/shell-layout-templates/useShellLayout.d.ts +51 -0
  46. package/types/src/shell.d.ts +17 -0
  47. package/types/src/theme-switch/ThemeSwitch.d.ts +8 -0
  48. package/types/src/theme-switch/index.d.ts +1 -0
  49. package/types/src/user-settings/SettingsForm.d.ts +46 -0
  50. package/types/src/user-settings/UserSettingsPanel.d.ts +3 -0
  51. package/types/src/user-settings/index.d.ts +2 -0
  52. package/types/src/workspace-management/LayoutList.d.ts +2 -0
  53. package/types/src/workspace-management/LayoutTile.d.ts +7 -0
  54. package/types/src/workspace-management/SaveLayoutPanel.d.ts +9 -0
  55. package/types/src/workspace-management/WorkspaceProvider.d.ts +52 -0
  56. package/types/src/workspace-management/defaultWorkspaceJSON.d.ts +10 -0
  57. package/types/src/workspace-management/index.d.ts +5 -0
  58. package/types/src/workspace-management/screenshot-utils.d.ts +6 -0
  59. package/types/src/workspace-management/useWorkspaceContextMenuItems.d.ts +5 -0
  60. package/types/user-settings/SettingsForm.d.ts +46 -0
  61. package/types/user-settings/UserSettingsPanel.d.ts +3 -0
  62. package/types/user-settings/index.d.ts +2 -0
  63. package/types/workspace-management/WorkspaceProvider.d.ts +50 -61
  64. package/types/workspace-management/index.d.ts +5 -8
  65. package/types/workspace-management/shell-workspace-components.d.ts +1 -1
  66. package/src/persistence-manager/LocalWorkspacePersistenceService.js +0 -129
  67. package/src/persistence-manager/RemoteWorkspacePersistenceService.js +0 -112
  68. package/src/persistence-manager/WorkspacePersistenceService.js +0 -9
  69. package/src/workspace-management/WorkspaceController.js +0 -73
  70. package/src/workspace-management/WorkspaceHost.js +0 -194
  71. package/src/workspace-management/WorkspacePersistentState.js +0 -67
  72. package/src/workspace-management/WorkspaceProvider.js +0 -730
  73. package/src/workspace-management/WorkspaceRepository.js +0 -127
  74. package/src/workspace-management/WorkspaceStartPanel.css.js +0 -44
  75. package/src/workspace-management/WorkspaceStartPanel.js +0 -34
  76. package/src/workspace-management/workspace-component-registry.js +0 -30
  77. package/src/workspace-management/workspace-schemas.js +0 -257
@@ -0,0 +1,17 @@
1
+ import { VuuUser } from "@vuu-ui/vuu-utils";
2
+ import { type HTMLAttributes, type ReactNode } from "react";
3
+ import { ShellLayoutProps } from "./shell-layout-templates";
4
+ import { SettingsSchema } from "./user-settings";
5
+ import { WorkspaceProps } from "./workspace-management";
6
+ export type LayoutTemplateName = "full-height" | "inlay";
7
+ export interface ShellProps extends HTMLAttributes<HTMLDivElement> {
8
+ shellLayoutProps?: ShellLayoutProps;
9
+ userSettingsSchema?: SettingsSchema;
10
+ workspaceProps?: WorkspaceProps;
11
+ children?: ReactNode;
12
+ logout?: () => void;
13
+ saveUrl?: string;
14
+ serverUrl?: string;
15
+ user: VuuUser;
16
+ }
17
+ export declare const Shell: ({ logout, user, userSettingsSchema, workspaceProps, ...props }: ShellProps) => import("react").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { HTMLAttributes } from "react";
2
+ import { ThemeMode } from "@vuu-ui/vuu-utils";
3
+ export interface ThemeSwitchProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
4
+ defaultMode?: ThemeMode;
5
+ mode?: ThemeMode;
6
+ onChange: (mode: ThemeMode) => void;
7
+ }
8
+ export declare const ThemeSwitch: ({ className: classNameProp, defaultMode: defaultModeProp, mode: modeProp, onChange, ...htmlAttributes }: ThemeSwitchProps) => import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ export * from "./ThemeSwitch";
@@ -0,0 +1,46 @@
1
+ import type { VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
2
+ import { type Settings } from "@vuu-ui/vuu-utils";
3
+ import { type DropdownProps } from "@salt-ds/core";
4
+ import { type FormEventHandler, type HTMLAttributes } from "react";
5
+ export interface SettingsSchema {
6
+ properties: SettingsProperty[];
7
+ }
8
+ export type OptionType<T> = {
9
+ label: string;
10
+ value: T;
11
+ };
12
+ export declare const isOption: (value: OptionType<number | string> | number | string) => value is OptionType<number | string>;
13
+ export interface BaseProperty {
14
+ name: string;
15
+ label: string;
16
+ }
17
+ export interface StringProperty extends BaseProperty {
18
+ values?: string[] | OptionType<string>[];
19
+ defaultValue?: string;
20
+ type: "string";
21
+ }
22
+ export interface NumericProperty extends BaseProperty {
23
+ values?: number[] | OptionType<number>[];
24
+ defaultValue?: number;
25
+ type: "number";
26
+ }
27
+ export interface BooleanProperty extends BaseProperty {
28
+ defaultValue?: boolean;
29
+ type: "boolean";
30
+ }
31
+ export type SettingsProperty = StringProperty | NumericProperty | BooleanProperty;
32
+ export declare const isBooleanProperty: (property: SettingsProperty) => property is BooleanProperty;
33
+ export declare const isStringOrNumber: (value: unknown) => value is string | number;
34
+ export declare function FormControl({ property, changeHandler, selectHandler, inputHandler, currentValue, }: {
35
+ property: SettingsProperty;
36
+ changeHandler: FormEventHandler;
37
+ selectHandler: DropdownProps["onSelectionChange"];
38
+ inputHandler: FormEventHandler;
39
+ currentValue: VuuRowDataItemType;
40
+ }): import("react").JSX.Element | null;
41
+ export interface SettingsFormProps extends HTMLAttributes<HTMLDivElement> {
42
+ settingsSchema: SettingsSchema;
43
+ settings: Settings;
44
+ onSettingChanged: (propertyName: string, value: string | number | boolean) => void;
45
+ }
46
+ export declare const SettingsForm: ({ className, settingsSchema, settings, onSettingChanged, ...htmlAttributes }: SettingsFormProps) => import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import { HTMLAttributes } from "react";
2
+ export type UserSettingsPanelProps = HTMLAttributes<HTMLDivElement>;
3
+ export declare const UserSettingsPanel: ({ ...htmlAttributes }: UserSettingsPanelProps) => import("react").JSX.Element | null;
@@ -0,0 +1,2 @@
1
+ export * from "./UserSettingsPanel";
2
+ export * from "./SettingsForm";
@@ -0,0 +1,2 @@
1
+ import { HTMLAttributes } from "react";
2
+ export declare const LayoutList: ({ className, title, ...htmlAttributes }: HTMLAttributes<HTMLDivElement>) => import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { LayoutJSON, LayoutMetadata, SystemLayoutMetadata } from "@vuu-ui/vuu-utils";
2
+ import { HTMLAttributes } from "react";
3
+ export interface LayoutTileProps extends HTMLAttributes<HTMLDivElement> {
4
+ metadata: LayoutMetadata | SystemLayoutMetadata;
5
+ onLoadLayout: (layoutId?: string, layoutJSON?: LayoutJSON) => void;
6
+ }
7
+ export declare const LayoutTile: ({ metadata, onLoadLayout, ...htmlAttributes }: LayoutTileProps) => import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { LayoutMetadataDto } from "@vuu-ui/vuu-utils";
2
+ type SaveLayoutPanelProps = {
3
+ componentId?: string;
4
+ defaultTitle?: string;
5
+ onCancel: () => void;
6
+ onSave: (layoutMetadata: LayoutMetadataDto) => void;
7
+ };
8
+ export declare const SaveLayoutPanel: (props: SaveLayoutPanelProps) => import("react").JSX.Element;
9
+ export {};
@@ -0,0 +1,52 @@
1
+ import { LayoutMetadata, LayoutMetadataDto, type ApplicationSetting, type ApplicationSettings, type LayoutJSON } from "@vuu-ui/vuu-utils";
2
+ import { ReactElement } from "react";
3
+ import { type WorkspaceStackProps } from "./defaultWorkspaceJSON";
4
+ export type WorkspaceProps = WorkspaceStackProps & {
5
+ layoutPlaceholderJSON?: LayoutJSON;
6
+ /**
7
+ * layoutJSON defines the default layout to render on first load and until such time as
8
+ * layout state has been persisted. After that, the persisted state will be rendered.
9
+ */
10
+ layoutJSON?: LayoutJSON | LayoutJSON[];
11
+ activeLayoutIndex?: number;
12
+ /**
13
+ * The Vuu workspace is the container into which layouts are loaded. By default, it will be
14
+ * a Tabbed Panel (Stack + Tabstrip), showing a tab per Layout.
15
+ */
16
+ workspaceJSON?: LayoutJSON | LayoutJSON[];
17
+ };
18
+ export interface WorkspaceProviderProps extends WorkspaceProps {
19
+ children: ReactElement | ReactElement[];
20
+ /**
21
+ * layoutPlaceholderJSON defines the layout to render when a new workspace layout is created.
22
+ */
23
+ layoutPlaceholderJSON?: LayoutJSON;
24
+ }
25
+ /**
26
+ * LayoutManagementProvider supplies an API for loading and saving layout documents.
27
+ * Initial layout is automatically loaded on startup. Because this hook is responsible
28
+ * only for loading and saving layouts, it only triggers a render when content is loaded.
29
+ *
30
+ * Initial layout displays a loading state
31
+ * User may supply a default layout. This will not be displayed until call has been made to
32
+ * persistenceManager to retrieve stored layout state. If no stored state is returned, the
33
+ * default layout provided by user will be set as current state (and hence rendered). If no
34
+ * default layout has been provided by user, the sysem default will be used (simple PlaceHolder)
35
+ * If saved layout state has been returned, that will be set as current state (and rendered)
36
+ *
37
+ */
38
+ export declare const WorkspaceProvider: ({ TabstripProps, children, layoutJSON, activeLayoutIndex, layoutPlaceholderJSON, showTabs, workspaceJSON: customWorkspaceJSON, }: WorkspaceProviderProps) => import("react").JSX.Element;
39
+ export declare const useWorkspace: () => {
40
+ layoutMetadata: LayoutMetadata[];
41
+ layoutPlaceholderJSON?: LayoutJSON;
42
+ getApplicationSettings: (key?: keyof ApplicationSettings) => ApplicationSettings | ApplicationSetting | undefined;
43
+ loadLayoutById: (id: string) => void;
44
+ saveApplicationSettings: (settings: ApplicationSettings | ApplicationSetting, key?: keyof ApplicationSettings) => void;
45
+ saveLayout: (n: LayoutMetadataDto) => void;
46
+ saveApplicationLayout: (layout: LayoutJSON) => void;
47
+ workspaceJSON: LayoutJSON<{
48
+ [key: string]: any;
49
+ }>[] | LayoutJSON<{
50
+ [key: string]: any;
51
+ }>;
52
+ };
@@ -0,0 +1,10 @@
1
+ import { StackProps } from "@vuu-ui/vuu-layout";
2
+ import { LayoutJSON } from "@vuu-ui/vuu-utils";
3
+ export type WorkspaceStackProps = Pick<StackProps, "showTabs" | "TabstripProps">;
4
+ export declare const warningLayout: LayoutJSON;
5
+ export declare const loadingJSON: Readonly<LayoutJSON>;
6
+ export declare const defaultWorkspaceJSON: LayoutJSON<StackProps & {
7
+ preserve: boolean;
8
+ }>;
9
+ export declare const getStackWorkspaceJSON: (activeLayoutIndex?: number) => LayoutJSON;
10
+ export declare const getWorkspaceWithLayoutJSON: (customWorkspaceJSON?: LayoutJSON | LayoutJSON[], layoutJSON?: LayoutJSON | LayoutJSON[], activeLayoutIndex?: number, stackProps?: WorkspaceStackProps) => LayoutJSON | LayoutJSON[];
@@ -0,0 +1,5 @@
1
+ export * from "./SaveLayoutPanel";
2
+ export * from "./LayoutList";
3
+ export * from "./WorkspaceProvider";
4
+ export * from "./defaultWorkspaceJSON";
5
+ export * from "./useWorkspaceContextMenuItems";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Takes a screenshot of the given node and returns the base64 encoded image url
3
+ * @param node HTMLElement to take screenshot of
4
+ * @returns Base64 encoded image url
5
+ */
6
+ export declare const takeScreenshot: (node: HTMLElement) => Promise<string>;
@@ -0,0 +1,5 @@
1
+ import { MenuActionHandler, MenuBuilder } from "@vuu-ui/vuu-context-menu";
2
+ export declare const useWorkspaceContextMenuItems: () => {
3
+ buildMenuOptions: MenuBuilder;
4
+ handleMenuAction: MenuActionHandler;
5
+ };
@@ -0,0 +1,46 @@
1
+ import type { VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
2
+ import { type Settings } from "@vuu-ui/vuu-utils";
3
+ import { type DropdownProps } from "@salt-ds/core";
4
+ import { type FormEventHandler, type HTMLAttributes } from "react";
5
+ export interface SettingsSchema {
6
+ properties: SettingsProperty[];
7
+ }
8
+ export type OptionType<T> = {
9
+ label: string;
10
+ value: T;
11
+ };
12
+ export declare const isOption: (value: OptionType<number | string> | number | string) => value is OptionType<number | string>;
13
+ export interface BaseProperty {
14
+ name: string;
15
+ label: string;
16
+ }
17
+ export interface StringProperty extends BaseProperty {
18
+ values?: string[] | OptionType<string>[];
19
+ defaultValue?: string;
20
+ type: "string";
21
+ }
22
+ export interface NumericProperty extends BaseProperty {
23
+ values?: number[] | OptionType<number>[];
24
+ defaultValue?: number;
25
+ type: "number";
26
+ }
27
+ export interface BooleanProperty extends BaseProperty {
28
+ defaultValue?: boolean;
29
+ type: "boolean";
30
+ }
31
+ export type SettingsProperty = StringProperty | NumericProperty | BooleanProperty;
32
+ export declare const isBooleanProperty: (property: SettingsProperty) => property is BooleanProperty;
33
+ export declare const isStringOrNumber: (value: unknown) => value is string | number;
34
+ export declare function FormControl({ property, changeHandler, selectHandler, inputHandler, currentValue, }: {
35
+ property: SettingsProperty;
36
+ changeHandler: FormEventHandler;
37
+ selectHandler: DropdownProps["onSelectionChange"];
38
+ inputHandler: FormEventHandler;
39
+ currentValue: VuuRowDataItemType;
40
+ }): import("react/jsx-runtime").JSX.Element | null;
41
+ export interface SettingsFormProps extends HTMLAttributes<HTMLDivElement> {
42
+ settingsSchema: SettingsSchema;
43
+ settings: Settings;
44
+ onSettingChanged: (propertyName: string, value: string | number | boolean) => void;
45
+ }
46
+ export declare const SettingsForm: ({ className, settingsSchema, settings, onSettingChanged, ...htmlAttributes }: SettingsFormProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import { HTMLAttributes } from "react";
2
+ export type UserSettingsPanelProps = HTMLAttributes<HTMLDivElement>;
3
+ export declare const UserSettingsPanel: ({ ...htmlAttributes }: UserSettingsPanelProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,2 @@
1
+ export * from "./UserSettingsPanel";
2
+ export * from "./SettingsForm";
@@ -1,63 +1,52 @@
1
- import { type GridComponentRendererRegistry, type GridComponentSettingsRegistry, type JsonValue } from "@vuu-ui/grid-layout";
2
- import type { LayoutJSON } from "@vuu-ui/vuu-utils";
3
- import { type ReactElement, type ReactNode } from "react";
4
- import { type WorkspacePersistenceService } from "../persistence-manager";
5
- import { WorkspaceController } from "./WorkspaceController";
6
- import { type NamedWorkspaceDefinitionV1, type NamedWorkspaceMetadataV1, type WorkspaceSnapshotV1 } from "./workspace-schemas";
7
- export declare const emptyWorkspaceSnapshot: WorkspaceSnapshotV1;
8
- export type WorkspaceStatus = "empty" | "error" | "loading" | "ready";
9
- export interface WorkspaceProps {
10
- /** @deprecated Migrate this layout to defaultWorkspace. */
11
- readonly activeLayoutIndex?: number;
12
- readonly componentRenderers?: GridComponentRendererRegistry;
13
- readonly defaultWorkspace?: WorkspaceSnapshotV1;
14
- /** @deprecated Migrate this layout to defaultWorkspace. */
15
- readonly layoutJSON?: LayoutJSON | readonly LayoutJSON[];
16
- /** @deprecated Workspace snapshots contain their own placeholders. */
17
- readonly layoutPlaceholderJSON?: LayoutJSON;
18
- readonly settingsCodecs?: GridComponentSettingsRegistry;
19
- /** @deprecated Tabs are managed by WorkspaceHost. */
20
- readonly showTabs?: boolean | "left" | "right";
21
- readonly systemWorkspaces?: readonly NamedWorkspaceDefinitionV1[];
22
- /** @deprecated Tabs are managed by WorkspaceHost. */
23
- readonly TabstripProps?: Readonly<Record<string, unknown>>;
24
- /** @deprecated Migrate this layout to defaultWorkspace. */
25
- readonly workspaceJSON?: LayoutJSON | readonly LayoutJSON[];
26
- }
1
+ import { LayoutMetadata, LayoutMetadataDto, type ApplicationSetting, type ApplicationSettings, type LayoutJSON } from "@vuu-ui/vuu-utils";
2
+ import { ReactElement } from "react";
3
+ import { type WorkspaceStackProps } from "./defaultWorkspaceJSON";
4
+ export type WorkspaceProps = WorkspaceStackProps & {
5
+ layoutPlaceholderJSON?: LayoutJSON;
6
+ /**
7
+ * layoutJSON defines the default layout to render on first load and until such time as
8
+ * layout state has been persisted. After that, the persisted state will be rendered.
9
+ */
10
+ layoutJSON?: LayoutJSON | LayoutJSON[];
11
+ activeLayoutIndex?: number;
12
+ /**
13
+ * The Vuu workspace is the container into which layouts are loaded. By default, it will be
14
+ * a Tabbed Panel (Stack + Tabstrip), showing a tab per Layout.
15
+ */
16
+ workspaceJSON?: LayoutJSON | LayoutJSON[];
17
+ };
27
18
  export interface WorkspaceProviderProps extends WorkspaceProps {
28
- readonly children: ReactNode;
29
- readonly persistenceService?: WorkspacePersistenceService;
30
- readonly userId?: string;
31
- }
32
- export interface WorkspaceContextValue {
33
- readonly activeWorkspace?: WorkspaceController;
34
- readonly activeWorkspaceInstanceId: string | null;
35
- readonly closeWorkspace: (instanceId: string) => Promise<void>;
36
- readonly componentRenderers?: GridComponentRendererRegistry;
37
- readonly controllers: readonly WorkspaceController[];
38
- readonly createWorkspaceFromSnapshot: (snapshot: WorkspaceSnapshotV1, title?: string) => Promise<string>;
39
- readonly deleteNamedWorkspace: (definitionId: string) => Promise<void>;
40
- readonly error?: Error;
41
- readonly getApplicationSetting: (key: string) => JsonValue | undefined;
42
- readonly getApplicationSettings: (key?: string) => JsonValue | Readonly<Record<string, JsonValue>> | undefined;
43
- readonly namedWorkspaces: readonly NamedWorkspaceMetadataV1[];
44
- readonly openNamedWorkspace: (definitionId: string) => Promise<void>;
45
- readonly openSystemWorkspace: (definition: NamedWorkspaceDefinitionV1) => Promise<void>;
46
- readonly renameWorkspace: (instanceId: string, title: string) => Promise<void>;
47
- readonly saveActiveWorkspaceAs: (name: string, description?: string) => Promise<void>;
48
- readonly saveApplicationSettings: (settings: JsonValue, key?: string) => Promise<void>;
49
- readonly selectWorkspace: (instanceId: string) => Promise<void>;
50
- readonly setApplicationSetting: (key: string, value: JsonValue) => Promise<void>;
51
- readonly settings: Readonly<Record<string, JsonValue>>;
52
- readonly settingsCodecs?: GridComponentSettingsRegistry;
53
- /** Identifies the authenticated persistence scope. Changes synchronously on a scope transition. */
54
- readonly scopeIdentity: string;
55
- readonly status: WorkspaceStatus;
56
- readonly systemWorkspaces: readonly NamedWorkspaceDefinitionV1[];
57
- readonly resetApplication: () => Promise<void>;
58
- }
59
- export declare class StaleWorkspaceScopeError extends Error {
60
- constructor();
19
+ children: ReactElement | ReactElement[];
20
+ /**
21
+ * layoutPlaceholderJSON defines the layout to render when a new workspace layout is created.
22
+ */
23
+ layoutPlaceholderJSON?: LayoutJSON;
61
24
  }
62
- export declare const WorkspaceProvider: ({ activeLayoutIndex, children, componentRenderers, defaultWorkspace, layoutJSON, layoutPlaceholderJSON, persistenceService: serviceProp, settingsCodecs, showTabs, systemWorkspaces, TabstripProps, userId, workspaceJSON, }: WorkspaceProviderProps) => ReactElement;
63
- export declare const useWorkspace: () => WorkspaceContextValue;
25
+ /**
26
+ * LayoutManagementProvider supplies an API for loading and saving layout documents.
27
+ * Initial layout is automatically loaded on startup. Because this hook is responsible
28
+ * only for loading and saving layouts, it only triggers a render when content is loaded.
29
+ *
30
+ * Initial layout displays a loading state
31
+ * User may supply a default layout. This will not be displayed until call has been made to
32
+ * persistenceManager to retrieve stored layout state. If no stored state is returned, the
33
+ * default layout provided by user will be set as current state (and hence rendered). If no
34
+ * default layout has been provided by user, the sysem default will be used (simple PlaceHolder)
35
+ * If saved layout state has been returned, that will be set as current state (and rendered)
36
+ *
37
+ */
38
+ export declare const WorkspaceProvider: ({ TabstripProps, children, layoutJSON, activeLayoutIndex, layoutPlaceholderJSON, showTabs, workspaceJSON: customWorkspaceJSON, }: WorkspaceProviderProps) => import("react/jsx-runtime").JSX.Element;
39
+ export declare const useWorkspace: () => {
40
+ workspaceJSON: LayoutJSON<{
41
+ [key: string]: any;
42
+ }> | LayoutJSON<{
43
+ [key: string]: any;
44
+ }>[];
45
+ layoutMetadata: LayoutMetadata[];
46
+ layoutPlaceholderJSON?: LayoutJSON;
47
+ getApplicationSettings: (key?: keyof ApplicationSettings) => ApplicationSettings | ApplicationSetting | undefined;
48
+ loadLayoutById: (id: string) => void;
49
+ saveApplicationSettings: (settings: ApplicationSettings | ApplicationSetting, key?: keyof ApplicationSettings) => void;
50
+ saveLayout: (n: LayoutMetadataDto) => void;
51
+ saveApplicationLayout: (layout: LayoutJSON) => void;
52
+ };
@@ -1,13 +1,10 @@
1
1
  export * from "./SaveLayoutPanel";
2
2
  export * from "./LayoutList";
3
- export * from "./WorkspaceProvider";
4
3
  export * from "./defaultWorkspaceJSON";
5
4
  export * from "./useWorkspaceContextMenuItems";
6
- export * from "./workspace-schemas";
7
- export * from "./WorkspaceRepository";
8
- export * from "./WorkspacePersistentState";
9
- export * from "./WorkspaceController";
10
- export * from "./workspace-component-registry";
11
- export * from "./WorkspaceHost";
12
- export * from "./WorkspaceStartPanel";
13
5
  export * from "./shell-workspace-components";
6
+ /**
7
+ * The workspace model now lives in @vuu-ui/core. These re-exports keep
8
+ * existing @vuu-ui/vuu-shell imports working.
9
+ */
10
+ export { APPLICATION_SESSION_VERSION, type ApplicationSessionV1, type ComponentPersistentStateV1, type ComponentStateUpdate, cloneWorkspaceValue, createWorkspaceComponentRegistries, emptyWorkspaceSnapshot, jsonValueWorkspaceComponentCodec, NAMED_WORKSPACE_DEFINITION_VERSION, type NamedWorkspaceDefinitionV1, type NamedWorkspaceMetadataV1, type OpenWorkspaceInstanceV1, StaleWorkspaceScopeError, useComponentPersistentState, useWorkspace, useWorkspacePersistentStateStore, validateApplicationSessionV1, validateNamedWorkspaceDefinitionV1, validateNamedWorkspaceMetadataV1, validateWorkspaceSnapshotRecordV1, validateWorkspaceSnapshotV1, WORKSPACE_SNAPSHOT_RECORD_VERSION, WORKSPACE_SNAPSHOT_VERSION, type WorkspaceComponentRegistration, type WorkspaceComponentRegistries, type WorkspaceContextValue, WorkspaceController, type WorkspaceControllerOptions, WorkspaceHost, type WorkspaceKind, workspaceMetadata, WorkspacePersistentStateProvider, type WorkspacePersistentStateProviderProps, WorkspacePersistentStateStore, type WorkspaceProps, WorkspaceProvider, type WorkspaceProviderProps, WorkspaceRepository, WorkspaceRepositoryDisposedError, type WorkspaceSchemaName, type WorkspaceSnapshotRecordV1, type WorkspaceSnapshotV1, WorkspaceStartPanel, type WorkspaceStatus, type WorkspaceSummary, WorkspaceValidationError, type WorkspaceValidationIssue, } from "@vuu-ui/core";
@@ -1,2 +1,2 @@
1
- import type { WorkspaceComponentRegistration } from "./workspace-component-registry";
1
+ import type { WorkspaceComponentRegistration } from "@vuu-ui/core";
2
2
  export declare const shellWorkspaceComponentRegistrations: readonly WorkspaceComponentRegistration<unknown>[];
@@ -1,129 +0,0 @@
1
- import { WorkspaceValidationError, cloneWorkspaceValue, validateApplicationSessionV1, validateNamedWorkspaceDefinitionV1, validateNamedWorkspaceMetadataV1, validateWorkspaceSnapshotRecordV1, workspaceMetadata } from "../workspace-management/workspace-schemas.js";
2
- import { WorkspacePersistenceError } from "./WorkspacePersistenceService.js";
3
- const validateScope = (scope)=>{
4
- for (const [name, value] of Object.entries(scope))if (!value) throw new WorkspacePersistenceError(`Persistence scope ${name} must not be empty`, "construct");
5
- };
6
- const requireId = (id, operation)=>{
7
- if (!id) throw new WorkspacePersistenceError("Entity id must not be empty", operation);
8
- return id;
9
- };
10
- class LocalWorkspacePersistenceService {
11
- scope;
12
- #storage;
13
- #prefix;
14
- constructor(scope, storage = localStorage){
15
- validateScope(scope);
16
- this.scope = Object.freeze({
17
- ...scope
18
- });
19
- this.#storage = storage;
20
- this.#prefix = [
21
- "vuu-workspace",
22
- scope.applicationNamespace,
23
- scope.applicationId,
24
- scope.userId
25
- ].map(encodeURIComponent).join(":");
26
- }
27
- async loadApplicationSession() {
28
- return this.#read("application-session", void 0, validateApplicationSessionV1);
29
- }
30
- async saveApplicationSession(session) {
31
- this.#write("application-session", void 0, validateApplicationSessionV1(session));
32
- }
33
- async deleteApplicationSession() {
34
- this.#remove("application-session");
35
- }
36
- async listWorkspaceSnapshots() {
37
- return this.#ids("snapshot").map((id)=>{
38
- const snapshot = this.#read("snapshot", id, validateWorkspaceSnapshotRecordV1);
39
- if (!snapshot) throw new WorkspacePersistenceError(`Snapshot index references missing workspace "${id}"`, "listWorkspaceSnapshots");
40
- return snapshot;
41
- });
42
- }
43
- async loadWorkspaceSnapshot(workspaceInstanceId) {
44
- return this.#read("snapshot", requireId(workspaceInstanceId, "loadWorkspaceSnapshot"), validateWorkspaceSnapshotRecordV1);
45
- }
46
- async saveWorkspaceSnapshot(snapshot) {
47
- const validated = validateWorkspaceSnapshotRecordV1(snapshot);
48
- this.#write("snapshot", validated.workspaceInstanceId, validated);
49
- this.#addId("snapshot", validated.workspaceInstanceId);
50
- }
51
- async deleteWorkspaceSnapshot(workspaceInstanceId) {
52
- const id = requireId(workspaceInstanceId, "deleteWorkspaceSnapshot");
53
- this.#remove("snapshot", id);
54
- this.#deleteId("snapshot", id);
55
- }
56
- async listNamedWorkspaceMetadata() {
57
- return this.#ids("definition").map((id)=>{
58
- const metadata = this.#read("definition-metadata", id, validateNamedWorkspaceMetadataV1);
59
- if (!metadata) throw new WorkspacePersistenceError(`Definition index references missing metadata "${id}"`, "listNamedWorkspaceMetadata");
60
- return metadata;
61
- });
62
- }
63
- async loadNamedWorkspaceDefinition(id) {
64
- return this.#read("definition", requireId(id, "loadNamedWorkspaceDefinition"), validateNamedWorkspaceDefinitionV1);
65
- }
66
- async saveNamedWorkspaceDefinition(definition) {
67
- const validated = validateNamedWorkspaceDefinitionV1(definition);
68
- this.#write("definition", validated.id, validated);
69
- this.#write("definition-metadata", validated.id, workspaceMetadata(validated));
70
- this.#addId("definition", validated.id);
71
- }
72
- async deleteNamedWorkspaceDefinition(id) {
73
- const validatedId = requireId(id, "deleteNamedWorkspaceDefinition");
74
- this.#remove("definition", validatedId);
75
- this.#remove("definition-metadata", validatedId);
76
- this.#deleteId("definition", validatedId);
77
- }
78
- #key(entity, id) {
79
- return `${this.#prefix}:${encodeURIComponent(entity)}${void 0 === id ? "" : `:${encodeURIComponent(id)}`}`;
80
- }
81
- #read(entity, id, validator) {
82
- const stored = this.#storage.getItem(this.#key(entity, id));
83
- if (null === stored) return;
84
- let parsed;
85
- try {
86
- parsed = JSON.parse(stored);
87
- } catch (error) {
88
- if (!(error instanceof SyntaxError)) throw error;
89
- throw new WorkspacePersistenceError(`Stored ${entity} is not valid JSON: ${error.message}`, `load:${entity}`);
90
- }
91
- try {
92
- return cloneWorkspaceValue(validator(parsed));
93
- } catch (error) {
94
- if (!(error instanceof WorkspaceValidationError)) throw error;
95
- throw new WorkspacePersistenceError(`Stored ${entity} is invalid: ${error.message}`, `load:${entity}`);
96
- }
97
- }
98
- #write(entity, id, value) {
99
- this.#storage.setItem(this.#key(entity, id), JSON.stringify(cloneWorkspaceValue(value)));
100
- }
101
- #remove(entity, id) {
102
- this.#storage.removeItem(this.#key(entity, id));
103
- }
104
- #ids(entity) {
105
- const stored = this.#storage.getItem(this.#key(`${entity}-index`));
106
- if (null === stored) return [];
107
- let parsed;
108
- try {
109
- parsed = JSON.parse(stored);
110
- } catch (error) {
111
- if (!(error instanceof SyntaxError)) throw error;
112
- throw new WorkspacePersistenceError(`Stored ${entity} index is not valid JSON: ${error.message}`, `list:${entity}`);
113
- }
114
- if (!Array.isArray(parsed) || parsed.some((id)=>"string" != typeof id || !id) || new Set(parsed).size !== parsed.length) throw new WorkspacePersistenceError(`Stored ${entity} index is invalid`, `list:${entity}`);
115
- return parsed;
116
- }
117
- #addId(entity, id) {
118
- const ids = this.#ids(entity);
119
- if (!ids.includes(id)) this.#storage.setItem(this.#key(`${entity}-index`), JSON.stringify([
120
- ...ids,
121
- id
122
- ]));
123
- }
124
- #deleteId(entity, id) {
125
- const ids = this.#ids(entity).filter((existing)=>existing !== id);
126
- this.#storage.setItem(this.#key(`${entity}-index`), JSON.stringify(ids));
127
- }
128
- }
129
- export { LocalWorkspacePersistenceService };
@@ -1,112 +0,0 @@
1
- import { cloneWorkspaceValue, validateApplicationSessionV1, validateNamedWorkspaceDefinitionV1, validateNamedWorkspaceMetadataV1, validateWorkspaceSnapshotRecordV1 } from "../workspace-management/workspace-schemas.js";
2
- import { WorkspacePersistenceError } from "./WorkspacePersistenceService.js";
3
- const trimSlash = (value)=>value.replace(/\/+$/, "");
4
- const requireId = (id, operation)=>{
5
- if (!id) throw new WorkspacePersistenceError("Entity id must not be empty", operation);
6
- return encodeURIComponent(id);
7
- };
8
- class RemoteWorkspacePersistenceService {
9
- scope;
10
- #baseUrl;
11
- #requestInit;
12
- #requestInitProvider;
13
- #fetch;
14
- constructor(scope, { baseUrl, requestInit, requestInitProvider, fetch: fetchImplementation = globalThis.fetch }){
15
- if (!scope.applicationNamespace || !scope.applicationId || !scope.userId || !baseUrl) throw new WorkspacePersistenceError("Remote persistence scope and base URL must not be empty", "construct");
16
- this.scope = Object.freeze({
17
- ...scope
18
- });
19
- this.#baseUrl = trimSlash(baseUrl);
20
- this.#requestInit = requestInit;
21
- this.#requestInitProvider = requestInitProvider;
22
- this.#fetch = fetchImplementation;
23
- }
24
- async loadApplicationSession() {
25
- return this.#optional("loadApplicationSession", "application-session", validateApplicationSessionV1);
26
- }
27
- async saveApplicationSession(session) {
28
- await this.#void("saveApplicationSession", "application-session", "PUT", validateApplicationSessionV1(session));
29
- }
30
- async deleteApplicationSession() {
31
- await this.#void("deleteApplicationSession", "application-session", "DELETE");
32
- }
33
- async listWorkspaceSnapshots() {
34
- const value = await this.#json("listWorkspaceSnapshots", "snapshots");
35
- if (!Array.isArray(value)) throw new WorkspacePersistenceError("Remote snapshot list response must be an array", "listWorkspaceSnapshots");
36
- return value.map(validateWorkspaceSnapshotRecordV1);
37
- }
38
- async loadWorkspaceSnapshot(workspaceInstanceId) {
39
- return this.#optional("loadWorkspaceSnapshot", `snapshots/${requireId(workspaceInstanceId, "loadWorkspaceSnapshot")}`, validateWorkspaceSnapshotRecordV1);
40
- }
41
- async saveWorkspaceSnapshot(snapshot) {
42
- const validated = validateWorkspaceSnapshotRecordV1(snapshot);
43
- await this.#void("saveWorkspaceSnapshot", `snapshots/${encodeURIComponent(validated.workspaceInstanceId)}`, "PUT", validated);
44
- }
45
- async deleteWorkspaceSnapshot(workspaceInstanceId) {
46
- await this.#void("deleteWorkspaceSnapshot", `snapshots/${requireId(workspaceInstanceId, "deleteWorkspaceSnapshot")}`, "DELETE");
47
- }
48
- async listNamedWorkspaceMetadata() {
49
- const value = await this.#json("listNamedWorkspaceMetadata", "named-workspaces");
50
- if (!Array.isArray(value)) throw new WorkspacePersistenceError("Remote workspace metadata response must be an array", "listNamedWorkspaceMetadata");
51
- return value.map(validateNamedWorkspaceMetadataV1);
52
- }
53
- async loadNamedWorkspaceDefinition(id) {
54
- return this.#optional("loadNamedWorkspaceDefinition", `named-workspaces/${requireId(id, "loadNamedWorkspaceDefinition")}`, validateNamedWorkspaceDefinitionV1);
55
- }
56
- async saveNamedWorkspaceDefinition(definition) {
57
- const validated = validateNamedWorkspaceDefinitionV1(definition);
58
- await this.#void("saveNamedWorkspaceDefinition", `named-workspaces/${encodeURIComponent(validated.id)}`, "PUT", validated);
59
- }
60
- async deleteNamedWorkspaceDefinition(id) {
61
- await this.#void("deleteNamedWorkspaceDefinition", `named-workspaces/${requireId(id, "deleteNamedWorkspaceDefinition")}`, "DELETE");
62
- }
63
- async #optional(operation, path, validator) {
64
- const response = await this.#request(operation, path, "GET");
65
- if (404 === response.status) return;
66
- await this.#assertOk(response, operation);
67
- return cloneWorkspaceValue(validator(await response.json()));
68
- }
69
- async #json(operation, path) {
70
- const response = await this.#request(operation, path, "GET");
71
- await this.#assertOk(response, operation);
72
- return response.json();
73
- }
74
- async #void(operation, path, method, body) {
75
- const response = await this.#request(operation, path, method, body);
76
- await this.#assertOk(response, operation);
77
- }
78
- async #request(operation, path, method, body) {
79
- const provided = this.#requestInitProvider ? await this.#requestInitProvider() : {};
80
- const configured = this.#requestInit ?? {};
81
- const headers = new Headers(configured.headers);
82
- new Headers(provided.headers).forEach((value, key)=>{
83
- headers.set(key, value);
84
- });
85
- headers.set("Accept", "application/json");
86
- headers.set("X-Vuu-Application-Namespace", this.scope.applicationNamespace);
87
- headers.set("X-Vuu-Application-Id", this.scope.applicationId);
88
- headers.set("X-Vuu-User-Id", this.scope.userId);
89
- if (void 0 !== body) headers.set("Content-Type", "application/json");
90
- const scopePath = [
91
- this.scope.applicationNamespace,
92
- this.scope.applicationId,
93
- this.scope.userId
94
- ].map(encodeURIComponent).join("/");
95
- try {
96
- return await this.#fetch(`${this.#baseUrl}/${scopePath}/${path}`, {
97
- ...configured,
98
- ...provided,
99
- headers,
100
- method,
101
- body: void 0 === body ? void 0 : JSON.stringify(cloneWorkspaceValue(body))
102
- });
103
- } catch (error) {
104
- if (!(error instanceof Error)) throw error;
105
- throw new WorkspacePersistenceError(error.message, operation);
106
- }
107
- }
108
- async #assertOk(response, operation) {
109
- if (!response.ok) throw new WorkspacePersistenceError(response.statusText || `Remote persistence request failed (${response.status})`, operation, response.status);
110
- }
111
- }
112
- export { RemoteWorkspacePersistenceService };