@vuu-ui/vuu-shell 0.7.4 → 0.7.5-debug
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/cjs/index.js +1067 -2
- package/cjs/index.js.map +2 -2
- package/esm/index.js +1072 -2
- package/esm/index.js.map +2 -2
- package/index.css +208 -1
- package/index.css.map +1 -1
- package/package.json +4 -4
package/cjs/index.js
CHANGED
|
@@ -1,4 +1,1069 @@
|
|
|
1
|
-
"use strict";var pt=Object.create;var W=Object.defineProperty;var ft=Object.getOwnPropertyDescriptor;var gt=Object.getOwnPropertyNames;var ht=Object.getPrototypeOf,yt=Object.prototype.hasOwnProperty;var vt=(e,t)=>{for(var o in t)W(e,o,{get:t[o],enumerable:!0})},Se=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of gt(t))!yt.call(e,n)&&n!==o&&W(e,n,{get:()=>t[n],enumerable:!(r=ft(t,n))||r.enumerable});return e};var w=(e,t,o)=>(o=e!=null?pt(ht(e)):{},Se(t||!e||!e.__esModule?W(o,"default",{value:e,enumerable:!0}):o,e)),St=e=>Se(W({},"__esModule",{value:!0}),e);var $t={};vt($t,{ConnectionStatusIcon:()=>Tt,DEFAULT_DENSITY:()=>it,DEFAULT_THEME:()=>lt,DEFAULT_THEME_MODE:()=>ut,DensitySwitch:()=>wt,Feature:()=>ie,LoginPanel:()=>bt,SessionEditingForm:()=>Nt,Shell:()=>At,ShellContextProvider:()=>fe,ThemeContext:()=>ye,ThemeProvider:()=>ct,ThemeSwitch:()=>ge,getAuthDetailsFromCookies:()=>Mt,logout:()=>ce,redirectToLogin:()=>He,useShellContext:()=>Ft});module.exports=St($t);var A=w(require("react")),Te=w(require("classnames"));var k=require("react/jsx-runtime"),Tt=({connectionStatus:e,className:t,element:o="span",...r})=>{let[n,a]=(0,A.useState)("vuuConnectingStatus");(0,A.useEffect)(()=>{switch(e){case"connected":case"reconnected":a("vuuActiveStatus");break;case"connecting":a("vuuConnectingStatus");break;case"disconnected":a("vuuDisconnectedStatus");break;default:break}},[e]);let l=A.default.createElement(o,{...r,className:(0,Te.default)("vuuStatus vuuIcon",n,t)});return(0,k.jsx)(k.Fragment,{children:(0,k.jsxs)("div",{className:"vuuStatus-container salt-theme",children:[l,(0,k.jsxs)("div",{className:"vuuStatus-text",children:["Status: ",e.toUpperCase()]})]})})};var xe=require("@heswell/salt-lab"),Ce=require("react"),Le=w(require("classnames")),we=require("react/jsx-runtime"),xt="vuuDensitySwitch",Ct=["high","medium","low","touch"],Lt="high",wt=({className:e,defaultDensity:t=Lt,onDensityChange:o})=>{let r=(0,Ce.useCallback)((a,l)=>{o(l)},[o]),n=(0,Le.default)(xt,e);return(0,we.jsx)(xe.Dropdown,{className:n,source:Ct,defaultSelected:t,onSelectionChange:r})};var N=w(require("react")),Me=require("@vuu-ui/vuu-layout");var De=w(require("react")),U=require("react/jsx-runtime"),Q=class extends De.default.Component{constructor(t){super(t),this.state={errorMessage:null}}static getDerivedStateFromError(t){return{errorMessage:t.message}}componentDidCatch(t,o){console.log(t,o)}render(){return this.state.errorMessage?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)("h1",{children:"Something went wrong."}),(0,U.jsx)("p",{children:this.state.errorMessage})]}):this.props.children}};var be=require("react/jsx-runtime"),Ee=()=>(0,be.jsx)("div",{className:"hwLoader",children:"loading"});var q=require("react/jsx-runtime"),X=new Map,Dt=e=>((0,N.useEffect)(()=>()=>{X.delete(e)},[e]),X.has(e)||X.set(e,N.default.lazy(()=>import(e))),X.get(e));function Et({url:e,css:t,params:o,...r}){console.log("Feature render",{css:t,url:e,props:r}),(0,N.useEffect)(()=>(console.log("%cFeature mount","color: green;"),()=>{console.log("%cFeature unmount","color:red;")}),[]),t&&import(t).then(a=>{console.log("%cInject Styles","color: blue;font-weight: bold"),document.adoptedStyleSheets=[...document.adoptedStyleSheets,a.default]});let n=Dt(e);return(0,q.jsx)(Q,{children:(0,q.jsx)(N.Suspense,{fallback:(0,q.jsx)(Ee,{}),children:(0,q.jsx)(n,{...r,...o})})})}var ie=N.default.memo(Et);ie.displayName="Feature";(0,Me.registerComponent)("Feature",ie,"view");var le=require("react"),Ne=require("@salt-ds/core"),O=require("@heswell/salt-lab");var H=require("react/jsx-runtime"),Pe="vuuLoginPanel",bt=({onSubmit:e})=>{let[t,o]=(0,le.useState)(""),[r,n]=(0,le.useState)(""),a=()=>{e(t,r)},l=(m,u)=>{o(u)},c=(m,u)=>{n(u)},i=t.trim()!==""&&r.trim()!=="";return(0,H.jsxs)("div",{className:Pe,children:[(0,H.jsx)(O.FormField,{label:"Username",style:{width:200},children:(0,H.jsx)(O.Input,{value:t,id:"text-username",onChange:l})}),(0,H.jsx)(O.FormField,{label:"Password",style:{width:200},children:(0,H.jsx)(O.Input,{type:"password",value:r,id:"text-password",onChange:c})}),(0,H.jsx)(Ne.Button,{className:`${Pe}-login`,disabled:!i,onClick:a,variant:"cta",children:"Login"})]})};var ue=require("@vuu-ui/vuu-utils"),Mt=()=>{let e=(0,ue.getCookieValue)("vuu-username"),t=(0,ue.getCookieValue)("vuu-auth-token");return[e,t]},He=(e="login.html")=>{window.location.href=e},ce=e=>{document.cookie="vuu-username= ; expires = Thu, 01 Jan 1970 00:00:00 GMT",document.cookie="vuu-auth-token= ; expires = Thu, 01 Jan 1970 00:00:00 GMT",He(e)};var g=require("react"),me=w(require("classnames")),ke=require("@salt-ds/core"),de=require("@salt-ds/core"),Z=require("@vuu-ui/vuu-data"),I=require("@vuu-ui/vuu-utils");var T=require("react/jsx-runtime"),b="vuuSessionEditingForm",Re=(e,t)=>{let o=e.find(r=>r.name===t);if(o)return o;throw Error(`SessionEditingForm, no field '${t}' found`)},Fe=e=>{let{dataset:{field:t},value:o}=e.target;if(t===void 0)throw Error("SessionEditingForm, form field has no field name");return[t,o]},M={uninitialised:0,unchanged:1,changed:2,invalid:3};function Ve(e,t,o=!1){switch(t){case"int":case"long":{let r=parseInt(e,10);if((0,I.isValidNumber)(r))return r;if(o)throw Error("SessionEditingForm getTypedValue");return}case"double":{let r=parseFloat(e);return(0,I.isValidNumber)(r)?r:void 0}case"boolean":return e==="true";default:return e}}var Pt=(e,t)=>{if(e)return e;if(t)return new Z.RemoteDataSource({bufferSize:0,table:t.table,columns:t.columns.map(o=>o.name)});throw Error("SessionEditingForm: either a DataSource or a TableSchema must be provided")},Nt=({className:e,config:{fields:t,key:o},dataSource:r,id:n,onClose:a,schema:l,...c})=>{let[i,m]=(0,g.useState)(),[u,h]=(0,g.useState)(""),d=(0,g.useRef)(null),p=(0,g.useRef)(),y=(0,g.useRef)(M.uninitialised),L=(0,g.useMemo)(()=>{let s=D=>{if(S){let E={};for(let B of L.columns)E[B]=D[S[B]];y.current===M.uninitialised&&(y.current=M.unchanged,p.current=E),m(E)}},f=Pt(r,l),S=(0,I.buildColumnMap)(f.columns);return f.subscribe({range:{from:0,to:5}},D=>{D.type==="viewport-update"&&D.rows&&(y.current===M.uninitialised?s(D.rows[0]):console.log("what do we do with server updates"))}),f},[r,l]),J=(0,ke.useIdMemo)(n),Y=(0,g.useCallback)(s=>{let[f,S]=Fe(s),{type:D}=Re(t,f),E=Ve(S,D);m((B={})=>{let ve={...B,[f]:E},dt=(0,I.shallowEquals)(ve,p.current);return y.current=dt?M.unchanged:E!==void 0?M.changed:M.invalid,ve})},[t]),oe=(0,g.useCallback)(s=>{let[f,S]=Fe(s),{type:D}=Re(t,f);console.log("BLUR",{keyField:o});let E=i==null?void 0:i[o],B=Ve(S,D,!0);typeof E=="string"&&L.menuRpcCall({rowKey:E,field:f,value:B,type:"VP_EDIT_CELL_RPC"})},[L,t,o,i]),_=(0,g.useCallback)(async()=>{let s=await L.menuRpcCall({type:"VP_EDIT_SUBMIT_FORM_RPC"});(0,Z.isErrorResponse)(s)&&h(s.error)},[L]),re=(0,g.useCallback)(s=>{s.key==="Enter"&&y.current===M.changed&&_()},[_]),ne=(0,g.useCallback)(()=>{a()},[a]),se=s=>{var S;let f=String((S=i==null?void 0:i[s.name])!=null?S:"");return s.readonly||s.name===o?(0,T.jsx)("div",{className:`${b}-fieldValue vuuReadOnly`,children:f}):(0,T.jsx)("input",{className:`${b}-fieldValue`,"data-field":s.name,onBlur:oe,onChange:Y,type:"text",value:f,id:`${J}-input-${s.name}`})};(0,g.useEffect)(()=>{if(d.current){let s=d.current.querySelector("input");s&&setTimeout(()=>{s.focus(),console.log("select item"),s.select()},100)}},[]);let ae=y.current===M.changed;return(0,T.jsxs)("div",{...c,className:(0,me.default)(b,e),children:[u?(0,T.jsx)("div",{className:`${b}-errorBanner`,"data-icon":"error",title:u,children:"Error, edit(s) not saved"}):void 0,(0,T.jsx)("div",{className:`${b}-content`,ref:d,onKeyDown:re,children:t.map(s=>{var f;return(0,T.jsxs)("div",{className:`${b}-field`,children:[(0,T.jsx)("label",{className:(0,me.default)(`${b}-fieldLabel`,{[`${b}-required`]:s.required}),htmlFor:`${J}-input-${s.name}`,children:(f=s==null?void 0:s.label)!=null?f:s.description}),se(s)]},s.name)})}),(0,T.jsxs)("div",{className:`${b}-buttonbar salt-theme salt-density-high`,children:[(0,T.jsx)(de.Button,{type:"submit",variant:"cta",disabled:!ae,onClick:_,children:"Submit"}),(0,T.jsx)(de.Button,{variant:"secondary",onClick:ne,children:"Cancel"})]})]})};var rt=require("@vuu-ui/vuu-data"),nt=w(require("classnames")),x=require("react");var ee=require("react"),j=require("react/jsx-runtime"),Ht={},pe=(0,ee.createContext)(Ht),Rt=({children:e,context:t,inheritedContext:o})=>{let r={...o,...t};return(0,j.jsx)(pe.Provider,{value:r,children:e})},fe=({children:e,value:t})=>(0,j.jsx)(pe.Consumer,{children:o=>(0,j.jsx)(Rt,{context:t,inheritedContext:o,children:e})}),Ft=()=>(0,ee.useContext)(pe);var R=require("react");var Ue=(e,t,o="latest")=>new Promise((r,n)=>{console.log(`load local config at ${e} for user ${t.username}, id ${o}`);let a=localStorage.getItem(e);if(a){let l=JSON.parse(a);r(l)}else n()}),Ie=(e,t,o)=>new Promise((r,n)=>{try{localStorage.setItem(e,JSON.stringify(o)),r(void 0)}catch{n()}});var Be=(e,t,o="latest")=>new Promise((r,n)=>{fetch(`${e}/${t.username}/${o}`,{}).then(a=>{a.ok?r(a.json()):n(void 0)}).catch(()=>{n(void 0)})}),Ae=(e,t,o)=>new Promise((r,n)=>{fetch(`${e}/${t.username}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)}).then(a=>{a.ok?r(void 0):n()})});var Oe=({saveLocation:e,saveUrl:t="api/vui",user:o,defaultLayout:r})=>{let[n,a]=(0,R.useState)(r),l=e==="remote",c=l?Be:Ue,i=l?Ae:Ie,m=p=>{a(p)},u=(0,R.useCallback)(async(p="latest")=>{try{let y=await c(t,o,p);m(y)}catch{m(r)}},[r,c,t,o]);(0,R.useEffect)(()=>{u()},[u]);let h=(0,R.useCallback)(p=>{i(t,o,p)},[i,t,o]),d=(0,R.useCallback)(p=>{u(p)},[u]);return[n,h,d]};var v=require("@vuu-ui/vuu-layout");var et=require("react");var ze=require("@salt-ds/core"),Ke=require("@heswell/salt-lab"),Ye=require("@salt-ds/icons");var Je=require("@vuu-ui/vuu-utils"),te=require("@heswell/salt-lab"),_e=require("@salt-ds/core"),qe=require("@salt-ds/icons"),P=require("react");var $e=async e=>await fetch(`api/vui/${e.username}`,{}).then(o=>o.ok?o.json():null).catch(()=>{console.log("error getting history")});var F=require("react/jsx-runtime"),Vt=({lastUpdate:e},{lastUpdate:t})=>t===e?0:t<e?-1:1,kt=e=>(0,F.jsx)(te.ListItem,{...e}),Ge=(0,P.forwardRef)(function({loginUrl:t,onNavigate:o,user:r,layoutId:n="latest"},a){let[l,c]=(0,P.useState)([]);(0,P.useEffect)(()=>{async function h(){let p=(await $e(r)).filter(y=>y.id!=="latest").sort(Vt).map(({id:y,lastUpdate:L})=>({lastUpdate:L,id:y,label:`Saved at ${(0,Je.formatDate)(new Date(L),"kk:mm:ss")}`}));console.log({sortedHistory:p}),c(p)}h()},[r]);let i=(0,P.useCallback)((h,d)=>{d&&o(d.id)},[o]),m=(0,P.useCallback)(()=>{ce(t)},[t]),u=l.length===0?null:n==="latest"?l[0]:l.find(h=>h.id===n);return(0,F.jsxs)("div",{className:"vuuUserPanel",ref:a,children:[(0,F.jsx)(te.List,{ListItem:kt,className:"vuuUserPanel-history",onSelect:i,selected:u,source:l}),(0,F.jsx)("div",{className:"vuuUserPanel-buttonBar",children:(0,F.jsxs)(_e.Button,{"aria-label":"logout",onClick:m,children:[(0,F.jsx)(qe.ExportIcon,{})," Logout"]})})]})});var $=require("react/jsx-runtime"),We=({layoutId:e,loginUrl:t,onNavigate:o,user:r})=>(0,$.jsxs)(Ke.DropdownBase,{className:"vuuUserProfile",placement:"bottom-end",children:[(0,$.jsx)(ze.Button,{variant:"secondary",children:(0,$.jsx)(Ye.UserSolidIcon,{})}),(0,$.jsx)(Ge,{layoutId:e,loginUrl:t,onNavigate:a=>{o(a)},user:r})]});var G=require("@heswell/salt-lab"),Xe=w(require("classnames")),Ze=require("@salt-ds/core"),je=require("react");var z=require("react/jsx-runtime"),Ut="vuuThemeSwitch",Qe=["light","dark"],ge=({className:e,defaultMode:t,mode:o,onChange:r,...n})=>{let[a,l]=(0,Ze.useControlled)({controlled:o,default:t!=null?t:"light",name:"ThemeSwitch",state:"mode"}),c=Qe.indexOf(a),i=(0,je.useCallback)((u,h)=>{let d=Qe[h];l(d),r(d)},[r,l]),m=(0,Xe.default)(Ut,e);return(0,z.jsxs)(G.ToggleButtonGroup,{className:m,...n,onChange:i,selectedIndex:c,children:[(0,z.jsx)(G.ToggleButton,{"aria-label":"alert",tooltipText:"Light Theme","data-icon":"light"}),(0,z.jsx)(G.ToggleButton,{"aria-label":"home",tooltipText:"Dark Theme","data-icon":"dark"})]})};var tt=w(require("classnames"));var K=require("react/jsx-runtime"),It="vuuAppHeader",ot=({className:e,layoutId:t,loginUrl:o,onNavigate:r,onSwitchTheme:n,themeMode:a="light",user:l,...c})=>{let i=(0,tt.default)(It,e),m=(0,et.useCallback)(u=>n==null?void 0:n(u),[n]);return(0,K.jsxs)("header",{className:i,...c,children:[(0,K.jsx)(ge,{defaultMode:a,onChange:m}),(0,K.jsx)(We,{layoutId:t,loginUrl:o,onNavigate:r,user:l})]})};var st=require("@vuu-ui/vuu-utils");var C=require("react/jsx-runtime"),{error:he}=(0,st.logger)("Shell"),Bt={type:"View",props:{style:{height:"calc(100% - 6px)"}},children:[{props:{className:"vuuShell-warningPlaceholder"},type:"Placeholder"}]},At=({children:e,className:t,defaultLayout:o=Bt,leftSidePanel:r,loginUrl:n,saveLocation:a="remote",saveUrl:l,serverUrl:c,user:i,...m})=>{let u=(0,x.useRef)(null),h=(0,x.useRef)(null),[d,p]=(0,x.useState)(!1),y=(0,x.useRef)("latest"),[L,J,Y]=Oe({defaultLayout:o,saveLocation:a,user:i}),oe=(0,x.useCallback)(s=>{try{J(s)}catch{he==null||he("Failed to save layout")}},[J]),_=(0,x.useCallback)(s=>{u.current&&(u.current.dataset.mode=s)},[]),re=s=>{var S;let f=s.target;(S=h.current)!=null&&S.contains(f)||p(!d)},ne=(0,x.useCallback)(s=>{y.current=s,Y(s)},[Y]);(0,x.useEffect)(()=>{c&&i.token&&(0,rt.connectToServer)({authToken:i.token,url:c,username:i.username})},[c,i.token,i.username]);let se=()=>{let s=[];return r&&s.push((0,C.jsx)(v.Drawer,{onClick:re,open:d,position:"left",inline:!0,peekaboo:!0,sizeOpen:200,toggleButton:"end",children:(0,C.jsx)(v.View,{className:"vuuShell-palette",id:"vw-app-palette",ref:h,style:{height:"100%"},children:r},"app-palette")},"left-panel")),s},ae=(0,nt.default)("vuuShell",t,"salt-theme","salt-density-high");return(0,C.jsxs)(fe,{value:void 0,children:[(0,C.jsx)(v.LayoutProvider,{layout:L,onLayoutChange:oe,children:(0,C.jsx)(v.DraggableLayout,{className:ae,"data-mode":"light",ref:u,...m,children:(0,C.jsxs)(v.Flexbox,{className:"App",style:{flexDirection:"column",height:"100%",width:"100%"},children:[(0,C.jsx)(ot,{layoutId:y.current,loginUrl:n,user:i,onNavigate:ne,onSwitchTheme:_}),(0,C.jsx)(v.DockLayout,{style:{flex:1},children:se().concat((0,C.jsx)(v.DraggableLayout,{dropTarget:!0,style:{width:"100%",height:"100%"}},"main-content"))})]})})}),e]})};var V=require("react"),at=w(require("classnames")),mt=require("react/jsx-runtime"),it="medium",lt="salt-theme",ut="light",ye=(0,V.createContext)({density:"high",theme:"salt-theme",themeMode:"light"}),Ot=(e,t,o,r)=>{var n;return(0,V.isValidElement)(e)?(0,V.cloneElement)(e,{className:(0,at.default)((n=e.props)==null?void 0:n.className,t,`salt-density-${r}`),"data-mode":o}):(console.warn(`
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
ConnectionStatusIcon: () => ConnectionStatusIcon,
|
|
34
|
+
DEFAULT_DENSITY: () => DEFAULT_DENSITY2,
|
|
35
|
+
DEFAULT_THEME: () => DEFAULT_THEME,
|
|
36
|
+
DEFAULT_THEME_MODE: () => DEFAULT_THEME_MODE,
|
|
37
|
+
DensitySwitch: () => DensitySwitch,
|
|
38
|
+
Feature: () => Feature,
|
|
39
|
+
LoginPanel: () => LoginPanel,
|
|
40
|
+
SessionEditingForm: () => SessionEditingForm,
|
|
41
|
+
Shell: () => Shell,
|
|
42
|
+
ShellContextProvider: () => ShellContextProvider,
|
|
43
|
+
ThemeContext: () => ThemeContext,
|
|
44
|
+
ThemeProvider: () => ThemeProvider,
|
|
45
|
+
ThemeSwitch: () => ThemeSwitch,
|
|
46
|
+
getAuthDetailsFromCookies: () => getAuthDetailsFromCookies,
|
|
47
|
+
logout: () => logout,
|
|
48
|
+
redirectToLogin: () => redirectToLogin,
|
|
49
|
+
useShellContext: () => useShellContext
|
|
50
|
+
});
|
|
51
|
+
module.exports = __toCommonJS(src_exports);
|
|
52
|
+
|
|
53
|
+
// src/connection-status/ConnectionStatusIcon.tsx
|
|
54
|
+
var import_react = __toESM(require("react"));
|
|
55
|
+
var import_classnames = __toESM(require("classnames"));
|
|
56
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
57
|
+
var ConnectionStatusIcon = ({ connectionStatus, className, element = "span", ...props }) => {
|
|
58
|
+
const [classBase6, setClassBase] = (0, import_react.useState)("vuuConnectingStatus");
|
|
59
|
+
(0, import_react.useEffect)(() => {
|
|
60
|
+
switch (connectionStatus) {
|
|
61
|
+
case "connected":
|
|
62
|
+
case "reconnected":
|
|
63
|
+
setClassBase("vuuActiveStatus");
|
|
64
|
+
break;
|
|
65
|
+
case "connecting":
|
|
66
|
+
setClassBase("vuuConnectingStatus");
|
|
67
|
+
break;
|
|
68
|
+
case "disconnected":
|
|
69
|
+
setClassBase("vuuDisconnectedStatus");
|
|
70
|
+
break;
|
|
71
|
+
default:
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}, [connectionStatus]);
|
|
75
|
+
const statusIcon = import_react.default.createElement(
|
|
76
|
+
element,
|
|
77
|
+
{
|
|
78
|
+
...props,
|
|
79
|
+
className: (0, import_classnames.default)("vuuStatus vuuIcon", classBase6, className)
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "vuuStatus-container salt-theme", children: [
|
|
83
|
+
statusIcon,
|
|
84
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "vuuStatus-text", children: [
|
|
85
|
+
"Status: ",
|
|
86
|
+
connectionStatus.toUpperCase()
|
|
87
|
+
] })
|
|
88
|
+
] }) });
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// src/density-switch/DensitySwitch.tsx
|
|
92
|
+
var import_salt_lab = require("@heswell/salt-lab");
|
|
93
|
+
var import_react2 = require("react");
|
|
94
|
+
var import_classnames2 = __toESM(require("classnames"));
|
|
95
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
96
|
+
var classBase = "vuuDensitySwitch";
|
|
97
|
+
var densities = ["high", "medium", "low", "touch"];
|
|
98
|
+
var DEFAULT_DENSITY = "high";
|
|
99
|
+
var DensitySwitch = ({
|
|
100
|
+
className: classNameProp,
|
|
101
|
+
defaultDensity = DEFAULT_DENSITY,
|
|
102
|
+
onDensityChange
|
|
103
|
+
}) => {
|
|
104
|
+
const handleSelectionChange = (0, import_react2.useCallback)((_event, selectedItem) => {
|
|
105
|
+
onDensityChange(selectedItem);
|
|
106
|
+
}, [onDensityChange]);
|
|
107
|
+
const className = (0, import_classnames2.default)(classBase, classNameProp);
|
|
108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
109
|
+
import_salt_lab.Dropdown,
|
|
110
|
+
{
|
|
111
|
+
className,
|
|
112
|
+
source: densities,
|
|
113
|
+
defaultSelected: defaultDensity,
|
|
114
|
+
onSelectionChange: handleSelectionChange
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// src/feature/Feature.tsx
|
|
120
|
+
var import_react4 = __toESM(require("react"));
|
|
121
|
+
var import_vuu_layout = require("@vuu-ui/vuu-layout");
|
|
122
|
+
|
|
123
|
+
// src/feature/ErrorBoundary.jsx
|
|
124
|
+
var import_react3 = __toESM(require("react"));
|
|
125
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
126
|
+
var ErrorBoundary = class extends import_react3.default.Component {
|
|
127
|
+
constructor(props) {
|
|
128
|
+
super(props);
|
|
129
|
+
this.state = { errorMessage: null };
|
|
130
|
+
}
|
|
131
|
+
static getDerivedStateFromError(error2) {
|
|
132
|
+
return { errorMessage: error2.message };
|
|
133
|
+
}
|
|
134
|
+
componentDidCatch(error2, errorInfo) {
|
|
135
|
+
console.log(error2, errorInfo);
|
|
136
|
+
}
|
|
137
|
+
render() {
|
|
138
|
+
if (this.state.errorMessage) {
|
|
139
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
140
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { children: "Something went wrong." }),
|
|
141
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: this.state.errorMessage })
|
|
142
|
+
] });
|
|
143
|
+
}
|
|
144
|
+
return this.props.children;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// src/feature/Loader.tsx
|
|
149
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
150
|
+
var Loader = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hwLoader", children: "loading" });
|
|
151
|
+
|
|
152
|
+
// src/feature/Feature.tsx
|
|
153
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
154
|
+
var componentsMap = /* @__PURE__ */ new Map();
|
|
155
|
+
var useCachedFeature = (url) => {
|
|
156
|
+
(0, import_react4.useEffect)(
|
|
157
|
+
() => () => {
|
|
158
|
+
componentsMap.delete(url);
|
|
159
|
+
},
|
|
160
|
+
[url]
|
|
161
|
+
);
|
|
162
|
+
if (!componentsMap.has(url)) {
|
|
163
|
+
componentsMap.set(
|
|
164
|
+
url,
|
|
165
|
+
import_react4.default.lazy(() => import(
|
|
166
|
+
/* @vite-ignore */
|
|
167
|
+
url
|
|
168
|
+
))
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
return componentsMap.get(url);
|
|
172
|
+
};
|
|
173
|
+
function RawFeature({
|
|
174
|
+
url,
|
|
175
|
+
css,
|
|
176
|
+
params,
|
|
177
|
+
...props
|
|
178
|
+
}) {
|
|
179
|
+
console.log("Feature render", { css, url, props });
|
|
180
|
+
(0, import_react4.useEffect)(() => {
|
|
181
|
+
console.log("%cFeature mount", "color: green;");
|
|
182
|
+
return () => {
|
|
183
|
+
console.log("%cFeature unmount", "color:red;");
|
|
184
|
+
};
|
|
185
|
+
}, []);
|
|
186
|
+
if (css) {
|
|
187
|
+
import(
|
|
188
|
+
/* @vite-ignore */
|
|
189
|
+
css
|
|
190
|
+
).then(
|
|
191
|
+
(cssModule) => {
|
|
192
|
+
console.log("%cInject Styles", "color: blue;font-weight: bold");
|
|
193
|
+
document.adoptedStyleSheets = [
|
|
194
|
+
...document.adoptedStyleSheets,
|
|
195
|
+
cssModule.default
|
|
196
|
+
];
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
const LazyFeature = useCachedFeature(url);
|
|
201
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react4.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Loader, {}), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LazyFeature, { ...props, ...params }) }) });
|
|
202
|
+
}
|
|
203
|
+
var Feature = import_react4.default.memo(RawFeature);
|
|
204
|
+
Feature.displayName = "Feature";
|
|
205
|
+
(0, import_vuu_layout.registerComponent)("Feature", Feature, "view");
|
|
206
|
+
|
|
207
|
+
// src/login/LoginPanel.tsx
|
|
208
|
+
var import_react5 = require("react");
|
|
209
|
+
var import_core = require("@salt-ds/core");
|
|
210
|
+
var import_salt_lab2 = require("@heswell/salt-lab");
|
|
211
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
212
|
+
var classBase2 = "vuuLoginPanel";
|
|
213
|
+
var LoginPanel = ({ onSubmit }) => {
|
|
214
|
+
const [username, setUserName] = (0, import_react5.useState)("");
|
|
215
|
+
const [password, setPassword] = (0, import_react5.useState)("");
|
|
216
|
+
const login = () => {
|
|
217
|
+
onSubmit(username, password);
|
|
218
|
+
};
|
|
219
|
+
const handleUsername = (_event, value) => {
|
|
220
|
+
setUserName(value);
|
|
221
|
+
};
|
|
222
|
+
const handlePassword = (_event, value) => {
|
|
223
|
+
setPassword(value);
|
|
224
|
+
};
|
|
225
|
+
const dataIsValid = username.trim() !== "" && password.trim() !== "";
|
|
226
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: classBase2, children: [
|
|
227
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_salt_lab2.FormField, { label: "Username", style: { width: 200 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_salt_lab2.Input, { value: username, id: "text-username", onChange: handleUsername }) }),
|
|
228
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_salt_lab2.FormField, { label: "Password", style: { width: 200 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
229
|
+
import_salt_lab2.Input,
|
|
230
|
+
{
|
|
231
|
+
type: "password",
|
|
232
|
+
value: password,
|
|
233
|
+
id: "text-password",
|
|
234
|
+
onChange: handlePassword
|
|
235
|
+
}
|
|
236
|
+
) }),
|
|
237
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
238
|
+
import_core.Button,
|
|
239
|
+
{
|
|
240
|
+
className: `${classBase2}-login`,
|
|
241
|
+
disabled: !dataIsValid,
|
|
242
|
+
onClick: login,
|
|
243
|
+
variant: "cta",
|
|
244
|
+
children: "Login"
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
] });
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// src/login/login-utils.ts
|
|
251
|
+
var import_vuu_utils = require("@vuu-ui/vuu-utils");
|
|
252
|
+
var getAuthDetailsFromCookies = () => {
|
|
253
|
+
const username = (0, import_vuu_utils.getCookieValue)("vuu-username");
|
|
254
|
+
const token = (0, import_vuu_utils.getCookieValue)("vuu-auth-token");
|
|
255
|
+
return [username, token];
|
|
256
|
+
};
|
|
257
|
+
var redirectToLogin = (loginUrl = "login.html") => {
|
|
258
|
+
window.location.href = loginUrl;
|
|
259
|
+
};
|
|
260
|
+
var logout = (loginUrl) => {
|
|
261
|
+
document.cookie = "vuu-username= ; expires = Thu, 01 Jan 1970 00:00:00 GMT";
|
|
262
|
+
document.cookie = "vuu-auth-token= ; expires = Thu, 01 Jan 1970 00:00:00 GMT";
|
|
263
|
+
redirectToLogin(loginUrl);
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
// src/session-editing-form/SessionEditingForm.tsx
|
|
267
|
+
var import_react6 = require("react");
|
|
268
|
+
var import_classnames3 = __toESM(require("classnames"));
|
|
269
|
+
var import_core2 = require("@salt-ds/core");
|
|
270
|
+
var import_core3 = require("@salt-ds/core");
|
|
271
|
+
var import_vuu_data = require("@vuu-ui/vuu-data");
|
|
272
|
+
var import_vuu_utils2 = require("@vuu-ui/vuu-utils");
|
|
273
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
274
|
+
var classBase3 = "vuuSessionEditingForm";
|
|
275
|
+
var getField = (fields, name) => {
|
|
276
|
+
const field = fields.find((f) => f.name === name);
|
|
277
|
+
if (field) {
|
|
278
|
+
return field;
|
|
279
|
+
} else {
|
|
280
|
+
throw Error(`SessionEditingForm, no field '${name}' found`);
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
var getFieldNameAndValue = (evt) => {
|
|
284
|
+
const {
|
|
285
|
+
dataset: { field },
|
|
286
|
+
value
|
|
287
|
+
} = evt.target;
|
|
288
|
+
if (field === void 0) {
|
|
289
|
+
throw Error("SessionEditingForm, form field has no field name");
|
|
290
|
+
}
|
|
291
|
+
return [field, value];
|
|
292
|
+
};
|
|
293
|
+
var Status = {
|
|
294
|
+
uninitialised: 0,
|
|
295
|
+
unchanged: 1,
|
|
296
|
+
changed: 2,
|
|
297
|
+
invalid: 3
|
|
298
|
+
};
|
|
299
|
+
function getTypedValue(value, type, throwIfUndefined = false) {
|
|
300
|
+
switch (type) {
|
|
301
|
+
case "int":
|
|
302
|
+
case "long": {
|
|
303
|
+
const typedValue = parseInt(value, 10);
|
|
304
|
+
if ((0, import_vuu_utils2.isValidNumber)(typedValue)) {
|
|
305
|
+
return typedValue;
|
|
306
|
+
} else if (throwIfUndefined) {
|
|
307
|
+
throw Error("SessionEditingForm getTypedValue");
|
|
308
|
+
} else {
|
|
309
|
+
return void 0;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
case "double": {
|
|
313
|
+
const typedValue = parseFloat(value);
|
|
314
|
+
if ((0, import_vuu_utils2.isValidNumber)(typedValue)) {
|
|
315
|
+
return typedValue;
|
|
316
|
+
}
|
|
317
|
+
return void 0;
|
|
318
|
+
}
|
|
319
|
+
case "boolean":
|
|
320
|
+
return value === "true" ? true : false;
|
|
321
|
+
default:
|
|
322
|
+
return value;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
var getDataSource = (dataSource, schema) => {
|
|
326
|
+
if (dataSource) {
|
|
327
|
+
return dataSource;
|
|
328
|
+
} else if (schema) {
|
|
329
|
+
return new import_vuu_data.RemoteDataSource({
|
|
330
|
+
bufferSize: 0,
|
|
331
|
+
table: schema.table,
|
|
332
|
+
columns: schema.columns.map((col) => col.name)
|
|
333
|
+
});
|
|
334
|
+
} else {
|
|
335
|
+
throw Error(
|
|
336
|
+
"SessionEditingForm: either a DataSource or a TableSchema must be provided"
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
var SessionEditingForm = ({
|
|
341
|
+
className,
|
|
342
|
+
config: { fields, key: keyField },
|
|
343
|
+
dataSource: dataSourceProp,
|
|
344
|
+
id: idProp,
|
|
345
|
+
onClose,
|
|
346
|
+
schema,
|
|
347
|
+
...htmlAttributes
|
|
348
|
+
}) => {
|
|
349
|
+
const [values, setValues] = (0, import_react6.useState)();
|
|
350
|
+
const [errorMessage, setErrorMessage] = (0, import_react6.useState)("");
|
|
351
|
+
const formContentRef = (0, import_react6.useRef)(null);
|
|
352
|
+
const initialDataRef = (0, import_react6.useRef)();
|
|
353
|
+
const dataStatusRef = (0, import_react6.useRef)(Status.uninitialised);
|
|
354
|
+
const dataSource = (0, import_react6.useMemo)(() => {
|
|
355
|
+
const applyServerData = (data) => {
|
|
356
|
+
if (columnMap) {
|
|
357
|
+
const values2 = {};
|
|
358
|
+
for (const column of dataSource.columns) {
|
|
359
|
+
values2[column] = data[columnMap[column]];
|
|
360
|
+
}
|
|
361
|
+
if (dataStatusRef.current === Status.uninitialised) {
|
|
362
|
+
dataStatusRef.current = Status.unchanged;
|
|
363
|
+
initialDataRef.current = values2;
|
|
364
|
+
}
|
|
365
|
+
setValues(values2);
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
const ds = getDataSource(dataSourceProp, schema);
|
|
369
|
+
const columnMap = (0, import_vuu_utils2.buildColumnMap)(ds.columns);
|
|
370
|
+
ds.subscribe({ range: { from: 0, to: 5 } }, (message) => {
|
|
371
|
+
if (message.type === "viewport-update" && message.rows) {
|
|
372
|
+
if (dataStatusRef.current === Status.uninitialised) {
|
|
373
|
+
applyServerData(message.rows[0]);
|
|
374
|
+
} else {
|
|
375
|
+
console.log("what do we do with server updates");
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
return ds;
|
|
380
|
+
}, [dataSourceProp, schema]);
|
|
381
|
+
const id = (0, import_core2.useIdMemo)(idProp);
|
|
382
|
+
const handleChange = (0, import_react6.useCallback)(
|
|
383
|
+
(evt) => {
|
|
384
|
+
const [field, value] = getFieldNameAndValue(evt);
|
|
385
|
+
const { type } = getField(fields, field);
|
|
386
|
+
const typedValue = getTypedValue(value, type);
|
|
387
|
+
setValues((values2 = {}) => {
|
|
388
|
+
const newValues = {
|
|
389
|
+
...values2,
|
|
390
|
+
[field]: typedValue
|
|
391
|
+
};
|
|
392
|
+
const notUpdated = (0, import_vuu_utils2.shallowEquals)(newValues, initialDataRef.current);
|
|
393
|
+
dataStatusRef.current = notUpdated ? Status.unchanged : typedValue !== void 0 ? Status.changed : Status.invalid;
|
|
394
|
+
return newValues;
|
|
395
|
+
});
|
|
396
|
+
},
|
|
397
|
+
[fields]
|
|
398
|
+
);
|
|
399
|
+
const handleBlur = (0, import_react6.useCallback)(
|
|
400
|
+
(evt) => {
|
|
401
|
+
const [field, value] = getFieldNameAndValue(evt);
|
|
402
|
+
const { type } = getField(fields, field);
|
|
403
|
+
console.log("BLUR", {
|
|
404
|
+
keyField
|
|
405
|
+
});
|
|
406
|
+
const rowKey = values == null ? void 0 : values[keyField];
|
|
407
|
+
const typedValue = getTypedValue(value, type, true);
|
|
408
|
+
if (typeof rowKey === "string") {
|
|
409
|
+
dataSource.menuRpcCall({
|
|
410
|
+
rowKey,
|
|
411
|
+
field,
|
|
412
|
+
value: typedValue,
|
|
413
|
+
type: "VP_EDIT_CELL_RPC"
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
[dataSource, fields, keyField, values]
|
|
418
|
+
);
|
|
419
|
+
const handleSubmit = (0, import_react6.useCallback)(async () => {
|
|
420
|
+
const response = await dataSource.menuRpcCall({
|
|
421
|
+
type: "VP_EDIT_SUBMIT_FORM_RPC"
|
|
422
|
+
});
|
|
423
|
+
if ((0, import_vuu_data.isErrorResponse)(response)) {
|
|
424
|
+
setErrorMessage(response.error);
|
|
425
|
+
}
|
|
426
|
+
}, [dataSource]);
|
|
427
|
+
const handleKeyDown = (0, import_react6.useCallback)(
|
|
428
|
+
(evt) => {
|
|
429
|
+
if (evt.key === "Enter" && dataStatusRef.current === Status.changed) {
|
|
430
|
+
handleSubmit();
|
|
431
|
+
}
|
|
432
|
+
},
|
|
433
|
+
[handleSubmit]
|
|
434
|
+
);
|
|
435
|
+
const handleCancel = (0, import_react6.useCallback)(() => {
|
|
436
|
+
onClose();
|
|
437
|
+
}, [onClose]);
|
|
438
|
+
const getFormControl = (field) => {
|
|
439
|
+
var _a;
|
|
440
|
+
const value = String((_a = values == null ? void 0 : values[field.name]) != null ? _a : "");
|
|
441
|
+
if (field.readonly || field.name === keyField) {
|
|
442
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `${classBase3}-fieldValue vuuReadOnly`, children: value });
|
|
443
|
+
} else {
|
|
444
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
445
|
+
"input",
|
|
446
|
+
{
|
|
447
|
+
className: `${classBase3}-fieldValue`,
|
|
448
|
+
"data-field": field.name,
|
|
449
|
+
onBlur: handleBlur,
|
|
450
|
+
onChange: handleChange,
|
|
451
|
+
type: "text",
|
|
452
|
+
value,
|
|
453
|
+
id: `${id}-input-${field.name}`
|
|
454
|
+
}
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
(0, import_react6.useEffect)(() => {
|
|
459
|
+
if (formContentRef.current) {
|
|
460
|
+
const firstInput = formContentRef.current.querySelector(
|
|
461
|
+
"input"
|
|
462
|
+
);
|
|
463
|
+
if (firstInput) {
|
|
464
|
+
setTimeout(() => {
|
|
465
|
+
firstInput.focus();
|
|
466
|
+
console.log("select item");
|
|
467
|
+
firstInput.select();
|
|
468
|
+
}, 100);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}, []);
|
|
472
|
+
const isDirty = dataStatusRef.current === Status.changed;
|
|
473
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ...htmlAttributes, className: (0, import_classnames3.default)(classBase3, className), children: [
|
|
474
|
+
errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
475
|
+
"div",
|
|
476
|
+
{
|
|
477
|
+
className: `${classBase3}-errorBanner`,
|
|
478
|
+
"data-icon": "error",
|
|
479
|
+
title: errorMessage,
|
|
480
|
+
children: "Error, edit(s) not saved"
|
|
481
|
+
}
|
|
482
|
+
) : void 0,
|
|
483
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
484
|
+
"div",
|
|
485
|
+
{
|
|
486
|
+
className: `${classBase3}-content`,
|
|
487
|
+
ref: formContentRef,
|
|
488
|
+
onKeyDown: handleKeyDown,
|
|
489
|
+
children: fields.map((field) => {
|
|
490
|
+
var _a;
|
|
491
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `${classBase3}-field`, children: [
|
|
492
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
493
|
+
"label",
|
|
494
|
+
{
|
|
495
|
+
className: (0, import_classnames3.default)(`${classBase3}-fieldLabel`, {
|
|
496
|
+
[`${classBase3}-required`]: field.required
|
|
497
|
+
}),
|
|
498
|
+
htmlFor: `${id}-input-${field.name}`,
|
|
499
|
+
children: (_a = field == null ? void 0 : field.label) != null ? _a : field.description
|
|
500
|
+
}
|
|
501
|
+
),
|
|
502
|
+
getFormControl(field)
|
|
503
|
+
] }, field.name);
|
|
504
|
+
})
|
|
505
|
+
}
|
|
506
|
+
),
|
|
507
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `${classBase3}-buttonbar salt-theme salt-density-high`, children: [
|
|
508
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
509
|
+
import_core3.Button,
|
|
510
|
+
{
|
|
511
|
+
type: "submit",
|
|
512
|
+
variant: "cta",
|
|
513
|
+
disabled: !isDirty,
|
|
514
|
+
onClick: handleSubmit,
|
|
515
|
+
children: "Submit"
|
|
516
|
+
}
|
|
517
|
+
),
|
|
518
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core3.Button, { variant: "secondary", onClick: handleCancel, children: "Cancel" })
|
|
519
|
+
] })
|
|
520
|
+
] });
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
// src/shell.tsx
|
|
524
|
+
var import_vuu_data2 = require("@vuu-ui/vuu-data");
|
|
525
|
+
var import_classnames6 = __toESM(require("classnames"));
|
|
526
|
+
var import_react12 = require("react");
|
|
527
|
+
|
|
528
|
+
// src/ShellContextProvider.tsx
|
|
529
|
+
var import_react7 = require("react");
|
|
530
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
531
|
+
var defaultConfig = {};
|
|
532
|
+
var ShellContext = (0, import_react7.createContext)(defaultConfig);
|
|
533
|
+
var Provider = ({
|
|
534
|
+
children,
|
|
535
|
+
context,
|
|
536
|
+
inheritedContext
|
|
537
|
+
}) => {
|
|
538
|
+
const mergedContext = {
|
|
539
|
+
...inheritedContext,
|
|
540
|
+
...context
|
|
541
|
+
};
|
|
542
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ShellContext.Provider, { value: mergedContext, children });
|
|
543
|
+
};
|
|
544
|
+
var ShellContextProvider = ({
|
|
545
|
+
children,
|
|
546
|
+
value
|
|
547
|
+
}) => {
|
|
548
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ShellContext.Consumer, { children: (context) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Provider, { context: value, inheritedContext: context, children }) });
|
|
549
|
+
};
|
|
550
|
+
var useShellContext = () => {
|
|
551
|
+
return (0, import_react7.useContext)(ShellContext);
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
// src/layout-config/use-layout-config.ts
|
|
555
|
+
var import_react8 = require("react");
|
|
556
|
+
|
|
557
|
+
// src/layout-config/local-config.ts
|
|
558
|
+
var loadLocalConfig = (saveUrl, user, id = "latest") => new Promise((resolve, reject) => {
|
|
559
|
+
console.log(
|
|
560
|
+
`load local config at ${saveUrl} for user ${user.username}, id ${id}`
|
|
561
|
+
);
|
|
562
|
+
const data = localStorage.getItem(saveUrl);
|
|
563
|
+
if (data) {
|
|
564
|
+
const layout = JSON.parse(data);
|
|
565
|
+
resolve(layout);
|
|
566
|
+
} else {
|
|
567
|
+
reject();
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
var saveLocalConfig = (saveUrl, user, data) => new Promise((resolve, reject) => {
|
|
571
|
+
try {
|
|
572
|
+
localStorage.setItem(saveUrl, JSON.stringify(data));
|
|
573
|
+
resolve(void 0);
|
|
574
|
+
} catch {
|
|
575
|
+
reject();
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
// src/layout-config/remote-config.ts
|
|
580
|
+
var loadRemoteConfig = (saveUrl, user, id = "latest") => new Promise((resolve, reject) => {
|
|
581
|
+
fetch(`${saveUrl}/${user.username}/${id}`, {}).then((response) => {
|
|
582
|
+
if (response.ok) {
|
|
583
|
+
resolve(response.json());
|
|
584
|
+
} else {
|
|
585
|
+
reject(void 0);
|
|
586
|
+
}
|
|
587
|
+
}).catch(() => {
|
|
588
|
+
reject(void 0);
|
|
589
|
+
});
|
|
590
|
+
});
|
|
591
|
+
var saveRemoteConfig = (saveUrl, user, data) => new Promise((resolve, reject) => {
|
|
592
|
+
fetch(`${saveUrl}/${user.username}`, {
|
|
593
|
+
method: "POST",
|
|
594
|
+
headers: {
|
|
595
|
+
"Content-Type": "application/json"
|
|
596
|
+
},
|
|
597
|
+
body: JSON.stringify(data)
|
|
598
|
+
}).then((response) => {
|
|
599
|
+
if (response.ok) {
|
|
600
|
+
resolve(void 0);
|
|
601
|
+
} else {
|
|
602
|
+
reject();
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
// src/layout-config/use-layout-config.ts
|
|
608
|
+
var useLayoutConfig = ({
|
|
609
|
+
saveLocation,
|
|
610
|
+
saveUrl = "api/vui",
|
|
611
|
+
user,
|
|
612
|
+
defaultLayout
|
|
613
|
+
}) => {
|
|
614
|
+
const [layout, _setLayout] = (0, import_react8.useState)(defaultLayout);
|
|
615
|
+
const usingRemote = saveLocation === "remote";
|
|
616
|
+
const loadConfig = usingRemote ? loadRemoteConfig : loadLocalConfig;
|
|
617
|
+
const saveConfig = usingRemote ? saveRemoteConfig : saveLocalConfig;
|
|
618
|
+
const setLayout = (layout2) => {
|
|
619
|
+
_setLayout(layout2);
|
|
620
|
+
};
|
|
621
|
+
const load = (0, import_react8.useCallback)(
|
|
622
|
+
async (id = "latest") => {
|
|
623
|
+
try {
|
|
624
|
+
const layout2 = await loadConfig(saveUrl, user, id);
|
|
625
|
+
setLayout(layout2);
|
|
626
|
+
} catch {
|
|
627
|
+
setLayout(defaultLayout);
|
|
628
|
+
}
|
|
629
|
+
},
|
|
630
|
+
[defaultLayout, loadConfig, saveUrl, user]
|
|
631
|
+
);
|
|
632
|
+
(0, import_react8.useEffect)(() => {
|
|
633
|
+
load();
|
|
634
|
+
}, [load]);
|
|
635
|
+
const saveData = (0, import_react8.useCallback)(
|
|
636
|
+
(data) => {
|
|
637
|
+
saveConfig(saveUrl, user, data);
|
|
638
|
+
},
|
|
639
|
+
[saveConfig, saveUrl, user]
|
|
640
|
+
);
|
|
641
|
+
const loadLayoutById = (0, import_react8.useCallback)(
|
|
642
|
+
(id) => {
|
|
643
|
+
load(id);
|
|
644
|
+
},
|
|
645
|
+
[load]
|
|
646
|
+
);
|
|
647
|
+
return [layout, saveData, loadLayoutById];
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
// src/shell.tsx
|
|
651
|
+
var import_vuu_layout2 = require("@vuu-ui/vuu-layout");
|
|
652
|
+
|
|
653
|
+
// src/app-header/AppHeader.tsx
|
|
654
|
+
var import_react11 = require("react");
|
|
655
|
+
|
|
656
|
+
// src/user-profile/UserProfile.tsx
|
|
657
|
+
var import_core5 = require("@salt-ds/core");
|
|
658
|
+
var import_salt_lab4 = require("@heswell/salt-lab");
|
|
659
|
+
var import_icons2 = require("@salt-ds/icons");
|
|
660
|
+
|
|
661
|
+
// src/user-profile/UserPanel.tsx
|
|
662
|
+
var import_vuu_utils3 = require("@vuu-ui/vuu-utils");
|
|
663
|
+
var import_salt_lab3 = require("@heswell/salt-lab");
|
|
664
|
+
var import_core4 = require("@salt-ds/core");
|
|
665
|
+
var import_icons = require("@salt-ds/icons");
|
|
666
|
+
var import_react9 = require("react");
|
|
667
|
+
|
|
668
|
+
// src/get-layout-history.ts
|
|
669
|
+
var getLayoutHistory = async (user) => {
|
|
670
|
+
const history = await fetch(`api/vui/${user.username}`, {}).then((response) => {
|
|
671
|
+
return response.ok ? response.json() : null;
|
|
672
|
+
}).catch(() => {
|
|
673
|
+
console.log("error getting history");
|
|
674
|
+
});
|
|
675
|
+
return history;
|
|
676
|
+
};
|
|
677
|
+
|
|
678
|
+
// src/user-profile/UserPanel.tsx
|
|
679
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
680
|
+
var byLastUpdate = ({ lastUpdate: l1 }, { lastUpdate: l2 }) => {
|
|
681
|
+
return l2 === l1 ? 0 : l2 < l1 ? -1 : 1;
|
|
682
|
+
};
|
|
683
|
+
var HistoryListItem = (props) => {
|
|
684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_salt_lab3.ListItem, { ...props });
|
|
685
|
+
};
|
|
686
|
+
var UserPanel = (0, import_react9.forwardRef)(function UserPanel2({ loginUrl, onNavigate, user, layoutId = "latest" }, forwardedRef) {
|
|
687
|
+
const [history, setHistory] = (0, import_react9.useState)([]);
|
|
688
|
+
(0, import_react9.useEffect)(() => {
|
|
689
|
+
async function getHistory() {
|
|
690
|
+
const history2 = await getLayoutHistory(user);
|
|
691
|
+
const sortedHistory = history2.filter((item) => item.id !== "latest").sort(byLastUpdate).map(({ id, lastUpdate }) => ({
|
|
692
|
+
lastUpdate,
|
|
693
|
+
id,
|
|
694
|
+
label: `Saved at ${(0, import_vuu_utils3.formatDate)(new Date(lastUpdate), "kk:mm:ss")}`
|
|
695
|
+
}));
|
|
696
|
+
console.log({ sortedHistory });
|
|
697
|
+
setHistory(sortedHistory);
|
|
698
|
+
}
|
|
699
|
+
getHistory();
|
|
700
|
+
}, [user]);
|
|
701
|
+
const handleHisorySelected = (0, import_react9.useCallback)(
|
|
702
|
+
(evt, selected2) => {
|
|
703
|
+
if (selected2) {
|
|
704
|
+
onNavigate(selected2.id);
|
|
705
|
+
}
|
|
706
|
+
},
|
|
707
|
+
[onNavigate]
|
|
708
|
+
);
|
|
709
|
+
const handleLogout = (0, import_react9.useCallback)(() => {
|
|
710
|
+
logout(loginUrl);
|
|
711
|
+
}, [loginUrl]);
|
|
712
|
+
const selected = history.length === 0 ? null : layoutId === "latest" ? history[0] : history.find((i) => i.id === layoutId);
|
|
713
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vuuUserPanel", ref: forwardedRef, children: [
|
|
714
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
715
|
+
import_salt_lab3.List,
|
|
716
|
+
{
|
|
717
|
+
ListItem: HistoryListItem,
|
|
718
|
+
className: "vuuUserPanel-history",
|
|
719
|
+
onSelect: handleHisorySelected,
|
|
720
|
+
selected,
|
|
721
|
+
source: history
|
|
722
|
+
}
|
|
723
|
+
),
|
|
724
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vuuUserPanel-buttonBar", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_core4.Button, { "aria-label": "logout", onClick: handleLogout, children: [
|
|
725
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons.ExportIcon, {}),
|
|
726
|
+
" Logout"
|
|
727
|
+
] }) })
|
|
728
|
+
] });
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
// src/user-profile/UserProfile.tsx
|
|
732
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
733
|
+
var UserProfile = ({
|
|
734
|
+
layoutId,
|
|
735
|
+
loginUrl,
|
|
736
|
+
onNavigate,
|
|
737
|
+
user
|
|
738
|
+
}) => {
|
|
739
|
+
const handleNavigate = (id) => {
|
|
740
|
+
onNavigate(id);
|
|
741
|
+
};
|
|
742
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_salt_lab4.DropdownBase, { className: "vuuUserProfile", placement: "bottom-end", children: [
|
|
743
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_core5.Button, { variant: "secondary", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons2.UserSolidIcon, {}) }),
|
|
744
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
745
|
+
UserPanel,
|
|
746
|
+
{
|
|
747
|
+
layoutId,
|
|
748
|
+
loginUrl,
|
|
749
|
+
onNavigate: handleNavigate,
|
|
750
|
+
user
|
|
751
|
+
}
|
|
752
|
+
)
|
|
753
|
+
] });
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
// src/theme-switch/ThemeSwitch.tsx
|
|
757
|
+
var import_salt_lab5 = require("@heswell/salt-lab");
|
|
758
|
+
var import_classnames4 = __toESM(require("classnames"));
|
|
759
|
+
var import_core6 = require("@salt-ds/core");
|
|
760
|
+
var import_react10 = require("react");
|
|
761
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
762
|
+
var classBase4 = "vuuThemeSwitch";
|
|
763
|
+
var modes = ["light", "dark"];
|
|
764
|
+
var ThemeSwitch = ({
|
|
765
|
+
className: classNameProp,
|
|
766
|
+
defaultMode: defaultModeProp,
|
|
767
|
+
mode: modeProp,
|
|
768
|
+
onChange,
|
|
769
|
+
...htmlAttributes
|
|
770
|
+
}) => {
|
|
771
|
+
const [mode, setMode] = (0, import_core6.useControlled)({
|
|
772
|
+
controlled: modeProp,
|
|
773
|
+
default: defaultModeProp != null ? defaultModeProp : "light",
|
|
774
|
+
name: "ThemeSwitch",
|
|
775
|
+
state: "mode"
|
|
776
|
+
});
|
|
777
|
+
const selectedIndex = modes.indexOf(mode);
|
|
778
|
+
const handleChangeSecondary = (0, import_react10.useCallback)(
|
|
779
|
+
(_evt, index) => {
|
|
780
|
+
const mode2 = modes[index];
|
|
781
|
+
setMode(mode2);
|
|
782
|
+
onChange(mode2);
|
|
783
|
+
},
|
|
784
|
+
[onChange, setMode]
|
|
785
|
+
);
|
|
786
|
+
const className = (0, import_classnames4.default)(classBase4, classNameProp);
|
|
787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
788
|
+
import_salt_lab5.ToggleButtonGroup,
|
|
789
|
+
{
|
|
790
|
+
className,
|
|
791
|
+
...htmlAttributes,
|
|
792
|
+
onChange: handleChangeSecondary,
|
|
793
|
+
selectedIndex,
|
|
794
|
+
children: [
|
|
795
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
796
|
+
import_salt_lab5.ToggleButton,
|
|
797
|
+
{
|
|
798
|
+
"aria-label": "alert",
|
|
799
|
+
tooltipText: "Light Theme",
|
|
800
|
+
"data-icon": "light"
|
|
801
|
+
}
|
|
802
|
+
),
|
|
803
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
804
|
+
import_salt_lab5.ToggleButton,
|
|
805
|
+
{
|
|
806
|
+
"aria-label": "home",
|
|
807
|
+
tooltipText: "Dark Theme",
|
|
808
|
+
"data-icon": "dark"
|
|
809
|
+
}
|
|
810
|
+
)
|
|
811
|
+
]
|
|
812
|
+
}
|
|
813
|
+
);
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
// src/app-header/AppHeader.tsx
|
|
817
|
+
var import_classnames5 = __toESM(require("classnames"));
|
|
818
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
819
|
+
var classBase5 = "vuuAppHeader";
|
|
820
|
+
var AppHeader = ({
|
|
821
|
+
className: classNameProp,
|
|
822
|
+
layoutId,
|
|
823
|
+
loginUrl,
|
|
824
|
+
onNavigate,
|
|
825
|
+
onSwitchTheme,
|
|
826
|
+
themeMode = "light",
|
|
827
|
+
user,
|
|
828
|
+
...htmlAttributes
|
|
829
|
+
}) => {
|
|
830
|
+
const className = (0, import_classnames5.default)(classBase5, classNameProp);
|
|
831
|
+
const handleSwitchTheme = (0, import_react11.useCallback)(
|
|
832
|
+
(mode) => onSwitchTheme == null ? void 0 : onSwitchTheme(mode),
|
|
833
|
+
[onSwitchTheme]
|
|
834
|
+
);
|
|
835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("header", { className, ...htmlAttributes, children: [
|
|
836
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ThemeSwitch, { defaultMode: themeMode, onChange: handleSwitchTheme }),
|
|
837
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
838
|
+
UserProfile,
|
|
839
|
+
{
|
|
840
|
+
layoutId,
|
|
841
|
+
loginUrl,
|
|
842
|
+
onNavigate,
|
|
843
|
+
user
|
|
844
|
+
}
|
|
845
|
+
)
|
|
846
|
+
] });
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
// src/shell.tsx
|
|
850
|
+
var import_vuu_utils4 = require("@vuu-ui/vuu-utils");
|
|
851
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
852
|
+
var { error } = (0, import_vuu_utils4.logger)("Shell");
|
|
853
|
+
var warningLayout = {
|
|
854
|
+
type: "View",
|
|
855
|
+
props: {
|
|
856
|
+
style: { height: "calc(100% - 6px)" }
|
|
857
|
+
},
|
|
858
|
+
children: [
|
|
859
|
+
{
|
|
860
|
+
props: {
|
|
861
|
+
className: "vuuShell-warningPlaceholder"
|
|
862
|
+
},
|
|
863
|
+
type: "Placeholder"
|
|
864
|
+
}
|
|
865
|
+
]
|
|
866
|
+
};
|
|
867
|
+
var Shell = ({
|
|
868
|
+
children,
|
|
869
|
+
className: classNameProp,
|
|
870
|
+
defaultLayout = warningLayout,
|
|
871
|
+
leftSidePanel,
|
|
872
|
+
loginUrl,
|
|
873
|
+
saveLocation = "remote",
|
|
874
|
+
saveUrl,
|
|
875
|
+
serverUrl,
|
|
876
|
+
user,
|
|
877
|
+
...htmlAttributes
|
|
878
|
+
}) => {
|
|
879
|
+
const rootRef = (0, import_react12.useRef)(null);
|
|
880
|
+
const paletteView = (0, import_react12.useRef)(null);
|
|
881
|
+
const [open, setOpen] = (0, import_react12.useState)(false);
|
|
882
|
+
const layoutId = (0, import_react12.useRef)("latest");
|
|
883
|
+
const [layout, saveLayoutConfig, loadLayoutById] = useLayoutConfig({
|
|
884
|
+
defaultLayout,
|
|
885
|
+
saveLocation,
|
|
886
|
+
user
|
|
887
|
+
});
|
|
888
|
+
const handleLayoutChange = (0, import_react12.useCallback)(
|
|
889
|
+
(layout2) => {
|
|
890
|
+
try {
|
|
891
|
+
saveLayoutConfig(layout2);
|
|
892
|
+
} catch {
|
|
893
|
+
error == null ? void 0 : error("Failed to save layout");
|
|
894
|
+
}
|
|
895
|
+
},
|
|
896
|
+
[saveLayoutConfig]
|
|
897
|
+
);
|
|
898
|
+
const handleSwitchTheme = (0, import_react12.useCallback)((mode) => {
|
|
899
|
+
if (rootRef.current) {
|
|
900
|
+
rootRef.current.dataset.mode = mode;
|
|
901
|
+
}
|
|
902
|
+
}, []);
|
|
903
|
+
const handleDrawerClick = (e) => {
|
|
904
|
+
var _a;
|
|
905
|
+
const target = e.target;
|
|
906
|
+
if (!((_a = paletteView.current) == null ? void 0 : _a.contains(target))) {
|
|
907
|
+
setOpen(!open);
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
const handleNavigate = (0, import_react12.useCallback)(
|
|
911
|
+
(id) => {
|
|
912
|
+
layoutId.current = id;
|
|
913
|
+
loadLayoutById(id);
|
|
914
|
+
},
|
|
915
|
+
[loadLayoutById]
|
|
916
|
+
);
|
|
917
|
+
(0, import_react12.useEffect)(() => {
|
|
918
|
+
if (serverUrl && user.token) {
|
|
919
|
+
(0, import_vuu_data2.connectToServer)({
|
|
920
|
+
authToken: user.token,
|
|
921
|
+
url: serverUrl,
|
|
922
|
+
username: user.username
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
}, [serverUrl, user.token, user.username]);
|
|
926
|
+
const getDrawers = () => {
|
|
927
|
+
const drawers = [];
|
|
928
|
+
if (leftSidePanel) {
|
|
929
|
+
drawers.push(
|
|
930
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
931
|
+
import_vuu_layout2.Drawer,
|
|
932
|
+
{
|
|
933
|
+
onClick: handleDrawerClick,
|
|
934
|
+
open,
|
|
935
|
+
position: "left",
|
|
936
|
+
inline: true,
|
|
937
|
+
peekaboo: true,
|
|
938
|
+
sizeOpen: 200,
|
|
939
|
+
toggleButton: "end",
|
|
940
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
941
|
+
import_vuu_layout2.View,
|
|
942
|
+
{
|
|
943
|
+
className: "vuuShell-palette",
|
|
944
|
+
id: "vw-app-palette",
|
|
945
|
+
ref: paletteView,
|
|
946
|
+
style: { height: "100%" },
|
|
947
|
+
children: leftSidePanel
|
|
948
|
+
},
|
|
949
|
+
"app-palette"
|
|
950
|
+
)
|
|
951
|
+
},
|
|
952
|
+
"left-panel"
|
|
953
|
+
)
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
return drawers;
|
|
957
|
+
};
|
|
958
|
+
const className = (0, import_classnames6.default)(
|
|
959
|
+
"vuuShell",
|
|
960
|
+
classNameProp,
|
|
961
|
+
"salt-theme",
|
|
962
|
+
"salt-density-high"
|
|
963
|
+
);
|
|
964
|
+
return (
|
|
965
|
+
// ShellContext TBD
|
|
966
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(ShellContextProvider, { value: void 0, children: [
|
|
967
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_vuu_layout2.LayoutProvider, { layout, onLayoutChange: handleLayoutChange, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
968
|
+
import_vuu_layout2.DraggableLayout,
|
|
969
|
+
{
|
|
970
|
+
className,
|
|
971
|
+
"data-mode": "light",
|
|
972
|
+
ref: rootRef,
|
|
973
|
+
...htmlAttributes,
|
|
974
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
975
|
+
import_vuu_layout2.Flexbox,
|
|
976
|
+
{
|
|
977
|
+
className: "App",
|
|
978
|
+
style: { flexDirection: "column", height: "100%", width: "100%" },
|
|
979
|
+
children: [
|
|
980
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
981
|
+
AppHeader,
|
|
982
|
+
{
|
|
983
|
+
layoutId: layoutId.current,
|
|
984
|
+
loginUrl,
|
|
985
|
+
user,
|
|
986
|
+
onNavigate: handleNavigate,
|
|
987
|
+
onSwitchTheme: handleSwitchTheme
|
|
988
|
+
}
|
|
989
|
+
),
|
|
990
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_vuu_layout2.DockLayout, { style: { flex: 1 }, children: getDrawers().concat(
|
|
991
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
992
|
+
import_vuu_layout2.DraggableLayout,
|
|
993
|
+
{
|
|
994
|
+
dropTarget: true,
|
|
995
|
+
style: { width: "100%", height: "100%" }
|
|
996
|
+
},
|
|
997
|
+
"main-content"
|
|
998
|
+
)
|
|
999
|
+
) })
|
|
1000
|
+
]
|
|
1001
|
+
}
|
|
1002
|
+
)
|
|
1003
|
+
}
|
|
1004
|
+
) }),
|
|
1005
|
+
children
|
|
1006
|
+
] })
|
|
1007
|
+
);
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
// src/theme-provider/ThemeProvider.tsx
|
|
1011
|
+
var import_react13 = require("react");
|
|
1012
|
+
var import_classnames7 = __toESM(require("classnames"));
|
|
1013
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1014
|
+
var DEFAULT_DENSITY2 = "medium";
|
|
1015
|
+
var DEFAULT_THEME = "salt-theme";
|
|
1016
|
+
var DEFAULT_THEME_MODE = "light";
|
|
1017
|
+
var ThemeContext = (0, import_react13.createContext)({
|
|
1018
|
+
density: "high",
|
|
1019
|
+
theme: "salt-theme",
|
|
1020
|
+
themeMode: "light"
|
|
1021
|
+
});
|
|
1022
|
+
var createThemedChildren = (children, theme, themeMode, density) => {
|
|
1023
|
+
var _a;
|
|
1024
|
+
if ((0, import_react13.isValidElement)(children)) {
|
|
1025
|
+
return (0, import_react13.cloneElement)(children, {
|
|
1026
|
+
className: (0, import_classnames7.default)(
|
|
1027
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1028
|
+
(_a = children.props) == null ? void 0 : _a.className,
|
|
1029
|
+
theme,
|
|
1030
|
+
`salt-density-${density}`
|
|
1031
|
+
),
|
|
1032
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1033
|
+
// @ts-expect-error
|
|
1034
|
+
"data-mode": themeMode
|
|
1035
|
+
});
|
|
1036
|
+
} else {
|
|
1037
|
+
console.warn(
|
|
1038
|
+
`
|
|
2
1039
|
ThemeProvider can only apply CSS classes for theming to a single nested child element of the ThemeProvider.
|
|
3
|
-
Wrap elements with a single container`
|
|
1040
|
+
Wrap elements with a single container`
|
|
1041
|
+
);
|
|
1042
|
+
return children;
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
var ThemeProvider = ({
|
|
1046
|
+
children,
|
|
1047
|
+
theme: themeProp,
|
|
1048
|
+
themeMode: themeModeProp,
|
|
1049
|
+
density: densityProp
|
|
1050
|
+
}) => {
|
|
1051
|
+
var _a, _b, _c;
|
|
1052
|
+
const {
|
|
1053
|
+
density: inheritedDensity,
|
|
1054
|
+
themeMode: inheritedThemeMode,
|
|
1055
|
+
theme: inheritedTheme
|
|
1056
|
+
} = (0, import_react13.useContext)(ThemeContext);
|
|
1057
|
+
const density = (_a = densityProp != null ? densityProp : inheritedDensity) != null ? _a : DEFAULT_DENSITY2;
|
|
1058
|
+
const themeMode = (_b = themeModeProp != null ? themeModeProp : inheritedThemeMode) != null ? _b : DEFAULT_THEME_MODE;
|
|
1059
|
+
const theme = (_c = themeProp != null ? themeProp : inheritedTheme) != null ? _c : DEFAULT_THEME;
|
|
1060
|
+
const themedChildren = createThemedChildren(
|
|
1061
|
+
children,
|
|
1062
|
+
theme,
|
|
1063
|
+
themeMode,
|
|
1064
|
+
density
|
|
1065
|
+
);
|
|
1066
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ThemeContext.Provider, { value: { themeMode, density, theme }, children: themedChildren });
|
|
1067
|
+
};
|
|
1068
|
+
ThemeProvider.displayName = "ThemeProvider";
|
|
4
1069
|
//# sourceMappingURL=index.js.map
|