@vuu-ui/vuu-shell 0.5.4 → 0.5.6

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/src/shell.tsx DELETED
@@ -1,171 +0,0 @@
1
- import { connectToServer } from "@vuu-ui/vuu-data";
2
- import {
3
- HTMLAttributes,
4
- MouseEvent,
5
- ReactElement,
6
- ReactNode,
7
- useCallback,
8
- useEffect,
9
- useRef,
10
- useState,
11
- } from "react";
12
- import useLayoutConfig from "./use-layout-config";
13
- import { ShellContextProvider } from "./ShellContextProvider";
14
- import cx from "classnames";
15
-
16
- import {
17
- Chest,
18
- DraggableLayout,
19
- Drawer,
20
- FlexboxLayout as Flexbox,
21
- LayoutProvider,
22
- View,
23
- } from "@vuu-ui/vuu-layout";
24
-
25
- import { AppHeader } from "./app-header";
26
- // import { AppPalette } from "./app-palette";
27
-
28
- import { LayoutJSON } from "@vuu-ui/vuu-layout/src/layout-reducer";
29
- import "./shell.css";
30
-
31
- export type VuuUser = {
32
- username: string;
33
- token: string;
34
- };
35
-
36
- const warningLayout = {
37
- type: "View",
38
- props: {
39
- style: { height: "calc(100% - 6px)" },
40
- },
41
- children: [
42
- {
43
- props: {
44
- className: "vuuShell-warningPlaceholder",
45
- },
46
- type: "Placeholder",
47
- },
48
- ],
49
- };
50
-
51
- export interface ShellProps extends HTMLAttributes<HTMLDivElement> {
52
- children?: ReactNode;
53
- defaultLayout?: LayoutJSON;
54
- leftSidePanel?: ReactElement;
55
- loginUrl?: string;
56
- // paletteConfig: any;
57
- serverUrl?: string;
58
- user: VuuUser;
59
- }
60
-
61
- export const Shell = ({
62
- children,
63
- className,
64
- defaultLayout = warningLayout,
65
- leftSidePanel,
66
- loginUrl,
67
- serverUrl,
68
- user,
69
- ...htmlAttributes
70
- }: ShellProps) => {
71
- const paletteView = useRef<HTMLDivElement>(null);
72
- const [open, setOpen] = useState(false);
73
- const layoutId = useRef("latest");
74
-
75
- const [layout, setLayoutConfig, loadLayoutById] = useLayoutConfig(
76
- user,
77
- defaultLayout
78
- );
79
-
80
- const handleLayoutChange = useCallback(
81
- (layout) => {
82
- setLayoutConfig(layout);
83
- },
84
- [setLayoutConfig]
85
- );
86
-
87
- const handleDrawerClick = (e: MouseEvent<HTMLElement>) => {
88
- const target = e.target as HTMLElement;
89
- if (!paletteView.current?.contains(target)) {
90
- setOpen(!open);
91
- }
92
- };
93
-
94
- const handleNavigate = useCallback(
95
- (id) => {
96
- layoutId.current = id;
97
- loadLayoutById(id);
98
- },
99
- [loadLayoutById]
100
- );
101
-
102
- useEffect(() => {
103
- if (serverUrl && user.token) {
104
- connectToServer(serverUrl, user.token);
105
- }
106
- }, [serverUrl, user.token]);
107
-
108
- const getDrawers = () => {
109
- const drawers: ReactElement[] = [];
110
- if (leftSidePanel) {
111
- drawers.push(
112
- <Drawer
113
- key="left-panel"
114
- onClick={handleDrawerClick}
115
- open={open}
116
- position="left"
117
- inline
118
- peekaboo
119
- sizeOpen={200}
120
- toggleButton="end"
121
- >
122
- <View
123
- className="vuuShell-palette"
124
- id="vw-app-palette"
125
- key="app-palette"
126
- ref={paletteView}
127
- style={{ height: "100%" }}
128
- >
129
- {leftSidePanel}
130
- </View>
131
- </Drawer>
132
- );
133
- }
134
-
135
- return drawers;
136
- };
137
-
138
- return (
139
- // ShellContext TBD
140
- <ShellContextProvider value={undefined}>
141
- <LayoutProvider layout={layout} onLayoutChange={handleLayoutChange}>
142
- <DraggableLayout
143
- className={cx("vuuShell", className)}
144
- {...htmlAttributes}
145
- >
146
- <Flexbox
147
- className="App"
148
- style={{ flexDirection: "column", height: "100%", width: "100%" }}
149
- >
150
- <AppHeader
151
- layoutId={layoutId.current}
152
- loginUrl={loginUrl}
153
- user={user}
154
- onNavigate={handleNavigate}
155
- />
156
- <Chest style={{ flex: 1 }}>
157
- {getDrawers().concat(
158
- <DraggableLayout
159
- dropTarget
160
- key="main-content"
161
- style={{ width: "100%", height: "100%" }}
162
- />
163
- )}
164
- </Chest>
165
- </Flexbox>
166
- </DraggableLayout>
167
- </LayoutProvider>
168
- {children}
169
- </ShellContextProvider>
170
- );
171
- };
package/src/shellTypes.ts DELETED
@@ -1,18 +0,0 @@
1
- declare global {
2
- const vuuConfig: Promise<VuuConfig>;
3
- }
4
-
5
- export interface FeatureConfig {
6
- name: string;
7
- title: string;
8
- url: string;
9
- css?: string;
10
- }
11
-
12
- export type Features = {
13
- [key: string]: FeatureConfig;
14
- };
15
- export interface VuuConfig {
16
- features?: Features;
17
- websocketUrl: string;
18
- }
@@ -1,6 +0,0 @@
1
- import { useState } from 'react';
2
-
3
- export const useForceRender = () => {
4
- const [, forceUpdate] = useState({});
5
- return forceUpdate;
6
- };
@@ -1,55 +0,0 @@
1
- import { useCallback, useEffect, useState } from "react";
2
-
3
- const useLayoutConfig = (user, defaultLayout) => {
4
- const [layout, _setLayout] = useState(defaultLayout);
5
-
6
- const setLayout = (layout) => {
7
- _setLayout(layout);
8
- };
9
-
10
- const load = useCallback(
11
- async (id = "latest") => {
12
- fetch(`api/vui/${user.username}/${id}`, {})
13
- .then((response) => {
14
- return response.ok ? response.json() : defaultLayout;
15
- })
16
- .then(setLayout)
17
- .catch(() => {
18
- // TODO we should set a layout with a warning here
19
- setLayout(defaultLayout);
20
- });
21
- },
22
- [defaultLayout, user.username]
23
- );
24
-
25
- useEffect(() => {
26
- load();
27
- }, [load]);
28
-
29
- const saveData = useCallback(
30
- (data) => {
31
- fetch(`api/vui/${user.username}`, {
32
- method: "POST",
33
- headers: {
34
- "Content-Type": "application/json",
35
- },
36
- body: JSON.stringify(data),
37
- }).then((response) => {
38
- return response.ok ? response.json() : defaultLayout;
39
- });
40
- // .then((data) => console.log(data));
41
- },
42
- [defaultLayout, user]
43
- );
44
-
45
- const loadLayoutById = useCallback(
46
- (id) => {
47
- load(id);
48
- },
49
- [load]
50
- );
51
-
52
- return [layout, saveData, loadLayoutById];
53
- };
54
-
55
- export default useLayoutConfig;
@@ -1,26 +0,0 @@
1
- .vuuUserPanel {
2
- background-color: white;
3
- display: flex;
4
- flex-direction: column;
5
- max-height: 400px;
6
- padding: 12px;
7
- }
8
-
9
- vuuUserPanel-history {
10
- flex: 1 1 auto;
11
- }
12
-
13
- .vuuUserPanel-buttonBar {
14
- --saltButton-width: 100%;
15
- align-items: flex-end;
16
- border-top: 1px solid var(--surface3);
17
- display: flex;
18
- flex: 0 0 32px;
19
- justify-content: flex-start;
20
- }
21
-
22
- .btn-logout {
23
- --hwButton-icon-left: 12px;
24
- --hwButton-padding: 0 6px 0 24px;
25
- padding-left: 24px;
26
- }
@@ -1,81 +0,0 @@
1
- import React, { forwardRef, useCallback, useEffect, useState } from "react";
2
- import { formatDate } from "@vuu-ui/vuu-utils";
3
- import { logout } from "../login";
4
- import { getLayoutHistory } from "../get-layout-history";
5
- import { ExportIcon } from "@salt-ds/icons";
6
- import { Button } from "@salt-ds/core";
7
- import { List, ListItem } from "@heswell/salt-lab";
8
-
9
- import "./UserPanel.css";
10
-
11
- const byLastUpdate = ({ lastUpdate: l1 }, { lastUpdate: l2 }) => {
12
- return l2 === l1 ? 0 : l2 < l1 ? -1 : 1;
13
- };
14
-
15
- const HistoryListItem = (props) => {
16
- return <ListItem {...props} />;
17
- };
18
-
19
- export const UserPanel = forwardRef(function UserPanel(
20
- { loginUrl, onNavigate, user, layoutId = "latest" },
21
- forwardedRef
22
- ) {
23
- const [history, setHistory] = useState([]);
24
-
25
- useEffect(() => {
26
- async function getHistory() {
27
- const history = await getLayoutHistory(user);
28
- console.log({ history });
29
- const sortedHistory = history
30
- .filter((item) => item.id !== "latest")
31
- .sort(byLastUpdate)
32
- .map(({ id, lastUpdate }) => ({
33
- lastUpdate,
34
- id,
35
- label: `Saved at ${formatDate(new Date(lastUpdate), "kk:mm:ss")}`,
36
- }));
37
- console.log({ sortedHistory });
38
- setHistory(sortedHistory);
39
- }
40
-
41
- getHistory();
42
- }, [user]);
43
-
44
- const handleHisorySelected = useCallback(
45
- (evt, selected) => {
46
- if (selected) {
47
- onNavigate(selected.id);
48
- }
49
- },
50
- [onNavigate]
51
- );
52
-
53
- const handleLogout = useCallback(() => {
54
- logout(loginUrl);
55
- }, [loginUrl]);
56
-
57
- const selected =
58
- history.length === 0
59
- ? []
60
- : layoutId === "latest"
61
- ? history[0]
62
- : history.find((i) => i.id === layoutId);
63
- console.log({ selected });
64
-
65
- return (
66
- <div className="vuuUserPanel" ref={forwardedRef}>
67
- <List
68
- ListItem={HistoryListItem}
69
- className="vuuUserPanel-history"
70
- onSelect={handleHisorySelected}
71
- selected={selected}
72
- source={history}
73
- />
74
- <div className="vuuUserPanel-buttonBar">
75
- <Button aria-label="logout" onClick={handleLogout}>
76
- <ExportIcon /> Logout
77
- </Button>
78
- </div>
79
- </div>
80
- );
81
- });
@@ -1,3 +0,0 @@
1
- .vuuUserProfile {
2
- --svg-icon: var(--svg-user);
3
- }
@@ -1,47 +0,0 @@
1
- import React, { useCallback, useRef, useState } from "react";
2
- import { Button } from "@salt-ds/core";
3
- import { DropdownBase } from "@heswell/salt-lab";
4
- import { UserSolidIcon } from "@salt-ds/icons";
5
- import { UserPanel } from "./UserPanel";
6
-
7
- import "./UserProfile.css";
8
-
9
- export const UserProfile = ({ layoutId, loginUrl, onNavigate, user }) => {
10
- const [open, setOpen] = useState(false);
11
- const openRef = useRef(false);
12
- const buttonRef = useRef(null);
13
-
14
- const toggle = useCallback(() => {
15
- setOpen((isOpen) => {
16
- return (openRef.current = !isOpen);
17
- });
18
- requestAnimationFrame(() => {
19
- if (!openRef.current) {
20
- requestAnimationFrame(() => {
21
- buttonRef.current.focus();
22
- });
23
- }
24
- });
25
- }, []);
26
-
27
- const handleNavigate = (id) => {
28
- setOpen(false);
29
- onNavigate(id);
30
- };
31
-
32
- return (
33
- <div className="vuuUserProfile">
34
- <DropdownBase placement="bottom-end" onCancel={toggle}>
35
- <Button ref={buttonRef} variant="secondary">
36
- <UserSolidIcon />
37
- </Button>
38
- <UserPanel
39
- layoutId={layoutId}
40
- loginUrl={loginUrl}
41
- onNavigate={handleNavigate}
42
- user={user}
43
- />
44
- </DropdownBase>
45
- </div>
46
- );
47
- };
@@ -1 +0,0 @@
1
- export * from './UserProfile';