@vuu-ui/vuu-shell 4.0.0-alpha.24 → 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.
- package/package.json +15 -15
- package/src/persistence-manager/PersistenceProvider.js +5 -7
- package/src/persistence-manager/index.js +1 -3
- package/src/workspace-management/LayoutList.js +1 -1
- package/src/workspace-management/index.js +1 -8
- package/src/workspace-management/useWorkspaceContextMenuItems.js +1 -2
- package/types/feature/FeatureErrorBoundary.d.ts +13 -0
- package/types/persistence-manager/PersistenceProvider.d.ts +2 -3
- package/types/persistence-manager/index.d.ts +1 -3
- package/types/src/ShellContextProvider.d.ts +7 -0
- package/types/src/app-header/AppHeader.d.ts +6 -0
- package/types/src/app-header/index.d.ts +1 -0
- package/types/src/application-provider/ApplicationContext.d.ts +11 -0
- package/types/src/application-provider/ApplicationProvider.d.ts +17 -0
- package/types/src/application-provider/index.d.ts +1 -0
- package/types/src/feature/Feature.d.ts +10 -0
- package/types/src/feature/FeatureErrorBoundary.d.ts +13 -0
- package/types/src/feature/Loader.d.ts +1 -0
- package/types/src/feature/index.d.ts +1 -0
- package/types/src/feature-and-layout-provider/FeatureAndLayoutProvider.d.ts +19 -0
- package/types/src/feature-and-layout-provider/index.d.ts +1 -0
- package/types/src/feature-list/FeatureList.d.ts +7 -0
- package/types/src/feature-list/index.d.ts +1 -0
- package/types/src/get-layout-history.d.ts +8 -0
- package/types/src/index.d.ts +14 -0
- package/types/src/left-nav/LeftNav.d.ts +14 -0
- package/types/src/left-nav/index.d.ts +1 -0
- package/types/src/login/LoginPanel.d.ts +6 -0
- package/types/src/login/VuuLogo.d.ts +1 -0
- package/types/src/persistence-manager/LocalPersistenceManager.d.ts +20 -0
- package/types/src/persistence-manager/PersistenceManager.d.ts +71 -0
- package/types/src/persistence-manager/PersistenceProvider.d.ts +11 -0
- package/types/src/persistence-manager/RemotePersistenceManager.d.ts +25 -0
- package/types/src/persistence-manager/StaticPersistenceManager.d.ts +25 -0
- package/types/src/persistence-manager/index.d.ts +5 -0
- package/types/src/shell-layout-templates/context-panel/ContextPanel.d.ts +13 -0
- package/types/src/shell-layout-templates/context-panel/index.d.ts +1 -0
- package/types/src/shell-layout-templates/full-height-left-panel/useFullHeightLeftPanel.d.ts +2 -0
- package/types/src/shell-layout-templates/index.d.ts +3 -0
- package/types/src/shell-layout-templates/inlay-left-panel/useInlayLeftPanel.d.ts +2 -0
- package/types/src/shell-layout-templates/left-main-tabs/useLeftMainTabs.d.ts +2 -0
- package/types/src/shell-layout-templates/side-panel/SidePanel.d.ts +8 -0
- package/types/src/shell-layout-templates/side-panel/index.d.ts +1 -0
- package/types/src/shell-layout-templates/simple-content-pane/useSimpleContentPane.d.ts +2 -0
- package/types/src/shell-layout-templates/useShellLayout.d.ts +51 -0
- package/types/src/shell.d.ts +17 -0
- package/types/src/theme-switch/ThemeSwitch.d.ts +8 -0
- package/types/src/theme-switch/index.d.ts +1 -0
- package/types/src/user-settings/SettingsForm.d.ts +46 -0
- package/types/src/user-settings/UserSettingsPanel.d.ts +3 -0
- package/types/src/user-settings/index.d.ts +2 -0
- package/types/src/workspace-management/LayoutList.d.ts +2 -0
- package/types/src/workspace-management/LayoutTile.d.ts +7 -0
- package/types/src/workspace-management/SaveLayoutPanel.d.ts +9 -0
- package/types/src/workspace-management/WorkspaceProvider.d.ts +52 -0
- package/types/src/workspace-management/defaultWorkspaceJSON.d.ts +10 -0
- package/types/src/workspace-management/index.d.ts +5 -0
- package/types/src/workspace-management/screenshot-utils.d.ts +6 -0
- package/types/src/workspace-management/useWorkspaceContextMenuItems.d.ts +5 -0
- package/types/user-settings/SettingsForm.d.ts +46 -0
- package/types/user-settings/UserSettingsPanel.d.ts +3 -0
- package/types/user-settings/index.d.ts +2 -0
- package/types/workspace-management/WorkspaceProvider.d.ts +50 -61
- package/types/workspace-management/index.d.ts +5 -8
- package/types/workspace-management/shell-workspace-components.d.ts +1 -1
- package/src/persistence-manager/LocalWorkspacePersistenceService.js +0 -129
- package/src/persistence-manager/RemoteWorkspacePersistenceService.js +0 -112
- package/src/persistence-manager/WorkspacePersistenceService.js +0 -9
- package/src/workspace-management/WorkspaceController.js +0 -73
- package/src/workspace-management/WorkspaceHost.js +0 -194
- package/src/workspace-management/WorkspacePersistentState.js +0 -67
- package/src/workspace-management/WorkspaceProvider.js +0 -730
- package/src/workspace-management/WorkspaceRepository.js +0 -127
- package/src/workspace-management/WorkspaceStartPanel.css.js +0 -44
- package/src/workspace-management/WorkspaceStartPanel.js +0 -34
- package/src/workspace-management/workspace-component-registry.js +0 -30
- 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,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,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;
|
|
@@ -1,63 +1,52 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import
|
|
3
|
-
import { type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
63
|
-
|
|
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 "
|
|
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 };
|