@vuu-ui/vuu-shell 0.6.25 → 0.6.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/cjs/index.js CHANGED
@@ -1,2 +1,4 @@
1
- "use strict";var Ve=Object.create;var R=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var $e=Object.getOwnPropertyNames;var Ge=Object.getPrototypeOf,_e=Object.prototype.hasOwnProperty;var Je=(t,e)=>{for(var o in e)R(t,o,{get:e[o],enumerable:!0})},X=(t,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of $e(e))!_e.call(t,n)&&n!==o&&R(t,n,{get:()=>e[n],enumerable:!(r=Oe(e,n))||r.enumerable});return t};var x=(t,e,o)=>(o=t!=null?Ve(Ge(t)):{},X(e||!t||!t.__esModule?R(o,"default",{value:t,enumerable:!0}):o,t)),ze=t=>X(R({},"__esModule",{value:!0}),t);var lt={};Je(lt,{ConnectionStatusIcon:()=>qe,Feature:()=>O,LoginPanel:()=>Ke,Shell:()=>it,ShellContextProvider:()=>z,ThemeSwitch:()=>q,getAuthDetailsFromCookies:()=>Qe,logout:()=>_,redirectToLogin:()=>ae,useShellContext:()=>je});module.exports=ze(lt);var D=x(require("react")),Z=x(require("classnames"));var P=require("react/jsx-runtime"),qe=({connectionStatus:t,className:e,element:o="span",...r})=>{let[n,a]=(0,D.useState)("vuuConnectingStatus");(0,D.useEffect)(()=>{switch(t){case"connected":case"reconnected":a("vuuActiveStatus");break;case"connecting":a("vuuConnectingStatus");break;case"disconnected":a("vuuDisconnectedStatus");break;default:break}},[t]);let s=D.default.createElement(o,{...r,className:(0,Z.default)("vuuStatus vuuIcon",n,e)});return(0,P.jsx)(P.Fragment,{children:(0,P.jsxs)("div",{className:"vuuStatus-container salt-theme",children:[s,(0,P.jsxs)("div",{className:"vuuStatus-text",children:["Status: ",t.toUpperCase()]})]})})};var k=x(require("react")),re=require("@vuu-ui/vuu-layout");var j=x(require("react")),T=require("react/jsx-runtime"),B=class extends j.default.Component{constructor(e){super(e),this.state={errorMessage:null}}static getDerivedStateFromError(e){return{errorMessage:e.message}}componentDidCatch(e,o){console.log(e,o)}render(){return this.state.errorMessage?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)("h1",{children:"Something went wrong."}),(0,T.jsx)("p",{children:this.state.errorMessage})]}):this.props.children}};var te=require("react/jsx-runtime"),ee=()=>(0,te.jsx)("div",{className:"hwLoader",children:"loading"});var oe=async t=>{let e=new CSSStyleSheet;return fetch(t).then(o=>o.text()).then(o=>e.replace(o))};var N=require("react/jsx-runtime");function Ye({url:t,css:e,params:o,...r}){e&&oe(e).then(a=>{document.adoptedStyleSheets=[...document.adoptedStyleSheets,a]});let n=k.default.lazy(()=>import(t));return(0,N.jsx)(B,{children:(0,N.jsx)(k.Suspense,{fallback:(0,N.jsx)(ee,{}),children:(0,N.jsx)(n,{...r,...o})})})}var O=k.default.memo(Ye);O.displayName="Feature";(0,re.registerComponent)("Feature",O,"view");var $=require("react"),se=require("@salt-ds/core"),H=require("@heswell/salt-lab");var S=require("react/jsx-runtime"),ne="vuuLoginPanel",Ke=({onSubmit:t})=>{let[e,o]=(0,$.useState)(""),[r,n]=(0,$.useState)(""),a=()=>{t(e,r)},s=(l,p)=>{o(p)},d=(l,p)=>{n(p)},i=e.trim()!==""&&r.trim()!=="";return(0,S.jsxs)("div",{className:ne,children:[(0,S.jsx)(H.FormField,{label:"Username",style:{width:200},children:(0,S.jsx)(H.Input,{value:e,id:"text-username",onChange:s})}),(0,S.jsx)(H.FormField,{label:"Password",style:{width:200},children:(0,S.jsx)(H.Input,{type:"password",value:r,id:"text-password",onChange:d})}),(0,S.jsx)(se.Button,{className:`${ne}-login`,disabled:!i,onClick:a,variant:"cta",children:"Login"})]})};var G=require("@vuu-ui/vuu-utils"),Qe=()=>{let t=(0,G.getCookieValue)("vuu-username"),e=(0,G.getCookieValue)("vuu-auth-token");return[t,e]},ae=(t="/login.html")=>{window.location.href=t},_=t=>{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",ae(t)};var Me=require("@vuu-ui/vuu-data"),m=require("react");var C=require("react"),We=(t,e)=>{let[o,r]=(0,C.useState)(e),n=i=>{r(i)},a=(0,C.useCallback)(async(i="latest")=>{fetch(`api/vui/${t.username}/${i}`,{}).then(l=>l.ok?l.json():e).then(n).catch(()=>{n(e)})},[e,t.username]);(0,C.useEffect)(()=>{a()},[a]);let s=(0,C.useCallback)(i=>{fetch(`api/vui/${t.username}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)}).then(l=>l.ok?l.json():e)},[e,t]),d=(0,C.useCallback)(i=>{a(i)},[a]);return[o,s,d]},ie=We;var F=require("react"),A=require("react/jsx-runtime"),Xe={},J=(0,F.createContext)(Xe),Ze=({children:t,context:e,inheritedContext:o})=>{let r={...o,...e};return(0,A.jsx)(J.Provider,{value:r,children:t})},z=({children:t,value:e})=>(0,A.jsx)(J.Consumer,{children:o=>(0,A.jsx)(Ze,{context:e,inheritedContext:o,children:t})}),je=()=>(0,F.useContext)(J);var Ne=x(require("classnames")),u=require("@vuu-ui/vuu-layout");var Y=require("react");var pe=require("@salt-ds/core"),he=require("@heswell/salt-lab"),ge=require("@salt-ds/icons");var me=require("@vuu-ui/vuu-utils"),V=require("@heswell/salt-lab"),ce=require("@salt-ds/core"),ue=require("@salt-ds/icons"),y=require("react");var le=async t=>await fetch(`api/vui/${t.username}`,{}).then(o=>o.ok?o.json():null).catch(()=>{console.log("error getting history")});var L=require("react/jsx-runtime"),et=({lastUpdate:t},{lastUpdate:e})=>e===t?0:e<t?-1:1,tt=t=>(0,L.jsx)(V.ListItem,{...t}),de=(0,y.forwardRef)(function({loginUrl:e,onNavigate:o,user:r,layoutId:n="latest"},a){let[s,d]=(0,y.useState)([]);(0,y.useEffect)(()=>{async function h(){let v=(await le(r)).filter(w=>w.id!=="latest").sort(et).map(({id:w,lastUpdate:I})=>({lastUpdate:I,id:w,label:`Saved at ${(0,me.formatDate)(new Date(I),"kk:mm:ss")}`}));console.log({sortedHistory:v}),d(v)}h()},[r]);let i=(0,y.useCallback)((h,g)=>{g&&o(g.id)},[o]),l=(0,y.useCallback)(()=>{_(e)},[e]),p=s.length===0?null:n==="latest"?s[0]:s.find(h=>h.id===n);return(0,L.jsxs)("div",{className:"vuuUserPanel",ref:a,children:[(0,L.jsx)(V.List,{ListItem:tt,className:"vuuUserPanel-history",onSelect:i,selected:p,source:s}),(0,L.jsx)("div",{className:"vuuUserPanel-buttonBar",children:(0,L.jsxs)(ce.Button,{"aria-label":"logout",onClick:l,children:[(0,L.jsx)(ue.ExportIcon,{})," Logout"]})})]})});var b=require("react/jsx-runtime"),fe=({layoutId:t,loginUrl:e,onNavigate:o,user:r})=>(0,b.jsxs)(he.DropdownBase,{className:"vuuUserProfile",placement:"bottom-end",children:[(0,b.jsx)(pe.Button,{variant:"secondary",children:(0,b.jsx)(ge.UserSolidIcon,{})}),(0,b.jsx)(de,{layoutId:t,loginUrl:e,onNavigate:a=>{o(a)},user:r})]});var E=require("@heswell/salt-lab"),ve=x(require("classnames")),xe=require("@salt-ds/core"),Se=require("react");var U=require("react/jsx-runtime"),ot="vuuThemeSwitch",ye=["light","dark"],q=({className:t,defaultMode:e,mode:o,onChange:r,...n})=>{let[a,s]=(0,xe.useControlled)({controlled:o,default:e!=null?e:"light",name:"ThemeSwitch",state:"mode"}),d=ye.indexOf(a),i=(0,Se.useCallback)((p,h)=>{let g=ye[h];s(g),r(g)},[r,s]),l=(0,ve.default)(ot,t);return(0,U.jsxs)(E.ToggleButtonGroup,{className:l,...n,onChange:i,selectedIndex:d,children:[(0,U.jsx)(E.ToggleButton,{"aria-label":"alert",tooltipText:"Light Theme","data-icon":"light"}),(0,U.jsx)(E.ToggleButton,{"aria-label":"home",tooltipText:"Dark Theme","data-icon":"dark"})]})};var He=x(require("classnames"));var Ce=require("@heswell/salt-lab"),Le=require("@salt-ds/core"),Pe=require("react"),Te=x(require("classnames")),De=require("react/jsx-runtime"),rt="vuuDensitySwitch",nt=["high","medium","low","touch"],we=({className:t,defaultDensity:e=Le.DEFAULT_DENSITY,onDensityChange:o})=>{let r=(0,Pe.useCallback)((a,s)=>{o(s)},[o]),n=(0,Te.default)(rt,t);return(0,De.jsx)(Ce.Dropdown,{className:n,source:nt,defaultSelected:e,onSelectionChange:r})};var M=require("react/jsx-runtime"),st="vuuAppHeader",be=({className:t,layoutId:e,loginUrl:o,onNavigate:r,onSwitchTheme:n,themeMode:a="light",onDensitySwitch:s,density:d="medium",user:i,...l})=>{let p=(0,He.default)(st,t,`salt-density-${d}`),h=(0,Y.useCallback)(v=>n==null?void 0:n(v),[n]),g=(0,Y.useCallback)(v=>s==null?void 0:s(v),[s]);return(0,M.jsxs)("header",{className:p,...l,children:[(0,M.jsx)(q,{defaultMode:a,onChange:h}),(0,M.jsx)(we,{defaultDensity:d,onDensityChange:g}),(0,M.jsx)(fe,{layoutId:e,loginUrl:o,onNavigate:r,user:i})]})};var f=require("react/jsx-runtime"),at={type:"View",props:{style:{height:"calc(100% - 6px)"}},children:[{props:{className:"vuuShell-warningPlaceholder"},type:"Placeholder"}]},it=({children:t,className:e,defaultLayout:o=at,leftSidePanel:r,loginUrl:n,serverUrl:a,user:s,...d})=>{let i=(0,m.useRef)(null),[l,p]=(0,m.useState)("medium"),h=(0,m.useRef)(null),[g,v]=(0,m.useState)(!1),w=(0,m.useRef)("latest"),[I,K,Q]=ie(s,o),ke=(0,m.useCallback)(c=>{K(c)},[K]),Ee=(0,m.useCallback)(c=>{i.current&&(i.current.dataset.mode=c)},[]),Ue=(0,m.useCallback)(c=>{p(c)},[p]),Ie=c=>{var W;let Fe=c.target;(W=h.current)!=null&&W.contains(Fe)||v(!g)},Re=(0,m.useCallback)(c=>{w.current=c,Q(c)},[Q]);(0,m.useEffect)(()=>{a&&s.token&&(0,Me.connectToServer)(a,s.token)},[a,s.token]);let Be=()=>{let c=[];return r&&c.push((0,f.jsx)(u.Drawer,{onClick:Ie,open:g,position:"left",inline:!0,peekaboo:!0,sizeOpen:200,toggleButton:"end",children:(0,f.jsx)(u.View,{className:"vuuShell-palette",id:"vw-app-palette",ref:h,style:{height:"100%"},children:r},"app-palette")},"left-panel")),c},Ae=(0,Ne.default)("vuuShell",e,"salt-theme",`salt-density-${l}`);return(0,f.jsxs)(z,{value:void 0,children:[(0,f.jsx)(u.LayoutProvider,{layout:I,onLayoutChange:ke,children:(0,f.jsx)(u.DraggableLayout,{className:Ae,"data-mode":"light",ref:i,...d,children:(0,f.jsxs)(u.Flexbox,{className:"App",style:{flexDirection:"column",height:"100%",width:"100%"},children:[(0,f.jsx)(be,{layoutId:w.current,loginUrl:n,user:s,onNavigate:Re,onSwitchTheme:Ee,onDensitySwitch:Ue}),(0,f.jsx)(u.Chest,{style:{flex:1},children:Be().concat((0,f.jsx)(u.DraggableLayout,{dropTarget:!0,style:{width:"100%",height:"100%"}},"main-content"))})]})})}),t]})};
1
+ "use strict";var _e=Object.create;var A=Object.defineProperty;var $e=Object.getOwnPropertyDescriptor;var Ge=Object.getOwnPropertyNames;var Je=Object.getPrototypeOf,ze=Object.prototype.hasOwnProperty;var Ye=(t,e)=>{for(var o in e)A(t,o,{get:e[o],enumerable:!0})},Q=(t,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Ge(e))!ze.call(t,n)&&n!==o&&A(t,n,{get:()=>e[n],enumerable:!(r=$e(e,n))||r.enumerable});return t};var y=(t,e,o)=>(o=t!=null?_e(Je(t)):{},Q(e||!t||!t.__esModule?A(o,"default",{value:t,enumerable:!0}):o,t)),qe=t=>Q(A({},"__esModule",{value:!0}),t);var pt={};Ye(pt,{ConnectionStatusIcon:()=>We,DEFAULT_DENSITY:()=>He,DEFAULT_THEME:()=>Ne,DEFAULT_THEME_MODE:()=>be,DensitySwitch:()=>Ze,Feature:()=>_,LoginPanel:()=>et,Shell:()=>ut,ShellContextProvider:()=>Y,ThemeContext:()=>W,ThemeProvider:()=>ke,ThemeSwitch:()=>q,getAuthDetailsFromCookies:()=>tt,logout:()=>J,redirectToLogin:()=>le,useShellContext:()=>nt});module.exports=qe(pt);var w=y(require("react")),X=y(require("classnames"));var P=require("react/jsx-runtime"),We=({connectionStatus:t,className:e,element:o="span",...r})=>{let[n,s]=(0,w.useState)("vuuConnectingStatus");(0,w.useEffect)(()=>{switch(t){case"connected":case"reconnected":s("vuuActiveStatus");break;case"connecting":s("vuuConnectingStatus");break;case"disconnected":s("vuuDisconnectedStatus");break;default:break}},[t]);let a=w.default.createElement(o,{...r,className:(0,X.default)("vuuStatus vuuIcon",n,e)});return(0,P.jsx)(P.Fragment,{children:(0,P.jsxs)("div",{className:"vuuStatus-container salt-theme",children:[a,(0,P.jsxs)("div",{className:"vuuStatus-text",children:["Status: ",t.toUpperCase()]})]})})};var Z=require("@heswell/salt-lab"),j=require("react"),ee=y(require("classnames")),te=require("react/jsx-runtime"),Ke="vuuDensitySwitch",Qe=["high","medium","low","touch"],Xe="high",Ze=({className:t,defaultDensity:e=Xe,onDensityChange:o})=>{let r=(0,j.useCallback)((s,a)=>{o(a)},[o]),n=(0,ee.default)(Ke,t);return(0,te.jsx)(Z.Dropdown,{className:n,source:Qe,defaultSelected:e,onSelectionChange:r})};var k=y(require("react")),se=require("@vuu-ui/vuu-layout");var oe=y(require("react")),M=require("react/jsx-runtime"),B=class extends oe.default.Component{constructor(e){super(e),this.state={errorMessage:null}}static getDerivedStateFromError(e){return{errorMessage:e.message}}componentDidCatch(e,o){console.log(e,o)}render(){return this.state.errorMessage?(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)("h1",{children:"Something went wrong."}),(0,M.jsx)("p",{children:this.state.errorMessage})]}):this.props.children}};var ne=require("react/jsx-runtime"),re=()=>(0,ne.jsx)("div",{className:"hwLoader",children:"loading"});var b=require("react/jsx-runtime");function je({url:t,css:e,params:o,...r}){e&&import(e).then(s=>{document.adoptedStyleSheets=[...document.adoptedStyleSheets,s.default]});let n=k.default.lazy(()=>import(t));return(0,b.jsx)(B,{children:(0,b.jsx)(k.Suspense,{fallback:(0,b.jsx)(re,{}),children:(0,b.jsx)(n,{...r,...o})})})}var _=k.default.memo(je);_.displayName="Feature";(0,se.registerComponent)("Feature",_,"view");var $=require("react"),ie=require("@salt-ds/core"),D=require("@heswell/salt-lab");var x=require("react/jsx-runtime"),ae="vuuLoginPanel",et=({onSubmit:t})=>{let[e,o]=(0,$.useState)(""),[r,n]=(0,$.useState)(""),s=()=>{t(e,r)},a=(l,c)=>{o(c)},m=(l,c)=>{n(c)},i=e.trim()!==""&&r.trim()!=="";return(0,x.jsxs)("div",{className:ae,children:[(0,x.jsx)(D.FormField,{label:"Username",style:{width:200},children:(0,x.jsx)(D.Input,{value:e,id:"text-username",onChange:a})}),(0,x.jsx)(D.FormField,{label:"Password",style:{width:200},children:(0,x.jsx)(D.Input,{type:"password",value:r,id:"text-password",onChange:m})}),(0,x.jsx)(ie.Button,{className:`${ae}-login`,disabled:!i,onClick:s,variant:"cta",children:"Login"})]})};var G=require("@vuu-ui/vuu-utils"),tt=()=>{let t=(0,G.getCookieValue)("vuu-username"),e=(0,G.getCookieValue)("vuu-auth-token");return[t,e]},le=(t="/login.html")=>{window.location.href=t},J=t=>{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",le(t)};var Ee=require("@vuu-ui/vuu-data"),we=y(require("classnames")),p=require("react");var V=require("react"),F=require("react/jsx-runtime"),ot={},z=(0,V.createContext)(ot),rt=({children:t,context:e,inheritedContext:o})=>{let r={...o,...e};return(0,F.jsx)(z.Provider,{value:r,children:t})},Y=({children:t,value:e})=>(0,F.jsx)(z.Consumer,{children:o=>(0,F.jsx)(rt,{context:e,inheritedContext:o,children:t})}),nt=()=>(0,V.useContext)(z);var T=require("react"),st=(t,e)=>{let[o,r]=(0,T.useState)(e),n=i=>{r(i)},s=(0,T.useCallback)(async(i="latest")=>{fetch(`api/vui/${t.username}/${i}`,{}).then(l=>l.ok?l.json():e).then(n).catch(()=>{n(e)})},[e,t.username]);(0,T.useEffect)(()=>{s()},[s]);let a=(0,T.useCallback)(i=>{fetch(`api/vui/${t.username}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)}).then(l=>l.ok?l.json():e)},[e,t]),m=(0,T.useCallback)(i=>{s(i)},[s]);return[o,a,m]},me=st;var u=require("@vuu-ui/vuu-layout");var Se=require("react");var ge=require("@salt-ds/core"),fe=require("@heswell/salt-lab"),ye=require("@salt-ds/icons");var ue=require("@vuu-ui/vuu-utils"),O=require("@heswell/salt-lab"),de=require("@salt-ds/core"),pe=require("@salt-ds/icons"),v=require("react");var ce=async t=>await fetch(`api/vui/${t.username}`,{}).then(o=>o.ok?o.json():null).catch(()=>{console.log("error getting history")});var C=require("react/jsx-runtime"),at=({lastUpdate:t},{lastUpdate:e})=>e===t?0:e<t?-1:1,it=t=>(0,C.jsx)(O.ListItem,{...t}),he=(0,v.forwardRef)(function({loginUrl:e,onNavigate:o,user:r,layoutId:n="latest"},s){let[a,m]=(0,v.useState)([]);(0,v.useEffect)(()=>{async function h(){let S=(await ce(r)).filter(E=>E.id!=="latest").sort(at).map(({id:E,lastUpdate:N})=>({lastUpdate:N,id:E,label:`Saved at ${(0,ue.formatDate)(new Date(N),"kk:mm:ss")}`}));console.log({sortedHistory:S}),m(S)}h()},[r]);let i=(0,v.useCallback)((h,d)=>{d&&o(d.id)},[o]),l=(0,v.useCallback)(()=>{J(e)},[e]),c=a.length===0?null:n==="latest"?a[0]:a.find(h=>h.id===n);return(0,C.jsxs)("div",{className:"vuuUserPanel",ref:s,children:[(0,C.jsx)(O.List,{ListItem:it,className:"vuuUserPanel-history",onSelect:i,selected:c,source:a}),(0,C.jsx)("div",{className:"vuuUserPanel-buttonBar",children:(0,C.jsxs)(de.Button,{"aria-label":"logout",onClick:l,children:[(0,C.jsx)(pe.ExportIcon,{})," Logout"]})})]})});var H=require("react/jsx-runtime"),ve=({layoutId:t,loginUrl:e,onNavigate:o,user:r})=>(0,H.jsxs)(fe.DropdownBase,{className:"vuuUserProfile",placement:"bottom-end",children:[(0,H.jsx)(ge.Button,{variant:"secondary",children:(0,H.jsx)(ye.UserSolidIcon,{})}),(0,H.jsx)(he,{layoutId:t,loginUrl:e,onNavigate:s=>{o(s)},user:r})]});var U=require("@heswell/salt-lab"),Te=y(require("classnames")),Ce=require("@salt-ds/core"),Le=require("react");var I=require("react/jsx-runtime"),lt="vuuThemeSwitch",xe=["light","dark"],q=({className:t,defaultMode:e,mode:o,onChange:r,...n})=>{let[s,a]=(0,Ce.useControlled)({controlled:o,default:e!=null?e:"light",name:"ThemeSwitch",state:"mode"}),m=xe.indexOf(s),i=(0,Le.useCallback)((c,h)=>{let d=xe[h];a(d),r(d)},[r,a]),l=(0,Te.default)(lt,t);return(0,I.jsxs)(U.ToggleButtonGroup,{className:l,...n,onChange:i,selectedIndex:m,children:[(0,I.jsx)(U.ToggleButton,{"aria-label":"alert",tooltipText:"Light Theme","data-icon":"light"}),(0,I.jsx)(U.ToggleButton,{"aria-label":"home",tooltipText:"Dark Theme","data-icon":"dark"})]})};var Pe=y(require("classnames"));var R=require("react/jsx-runtime"),mt="vuuAppHeader",Me=({className:t,layoutId:e,loginUrl:o,onNavigate:r,onSwitchTheme:n,themeMode:s="light",user:a,...m})=>{let i=(0,Pe.default)(mt,t),l=(0,Se.useCallback)(c=>n==null?void 0:n(c),[n]);return(0,R.jsxs)("header",{className:i,...m,children:[(0,R.jsx)(q,{defaultMode:s,onChange:l}),(0,R.jsx)(ve,{layoutId:e,loginUrl:o,onNavigate:r,user:a})]})};var f=require("react/jsx-runtime"),ct={type:"View",props:{style:{height:"calc(100% - 6px)"}},children:[{props:{className:"vuuShell-warningPlaceholder"},type:"Placeholder"}]},ut=({children:t,className:e,defaultLayout:o=ct,leftSidePanel:r,loginUrl:n,serverUrl:s,user:a,...m})=>{let i=(0,p.useRef)(null),l=(0,p.useRef)(null),[c,h]=(0,p.useState)(!1),d=(0,p.useRef)("latest"),[S,E,N]=me(a,o),Ie=(0,p.useCallback)(g=>{E(g)},[E]),Re=(0,p.useCallback)(g=>{i.current&&(i.current.dataset.mode=g)},[]),Ae=g=>{var K;let Oe=g.target;(K=l.current)!=null&&K.contains(Oe)||h(!c)},Be=(0,p.useCallback)(g=>{d.current=g,N(g)},[N]);(0,p.useEffect)(()=>{s&&a.token&&(0,Ee.connectToServer)(s,a.token)},[s,a.token]);let Fe=()=>{let g=[];return r&&g.push((0,f.jsx)(u.Drawer,{onClick:Ae,open:c,position:"left",inline:!0,peekaboo:!0,sizeOpen:200,toggleButton:"end",children:(0,f.jsx)(u.View,{className:"vuuShell-palette",id:"vw-app-palette",ref:l,style:{height:"100%"},children:r},"app-palette")},"left-panel")),g},Ve=(0,we.default)("vuuShell",e,"salt-theme","salt-density-high");return(0,f.jsxs)(Y,{value:void 0,children:[(0,f.jsx)(u.LayoutProvider,{layout:S,onLayoutChange:Ie,children:(0,f.jsx)(u.DraggableLayout,{className:Ve,"data-mode":"light",ref:i,...m,children:(0,f.jsxs)(u.Flexbox,{className:"App",style:{flexDirection:"column",height:"100%",width:"100%"},children:[(0,f.jsx)(Me,{layoutId:d.current,loginUrl:n,user:a,onNavigate:Be,onSwitchTheme:Re}),(0,f.jsx)(u.DockLayout,{style:{flex:1},children:Fe().concat((0,f.jsx)(u.DraggableLayout,{dropTarget:!0,style:{width:"100%",height:"100%"}},"main-content"))})]})})}),t]})};var L=require("react"),De=y(require("classnames")),Ue=require("react/jsx-runtime"),He="medium",Ne="salt-theme",be="light",W=(0,L.createContext)({density:"high",theme:"salt-theme",themeMode:"light"}),dt=(t,e,o,r)=>{var n;return(0,L.isValidElement)(t)?(0,L.cloneElement)(t,{className:(0,De.default)((n=t.props)==null?void 0:n.className,e,`salt-density-${r}`),"data-mode":o}):(console.warn(`
2
+ ThemeProvider can only apply CSS classes for theming to a single nested child element of the ThemeProvider.
3
+ Wrap elements with a single container`),t)},ke=({children:t,theme:e,themeMode:o,density:r})=>{var h,d,S;let{density:n,themeMode:s,theme:a}=(0,L.useContext)(W),m=(h=r!=null?r:n)!=null?h:He,i=(d=o!=null?o:s)!=null?d:be,l=(S=e!=null?e:a)!=null?S:Ne,c=dt(t,l,i,m);return(0,Ue.jsx)(W.Provider,{value:{themeMode:i,density:m,theme:l},children:c})};ke.displayName="ThemeProvider";
2
4
  //# sourceMappingURL=index.js.map
package/cjs/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../packages/vuu-shell/src/index.ts", "../../../packages/vuu-shell/src/connection-status/ConnectionStatusIcon.tsx", "../../../packages/vuu-shell/src/feature/Feature.tsx", "../../../packages/vuu-shell/src/feature/ErrorBoundary.jsx", "../../../packages/vuu-shell/src/feature/Loader.tsx", "../../../packages/vuu-shell/src/feature/css-module-loader.ts", "../../../packages/vuu-shell/src/login/LoginPanel.tsx", "../../../packages/vuu-shell/src/login/login-utils.ts", "../../../packages/vuu-shell/src/shell.tsx", "../../../packages/vuu-shell/src/use-layout-config.js", "../../../packages/vuu-shell/src/ShellContextProvider.tsx", "../../../packages/vuu-shell/src/app-header/AppHeader.tsx", "../../../packages/vuu-shell/src/user-profile/UserProfile.tsx", "../../../packages/vuu-shell/src/user-profile/UserPanel.tsx", "../../../packages/vuu-shell/src/get-layout-history.ts", "../../../packages/vuu-shell/src/theme-switch/ThemeSwitch.tsx", "../../../packages/vuu-shell/src/density-switch/DensitySwitch.tsx"],
4
- "sourcesContent": ["export * from \"./connection-status\";\nexport * from \"./feature\";\nexport * from \"./login\";\nexport * from \"./shell\";\nexport * from \"./shellTypes\";\nexport * from \"./ShellContextProvider\";\nexport * from \"./theme-switch\";\n", "import React, { useEffect, useState } from 'react';\nimport cx from 'classnames';\nimport './ConnectionStatusIcon.css';\n\ntype connectionStatus = 'connected' | 'reconnected' | 'connecting' | 'disconnected';\n\ninterface ConnectionStatusProps {\n\tconnectionStatus: connectionStatus\n\tclassName?: string;\n\tprops?: unknown;\n\telement?: string;\n}\n\nexport const ConnectionStatusIcon = ({ connectionStatus, className, element = 'span', ...props}: ConnectionStatusProps) => {\n\tconst [classBase, setClassBase] = useState<string>('vuuConnectingStatus');\n\tuseEffect(() => {\n\t\tswitch(connectionStatus) {\n\t\t\tcase 'connected':\n\t\t\tcase 'reconnected':\n\t\t\t\tsetClassBase('vuuActiveStatus');\n\t\t\t\tbreak;\n\t\t\tcase 'connecting':\n\t\t\t\tsetClassBase('vuuConnectingStatus');\n\t\t\t\tbreak;\n\t\t\tcase 'disconnected':\n\t\t\t\tsetClassBase('vuuDisconnectedStatus');\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}, [connectionStatus]);\n\n\tconst statusIcon = React.createElement (\n\t\telement,\n\t\t{\n\t\t\t...props,\n\t\t\tclassName: cx('vuuStatus vuuIcon', classBase, className)\n\t\t},\n\t)\n\n\treturn (\n\t\t<>\n\t\t\t<div className='vuuStatus-container salt-theme'>\n\t\t\t\t{statusIcon}\n\t\t\t\t<div\tclassName='vuuStatus-text'>Status: {connectionStatus.toUpperCase()}</div>\n\t\t\t</div>\n\t\t</>\n\t)\n}", "import React, { Suspense } from \"react\";\nimport { registerComponent } from \"@vuu-ui/vuu-layout\";\nimport { ErrorBoundary } from \"./ErrorBoundary\";\nimport { Loader } from \"./Loader\";\nimport { importCSS } from \"./css-module-loader\";\n\nexport interface FeatureProps<Params extends object | undefined = undefined> {\n height?: number;\n url: string;\n css?: string;\n width?: number;\n params: Params;\n}\n\n// const RawFeature = <Params extends object | undefined>({\nfunction RawFeature<Params extends object | undefined>({\n url,\n css,\n params,\n ...props\n}: FeatureProps<Params>) {\n if (css) {\n // import(/* @vite-ignore */ css, { assert: { type: \"css\" } }).then(\n // (cssModule) => {\n // document.adoptedStyleSheets = [\n // ...document.adoptedStyleSheets,\n // cssModule.default,\n // ];\n // }\n // );\n // Polyfill until vite build supports import assertions\n // Note: already fully supported in esbuild, so vite dev\n importCSS(css).then((styleSheet) => {\n document.adoptedStyleSheets = [\n ...document.adoptedStyleSheets,\n styleSheet,\n ];\n });\n }\n const LazyFeature = React.lazy(() => import(/* @vite-ignore */ url));\n return (\n <ErrorBoundary>\n <Suspense fallback={<Loader />}>\n <LazyFeature {...props} {...params} />\n </Suspense>\n </ErrorBoundary>\n );\n}\n\nexport const Feature = React.memo(RawFeature);\nFeature.displayName = \"Feature\";\nregisterComponent(\"Feature\", Feature, \"view\");\n", "import React from 'react';\n// TODO\nexport class ErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = { errorMessage: null };\n }\n\n static getDerivedStateFromError(error) {\n // Update state so the next render will show the fallback UI.\n return { errorMessage: error.message };\n }\n\n componentDidCatch(error, errorInfo) {\n // You can also log the error to an error reporting service\n console.log(error, errorInfo);\n }\n\n render() {\n if (this.state.errorMessage) {\n return (\n <>\n <h1>Something went wrong.</h1>\n <p>{this.state.errorMessage}</p>\n </>\n );\n }\n\n return this.props.children;\n }\n}\n", "// TODO\nexport const Loader = () => <div className=\"hwLoader\">loading</div>;\n", "export const importCSS = async (path: string) => {\n const container = new CSSStyleSheet();\n return fetch(path)\n .then((x) => x.text())\n .then((x) => container.replace(x));\n};\n", "import { ChangeEvent, HTMLAttributes, useState } from \"react\";\nimport { Button } from \"@salt-ds/core\";\nimport { FormField, Input } from \"@heswell/salt-lab\";\n\nimport \"./LoginPanel.css\";\n\nconst classBase = \"vuuLoginPanel\";\n\nexport interface LoginPanelProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onSubmit\"> {\n onSubmit: (username: string, password: string) => void;\n}\n\nexport const LoginPanel = ({ onSubmit }: LoginPanelProps) => {\n const [username, setUserName] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n\n const login = () => {\n onSubmit(username, password);\n };\n\n const handleUsername = (\n _event: ChangeEvent<HTMLInputElement>,\n value: string\n ) => {\n setUserName(value);\n };\n\n const handlePassword = (\n _event: ChangeEvent<HTMLInputElement>,\n value: string\n ) => {\n setPassword(value);\n };\n\n const dataIsValid = username.trim() !== \"\" && password.trim() !== \"\";\n\n return (\n <div className={classBase}>\n <FormField label=\"Username\" style={{ width: 200 }}>\n <Input value={username} id=\"text-username\" onChange={handleUsername} />\n </FormField>\n\n <FormField label=\"Password\" style={{ width: 200 }}>\n <Input\n type=\"password\"\n value={password}\n id=\"text-password\"\n onChange={handlePassword}\n />\n </FormField>\n\n <Button\n className={`${classBase}-login`}\n disabled={!dataIsValid}\n onClick={login}\n variant=\"cta\"\n >\n Login\n </Button>\n </div>\n );\n};\n", "import { getCookieValue } from \"@vuu-ui/vuu-utils\";\n\nexport const getAuthDetailsFromCookies = () => {\n const username = getCookieValue(\"vuu-username\");\n const token = getCookieValue(\"vuu-auth-token\");\n return [username, token];\n};\n\nexport const redirectToLogin = (loginUrl = \"/login.html\") => {\n window.location.href = loginUrl;\n};\n\nexport const logout = (loginUrl?: string) => {\n document.cookie = \"vuu-username= ; expires = Thu, 01 Jan 1970 00:00:00 GMT\";\n document.cookie = \"vuu-auth-token= ; expires = Thu, 01 Jan 1970 00:00:00 GMT\";\n redirectToLogin(loginUrl);\n};\n", "import { connectToServer } from \"@vuu-ui/vuu-data\";\nimport {\n HTMLAttributes,\n MouseEvent,\n ReactElement,\n ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport useLayoutConfig from \"./use-layout-config\";\nimport { ShellContextProvider } from \"./ShellContextProvider\";\nimport cx from \"classnames\";\n\nimport {\n Chest,\n DraggableLayout,\n Drawer,\n Flexbox,\n LayoutProvider,\n View,\n} from \"@vuu-ui/vuu-layout\";\n\nimport { AppHeader } from \"./app-header\";\n\nimport { LayoutJSON } from \"@vuu-ui/vuu-layout/src/layout-reducer\";\nimport \"./shell.css\";\nimport { ThemeMode } from \"./theme-switch\";\nimport { Density } from \"@salt-ds/core\";\n\nexport type VuuUser = {\n username: string;\n token: string;\n};\n\nconst warningLayout = {\n type: \"View\",\n props: {\n style: { height: \"calc(100% - 6px)\" },\n },\n children: [\n {\n props: {\n className: \"vuuShell-warningPlaceholder\",\n },\n type: \"Placeholder\",\n },\n ],\n};\n\nexport interface ShellProps extends HTMLAttributes<HTMLDivElement> {\n children?: ReactNode;\n defaultLayout?: LayoutJSON;\n leftSidePanel?: ReactElement;\n loginUrl?: string;\n // paletteConfig: any;\n serverUrl?: string;\n user: VuuUser;\n}\n\nexport const Shell = ({\n children,\n className: classNameProp,\n defaultLayout = warningLayout,\n leftSidePanel,\n loginUrl,\n serverUrl,\n user,\n ...htmlAttributes\n}: ShellProps) => {\n const rootRef = useRef<HTMLDivElement>(null);\n const [density, setDensity] = useState<Density>(\"medium\");\n const paletteView = useRef<HTMLDivElement>(null);\n const [open, setOpen] = useState(false);\n const layoutId = useRef(\"latest\");\n\n const [layout, setLayoutConfig, loadLayoutById] = useLayoutConfig(\n user,\n defaultLayout\n );\n\n const handleLayoutChange = useCallback(\n (layout) => {\n setLayoutConfig(layout);\n },\n [setLayoutConfig]\n );\n\n const handleSwitchTheme = useCallback((mode: ThemeMode) => {\n if (rootRef.current) {\n rootRef.current.dataset.mode = mode;\n }\n }, []);\n\n const handleDensitySwitch = useCallback(\n (density: Density) => {\n setDensity(density);\n },\n [setDensity]\n );\n\n const handleDrawerClick = (e: MouseEvent<HTMLElement>) => {\n const target = e.target as HTMLElement;\n if (!paletteView.current?.contains(target)) {\n setOpen(!open);\n }\n };\n\n const handleNavigate = useCallback(\n (id) => {\n layoutId.current = id;\n loadLayoutById(id);\n },\n [loadLayoutById]\n );\n\n useEffect(() => {\n if (serverUrl && user.token) {\n connectToServer(serverUrl, user.token);\n }\n }, [serverUrl, user.token]);\n\n const getDrawers = () => {\n const drawers: ReactElement[] = [];\n if (leftSidePanel) {\n drawers.push(\n <Drawer\n key=\"left-panel\"\n onClick={handleDrawerClick}\n open={open}\n position=\"left\"\n inline\n peekaboo\n sizeOpen={200}\n toggleButton=\"end\"\n >\n <View\n className=\"vuuShell-palette\"\n id=\"vw-app-palette\"\n key=\"app-palette\"\n ref={paletteView}\n style={{ height: \"100%\" }}\n >\n {leftSidePanel}\n </View>\n </Drawer>\n );\n }\n\n return drawers;\n };\n\n const className = cx(\n \"vuuShell\",\n classNameProp,\n \"salt-theme\",\n `salt-density-${density}`\n );\n\n return (\n // ShellContext TBD\n <ShellContextProvider value={undefined}>\n <LayoutProvider layout={layout} onLayoutChange={handleLayoutChange}>\n <DraggableLayout\n className={className}\n data-mode=\"light\"\n ref={rootRef}\n {...htmlAttributes}\n >\n <Flexbox\n className=\"App\"\n style={{ flexDirection: \"column\", height: \"100%\", width: \"100%\" }}\n >\n <AppHeader\n layoutId={layoutId.current}\n loginUrl={loginUrl}\n user={user}\n onNavigate={handleNavigate}\n onSwitchTheme={handleSwitchTheme}\n onDensitySwitch={handleDensitySwitch}\n />\n <Chest style={{ flex: 1 }}>\n {getDrawers().concat(\n <DraggableLayout\n dropTarget\n key=\"main-content\"\n style={{ width: \"100%\", height: \"100%\" }}\n />\n )}\n </Chest>\n </Flexbox>\n </DraggableLayout>\n </LayoutProvider>\n {children}\n </ShellContextProvider>\n );\n};\n", "import { useCallback, useEffect, useState } from \"react\";\n\nconst useLayoutConfig = (user, defaultLayout) => {\n const [layout, _setLayout] = useState(defaultLayout);\n\n const setLayout = (layout) => {\n _setLayout(layout);\n };\n\n const load = useCallback(\n async (id = \"latest\") => {\n fetch(`api/vui/${user.username}/${id}`, {})\n .then((response) => {\n return response.ok ? response.json() : defaultLayout;\n })\n .then(setLayout)\n .catch(() => {\n // TODO we should set a layout with a warning here\n setLayout(defaultLayout);\n });\n },\n [defaultLayout, user.username]\n );\n\n useEffect(() => {\n load();\n }, [load]);\n\n const saveData = useCallback(\n (data) => {\n fetch(`api/vui/${user.username}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(data),\n }).then((response) => {\n return response.ok ? response.json() : defaultLayout;\n });\n },\n [defaultLayout, user]\n );\n\n const loadLayoutById = useCallback(\n (id) => {\n load(id);\n },\n [load]\n );\n\n return [layout, saveData, loadLayoutById];\n};\n\nexport default useLayoutConfig;\n", "import { MenuRpcResponse } from \"@vuu-ui/vuu-data\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { createContext, ReactElement, ReactNode, useContext } from \"react\";\n\nexport interface ShellContextProps {\n getDefaultColumnConfig?: (\n tableName: string,\n columnName: string\n ) => Partial<ColumnDescriptor>;\n handleRpcResponse?: (response?: MenuRpcResponse) => void;\n}\n\nconst defaultConfig = {};\n\nconst ShellContext = createContext<ShellContextProps>(defaultConfig);\n\nexport interface ShellProviderProps {\n children: ReactNode;\n value?: ShellContextProps;\n}\n\nconst Provider = ({\n children,\n context,\n inheritedContext,\n}: {\n children: ReactNode;\n context?: ShellContextProps;\n inheritedContext?: ShellContextProps;\n}) => {\n // TODO functions provided at multiple levels must be merged\n const mergedContext = {\n ...inheritedContext,\n ...context,\n };\n return (\n <ShellContext.Provider value={mergedContext}>\n {children}\n </ShellContext.Provider>\n );\n};\n\nexport const ShellContextProvider = ({\n children,\n value,\n}: ShellProviderProps): ReactElement => {\n return (\n <ShellContext.Consumer>\n {(context) => (\n <Provider context={value} inheritedContext={context}>\n {children}\n </Provider>\n )}\n </ShellContext.Consumer>\n );\n};\n\nexport const useShellContext = () => {\n return useContext(ShellContext);\n};\n", "import { HTMLAttributes, useCallback } from \"react\";\nimport { VuuUser } from \"../shell\";\nimport { UserProfile } from \"../user-profile\";\nimport { ThemeMode, ThemeSwitch } from \"../theme-switch\";\nimport cx from \"classnames\";\n\nimport \"./AppHeader.css\";\nimport { Density } from \"@salt-ds/core\";\nimport { DensitySwitch } from \"../density-switch\";\n\nconst classBase = \"vuuAppHeader\";\nexport interface AppHeaderProps extends HTMLAttributes<HTMLDivElement> {\n layoutId: string;\n loginUrl?: string;\n onNavigate: (id: string) => void;\n onSwitchTheme?: (mode: ThemeMode) => void;\n themeMode?: ThemeMode;\n onDensitySwitch?: (density: Density) => void;\n density?: Density\n user: VuuUser;\n}\n\nexport const AppHeader = ({\n className: classNameProp,\n layoutId,\n loginUrl,\n onNavigate,\n onSwitchTheme,\n themeMode = \"light\",\n onDensitySwitch,\n density=\"medium\",\n user,\n ...htmlAttributes\n}: AppHeaderProps) => {\n const className = cx(classBase, classNameProp, `salt-density-${density}`);\n const handleSwitchTheme = useCallback(\n (mode: ThemeMode) => onSwitchTheme?.(mode),\n [onSwitchTheme]\n );\n const handleDensitySwitch = useCallback(\n (density: Density) => onDensitySwitch?.(density),\n [onDensitySwitch]\n );\n return (\n <header className={className} {...htmlAttributes}>\n <ThemeSwitch defaultMode={themeMode} onChange={handleSwitchTheme} />\n <DensitySwitch defaultDensity={density} onDensityChange={handleDensitySwitch} />\n <UserProfile\n layoutId={layoutId}\n loginUrl={loginUrl}\n onNavigate={onNavigate}\n user={user}\n />\n </header>\n );\n};\n", "import { Button } from \"@salt-ds/core\";\nimport { DropdownBase } from \"@heswell/salt-lab\";\nimport { UserSolidIcon } from \"@salt-ds/icons\";\nimport { UserPanel } from \"./UserPanel\";\n\nimport \"./UserProfile.css\";\nimport { VuuUser } from \"../shell\";\n\nexport interface UserProfileProps {\n layoutId: string;\n loginUrl?: string;\n onNavigate: (id: string) => void;\n user: VuuUser;\n}\n\nexport const UserProfile = ({\n layoutId,\n loginUrl,\n onNavigate,\n user,\n}: UserProfileProps) => {\n const handleNavigate = (id: string) => {\n onNavigate(id);\n };\n\n return (\n <DropdownBase className=\"vuuUserProfile\" placement=\"bottom-end\">\n <Button variant=\"secondary\">\n <UserSolidIcon />\n </Button>\n <UserPanel\n layoutId={layoutId}\n loginUrl={loginUrl}\n onNavigate={handleNavigate}\n user={user}\n />\n </DropdownBase>\n );\n};\n", "import { formatDate } from \"@vuu-ui/vuu-utils\";\nimport { List, ListItem, ListItemProps } from \"@heswell/salt-lab\";\nimport { Button } from \"@salt-ds/core\";\nimport { ExportIcon } from \"@salt-ds/icons\";\nimport {\n ForwardedRef,\n forwardRef,\n HTMLAttributes,\n useCallback,\n useEffect,\n useState,\n} from \"react\";\nimport { getLayoutHistory, LayoutHistoryItem } from \"../get-layout-history\";\nimport { logout } from \"../login\";\nimport { VuuUser } from \"../shell\";\n\nimport \"./UserPanel.css\";\n\nconst byLastUpdate = (\n { lastUpdate: l1 }: LayoutHistoryItem,\n { lastUpdate: l2 }: LayoutHistoryItem\n) => {\n return l2 === l1 ? 0 : l2 < l1 ? -1 : 1;\n};\n\ntype HistoryEntry = {\n id: string;\n label: string;\n lastUpdate: number;\n};\n\nconst HistoryListItem = (props: ListItemProps<HistoryEntry>) => {\n return <ListItem {...props} />;\n};\n\nexport interface UserPanelProps extends HTMLAttributes<HTMLDivElement> {\n loginUrl?: string;\n onNavigate: (id: string) => void;\n user: VuuUser;\n layoutId: string;\n}\n\nexport const UserPanel = forwardRef(function UserPanel(\n { loginUrl, onNavigate, user, layoutId = \"latest\" }: UserPanelProps,\n forwardedRef: ForwardedRef<HTMLDivElement>\n) {\n const [history, setHistory] = useState<HistoryEntry[]>([]);\n\n useEffect(() => {\n async function getHistory() {\n const history = await getLayoutHistory(user);\n const sortedHistory = history\n .filter((item) => item.id !== \"latest\")\n .sort(byLastUpdate)\n .map<HistoryEntry>(({ id, lastUpdate }) => ({\n lastUpdate,\n id,\n label: `Saved at ${formatDate(new Date(lastUpdate), \"kk:mm:ss\")}`,\n }));\n console.log({ sortedHistory });\n setHistory(sortedHistory);\n }\n\n getHistory();\n }, [user]);\n\n const handleHisorySelected = useCallback(\n (evt, selected) => {\n if (selected) {\n onNavigate(selected.id);\n }\n },\n [onNavigate]\n );\n\n const handleLogout = useCallback(() => {\n logout(loginUrl);\n }, [loginUrl]);\n\n const selected =\n history.length === 0\n ? null\n : layoutId === \"latest\"\n ? history[0]\n : history.find((i) => i.id === layoutId);\n\n return (\n <div className=\"vuuUserPanel\" ref={forwardedRef}>\n <List<HistoryEntry>\n ListItem={HistoryListItem}\n className=\"vuuUserPanel-history\"\n onSelect={handleHisorySelected}\n selected={selected}\n source={history}\n />\n <div className=\"vuuUserPanel-buttonBar\">\n <Button aria-label=\"logout\" onClick={handleLogout}>\n <ExportIcon /> Logout\n </Button>\n </div>\n </div>\n );\n});\n", "import { VuuUser } from \"./shell\";\n\nexport interface LayoutHistoryItem {\n user: string;\n id: string;\n uniqueId: string;\n lastUpdate: number;\n}\n\nexport const getLayoutHistory = async (\n user: VuuUser\n): Promise<LayoutHistoryItem[]> => {\n const history = await fetch(`api/vui/${user.username}`, {})\n .then((response) => {\n return response.ok ? response.json() : null;\n })\n .catch(() => {\n // TODO we should set a layout with a warning here\n console.log(\"error getting history\");\n });\n\n return history;\n};\n", "import {\n ToggleButton,\n ToggleButtonGroup,\n ToggleButtonGroupChangeEventHandler,\n} from \"@heswell/salt-lab\";\nimport cx from \"classnames\";\nimport { useControlled } from \"@salt-ds/core\";\nimport { HTMLAttributes, useCallback } from \"react\";\n\nimport \"./ThemeSwitch.css\";\n\nconst classBase = \"vuuThemeSwitch\";\n\nexport type ThemeMode = \"light\" | \"dark\";\n\nexport interface ThemeSwitchProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n defaultMode?: ThemeMode;\n mode?: ThemeMode;\n onChange: (mode: ThemeMode) => void;\n}\n\nconst modes: ThemeMode[] = [\"light\", \"dark\"];\n\nexport const ThemeSwitch = ({\n className: classNameProp,\n defaultMode: defaultModeProp,\n mode: modeProp,\n onChange,\n ...htmlAttributes\n}: ThemeSwitchProps) => {\n const [mode, setMode] = useControlled<ThemeMode>({\n controlled: modeProp,\n default: defaultModeProp ?? \"light\",\n name: \"ThemeSwitch\",\n state: \"mode\",\n });\n\n const selectedIndex = modes.indexOf(mode);\n\n const handleChangeSecondary: ToggleButtonGroupChangeEventHandler =\n useCallback(\n (_evt, index) => {\n const mode = modes[index];\n setMode(mode);\n onChange(mode);\n },\n [onChange, setMode]\n );\n const className = cx(classBase, classNameProp);\n return (\n <ToggleButtonGroup\n className={className}\n {...htmlAttributes}\n onChange={handleChangeSecondary}\n selectedIndex={selectedIndex}\n >\n <ToggleButton\n aria-label=\"alert\"\n tooltipText=\"Light Theme\"\n data-icon=\"light\"\n />\n <ToggleButton\n aria-label=\"home\"\n tooltipText=\"Dark Theme\"\n data-icon=\"dark\"\n />\n </ToggleButtonGroup>\n );\n};\n", "import { Dropdown, SelectionChangeHandler } from \"@heswell/salt-lab\";\nimport { DEFAULT_DENSITY, Density } from \"@salt-ds/core\";\nimport { HTMLAttributes, useCallback } from \"react\";\nimport cx from \"classnames\";\n\nconst classBase = \"vuuDensitySwitch\";\n\nconst densities:Density[] = [\"high\", \"medium\", \"low\", \"touch\"];\n\nexport interface DensitySwitchProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n defaultDensity?: Density;\n density?: Density;\n onDensityChange: (density: Density) => void;\n}\n\nexport const DensitySwitch = ({\n className: classNameProp,\n defaultDensity=DEFAULT_DENSITY,\n onDensityChange\n}:DensitySwitchProps) => {\n\n const handleSelectionChange:SelectionChangeHandler | string = useCallback((_event, selectedItem) => {\n onDensityChange(selectedItem);\n }, [onDensityChange])\n\n const className = cx(classBase, classNameProp);\n\n return (\n <Dropdown\n className={className}\n source={densities}\n defaultSelected={defaultDensity}\n onSelectionChange={handleSelectionChange}\n />\n )\n}"],
5
- "mappings": "skBAAA,IAAAA,GAAA,GAAAC,GAAAD,GAAA,0BAAAE,GAAA,YAAAC,EAAA,eAAAC,GAAA,UAAAC,GAAA,yBAAAC,EAAA,gBAAAC,EAAA,8BAAAC,GAAA,WAAAC,EAAA,oBAAAC,GAAA,oBAAAC,KAAA,eAAAC,GAAAZ,ICAA,IAAAa,EAA2C,oBAC3CC,EAAe,yBAwCb,IAAAC,EAAA,6BA5BWC,GAAuB,CAAC,CAAE,iBAAAC,EAAkB,UAAAC,EAAW,QAAAC,EAAU,OAAQ,GAAGC,CAAK,IAA6B,CAC1H,GAAM,CAACC,EAAWC,CAAY,KAAI,YAAiB,qBAAqB,KACxE,aAAU,IAAM,CACf,OAAOL,EAAkB,CACxB,IAAK,YACL,IAAK,cACJK,EAAa,iBAAiB,EAC9B,MACD,IAAK,aACJA,EAAa,qBAAqB,EAClC,MACD,IAAK,eACJA,EAAa,uBAAuB,EACpC,MACD,QACC,KACF,CACD,EAAG,CAACL,CAAgB,CAAC,EAErB,IAAMM,EAAa,EAAAC,QAAM,cACxBL,EACA,CACC,GAAGC,EACH,aAAW,EAAAK,SAAG,oBAAqBJ,EAAWH,CAAS,CACxD,CACD,EAEA,SACC,mBACC,oBAAC,OAAI,UAAU,iCACb,UAAAK,KACD,QAAC,OAAI,UAAU,iBAAiB,qBAASN,EAAiB,YAAY,GAAE,GACzE,EACD,CAEF,EChDA,IAAAS,EAAgC,oBAChCC,GAAkC,8BCDlC,IAAAC,EAAkB,oBAqBVC,EAAA,6BAnBKC,EAAN,cAA4B,EAAAC,QAAM,SAAU,CACjD,YAAYC,EAAO,CACjB,MAAMA,CAAK,EACX,KAAK,MAAQ,CAAE,aAAc,IAAK,CACpC,CAEA,OAAO,yBAAyBC,EAAO,CAErC,MAAO,CAAE,aAAcA,EAAM,OAAQ,CACvC,CAEA,kBAAkBA,EAAOC,EAAW,CAElC,QAAQ,IAAID,EAAOC,CAAS,CAC9B,CAEA,QAAS,CACP,OAAI,KAAK,MAAM,gBAEX,oBACE,oBAAC,MAAG,iCAAqB,KACzB,OAAC,KAAG,cAAK,MAAM,aAAa,GAC9B,EAIG,KAAK,MAAM,QACpB,CACF,EC7B4B,IAAAC,GAAA,6BAAfC,GAAS,OAAM,QAAC,OAAI,UAAU,WAAW,mBAAO,ECDtD,IAAMC,GAAY,MAAOC,GAAiB,CAC/C,IAAMC,EAAY,IAAI,cACtB,OAAO,MAAMD,CAAI,EACd,KAAME,GAAMA,EAAE,KAAK,CAAC,EACpB,KAAMA,GAAMD,EAAU,QAAQC,CAAC,CAAC,CACrC,EHqC0B,IAAAC,EAAA,6BA3B1B,SAASC,GAA8C,CACrD,IAAAC,EACA,IAAAC,EACA,OAAAC,EACA,GAAGC,CACL,EAAyB,CACnBF,GAWFG,GAAUH,CAAG,EAAE,KAAMI,GAAe,CAClC,SAAS,mBAAqB,CAC5B,GAAG,SAAS,mBACZA,CACF,CACF,CAAC,EAEH,IAAMC,EAAc,EAAAC,QAAM,KAAK,IAAM,OAA0BP,EAAI,EACnE,SACE,OAACQ,EAAA,CACC,mBAAC,YAAS,YAAU,OAACC,GAAA,EAAO,EAC1B,mBAACH,EAAA,CAAa,GAAGH,EAAQ,GAAGD,EAAQ,EACtC,EACF,CAEJ,CAEO,IAAMQ,EAAU,EAAAH,QAAM,KAAKR,EAAU,EAC5CW,EAAQ,YAAc,aACtB,sBAAkB,UAAWA,EAAS,MAAM,EInD5C,IAAAC,EAAsD,iBACtDC,GAAuB,yBACvBC,EAAiC,6BAoC7B,IAAAC,EAAA,6BAhCEC,GAAY,gBAOLC,GAAa,CAAC,CAAE,SAAAC,CAAS,IAAuB,CAC3D,GAAM,CAACC,EAAUC,CAAW,KAAI,YAAS,EAAE,EACrC,CAACC,EAAUC,CAAW,KAAI,YAAS,EAAE,EAErCC,EAAQ,IAAM,CAClBL,EAASC,EAAUE,CAAQ,CAC7B,EAEMG,EAAiB,CACrBC,EACAC,IACG,CACHN,EAAYM,CAAK,CACnB,EAEMC,EAAiB,CACrBF,EACAC,IACG,CACHJ,EAAYI,CAAK,CACnB,EAEME,EAAcT,EAAS,KAAK,IAAM,IAAME,EAAS,KAAK,IAAM,GAElE,SACE,QAAC,OAAI,UAAWL,GACd,oBAAC,aAAU,MAAM,WAAW,MAAO,CAAE,MAAO,GAAI,EAC9C,mBAAC,SAAM,MAAOG,EAAU,GAAG,gBAAgB,SAAUK,EAAgB,EACvE,KAEA,OAAC,aAAU,MAAM,WAAW,MAAO,CAAE,MAAO,GAAI,EAC9C,mBAAC,SACC,KAAK,WACL,MAAOH,EACP,GAAG,gBACH,SAAUM,EACZ,EACF,KAEA,OAAC,WACC,UAAW,GAAGX,WACd,SAAU,CAACY,EACX,QAASL,EACT,QAAQ,MACT,iBAED,GACF,CAEJ,EC9DA,IAAAM,EAA+B,6BAElBC,GAA4B,IAAM,CAC7C,IAAMC,KAAW,kBAAe,cAAc,EACxCC,KAAQ,kBAAe,gBAAgB,EAC7C,MAAO,CAACD,EAAUC,CAAK,CACzB,EAEaC,GAAkB,CAACC,EAAW,gBAAkB,CAC3D,OAAO,SAAS,KAAOA,CACzB,EAEaC,EAAUD,GAAsB,CAC3C,SAAS,OAAS,0DAClB,SAAS,OAAS,4DAClBD,GAAgBC,CAAQ,CAC1B,EChBA,IAAAE,GAAgC,4BAChCC,EASO,iBCVP,IAAAC,EAAiD,iBAE3CC,GAAkB,CAACC,EAAMC,IAAkB,CAC/C,GAAM,CAACC,EAAQC,CAAU,KAAI,YAASF,CAAa,EAE7CG,EAAaF,GAAW,CAC5BC,EAAWD,CAAM,CACnB,EAEMG,KAAO,eACX,MAAOC,EAAK,WAAa,CACvB,MAAM,WAAWN,EAAK,YAAYM,IAAM,CAAC,CAAC,EACvC,KAAMC,GACEA,EAAS,GAAKA,EAAS,KAAK,EAAIN,CACxC,EACA,KAAKG,CAAS,EACd,MAAM,IAAM,CAEXA,EAAUH,CAAa,CACzB,CAAC,CACL,EACA,CAACA,EAAeD,EAAK,QAAQ,CAC/B,KAEA,aAAU,IAAM,CACdK,EAAK,CACP,EAAG,CAACA,CAAI,CAAC,EAET,IAAMG,KAAW,eACdC,GAAS,CACR,MAAM,WAAWT,EAAK,WAAY,CAChC,OAAQ,OACR,QAAS,CACP,eAAgB,kBAClB,EACA,KAAM,KAAK,UAAUS,CAAI,CAC3B,CAAC,EAAE,KAAMF,GACAA,EAAS,GAAKA,EAAS,KAAK,EAAIN,CACxC,CACH,EACA,CAACA,EAAeD,CAAI,CACtB,EAEMU,KAAiB,eACpBJ,GAAO,CACND,EAAKC,CAAE,CACT,EACA,CAACD,CAAI,CACP,EAEA,MAAO,CAACH,EAAQM,EAAUE,CAAc,CAC1C,EAEOC,GAAQZ,GCnDf,IAAAa,EAAmE,iBAkC/DC,EAAA,6BAxBEC,GAAgB,CAAC,EAEjBC,KAAe,iBAAiCD,EAAa,EAO7DE,GAAW,CAAC,CAChB,SAAAC,EACA,QAAAC,EACA,iBAAAC,CACF,IAIM,CAEJ,IAAMC,EAAgB,CACpB,GAAGD,EACH,GAAGD,CACL,EACA,SACE,OAACH,EAAa,SAAb,CAAsB,MAAOK,EAC3B,SAAAH,EACH,CAEJ,EAEaI,EAAuB,CAAC,CACnC,SAAAJ,EACA,MAAAK,CACF,OAEI,OAACP,EAAa,SAAb,CACE,SAACG,MACA,OAACF,GAAA,CAAS,QAASM,EAAO,iBAAkBJ,EACzC,SAAAD,EACH,EAEJ,EAISM,GAAkB,OACtB,cAAWR,CAAY,EF7ChC,IAAAS,GAAe,yBAEfC,EAOO,8BGtBP,IAAAC,EAA4C,iBCA5C,IAAAC,GAAuB,yBACvBC,GAA6B,6BAC7BC,GAA8B,0BCF9B,IAAAC,GAA2B,6BAC3BC,EAA8C,6BAC9CC,GAAuB,yBACvBC,GAA2B,0BAC3BC,EAOO,iBCFA,IAAMC,GAAmB,MAC9BC,GAEgB,MAAM,MAAM,WAAWA,EAAK,WAAY,CAAC,CAAC,EACvD,KAAMC,GACEA,EAAS,GAAKA,EAAS,KAAK,EAAI,IACxC,EACA,MAAM,IAAM,CAEX,QAAQ,IAAI,uBAAuB,CACrC,CAAC,EDaI,IAAAC,EAAA,6BAdHC,GAAe,CACnB,CAAE,WAAYC,CAAG,EACjB,CAAE,WAAYC,CAAG,IAEVA,IAAOD,EAAK,EAAIC,EAAKD,EAAK,GAAK,EASlCE,GAAmBC,MAChB,OAAC,YAAU,GAAGA,EAAO,EAUjBC,MAAY,cAAW,SAClC,CAAE,SAAAC,EAAU,WAAAC,EAAY,KAAAC,EAAM,SAAAC,EAAW,QAAS,EAClDC,EACA,CACA,GAAM,CAACC,EAASC,CAAU,KAAI,YAAyB,CAAC,CAAC,KAEzD,aAAU,IAAM,CACd,eAAeC,GAAa,CAE1B,IAAMC,GADU,MAAMC,GAAiBP,CAAI,GAExC,OAAQQ,GAASA,EAAK,KAAO,QAAQ,EACrC,KAAKhB,EAAY,EACjB,IAAkB,CAAC,CAAE,GAAAiB,EAAI,WAAAC,CAAW,KAAO,CAC1C,WAAAA,EACA,GAAAD,EACA,MAAO,eAAY,eAAW,IAAI,KAAKC,CAAU,EAAG,UAAU,GAChE,EAAE,EACJ,QAAQ,IAAI,CAAE,cAAAJ,CAAc,CAAC,EAC7BF,EAAWE,CAAa,CAC1B,CAEAD,EAAW,CACb,EAAG,CAACL,CAAI,CAAC,EAET,IAAMW,KAAuB,eAC3B,CAACC,EAAKC,IAAa,CACbA,GACFd,EAAWc,EAAS,EAAE,CAE1B,EACA,CAACd,CAAU,CACb,EAEMe,KAAe,eAAY,IAAM,CACrCC,EAAOjB,CAAQ,CACjB,EAAG,CAACA,CAAQ,CAAC,EAEPe,EACJV,EAAQ,SAAW,EACf,KACAF,IAAa,SACbE,EAAQ,CAAC,EACTA,EAAQ,KAAMa,GAAMA,EAAE,KAAOf,CAAQ,EAE3C,SACE,QAAC,OAAI,UAAU,eAAe,IAAKC,EACjC,oBAAC,QACC,SAAUP,GACV,UAAU,uBACV,SAAUgB,EACV,SAAUE,EACV,OAAQV,EACV,KACA,OAAC,OAAI,UAAU,yBACb,oBAAC,WAAO,aAAW,SAAS,QAASW,EACnC,oBAAC,gBAAW,EAAE,WAChB,EACF,GACF,CAEJ,CAAC,ED5EG,IAAAG,EAAA,6BAXSC,GAAc,CAAC,CAC1B,SAAAC,EACA,SAAAC,EACA,WAAAC,EACA,KAAAC,CACF,OAMI,QAAC,iBAAa,UAAU,iBAAiB,UAAU,aACjD,oBAAC,WAAO,QAAQ,YACd,mBAAC,mBAAc,EACjB,KACA,OAACC,GAAA,CACC,SAAUJ,EACV,SAAUC,EACV,WAZkBI,GAAe,CACrCH,EAAWG,CAAE,CACf,EAWM,KAAMF,EACR,GACF,EGpCJ,IAAAG,EAIO,6BACPC,GAAe,yBACfC,GAA8B,yBAC9BC,GAA4C,iBA4CxC,IAAAC,EAAA,6BAxCEC,GAAY,iBAWZC,GAAqB,CAAC,QAAS,MAAM,EAE9BC,EAAc,CAAC,CAC1B,UAAWC,EACX,YAAaC,EACb,KAAMC,EACN,SAAAC,EACA,GAAGC,CACL,IAAwB,CACtB,GAAM,CAACC,EAAMC,CAAO,KAAI,kBAAyB,CAC/C,WAAYJ,EACZ,QAASD,GAAA,KAAAA,EAAmB,QAC5B,KAAM,cACN,MAAO,MACT,CAAC,EAEKM,EAAgBT,GAAM,QAAQO,CAAI,EAElCG,KACJ,gBACE,CAACC,EAAMC,IAAU,CACf,IAAML,EAAOP,GAAMY,CAAK,EACxBJ,EAAQD,CAAI,EACZF,EAASE,CAAI,CACf,EACA,CAACF,EAAUG,CAAO,CACpB,EACIK,KAAY,GAAAC,SAAGf,GAAWG,CAAa,EAC7C,SACE,QAAC,qBACC,UAAWW,EACV,GAAGP,EACJ,SAAUI,EACV,cAAeD,EAEf,oBAAC,gBACC,aAAW,QACX,YAAY,cACZ,YAAU,QACZ,KACA,OAAC,gBACC,aAAW,OACX,YAAY,aACZ,YAAU,OACZ,GACF,CAEJ,EJjEA,IAAAM,GAAe,yBKJf,IAAAC,GAAiD,6BACjDC,GAAyC,yBACzCC,GAA4C,iBAC5CC,GAAe,yBA0BXC,GAAA,6BAxBEC,GAAY,mBAEZC,GAAsB,CAAC,OAAQ,SAAU,MAAO,OAAO,EAShDC,GAAgB,CAAC,CAC5B,UAAWC,EACX,eAAAC,EAAe,mBACf,gBAAAC,CACF,IAAyB,CAEvB,IAAMC,KAAwD,gBAAY,CAACC,EAAQC,IAAiB,CAClGH,EAAgBG,CAAY,CAC9B,EAAG,CAACH,CAAe,CAAC,EAEdI,KAAY,GAAAC,SAAGV,GAAWG,CAAa,EAE7C,SACE,QAAC,aACD,UAAWM,EACX,OAAQR,GACR,gBAAiBG,EACjB,kBAAmBE,EACnB,CAEJ,ELQI,IAAAK,EAAA,6BAlCEC,GAAY,eAYLC,GAAY,CAAC,CACxB,UAAWC,EACX,SAAAC,EACA,SAAAC,EACA,WAAAC,EACA,cAAAC,EACA,UAAAC,EAAY,QACZ,gBAAAC,EACA,QAAAC,EAAQ,SACR,KAAAC,EACA,GAAGC,CACL,IAAsB,CACpB,IAAMC,KAAY,GAAAC,SAAGb,GAAWE,EAAe,gBAAgBO,GAAS,EAClEK,KAAoB,eACvBC,GAAoBT,GAAA,YAAAA,EAAgBS,GACrC,CAACT,CAAa,CAChB,EACMU,KAAsB,eACzBP,GAAqBD,GAAA,YAAAA,EAAkBC,GACxC,CAACD,CAAe,CAClB,EACA,SACE,QAAC,UAAO,UAAWI,EAAY,GAAGD,EAChC,oBAACM,EAAA,CAAY,YAAaV,EAAW,SAAUO,EAAmB,KAClE,OAACI,GAAA,CAAc,eAAgBT,EAAS,gBAAiBO,EAAqB,KAC9E,OAACG,GAAA,CACC,SAAUhB,EACV,SAAUC,EACV,WAAYC,EACZ,KAAMK,EACR,GACF,CAEJ,EHkFU,IAAAU,EAAA,6BArGJC,GAAgB,CACpB,KAAM,OACN,MAAO,CACL,MAAO,CAAE,OAAQ,kBAAmB,CACtC,EACA,SAAU,CACR,CACE,MAAO,CACL,UAAW,6BACb,EACA,KAAM,aACR,CACF,CACF,EAYaC,GAAQ,CAAC,CACpB,SAAAC,EACA,UAAWC,EACX,cAAAC,EAAgBJ,GAChB,cAAAK,EACA,SAAAC,EACA,UAAAC,EACA,KAAAC,EACA,GAAGC,CACL,IAAkB,CAChB,IAAMC,KAAU,UAAuB,IAAI,EACrC,CAACC,EAASC,CAAU,KAAI,YAAkB,QAAQ,EAClDC,KAAc,UAAuB,IAAI,EACzC,CAACC,EAAMC,CAAO,KAAI,YAAS,EAAK,EAChCC,KAAW,UAAO,QAAQ,EAE1B,CAACC,EAAQC,EAAiBC,CAAc,EAAIC,GAChDZ,EACAJ,CACF,EAEMiB,MAAqB,eACxBJ,GAAW,CACVC,EAAgBD,CAAM,CACxB,EACA,CAACC,CAAe,CAClB,EAEMI,MAAoB,eAAaC,GAAoB,CACrDb,EAAQ,UACVA,EAAQ,QAAQ,QAAQ,KAAOa,EAEnC,EAAG,CAAC,CAAC,EAECC,MAAsB,eACzBb,GAAqB,CACpBC,EAAWD,CAAO,CACpB,EACA,CAACC,CAAU,CACb,EAEMa,GAAqBC,GAA+B,CAtG5D,IAAAC,EAuGI,IAAMC,GAASF,EAAE,QACZC,EAAAd,EAAY,UAAZ,MAAAc,EAAqB,SAASC,KACjCb,EAAQ,CAACD,CAAI,CAEjB,EAEMe,MAAiB,eACpBC,GAAO,CACNd,EAAS,QAAUc,EACnBX,EAAeW,CAAE,CACnB,EACA,CAACX,CAAc,CACjB,KAEA,aAAU,IAAM,CACVZ,GAAaC,EAAK,UACpB,oBAAgBD,EAAWC,EAAK,KAAK,CAEzC,EAAG,CAACD,EAAWC,EAAK,KAAK,CAAC,EAE1B,IAAMuB,GAAa,IAAM,CACvB,IAAMC,EAA0B,CAAC,EACjC,OAAI3B,GACF2B,EAAQ,QACN,OAAC,UAEC,QAASP,GACT,KAAMX,EACN,SAAS,OACT,OAAM,GACN,SAAQ,GACR,SAAU,IACV,aAAa,MAEb,mBAAC,QACC,UAAU,mBACV,GAAG,iBAEH,IAAKD,EACL,MAAO,CAAE,OAAQ,MAAO,EAEvB,SAAAR,GAJG,aAKN,GAjBI,YAkBN,CACF,EAGK2B,CACT,EAEMC,MAAY,GAAAC,SAChB,WACA/B,EACA,aACA,gBAAgBQ,GAClB,EAEA,SAEE,QAACwB,EAAA,CAAqB,MAAO,OAC3B,oBAAC,kBAAe,OAAQlB,EAAQ,eAAgBI,GAC9C,mBAAC,mBACC,UAAWY,GACX,YAAU,QACV,IAAKvB,EACJ,GAAGD,EAEJ,oBAAC,WACC,UAAU,MACV,MAAO,CAAE,cAAe,SAAU,OAAQ,OAAQ,MAAO,MAAO,EAEhE,oBAAC2B,GAAA,CACC,SAAUpB,EAAS,QACnB,SAAUV,EACV,KAAME,EACN,WAAYqB,GACZ,cAAeP,GACf,gBAAiBE,GACnB,KACA,OAAC,SAAM,MAAO,CAAE,KAAM,CAAE,EACrB,SAAAO,GAAW,EAAE,UACZ,OAAC,mBACC,WAAU,GAEV,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAO,GADnC,cAEN,CACF,EACF,GACF,EACF,EACF,EACC7B,GACH,CAEJ",
6
- "names": ["src_exports", "__export", "ConnectionStatusIcon", "Feature", "LoginPanel", "Shell", "ShellContextProvider", "ThemeSwitch", "getAuthDetailsFromCookies", "logout", "redirectToLogin", "useShellContext", "__toCommonJS", "import_react", "import_classnames", "import_jsx_runtime", "ConnectionStatusIcon", "connectionStatus", "className", "element", "props", "classBase", "setClassBase", "statusIcon", "React", "cx", "import_react", "import_vuu_layout", "import_react", "import_jsx_runtime", "ErrorBoundary", "React", "props", "error", "errorInfo", "import_jsx_runtime", "Loader", "importCSS", "path", "container", "x", "import_jsx_runtime", "RawFeature", "url", "css", "params", "props", "importCSS", "styleSheet", "LazyFeature", "React", "ErrorBoundary", "Loader", "Feature", "import_react", "import_core", "import_salt_lab", "import_jsx_runtime", "classBase", "LoginPanel", "onSubmit", "username", "setUserName", "password", "setPassword", "login", "handleUsername", "_event", "value", "handlePassword", "dataIsValid", "import_vuu_utils", "getAuthDetailsFromCookies", "username", "token", "redirectToLogin", "loginUrl", "logout", "import_vuu_data", "import_react", "import_react", "useLayoutConfig", "user", "defaultLayout", "layout", "_setLayout", "setLayout", "load", "id", "response", "saveData", "data", "loadLayoutById", "use_layout_config_default", "import_react", "import_jsx_runtime", "defaultConfig", "ShellContext", "Provider", "children", "context", "inheritedContext", "mergedContext", "ShellContextProvider", "value", "useShellContext", "import_classnames", "import_vuu_layout", "import_react", "import_core", "import_salt_lab", "import_icons", "import_vuu_utils", "import_salt_lab", "import_core", "import_icons", "import_react", "getLayoutHistory", "user", "response", "import_jsx_runtime", "byLastUpdate", "l1", "l2", "HistoryListItem", "props", "UserPanel", "loginUrl", "onNavigate", "user", "layoutId", "forwardedRef", "history", "setHistory", "getHistory", "sortedHistory", "getLayoutHistory", "item", "id", "lastUpdate", "handleHisorySelected", "evt", "selected", "handleLogout", "logout", "i", "import_jsx_runtime", "UserProfile", "layoutId", "loginUrl", "onNavigate", "user", "UserPanel", "id", "import_salt_lab", "import_classnames", "import_core", "import_react", "import_jsx_runtime", "classBase", "modes", "ThemeSwitch", "classNameProp", "defaultModeProp", "modeProp", "onChange", "htmlAttributes", "mode", "setMode", "selectedIndex", "handleChangeSecondary", "_evt", "index", "className", "cx", "import_classnames", "import_salt_lab", "import_core", "import_react", "import_classnames", "import_jsx_runtime", "classBase", "densities", "DensitySwitch", "classNameProp", "defaultDensity", "onDensityChange", "handleSelectionChange", "_event", "selectedItem", "className", "cx", "import_jsx_runtime", "classBase", "AppHeader", "classNameProp", "layoutId", "loginUrl", "onNavigate", "onSwitchTheme", "themeMode", "onDensitySwitch", "density", "user", "htmlAttributes", "className", "cx", "handleSwitchTheme", "mode", "handleDensitySwitch", "ThemeSwitch", "DensitySwitch", "UserProfile", "import_jsx_runtime", "warningLayout", "Shell", "children", "classNameProp", "defaultLayout", "leftSidePanel", "loginUrl", "serverUrl", "user", "htmlAttributes", "rootRef", "density", "setDensity", "paletteView", "open", "setOpen", "layoutId", "layout", "setLayoutConfig", "loadLayoutById", "use_layout_config_default", "handleLayoutChange", "handleSwitchTheme", "mode", "handleDensitySwitch", "handleDrawerClick", "e", "_a", "target", "handleNavigate", "id", "getDrawers", "drawers", "className", "cx", "ShellContextProvider", "AppHeader"]
3
+ "sources": ["../../../packages/vuu-shell/src/index.ts", "../../../packages/vuu-shell/src/connection-status/ConnectionStatusIcon.tsx", "../../../packages/vuu-shell/src/density-switch/DensitySwitch.tsx", "../../../packages/vuu-shell/src/feature/Feature.tsx", "../../../packages/vuu-shell/src/feature/ErrorBoundary.jsx", "../../../packages/vuu-shell/src/feature/Loader.tsx", "../../../packages/vuu-shell/src/login/LoginPanel.tsx", "../../../packages/vuu-shell/src/login/login-utils.ts", "../../../packages/vuu-shell/src/shell.tsx", "../../../packages/vuu-shell/src/ShellContextProvider.tsx", "../../../packages/vuu-shell/src/use-layout-config.js", "../../../packages/vuu-shell/src/app-header/AppHeader.tsx", "../../../packages/vuu-shell/src/user-profile/UserProfile.tsx", "../../../packages/vuu-shell/src/user-profile/UserPanel.tsx", "../../../packages/vuu-shell/src/get-layout-history.ts", "../../../packages/vuu-shell/src/theme-switch/ThemeSwitch.tsx", "../../../packages/vuu-shell/src/theme-provider/ThemeProvider.tsx"],
4
+ "sourcesContent": ["export * from \"./connection-status\";\nexport * from \"./density-switch\";\nexport * from \"./feature\";\nexport * from \"./login\";\nexport * from \"./shell\";\nexport * from \"./shellTypes\";\nexport * from \"./ShellContextProvider\";\nexport * from \"./theme-provider\";\nexport * from \"./theme-switch\";\n", "import React, { useEffect, useState } from 'react';\nimport cx from 'classnames';\nimport './ConnectionStatusIcon.css';\n\ntype connectionStatus = 'connected' | 'reconnected' | 'connecting' | 'disconnected';\n\ninterface ConnectionStatusProps {\n\tconnectionStatus: connectionStatus\n\tclassName?: string;\n\tprops?: unknown;\n\telement?: string;\n}\n\nexport const ConnectionStatusIcon = ({ connectionStatus, className, element = 'span', ...props}: ConnectionStatusProps) => {\n\tconst [classBase, setClassBase] = useState<string>('vuuConnectingStatus');\n\tuseEffect(() => {\n\t\tswitch(connectionStatus) {\n\t\t\tcase 'connected':\n\t\t\tcase 'reconnected':\n\t\t\t\tsetClassBase('vuuActiveStatus');\n\t\t\t\tbreak;\n\t\t\tcase 'connecting':\n\t\t\t\tsetClassBase('vuuConnectingStatus');\n\t\t\t\tbreak;\n\t\t\tcase 'disconnected':\n\t\t\t\tsetClassBase('vuuDisconnectedStatus');\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}, [connectionStatus]);\n\n\tconst statusIcon = React.createElement (\n\t\telement,\n\t\t{\n\t\t\t...props,\n\t\t\tclassName: cx('vuuStatus vuuIcon', classBase, className)\n\t\t},\n\t)\n\n\treturn (\n\t\t<>\n\t\t\t<div className='vuuStatus-container salt-theme'>\n\t\t\t\t{statusIcon}\n\t\t\t\t<div\tclassName='vuuStatus-text'>Status: {connectionStatus.toUpperCase()}</div>\n\t\t\t</div>\n\t\t</>\n\t)\n}", "import { Dropdown } from \"@heswell/salt-lab\";\nimport { Density } from \"@salt-ds/core\";\nimport { HTMLAttributes, useCallback } from \"react\";\nimport cx from \"classnames\";\n\nconst classBase = \"vuuDensitySwitch\";\n\nconst densities:Density[] = [\"high\", \"medium\", \"low\", \"touch\"];\nconst DEFAULT_DENSITY = \"high\";\n\nexport interface DensitySwitchProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n defaultDensity?: Density;\n density?: Density;\n onDensityChange: (density: Density) => void;\n}\n\nexport const DensitySwitch = ({\n className: classNameProp,\n defaultDensity=DEFAULT_DENSITY,\n onDensityChange,\n}:DensitySwitchProps) => {\n const handleSelectionChange = useCallback((_event, selectedItem) => {\n onDensityChange(selectedItem);\n }, [onDensityChange])\n\n const className = cx(classBase, classNameProp);\n\n return (\n <Dropdown\n className={className}\n source={densities}\n defaultSelected={defaultDensity}\n onSelectionChange={handleSelectionChange}\n />\n )\n}", "import React, { Suspense } from \"react\";\nimport { registerComponent } from \"@vuu-ui/vuu-layout\";\nimport { ErrorBoundary } from \"./ErrorBoundary\";\nimport { Loader } from \"./Loader\";\n// import { importCSS } from \"./css-module-loader\";\n\nexport interface FeatureProps<Params extends object | undefined = undefined> {\n height?: number;\n url: string;\n css?: string;\n width?: number;\n params: Params;\n}\n\nfunction RawFeature<Params extends object | undefined>({\n url,\n css,\n params,\n ...props\n}: FeatureProps<Params>) {\n if (css) {\n import(/* @vite-ignore */ css, { assert: { type: \"css\" } }).then(\n (cssModule) => {\n document.adoptedStyleSheets = [\n ...document.adoptedStyleSheets,\n cssModule.default,\n ];\n }\n );\n // Polyfill until vite build supports import assertions\n // Note: already fully supported in esbuild, so vite dev\n // importCSS(css).then((styleSheet) => {\n // document.adoptedStyleSheets = [\n // ...document.adoptedStyleSheets,\n // styleSheet,\n // ];\n // });\n }\n const LazyFeature = React.lazy(() => import(/* @vite-ignore */ url));\n return (\n <ErrorBoundary>\n <Suspense fallback={<Loader />}>\n <LazyFeature {...props} {...params} />\n </Suspense>\n </ErrorBoundary>\n );\n}\n\nexport const Feature = React.memo(RawFeature);\nFeature.displayName = \"Feature\";\nregisterComponent(\"Feature\", Feature, \"view\");\n", "import React from 'react';\n// TODO\nexport class ErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = { errorMessage: null };\n }\n\n static getDerivedStateFromError(error) {\n // Update state so the next render will show the fallback UI.\n return { errorMessage: error.message };\n }\n\n componentDidCatch(error, errorInfo) {\n // You can also log the error to an error reporting service\n console.log(error, errorInfo);\n }\n\n render() {\n if (this.state.errorMessage) {\n return (\n <>\n <h1>Something went wrong.</h1>\n <p>{this.state.errorMessage}</p>\n </>\n );\n }\n\n return this.props.children;\n }\n}\n", "// TODO\nexport const Loader = () => <div className=\"hwLoader\">loading</div>;\n", "import { ChangeEvent, HTMLAttributes, useState } from \"react\";\nimport { Button } from \"@salt-ds/core\";\nimport { FormField, Input } from \"@heswell/salt-lab\";\n\nimport \"./LoginPanel.css\";\n\nconst classBase = \"vuuLoginPanel\";\n\nexport interface LoginPanelProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onSubmit\"> {\n onSubmit: (username: string, password: string) => void;\n}\n\nexport const LoginPanel = ({ onSubmit }: LoginPanelProps) => {\n const [username, setUserName] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n\n const login = () => {\n onSubmit(username, password);\n };\n\n const handleUsername = (\n _event: ChangeEvent<HTMLInputElement>,\n value: string\n ) => {\n setUserName(value);\n };\n\n const handlePassword = (\n _event: ChangeEvent<HTMLInputElement>,\n value: string\n ) => {\n setPassword(value);\n };\n\n const dataIsValid = username.trim() !== \"\" && password.trim() !== \"\";\n\n return (\n <div className={classBase}>\n <FormField label=\"Username\" style={{ width: 200 }}>\n <Input value={username} id=\"text-username\" onChange={handleUsername} />\n </FormField>\n\n <FormField label=\"Password\" style={{ width: 200 }}>\n <Input\n type=\"password\"\n value={password}\n id=\"text-password\"\n onChange={handlePassword}\n />\n </FormField>\n\n <Button\n className={`${classBase}-login`}\n disabled={!dataIsValid}\n onClick={login}\n variant=\"cta\"\n >\n Login\n </Button>\n </div>\n );\n};\n", "import { getCookieValue } from \"@vuu-ui/vuu-utils\";\n\nexport const getAuthDetailsFromCookies = () => {\n const username = getCookieValue(\"vuu-username\");\n const token = getCookieValue(\"vuu-auth-token\");\n return [username, token];\n};\n\nexport const redirectToLogin = (loginUrl = \"/login.html\") => {\n window.location.href = loginUrl;\n};\n\nexport const logout = (loginUrl?: string) => {\n document.cookie = \"vuu-username= ; expires = Thu, 01 Jan 1970 00:00:00 GMT\";\n document.cookie = \"vuu-auth-token= ; expires = Thu, 01 Jan 1970 00:00:00 GMT\";\n redirectToLogin(loginUrl);\n};\n", "import { connectToServer } from \"@vuu-ui/vuu-data\";\nimport cx from \"classnames\";\nimport {\n HTMLAttributes,\n MouseEvent,\n ReactElement,\n ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { ShellContextProvider } from \"./ShellContextProvider\";\nimport useLayoutConfig from \"./use-layout-config\";\nimport {\n DockLayout,\n DraggableLayout,\n Drawer,\n Flexbox,\n LayoutProvider,\n View,\n} from \"@vuu-ui/vuu-layout\";\nimport { LayoutJSON } from \"@vuu-ui/vuu-layout/src/layout-reducer\";\nimport { AppHeader } from \"./app-header\";\nimport { ThemeMode } from \"./theme-provider\";\n\nimport \"./shell.css\";\n\nexport type VuuUser = {\n username: string;\n token: string;\n};\n\nconst warningLayout = {\n type: \"View\",\n props: {\n style: { height: \"calc(100% - 6px)\" },\n },\n children: [\n {\n props: {\n className: \"vuuShell-warningPlaceholder\",\n },\n type: \"Placeholder\",\n },\n ],\n};\n\nexport interface ShellProps extends HTMLAttributes<HTMLDivElement> {\n children?: ReactNode;\n defaultLayout?: LayoutJSON;\n leftSidePanel?: ReactElement;\n loginUrl?: string;\n // paletteConfig: any;\n serverUrl?: string;\n user: VuuUser;\n}\n\nexport const Shell = ({\n children,\n className: classNameProp,\n defaultLayout = warningLayout,\n leftSidePanel,\n loginUrl,\n serverUrl,\n user,\n ...htmlAttributes\n}: ShellProps) => {\n const rootRef = useRef<HTMLDivElement>(null);\n const paletteView = useRef<HTMLDivElement>(null);\n const [open, setOpen] = useState(false);\n const layoutId = useRef(\"latest\");\n\n const [layout, setLayoutConfig, loadLayoutById] = useLayoutConfig(\n user,\n defaultLayout\n );\n\n const handleLayoutChange = useCallback(\n (layout) => {\n setLayoutConfig(layout);\n },\n [setLayoutConfig]\n );\n\n const handleSwitchTheme = useCallback((mode: ThemeMode) => {\n if (rootRef.current) {\n rootRef.current.dataset.mode = mode;\n }\n }, []);\n\n const handleDrawerClick = (e: MouseEvent<HTMLElement>) => {\n const target = e.target as HTMLElement;\n if (!paletteView.current?.contains(target)) {\n setOpen(!open);\n }\n };\n\n const handleNavigate = useCallback(\n (id) => {\n layoutId.current = id;\n loadLayoutById(id);\n },\n [loadLayoutById]\n );\n\n useEffect(() => {\n if (serverUrl && user.token) {\n connectToServer(serverUrl, user.token);\n }\n }, [serverUrl, user.token]);\n\n const getDrawers = () => {\n const drawers: ReactElement[] = [];\n if (leftSidePanel) {\n drawers.push(\n <Drawer\n key=\"left-panel\"\n onClick={handleDrawerClick}\n open={open}\n position=\"left\"\n inline\n peekaboo\n sizeOpen={200}\n toggleButton=\"end\"\n >\n <View\n className=\"vuuShell-palette\"\n id=\"vw-app-palette\"\n key=\"app-palette\"\n ref={paletteView}\n style={{ height: \"100%\" }}\n >\n {leftSidePanel}\n </View>\n </Drawer>\n );\n }\n\n return drawers;\n };\n\n const className = cx(\n \"vuuShell\",\n classNameProp,\n \"salt-theme\",\n \"salt-density-high\"\n );\n\n return (\n // ShellContext TBD\n <ShellContextProvider value={undefined}>\n <LayoutProvider layout={layout} onLayoutChange={handleLayoutChange}>\n <DraggableLayout\n className={className}\n data-mode=\"light\"\n ref={rootRef}\n {...htmlAttributes}\n >\n <Flexbox\n className=\"App\"\n style={{ flexDirection: \"column\", height: \"100%\", width: \"100%\" }}\n >\n <AppHeader\n layoutId={layoutId.current}\n loginUrl={loginUrl}\n user={user}\n onNavigate={handleNavigate}\n onSwitchTheme={handleSwitchTheme}\n />\n <DockLayout style={{ flex: 1 }}>\n {getDrawers().concat(\n <DraggableLayout\n dropTarget\n key=\"main-content\"\n style={{ width: \"100%\", height: \"100%\" }}\n />\n )}\n </DockLayout>\n </Flexbox>\n </DraggableLayout>\n </LayoutProvider>\n {children}\n </ShellContextProvider>\n );\n};\n", "import { MenuRpcResponse } from \"@vuu-ui/vuu-data\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { createContext, ReactElement, ReactNode, useContext } from \"react\";\n\nexport interface ShellContextProps {\n getDefaultColumnConfig?: (\n tableName: string,\n columnName: string\n ) => Partial<ColumnDescriptor>;\n handleRpcResponse?: (response?: MenuRpcResponse) => void;\n}\n\nconst defaultConfig = {};\n\nconst ShellContext = createContext<ShellContextProps>(defaultConfig);\n\nexport interface ShellProviderProps {\n children: ReactNode;\n value?: ShellContextProps;\n}\n\nconst Provider = ({\n children,\n context,\n inheritedContext,\n}: {\n children: ReactNode;\n context?: ShellContextProps;\n inheritedContext?: ShellContextProps;\n}) => {\n // TODO functions provided at multiple levels must be merged\n const mergedContext = {\n ...inheritedContext,\n ...context,\n };\n return (\n <ShellContext.Provider value={mergedContext}>\n {children}\n </ShellContext.Provider>\n );\n};\n\nexport const ShellContextProvider = ({\n children,\n value,\n}: ShellProviderProps): ReactElement => {\n return (\n <ShellContext.Consumer>\n {(context) => (\n <Provider context={value} inheritedContext={context}>\n {children}\n </Provider>\n )}\n </ShellContext.Consumer>\n );\n};\n\nexport const useShellContext = () => {\n return useContext(ShellContext);\n};\n", "import { useCallback, useEffect, useState } from \"react\";\n\nconst useLayoutConfig = (user, defaultLayout) => {\n const [layout, _setLayout] = useState(defaultLayout);\n\n const setLayout = (layout) => {\n _setLayout(layout);\n };\n\n const load = useCallback(\n async (id = \"latest\") => {\n fetch(`api/vui/${user.username}/${id}`, {})\n .then((response) => {\n return response.ok ? response.json() : defaultLayout;\n })\n .then(setLayout)\n .catch(() => {\n // TODO we should set a layout with a warning here\n setLayout(defaultLayout);\n });\n },\n [defaultLayout, user.username]\n );\n\n useEffect(() => {\n load();\n }, [load]);\n\n const saveData = useCallback(\n (data) => {\n fetch(`api/vui/${user.username}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(data),\n }).then((response) => {\n return response.ok ? response.json() : defaultLayout;\n });\n },\n [defaultLayout, user]\n );\n\n const loadLayoutById = useCallback(\n (id) => {\n load(id);\n },\n [load]\n );\n\n return [layout, saveData, loadLayoutById];\n};\n\nexport default useLayoutConfig;\n", "import { HTMLAttributes, useCallback } from \"react\";\nimport { VuuUser } from \"../shell\";\nimport { UserProfile } from \"../user-profile\";\nimport { ThemeSwitch } from \"../theme-switch\";\nimport { ThemeMode } from \"../theme-provider\";\nimport cx from \"classnames\";\n\nimport \"./AppHeader.css\";\n\nconst classBase = \"vuuAppHeader\";\nexport interface AppHeaderProps extends HTMLAttributes<HTMLDivElement> {\n layoutId: string;\n loginUrl?: string;\n onNavigate: (id: string) => void;\n onSwitchTheme?: (mode: ThemeMode) => void;\n themeMode?: ThemeMode;\n user: VuuUser;\n}\n\nexport const AppHeader = ({\n className: classNameProp,\n layoutId,\n loginUrl,\n onNavigate,\n onSwitchTheme,\n themeMode = \"light\",\n user,\n ...htmlAttributes\n}: AppHeaderProps) => {\n const className = cx(classBase, classNameProp);\n const handleSwitchTheme = useCallback(\n (mode: ThemeMode) => onSwitchTheme?.(mode),\n [onSwitchTheme]\n );\n return (\n <header className={className} {...htmlAttributes}>\n <ThemeSwitch defaultMode={themeMode} onChange={handleSwitchTheme} />\n <UserProfile\n layoutId={layoutId}\n loginUrl={loginUrl}\n onNavigate={onNavigate}\n user={user}\n />\n </header>\n );\n};\n", "import { Button } from \"@salt-ds/core\";\nimport { DropdownBase } from \"@heswell/salt-lab\";\nimport { UserSolidIcon } from \"@salt-ds/icons\";\nimport { UserPanel } from \"./UserPanel\";\n\nimport \"./UserProfile.css\";\nimport { VuuUser } from \"../shell\";\n\nexport interface UserProfileProps {\n layoutId: string;\n loginUrl?: string;\n onNavigate: (id: string) => void;\n user: VuuUser;\n}\n\nexport const UserProfile = ({\n layoutId,\n loginUrl,\n onNavigate,\n user,\n}: UserProfileProps) => {\n const handleNavigate = (id: string) => {\n onNavigate(id);\n };\n\n return (\n <DropdownBase className=\"vuuUserProfile\" placement=\"bottom-end\">\n <Button variant=\"secondary\">\n <UserSolidIcon />\n </Button>\n <UserPanel\n layoutId={layoutId}\n loginUrl={loginUrl}\n onNavigate={handleNavigate}\n user={user}\n />\n </DropdownBase>\n );\n};\n", "import { formatDate } from \"@vuu-ui/vuu-utils\";\nimport { List, ListItem, ListItemProps } from \"@heswell/salt-lab\";\nimport { Button } from \"@salt-ds/core\";\nimport { ExportIcon } from \"@salt-ds/icons\";\nimport {\n ForwardedRef,\n forwardRef,\n HTMLAttributes,\n useCallback,\n useEffect,\n useState,\n} from \"react\";\nimport { getLayoutHistory, LayoutHistoryItem } from \"../get-layout-history\";\nimport { logout } from \"../login\";\nimport { VuuUser } from \"../shell\";\n\nimport \"./UserPanel.css\";\n\nconst byLastUpdate = (\n { lastUpdate: l1 }: LayoutHistoryItem,\n { lastUpdate: l2 }: LayoutHistoryItem\n) => {\n return l2 === l1 ? 0 : l2 < l1 ? -1 : 1;\n};\n\ntype HistoryEntry = {\n id: string;\n label: string;\n lastUpdate: number;\n};\n\nconst HistoryListItem = (props: ListItemProps<HistoryEntry>) => {\n return <ListItem {...props} />;\n};\n\nexport interface UserPanelProps extends HTMLAttributes<HTMLDivElement> {\n loginUrl?: string;\n onNavigate: (id: string) => void;\n user: VuuUser;\n layoutId: string;\n}\n\nexport const UserPanel = forwardRef(function UserPanel(\n { loginUrl, onNavigate, user, layoutId = \"latest\" }: UserPanelProps,\n forwardedRef: ForwardedRef<HTMLDivElement>\n) {\n const [history, setHistory] = useState<HistoryEntry[]>([]);\n\n useEffect(() => {\n async function getHistory() {\n const history = await getLayoutHistory(user);\n const sortedHistory = history\n .filter((item) => item.id !== \"latest\")\n .sort(byLastUpdate)\n .map<HistoryEntry>(({ id, lastUpdate }) => ({\n lastUpdate,\n id,\n label: `Saved at ${formatDate(new Date(lastUpdate), \"kk:mm:ss\")}`,\n }));\n console.log({ sortedHistory });\n setHistory(sortedHistory);\n }\n\n getHistory();\n }, [user]);\n\n const handleHisorySelected = useCallback(\n (evt, selected) => {\n if (selected) {\n onNavigate(selected.id);\n }\n },\n [onNavigate]\n );\n\n const handleLogout = useCallback(() => {\n logout(loginUrl);\n }, [loginUrl]);\n\n const selected =\n history.length === 0\n ? null\n : layoutId === \"latest\"\n ? history[0]\n : history.find((i) => i.id === layoutId);\n\n return (\n <div className=\"vuuUserPanel\" ref={forwardedRef}>\n <List<HistoryEntry>\n ListItem={HistoryListItem}\n className=\"vuuUserPanel-history\"\n onSelect={handleHisorySelected}\n selected={selected}\n source={history}\n />\n <div className=\"vuuUserPanel-buttonBar\">\n <Button aria-label=\"logout\" onClick={handleLogout}>\n <ExportIcon /> Logout\n </Button>\n </div>\n </div>\n );\n});\n", "import { VuuUser } from \"./shell\";\n\nexport interface LayoutHistoryItem {\n user: string;\n id: string;\n uniqueId: string;\n lastUpdate: number;\n}\n\nexport const getLayoutHistory = async (\n user: VuuUser\n): Promise<LayoutHistoryItem[]> => {\n const history = await fetch(`api/vui/${user.username}`, {})\n .then((response) => {\n return response.ok ? response.json() : null;\n })\n .catch(() => {\n // TODO we should set a layout with a warning here\n console.log(\"error getting history\");\n });\n\n return history;\n};\n", "import {\n ToggleButton,\n ToggleButtonGroup,\n ToggleButtonGroupChangeEventHandler,\n} from \"@heswell/salt-lab\";\nimport cx from \"classnames\";\nimport { useControlled } from \"@salt-ds/core\";\nimport { HTMLAttributes, useCallback } from \"react\";\n\nimport \"./ThemeSwitch.css\";\nimport { ThemeMode } from \"../theme-provider\";\n\nconst classBase = \"vuuThemeSwitch\";\nexport interface ThemeSwitchProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n defaultMode?: ThemeMode;\n mode?: ThemeMode;\n onChange: (mode: ThemeMode) => void;\n}\n\nconst modes: ThemeMode[] = [\"light\", \"dark\"];\n\nexport const ThemeSwitch = ({\n className: classNameProp,\n defaultMode: defaultModeProp,\n mode: modeProp,\n onChange,\n ...htmlAttributes\n}: ThemeSwitchProps) => {\n const [mode, setMode] = useControlled<ThemeMode>({\n controlled: modeProp,\n default: defaultModeProp ?? \"light\",\n name: \"ThemeSwitch\",\n state: \"mode\",\n });\n\n const selectedIndex = modes.indexOf(mode);\n\n const handleChangeSecondary: ToggleButtonGroupChangeEventHandler =\n useCallback(\n (_evt, index) => {\n const mode = modes[index];\n setMode(mode);\n onChange(mode);\n },\n [onChange, setMode]\n );\n const className = cx(classBase, classNameProp);\n return (\n <ToggleButtonGroup\n className={className}\n {...htmlAttributes}\n onChange={handleChangeSecondary}\n selectedIndex={selectedIndex}\n >\n <ToggleButton\n aria-label=\"alert\"\n tooltipText=\"Light Theme\"\n data-icon=\"light\"\n />\n <ToggleButton\n aria-label=\"home\"\n tooltipText=\"Dark Theme\"\n data-icon=\"dark\"\n />\n </ToggleButtonGroup>\n );\n};\n", "import React, {\n createContext,\n HTMLAttributes,\n ReactNode,\n ReactElement,\n isValidElement,\n cloneElement,\n useContext,\n} from \"react\";\nimport cx from \"classnames\";\n\nexport const DEFAULT_DENSITY: Density = \"medium\";\nexport const DEFAULT_THEME = \"salt-theme\";\nexport const DEFAULT_THEME_MODE: ThemeMode = \"light\";\n\nexport type Density = \"high\" | \"medium\" | \"low\" | \"touch\";\nexport type ThemeMode = \"light\" | \"dark\";\nexport type TargetElement = \"root\" | \"scope\" | \"child\";\n\nexport interface ThemeContextProps {\n density: Density;\n theme: string;\n themeMode: ThemeMode;\n}\n\nexport const ThemeContext = createContext<ThemeContextProps>({\n density: \"high\",\n theme: \"salt-theme\",\n themeMode: \"light\",\n});\n\nconst createThemedChildren = (\n children: ReactNode,\n theme: string,\n themeMode: ThemeMode,\n density: Density\n) => {\n if (isValidElement<HTMLAttributes<HTMLElement>>(children)) {\n return cloneElement(children, {\n className: cx(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n children.props?.className,\n theme,\n `salt-density-${density}`\n ),\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n \"data-mode\": themeMode,\n });\n } else {\n console.warn(\n `\\nThemeProvider can only apply CSS classes for theming to a single nested child element of the ThemeProvider.\n Wrap elements with a single container`\n );\n return children;\n }\n};\n\ninterface ThemeProviderProps {\n children: ReactElement;\n density?: Density;\n theme?: string;\n themeMode?: ThemeMode;\n applyClassesTo?: TargetElement;\n}\n\nexport const ThemeProvider = ({\n children,\n theme: themeProp,\n themeMode: themeModeProp,\n density: densityProp,\n}: ThemeProviderProps) => {\n const {\n density: inheritedDensity,\n themeMode: inheritedThemeMode,\n theme: inheritedTheme,\n } = useContext(ThemeContext);\n\n const density = densityProp ?? inheritedDensity ?? DEFAULT_DENSITY;\n const themeMode = themeModeProp ?? inheritedThemeMode ?? DEFAULT_THEME_MODE;\n const theme = themeProp ?? inheritedTheme ?? DEFAULT_THEME;\n const themedChildren = createThemedChildren(\n children,\n theme,\n themeMode,\n density\n );\n\n return (\n <ThemeContext.Provider value={{ themeMode, density, theme }}>\n {themedChildren}\n </ThemeContext.Provider>\n );\n};\n\nThemeProvider.displayName = \"ThemeProvider\";\n"],
5
+ "mappings": "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",
6
+ "names": ["src_exports", "__export", "ConnectionStatusIcon", "DEFAULT_DENSITY", "DEFAULT_THEME", "DEFAULT_THEME_MODE", "DensitySwitch", "Feature", "LoginPanel", "Shell", "ShellContextProvider", "ThemeContext", "ThemeProvider", "ThemeSwitch", "getAuthDetailsFromCookies", "logout", "redirectToLogin", "useShellContext", "__toCommonJS", "import_react", "import_classnames", "import_jsx_runtime", "ConnectionStatusIcon", "connectionStatus", "className", "element", "props", "classBase", "setClassBase", "statusIcon", "React", "cx", "import_salt_lab", "import_react", "import_classnames", "import_jsx_runtime", "classBase", "densities", "DEFAULT_DENSITY", "DensitySwitch", "classNameProp", "defaultDensity", "onDensityChange", "handleSelectionChange", "_event", "selectedItem", "className", "cx", "import_react", "import_vuu_layout", "import_react", "import_jsx_runtime", "ErrorBoundary", "React", "props", "error", "errorInfo", "import_jsx_runtime", "Loader", "import_jsx_runtime", "RawFeature", "url", "css", "params", "props", "cssModule", "LazyFeature", "React", "ErrorBoundary", "Loader", "Feature", "import_react", "import_core", "import_salt_lab", "import_jsx_runtime", "classBase", "LoginPanel", "onSubmit", "username", "setUserName", "password", "setPassword", "login", "handleUsername", "_event", "value", "handlePassword", "dataIsValid", "import_vuu_utils", "getAuthDetailsFromCookies", "username", "token", "redirectToLogin", "loginUrl", "logout", "import_vuu_data", "import_classnames", "import_react", "import_react", "import_jsx_runtime", "defaultConfig", "ShellContext", "Provider", "children", "context", "inheritedContext", "mergedContext", "ShellContextProvider", "value", "useShellContext", "import_react", "useLayoutConfig", "user", "defaultLayout", "layout", "_setLayout", "setLayout", "load", "id", "response", "saveData", "data", "loadLayoutById", "use_layout_config_default", "import_vuu_layout", "import_react", "import_core", "import_salt_lab", "import_icons", "import_vuu_utils", "import_salt_lab", "import_core", "import_icons", "import_react", "getLayoutHistory", "user", "response", "import_jsx_runtime", "byLastUpdate", "l1", "l2", "HistoryListItem", "props", "UserPanel", "loginUrl", "onNavigate", "user", "layoutId", "forwardedRef", "history", "setHistory", "getHistory", "sortedHistory", "getLayoutHistory", "item", "id", "lastUpdate", "handleHisorySelected", "evt", "selected", "handleLogout", "logout", "i", "import_jsx_runtime", "UserProfile", "layoutId", "loginUrl", "onNavigate", "user", "UserPanel", "id", "import_salt_lab", "import_classnames", "import_core", "import_react", "import_jsx_runtime", "classBase", "modes", "ThemeSwitch", "classNameProp", "defaultModeProp", "modeProp", "onChange", "htmlAttributes", "mode", "setMode", "selectedIndex", "handleChangeSecondary", "_evt", "index", "className", "cx", "import_classnames", "import_jsx_runtime", "classBase", "AppHeader", "classNameProp", "layoutId", "loginUrl", "onNavigate", "onSwitchTheme", "themeMode", "user", "htmlAttributes", "className", "cx", "handleSwitchTheme", "mode", "ThemeSwitch", "UserProfile", "import_jsx_runtime", "warningLayout", "Shell", "children", "classNameProp", "defaultLayout", "leftSidePanel", "loginUrl", "serverUrl", "user", "htmlAttributes", "rootRef", "paletteView", "open", "setOpen", "layoutId", "layout", "setLayoutConfig", "loadLayoutById", "use_layout_config_default", "handleLayoutChange", "handleSwitchTheme", "mode", "handleDrawerClick", "e", "_a", "target", "handleNavigate", "id", "getDrawers", "drawers", "className", "cx", "ShellContextProvider", "AppHeader", "import_react", "import_classnames", "import_jsx_runtime", "DEFAULT_DENSITY", "DEFAULT_THEME", "DEFAULT_THEME_MODE", "ThemeContext", "createThemedChildren", "children", "theme", "themeMode", "density", "_a", "cx", "ThemeProvider", "themeProp", "themeModeProp", "densityProp", "_b", "_c", "inheritedDensity", "inheritedThemeMode", "inheritedTheme", "themedChildren"]
7
7
  }
package/esm/index.js CHANGED
@@ -1,2 +1,4 @@
1
- import ge,{useEffect as fe,useState as ye}from"react";import ve from"classnames";import{Fragment as xe,jsx as Se,jsxs as E}from"react/jsx-runtime";var bt=({connectionStatus:t,className:e,element:o="span",...r})=>{let[a,s]=ye("vuuConnectingStatus");fe(()=>{switch(t){case"connected":case"reconnected":s("vuuActiveStatus");break;case"connecting":s("vuuConnectingStatus");break;case"disconnected":s("vuuDisconnectedStatus");break;default:break}},[t]);let n=ge.createElement(o,{...r,className:ve("vuuStatus vuuIcon",a,e)});return Se(xe,{children:E("div",{className:"vuuStatus-container salt-theme",children:[n,E("div",{className:"vuuStatus-text",children:["Status: ",t.toUpperCase()]})]})})};import B,{Suspense as we}from"react";import{registerComponent as De}from"@vuu-ui/vuu-layout";import Ce from"react";import{Fragment as Le,jsx as U,jsxs as Pe}from"react/jsx-runtime";var x=class extends Ce.Component{constructor(e){super(e),this.state={errorMessage:null}}static getDerivedStateFromError(e){return{errorMessage:e.message}}componentDidCatch(e,o){console.log(e,o)}render(){return this.state.errorMessage?Pe(Le,{children:[U("h1",{children:"Something went wrong."}),U("p",{children:this.state.errorMessage})]}):this.props.children}};import{jsx as Te}from"react/jsx-runtime";var I=()=>Te("div",{className:"hwLoader",children:"loading"});var R=async t=>{let e=new CSSStyleSheet;return fetch(t).then(o=>o.text()).then(o=>e.replace(o))};import{jsx as S}from"react/jsx-runtime";function He({url:t,css:e,params:o,...r}){e&&R(e).then(s=>{document.adoptedStyleSheets=[...document.adoptedStyleSheets,s]});let a=B.lazy(()=>import(t));return S(x,{children:S(we,{fallback:S(I,{}),children:S(a,{...r,...o})})})}var A=B.memo(He);A.displayName="Feature";De("Feature",A,"view");import{useState as F}from"react";import{Button as be}from"@salt-ds/core";import{FormField as V,Input as O}from"@heswell/salt-lab";import{jsx as y,jsxs as Me}from"react/jsx-runtime";var $="vuuLoginPanel",oo=({onSubmit:t})=>{let[e,o]=F(""),[r,a]=F(""),s=()=>{t(e,r)},n=(l,u)=>{o(u)},c=(l,u)=>{a(u)},i=e.trim()!==""&&r.trim()!=="";return Me("div",{className:$,children:[y(V,{label:"Username",style:{width:200},children:y(O,{value:e,id:"text-username",onChange:n})}),y(V,{label:"Password",style:{width:200},children:y(O,{type:"password",value:r,id:"text-password",onChange:c})}),y(be,{className:`${$}-login`,disabled:!i,onClick:s,variant:"cta",children:"Login"})]})};import{getCookieValue as G}from"@vuu-ui/vuu-utils";var ao=()=>{let t=G("vuu-username"),e=G("vuu-auth-token");return[t,e]},Ne=(t="/login.html")=>{window.location.href=t},_=t=>{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",Ne(t)};import{connectToServer as ht}from"@vuu-ui/vuu-data";import{useCallback as L,useEffect as gt,useRef as b,useState as ne}from"react";import{useCallback as P,useEffect as ke,useState as Ee}from"react";var Ue=(t,e)=>{let[o,r]=Ee(e),a=i=>{r(i)},s=P(async(i="latest")=>{fetch(`api/vui/${t.username}/${i}`,{}).then(l=>l.ok?l.json():e).then(a).catch(()=>{a(e)})},[e,t.username]);ke(()=>{s()},[s]);let n=P(i=>{fetch(`api/vui/${t.username}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)}).then(l=>l.ok?l.json():e)},[e,t]),c=P(i=>{s(i)},[s]);return[o,n,c]},J=Ue;import{createContext as Ie,useContext as Re}from"react";import{jsx as T}from"react/jsx-runtime";var Be={},w=Ie(Be),Ae=({children:t,context:e,inheritedContext:o})=>{let r={...o,...e};return T(w.Provider,{value:r,children:t})},z=({children:t,value:e})=>T(w.Consumer,{children:o=>T(Ae,{context:e,inheritedContext:o,children:t})}),yo=()=>Re(w);import ft from"classnames";import{Chest as yt,DraggableLayout as se,Drawer as vt,Flexbox as xt,LayoutProvider as St,View as Ct}from"@vuu-ui/vuu-layout";import{useCallback as oe}from"react";import{Button as Ke}from"@salt-ds/core";import{DropdownBase as Qe}from"@heswell/salt-lab";import{UserSolidIcon as We}from"@salt-ds/icons";import{formatDate as Fe}from"@vuu-ui/vuu-utils";import{List as Ve,ListItem as Oe}from"@heswell/salt-lab";import{Button as $e}from"@salt-ds/core";import{ExportIcon as Ge}from"@salt-ds/icons";import{forwardRef as _e,useCallback as Y,useEffect as Je,useState as ze}from"react";var q=async t=>await fetch(`api/vui/${t.username}`,{}).then(o=>o.ok?o.json():null).catch(()=>{console.log("error getting history")});import{jsx as C,jsxs as K}from"react/jsx-runtime";var qe=({lastUpdate:t},{lastUpdate:e})=>e===t?0:e<t?-1:1,Ye=t=>C(Oe,{...t}),Q=_e(function({loginUrl:e,onNavigate:o,user:r,layoutId:a="latest"},s){let[n,c]=ze([]);Je(()=>{async function d(){let h=(await q(r)).filter(f=>f.id!=="latest").sort(qe).map(({id:f,lastUpdate:v})=>({lastUpdate:v,id:f,label:`Saved at ${Fe(new Date(v),"kk:mm:ss")}`}));console.log({sortedHistory:h}),c(h)}d()},[r]);let i=Y((d,p)=>{p&&o(p.id)},[o]),l=Y(()=>{_(e)},[e]),u=n.length===0?null:a==="latest"?n[0]:n.find(d=>d.id===a);return K("div",{className:"vuuUserPanel",ref:s,children:[C(Ve,{ListItem:Ye,className:"vuuUserPanel-history",onSelect:i,selected:u,source:n}),C("div",{className:"vuuUserPanel-buttonBar",children:K($e,{"aria-label":"logout",onClick:l,children:[C(Ge,{})," Logout"]})})]})});import{jsx as D,jsxs as Xe}from"react/jsx-runtime";var W=({layoutId:t,loginUrl:e,onNavigate:o,user:r})=>Xe(Qe,{className:"vuuUserProfile",placement:"bottom-end",children:[D(Ke,{variant:"secondary",children:D(We,{})}),D(Q,{layoutId:t,loginUrl:e,onNavigate:s=>{o(s)},user:r})]});import{ToggleButton as X,ToggleButtonGroup as Ze}from"@heswell/salt-lab";import je from"classnames";import{useControlled as et}from"@salt-ds/core";import{useCallback as tt}from"react";import{jsx as j,jsxs as rt}from"react/jsx-runtime";var ot="vuuThemeSwitch",Z=["light","dark"],ee=({className:t,defaultMode:e,mode:o,onChange:r,...a})=>{let[s,n]=et({controlled:o,default:e!=null?e:"light",name:"ThemeSwitch",state:"mode"}),c=Z.indexOf(s),i=tt((u,d)=>{let p=Z[d];n(p),r(p)},[r,n]),l=je(ot,t);return rt(Ze,{className:l,...a,onChange:i,selectedIndex:c,children:[j(X,{"aria-label":"alert",tooltipText:"Light Theme","data-icon":"light"}),j(X,{"aria-label":"home",tooltipText:"Dark Theme","data-icon":"dark"})]})};import ut from"classnames";import{Dropdown as nt}from"@heswell/salt-lab";import{DEFAULT_DENSITY as st}from"@salt-ds/core";import{useCallback as at}from"react";import it from"classnames";import{jsx as ct}from"react/jsx-runtime";var lt="vuuDensitySwitch",mt=["high","medium","low","touch"],te=({className:t,defaultDensity:e=st,onDensityChange:o})=>{let r=at((s,n)=>{o(n)},[o]),a=it(lt,t);return ct(nt,{className:a,source:mt,defaultSelected:e,onSelectionChange:r})};import{jsx as H,jsxs as pt}from"react/jsx-runtime";var dt="vuuAppHeader",re=({className:t,layoutId:e,loginUrl:o,onNavigate:r,onSwitchTheme:a,themeMode:s="light",onDensitySwitch:n,density:c="medium",user:i,...l})=>{let u=ut(dt,t,`salt-density-${c}`),d=oe(h=>a==null?void 0:a(h),[a]),p=oe(h=>n==null?void 0:n(h),[n]);return pt("header",{className:u,...l,children:[H(ee,{defaultMode:s,onChange:d}),H(te,{defaultDensity:c,onDensityChange:p}),H(W,{layoutId:e,loginUrl:o,onNavigate:r,user:i})]})};import{jsx as g,jsxs as ae}from"react/jsx-runtime";var Lt={type:"View",props:{style:{height:"calc(100% - 6px)"}},children:[{props:{className:"vuuShell-warningPlaceholder"},type:"Placeholder"}]},qr=({children:t,className:e,defaultLayout:o=Lt,leftSidePanel:r,loginUrl:a,serverUrl:s,user:n,...c})=>{let i=b(null),[l,u]=ne("medium"),d=b(null),[p,h]=ne(!1),f=b("latest"),[v,M,N]=J(n,o),ie=L(m=>{M(m)},[M]),le=L(m=>{i.current&&(i.current.dataset.mode=m)},[]),me=L(m=>{u(m)},[u]),ce=m=>{var k;let he=m.target;(k=d.current)!=null&&k.contains(he)||h(!p)},ue=L(m=>{f.current=m,N(m)},[N]);gt(()=>{s&&n.token&&ht(s,n.token)},[s,n.token]);let de=()=>{let m=[];return r&&m.push(g(vt,{onClick:ce,open:p,position:"left",inline:!0,peekaboo:!0,sizeOpen:200,toggleButton:"end",children:g(Ct,{className:"vuuShell-palette",id:"vw-app-palette",ref:d,style:{height:"100%"},children:r},"app-palette")},"left-panel")),m},pe=ft("vuuShell",e,"salt-theme",`salt-density-${l}`);return ae(z,{value:void 0,children:[g(St,{layout:v,onLayoutChange:ie,children:g(se,{className:pe,"data-mode":"light",ref:i,...c,children:ae(xt,{className:"App",style:{flexDirection:"column",height:"100%",width:"100%"},children:[g(re,{layoutId:f.current,loginUrl:a,user:n,onNavigate:ue,onSwitchTheme:le,onDensitySwitch:me}),g(yt,{style:{flex:1},children:de().concat(g(se,{dropTarget:!0,style:{width:"100%",height:"100%"}},"main-content"))})]})})}),t]})};export{bt as ConnectionStatusIcon,A as Feature,oo as LoginPanel,qr as Shell,z as ShellContextProvider,ee as ThemeSwitch,ao as getAuthDetailsFromCookies,_ as logout,Ne as redirectToLogin,yo as useShellContext};
1
+ import me,{useEffect as ce,useState as ue}from"react";import de from"classnames";import{Fragment as pe,jsx as he,jsxs as H}from"react/jsx-runtime";var Rt=({connectionStatus:t,className:e,element:o="span",...r})=>{let[n,s]=ue("vuuConnectingStatus");ce(()=>{switch(t){case"connected":case"reconnected":s("vuuActiveStatus");break;case"connecting":s("vuuConnectingStatus");break;case"disconnected":s("vuuDisconnectedStatus");break;default:break}},[t]);let a=me.createElement(o,{...r,className:de("vuuStatus vuuIcon",n,e)});return he(pe,{children:H("div",{className:"vuuStatus-container salt-theme",children:[a,H("div",{className:"vuuStatus-text",children:["Status: ",t.toUpperCase()]})]})})};import{Dropdown as ge}from"@heswell/salt-lab";import{useCallback as fe}from"react";import ye from"classnames";import{jsx as Ce}from"react/jsx-runtime";var ve="vuuDensitySwitch",xe=["high","medium","low","touch"],Te="high",Jt=({className:t,defaultDensity:e=Te,onDensityChange:o})=>{let r=fe((s,a)=>{o(a)},[o]),n=ye(ve,t);return Ce(ge,{className:n,source:xe,defaultSelected:e,onSelectionChange:r})};import k,{Suspense as Ee}from"react";import{registerComponent as we}from"@vuu-ui/vuu-layout";import Le from"react";import{Fragment as Se,jsx as N,jsxs as Pe}from"react/jsx-runtime";var x=class extends Le.Component{constructor(e){super(e),this.state={errorMessage:null}}static getDerivedStateFromError(e){return{errorMessage:e.message}}componentDidCatch(e,o){console.log(e,o)}render(){return this.state.errorMessage?Pe(Se,{children:[N("h1",{children:"Something went wrong."}),N("p",{children:this.state.errorMessage})]}):this.props.children}};import{jsx as Me}from"react/jsx-runtime";var b=()=>Me("div",{className:"hwLoader",children:"loading"});import{jsx as T}from"react/jsx-runtime";function De({url:t,css:e,params:o,...r}){e&&import(e).then(s=>{document.adoptedStyleSheets=[...document.adoptedStyleSheets,s.default]});let n=k.lazy(()=>import(t));return T(x,{children:T(Ee,{fallback:T(b,{}),children:T(n,{...r,...o})})})}var U=k.memo(De);U.displayName="Feature";we("Feature",U,"view");import{useState as I}from"react";import{Button as He}from"@salt-ds/core";import{FormField as R,Input as A}from"@heswell/salt-lab";import{jsx as v,jsxs as Ne}from"react/jsx-runtime";var B="vuuLoginPanel",yo=({onSubmit:t})=>{let[e,o]=I(""),[r,n]=I(""),s=()=>{t(e,r)},a=(l,c)=>{o(c)},m=(l,c)=>{n(c)},i=e.trim()!==""&&r.trim()!=="";return Ne("div",{className:B,children:[v(R,{label:"Username",style:{width:200},children:v(A,{value:e,id:"text-username",onChange:a})}),v(R,{label:"Password",style:{width:200},children:v(A,{type:"password",value:r,id:"text-password",onChange:m})}),v(He,{className:`${B}-login`,disabled:!i,onClick:s,variant:"cta",children:"Login"})]})};import{getCookieValue as F}from"@vuu-ui/vuu-utils";var Co=()=>{let t=F("vuu-username"),e=F("vuu-auth-token");return[t,e]},be=(t="/login.html")=>{window.location.href=t},V=t=>{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",be(t)};import{connectToServer as mt}from"@vuu-ui/vuu-data";import ct from"classnames";import{useCallback as E,useEffect as ut,useRef as w,useState as dt}from"react";import{createContext as ke,useContext as Ue}from"react";import{jsx as L}from"react/jsx-runtime";var Ie={},S=ke(Ie),Re=({children:t,context:e,inheritedContext:o})=>{let r={...o,...e};return L(S.Provider,{value:r,children:t})},O=({children:t,value:e})=>L(S.Consumer,{children:o=>L(Re,{context:e,inheritedContext:o,children:t})}),Ho=()=>Ue(S);import{useCallback as P,useEffect as Ae,useState as Be}from"react";var Fe=(t,e)=>{let[o,r]=Be(e),n=i=>{r(i)},s=P(async(i="latest")=>{fetch(`api/vui/${t.username}/${i}`,{}).then(l=>l.ok?l.json():e).then(n).catch(()=>{n(e)})},[e,t.username]);Ae(()=>{s()},[s]);let a=P(i=>{fetch(`api/vui/${t.username}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)}).then(l=>l.ok?l.json():e)},[e,t]),m=P(i=>{s(i)},[s]);return[o,a,m]},_=Fe;import{DockLayout as pt,DraggableLayout as j,Drawer as ht,Flexbox as gt,LayoutProvider as ft,View as yt}from"@vuu-ui/vuu-layout";import{useCallback as st}from"react";import{Button as Ke}from"@salt-ds/core";import{DropdownBase as Qe}from"@heswell/salt-lab";import{UserSolidIcon as Xe}from"@salt-ds/icons";import{formatDate as Ve}from"@vuu-ui/vuu-utils";import{List as Oe,ListItem as _e}from"@heswell/salt-lab";import{Button as $e}from"@salt-ds/core";import{ExportIcon as Ge}from"@salt-ds/icons";import{forwardRef as Je,useCallback as G,useEffect as ze,useState as Ye}from"react";var $=async t=>await fetch(`api/vui/${t.username}`,{}).then(o=>o.ok?o.json():null).catch(()=>{console.log("error getting history")});import{jsx as C,jsxs as J}from"react/jsx-runtime";var qe=({lastUpdate:t},{lastUpdate:e})=>e===t?0:e<t?-1:1,We=t=>C(_e,{...t}),z=Je(function({loginUrl:e,onNavigate:o,user:r,layoutId:n="latest"},s){let[a,m]=Ye([]);ze(()=>{async function d(){let h=(await $(r)).filter(f=>f.id!=="latest").sort(qe).map(({id:f,lastUpdate:y})=>({lastUpdate:y,id:f,label:`Saved at ${Ve(new Date(y),"kk:mm:ss")}`}));console.log({sortedHistory:h}),m(h)}d()},[r]);let i=G((d,u)=>{u&&o(u.id)},[o]),l=G(()=>{V(e)},[e]),c=a.length===0?null:n==="latest"?a[0]:a.find(d=>d.id===n);return J("div",{className:"vuuUserPanel",ref:s,children:[C(Oe,{ListItem:We,className:"vuuUserPanel-history",onSelect:i,selected:c,source:a}),C("div",{className:"vuuUserPanel-buttonBar",children:J($e,{"aria-label":"logout",onClick:l,children:[C(Ge,{})," Logout"]})})]})});import{jsx as M,jsxs as Ze}from"react/jsx-runtime";var Y=({layoutId:t,loginUrl:e,onNavigate:o,user:r})=>Ze(Qe,{className:"vuuUserProfile",placement:"bottom-end",children:[M(Ke,{variant:"secondary",children:M(Xe,{})}),M(z,{layoutId:t,loginUrl:e,onNavigate:s=>{o(s)},user:r})]});import{ToggleButton as q,ToggleButtonGroup as je}from"@heswell/salt-lab";import et from"classnames";import{useControlled as tt}from"@salt-ds/core";import{useCallback as ot}from"react";import{jsx as K,jsxs as nt}from"react/jsx-runtime";var rt="vuuThemeSwitch",W=["light","dark"],Q=({className:t,defaultMode:e,mode:o,onChange:r,...n})=>{let[s,a]=tt({controlled:o,default:e!=null?e:"light",name:"ThemeSwitch",state:"mode"}),m=W.indexOf(s),i=ot((c,d)=>{let u=W[d];a(u),r(u)},[r,a]),l=et(rt,t);return nt(je,{className:l,...n,onChange:i,selectedIndex:m,children:[K(q,{"aria-label":"alert",tooltipText:"Light Theme","data-icon":"light"}),K(q,{"aria-label":"home",tooltipText:"Dark Theme","data-icon":"dark"})]})};import at from"classnames";import{jsx as X,jsxs as lt}from"react/jsx-runtime";var it="vuuAppHeader",Z=({className:t,layoutId:e,loginUrl:o,onNavigate:r,onSwitchTheme:n,themeMode:s="light",user:a,...m})=>{let i=at(it,t),l=st(c=>n==null?void 0:n(c),[n]);return lt("header",{className:i,...m,children:[X(Q,{defaultMode:s,onChange:l}),X(Y,{layoutId:e,loginUrl:o,onNavigate:r,user:a})]})};import{jsx as g,jsxs as ee}from"react/jsx-runtime";var vt={type:"View",props:{style:{height:"calc(100% - 6px)"}},children:[{props:{className:"vuuShell-warningPlaceholder"},type:"Placeholder"}]},qr=({children:t,className:e,defaultLayout:o=vt,leftSidePanel:r,loginUrl:n,serverUrl:s,user:a,...m})=>{let i=w(null),l=w(null),[c,d]=dt(!1),u=w("latest"),[h,f,y]=_(a,o),oe=E(p=>{f(p)},[f]),re=E(p=>{i.current&&(i.current.dataset.mode=p)},[]),ne=p=>{var D;let le=p.target;(D=l.current)!=null&&D.contains(le)||d(!c)},se=E(p=>{u.current=p,y(p)},[y]);ut(()=>{s&&a.token&&mt(s,a.token)},[s,a.token]);let ae=()=>{let p=[];return r&&p.push(g(ht,{onClick:ne,open:c,position:"left",inline:!0,peekaboo:!0,sizeOpen:200,toggleButton:"end",children:g(yt,{className:"vuuShell-palette",id:"vw-app-palette",ref:l,style:{height:"100%"},children:r},"app-palette")},"left-panel")),p},ie=ct("vuuShell",e,"salt-theme","salt-density-high");return ee(O,{value:void 0,children:[g(ft,{layout:h,onLayoutChange:oe,children:g(j,{className:ie,"data-mode":"light",ref:i,...m,children:ee(gt,{className:"App",style:{flexDirection:"column",height:"100%",width:"100%"},children:[g(Z,{layoutId:u.current,loginUrl:n,user:a,onNavigate:se,onSwitchTheme:re}),g(pt,{style:{flex:1},children:ae().concat(g(j,{dropTarget:!0,style:{width:"100%",height:"100%"}},"main-content"))})]})})}),t]})};import{createContext as xt,isValidElement as Tt,cloneElement as Ct,useContext as Lt}from"react";import St from"classnames";import{jsx as Ht}from"react/jsx-runtime";var Pt="medium",Mt="salt-theme",Et="light",te=xt({density:"high",theme:"salt-theme",themeMode:"light"}),wt=(t,e,o,r)=>{var n;return Tt(t)?Ct(t,{className:St((n=t.props)==null?void 0:n.className,e,`salt-density-${r}`),"data-mode":o}):(console.warn(`
2
+ ThemeProvider can only apply CSS classes for theming to a single nested child element of the ThemeProvider.
3
+ Wrap elements with a single container`),t)},Dt=({children:t,theme:e,themeMode:o,density:r})=>{var d,u,h;let{density:n,themeMode:s,theme:a}=Lt(te),m=(d=r!=null?r:n)!=null?d:Pt,i=(u=o!=null?o:s)!=null?u:Et,l=(h=e!=null?e:a)!=null?h:Mt,c=wt(t,l,i,m);return Ht(te.Provider,{value:{themeMode:i,density:m,theme:l},children:c})};Dt.displayName="ThemeProvider";export{Rt as ConnectionStatusIcon,Pt as DEFAULT_DENSITY,Mt as DEFAULT_THEME,Et as DEFAULT_THEME_MODE,Jt as DensitySwitch,U as Feature,yo as LoginPanel,qr as Shell,O as ShellContextProvider,te as ThemeContext,Dt as ThemeProvider,Q as ThemeSwitch,Co as getAuthDetailsFromCookies,V as logout,be as redirectToLogin,Ho as useShellContext};
2
4
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../packages/vuu-shell/src/connection-status/ConnectionStatusIcon.tsx", "../../../packages/vuu-shell/src/feature/Feature.tsx", "../../../packages/vuu-shell/src/feature/ErrorBoundary.jsx", "../../../packages/vuu-shell/src/feature/Loader.tsx", "../../../packages/vuu-shell/src/feature/css-module-loader.ts", "../../../packages/vuu-shell/src/login/LoginPanel.tsx", "../../../packages/vuu-shell/src/login/login-utils.ts", "../../../packages/vuu-shell/src/shell.tsx", "../../../packages/vuu-shell/src/use-layout-config.js", "../../../packages/vuu-shell/src/ShellContextProvider.tsx", "../../../packages/vuu-shell/src/app-header/AppHeader.tsx", "../../../packages/vuu-shell/src/user-profile/UserProfile.tsx", "../../../packages/vuu-shell/src/user-profile/UserPanel.tsx", "../../../packages/vuu-shell/src/get-layout-history.ts", "../../../packages/vuu-shell/src/theme-switch/ThemeSwitch.tsx", "../../../packages/vuu-shell/src/density-switch/DensitySwitch.tsx"],
4
- "sourcesContent": ["import React, { useEffect, useState } from 'react';\nimport cx from 'classnames';\nimport './ConnectionStatusIcon.css';\n\ntype connectionStatus = 'connected' | 'reconnected' | 'connecting' | 'disconnected';\n\ninterface ConnectionStatusProps {\n\tconnectionStatus: connectionStatus\n\tclassName?: string;\n\tprops?: unknown;\n\telement?: string;\n}\n\nexport const ConnectionStatusIcon = ({ connectionStatus, className, element = 'span', ...props}: ConnectionStatusProps) => {\n\tconst [classBase, setClassBase] = useState<string>('vuuConnectingStatus');\n\tuseEffect(() => {\n\t\tswitch(connectionStatus) {\n\t\t\tcase 'connected':\n\t\t\tcase 'reconnected':\n\t\t\t\tsetClassBase('vuuActiveStatus');\n\t\t\t\tbreak;\n\t\t\tcase 'connecting':\n\t\t\t\tsetClassBase('vuuConnectingStatus');\n\t\t\t\tbreak;\n\t\t\tcase 'disconnected':\n\t\t\t\tsetClassBase('vuuDisconnectedStatus');\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}, [connectionStatus]);\n\n\tconst statusIcon = React.createElement (\n\t\telement,\n\t\t{\n\t\t\t...props,\n\t\t\tclassName: cx('vuuStatus vuuIcon', classBase, className)\n\t\t},\n\t)\n\n\treturn (\n\t\t<>\n\t\t\t<div className='vuuStatus-container salt-theme'>\n\t\t\t\t{statusIcon}\n\t\t\t\t<div\tclassName='vuuStatus-text'>Status: {connectionStatus.toUpperCase()}</div>\n\t\t\t</div>\n\t\t</>\n\t)\n}", "import React, { Suspense } from \"react\";\nimport { registerComponent } from \"@vuu-ui/vuu-layout\";\nimport { ErrorBoundary } from \"./ErrorBoundary\";\nimport { Loader } from \"./Loader\";\nimport { importCSS } from \"./css-module-loader\";\n\nexport interface FeatureProps<Params extends object | undefined = undefined> {\n height?: number;\n url: string;\n css?: string;\n width?: number;\n params: Params;\n}\n\n// const RawFeature = <Params extends object | undefined>({\nfunction RawFeature<Params extends object | undefined>({\n url,\n css,\n params,\n ...props\n}: FeatureProps<Params>) {\n if (css) {\n // import(/* @vite-ignore */ css, { assert: { type: \"css\" } }).then(\n // (cssModule) => {\n // document.adoptedStyleSheets = [\n // ...document.adoptedStyleSheets,\n // cssModule.default,\n // ];\n // }\n // );\n // Polyfill until vite build supports import assertions\n // Note: already fully supported in esbuild, so vite dev\n importCSS(css).then((styleSheet) => {\n document.adoptedStyleSheets = [\n ...document.adoptedStyleSheets,\n styleSheet,\n ];\n });\n }\n const LazyFeature = React.lazy(() => import(/* @vite-ignore */ url));\n return (\n <ErrorBoundary>\n <Suspense fallback={<Loader />}>\n <LazyFeature {...props} {...params} />\n </Suspense>\n </ErrorBoundary>\n );\n}\n\nexport const Feature = React.memo(RawFeature);\nFeature.displayName = \"Feature\";\nregisterComponent(\"Feature\", Feature, \"view\");\n", "import React from 'react';\n// TODO\nexport class ErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = { errorMessage: null };\n }\n\n static getDerivedStateFromError(error) {\n // Update state so the next render will show the fallback UI.\n return { errorMessage: error.message };\n }\n\n componentDidCatch(error, errorInfo) {\n // You can also log the error to an error reporting service\n console.log(error, errorInfo);\n }\n\n render() {\n if (this.state.errorMessage) {\n return (\n <>\n <h1>Something went wrong.</h1>\n <p>{this.state.errorMessage}</p>\n </>\n );\n }\n\n return this.props.children;\n }\n}\n", "// TODO\nexport const Loader = () => <div className=\"hwLoader\">loading</div>;\n", "export const importCSS = async (path: string) => {\n const container = new CSSStyleSheet();\n return fetch(path)\n .then((x) => x.text())\n .then((x) => container.replace(x));\n};\n", "import { ChangeEvent, HTMLAttributes, useState } from \"react\";\nimport { Button } from \"@salt-ds/core\";\nimport { FormField, Input } from \"@heswell/salt-lab\";\n\nimport \"./LoginPanel.css\";\n\nconst classBase = \"vuuLoginPanel\";\n\nexport interface LoginPanelProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onSubmit\"> {\n onSubmit: (username: string, password: string) => void;\n}\n\nexport const LoginPanel = ({ onSubmit }: LoginPanelProps) => {\n const [username, setUserName] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n\n const login = () => {\n onSubmit(username, password);\n };\n\n const handleUsername = (\n _event: ChangeEvent<HTMLInputElement>,\n value: string\n ) => {\n setUserName(value);\n };\n\n const handlePassword = (\n _event: ChangeEvent<HTMLInputElement>,\n value: string\n ) => {\n setPassword(value);\n };\n\n const dataIsValid = username.trim() !== \"\" && password.trim() !== \"\";\n\n return (\n <div className={classBase}>\n <FormField label=\"Username\" style={{ width: 200 }}>\n <Input value={username} id=\"text-username\" onChange={handleUsername} />\n </FormField>\n\n <FormField label=\"Password\" style={{ width: 200 }}>\n <Input\n type=\"password\"\n value={password}\n id=\"text-password\"\n onChange={handlePassword}\n />\n </FormField>\n\n <Button\n className={`${classBase}-login`}\n disabled={!dataIsValid}\n onClick={login}\n variant=\"cta\"\n >\n Login\n </Button>\n </div>\n );\n};\n", "import { getCookieValue } from \"@vuu-ui/vuu-utils\";\n\nexport const getAuthDetailsFromCookies = () => {\n const username = getCookieValue(\"vuu-username\");\n const token = getCookieValue(\"vuu-auth-token\");\n return [username, token];\n};\n\nexport const redirectToLogin = (loginUrl = \"/login.html\") => {\n window.location.href = loginUrl;\n};\n\nexport const logout = (loginUrl?: string) => {\n document.cookie = \"vuu-username= ; expires = Thu, 01 Jan 1970 00:00:00 GMT\";\n document.cookie = \"vuu-auth-token= ; expires = Thu, 01 Jan 1970 00:00:00 GMT\";\n redirectToLogin(loginUrl);\n};\n", "import { connectToServer } from \"@vuu-ui/vuu-data\";\nimport {\n HTMLAttributes,\n MouseEvent,\n ReactElement,\n ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport useLayoutConfig from \"./use-layout-config\";\nimport { ShellContextProvider } from \"./ShellContextProvider\";\nimport cx from \"classnames\";\n\nimport {\n Chest,\n DraggableLayout,\n Drawer,\n Flexbox,\n LayoutProvider,\n View,\n} from \"@vuu-ui/vuu-layout\";\n\nimport { AppHeader } from \"./app-header\";\n\nimport { LayoutJSON } from \"@vuu-ui/vuu-layout/src/layout-reducer\";\nimport \"./shell.css\";\nimport { ThemeMode } from \"./theme-switch\";\nimport { Density } from \"@salt-ds/core\";\n\nexport type VuuUser = {\n username: string;\n token: string;\n};\n\nconst warningLayout = {\n type: \"View\",\n props: {\n style: { height: \"calc(100% - 6px)\" },\n },\n children: [\n {\n props: {\n className: \"vuuShell-warningPlaceholder\",\n },\n type: \"Placeholder\",\n },\n ],\n};\n\nexport interface ShellProps extends HTMLAttributes<HTMLDivElement> {\n children?: ReactNode;\n defaultLayout?: LayoutJSON;\n leftSidePanel?: ReactElement;\n loginUrl?: string;\n // paletteConfig: any;\n serverUrl?: string;\n user: VuuUser;\n}\n\nexport const Shell = ({\n children,\n className: classNameProp,\n defaultLayout = warningLayout,\n leftSidePanel,\n loginUrl,\n serverUrl,\n user,\n ...htmlAttributes\n}: ShellProps) => {\n const rootRef = useRef<HTMLDivElement>(null);\n const [density, setDensity] = useState<Density>(\"medium\");\n const paletteView = useRef<HTMLDivElement>(null);\n const [open, setOpen] = useState(false);\n const layoutId = useRef(\"latest\");\n\n const [layout, setLayoutConfig, loadLayoutById] = useLayoutConfig(\n user,\n defaultLayout\n );\n\n const handleLayoutChange = useCallback(\n (layout) => {\n setLayoutConfig(layout);\n },\n [setLayoutConfig]\n );\n\n const handleSwitchTheme = useCallback((mode: ThemeMode) => {\n if (rootRef.current) {\n rootRef.current.dataset.mode = mode;\n }\n }, []);\n\n const handleDensitySwitch = useCallback(\n (density: Density) => {\n setDensity(density);\n },\n [setDensity]\n );\n\n const handleDrawerClick = (e: MouseEvent<HTMLElement>) => {\n const target = e.target as HTMLElement;\n if (!paletteView.current?.contains(target)) {\n setOpen(!open);\n }\n };\n\n const handleNavigate = useCallback(\n (id) => {\n layoutId.current = id;\n loadLayoutById(id);\n },\n [loadLayoutById]\n );\n\n useEffect(() => {\n if (serverUrl && user.token) {\n connectToServer(serverUrl, user.token);\n }\n }, [serverUrl, user.token]);\n\n const getDrawers = () => {\n const drawers: ReactElement[] = [];\n if (leftSidePanel) {\n drawers.push(\n <Drawer\n key=\"left-panel\"\n onClick={handleDrawerClick}\n open={open}\n position=\"left\"\n inline\n peekaboo\n sizeOpen={200}\n toggleButton=\"end\"\n >\n <View\n className=\"vuuShell-palette\"\n id=\"vw-app-palette\"\n key=\"app-palette\"\n ref={paletteView}\n style={{ height: \"100%\" }}\n >\n {leftSidePanel}\n </View>\n </Drawer>\n );\n }\n\n return drawers;\n };\n\n const className = cx(\n \"vuuShell\",\n classNameProp,\n \"salt-theme\",\n `salt-density-${density}`\n );\n\n return (\n // ShellContext TBD\n <ShellContextProvider value={undefined}>\n <LayoutProvider layout={layout} onLayoutChange={handleLayoutChange}>\n <DraggableLayout\n className={className}\n data-mode=\"light\"\n ref={rootRef}\n {...htmlAttributes}\n >\n <Flexbox\n className=\"App\"\n style={{ flexDirection: \"column\", height: \"100%\", width: \"100%\" }}\n >\n <AppHeader\n layoutId={layoutId.current}\n loginUrl={loginUrl}\n user={user}\n onNavigate={handleNavigate}\n onSwitchTheme={handleSwitchTheme}\n onDensitySwitch={handleDensitySwitch}\n />\n <Chest style={{ flex: 1 }}>\n {getDrawers().concat(\n <DraggableLayout\n dropTarget\n key=\"main-content\"\n style={{ width: \"100%\", height: \"100%\" }}\n />\n )}\n </Chest>\n </Flexbox>\n </DraggableLayout>\n </LayoutProvider>\n {children}\n </ShellContextProvider>\n );\n};\n", "import { useCallback, useEffect, useState } from \"react\";\n\nconst useLayoutConfig = (user, defaultLayout) => {\n const [layout, _setLayout] = useState(defaultLayout);\n\n const setLayout = (layout) => {\n _setLayout(layout);\n };\n\n const load = useCallback(\n async (id = \"latest\") => {\n fetch(`api/vui/${user.username}/${id}`, {})\n .then((response) => {\n return response.ok ? response.json() : defaultLayout;\n })\n .then(setLayout)\n .catch(() => {\n // TODO we should set a layout with a warning here\n setLayout(defaultLayout);\n });\n },\n [defaultLayout, user.username]\n );\n\n useEffect(() => {\n load();\n }, [load]);\n\n const saveData = useCallback(\n (data) => {\n fetch(`api/vui/${user.username}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(data),\n }).then((response) => {\n return response.ok ? response.json() : defaultLayout;\n });\n },\n [defaultLayout, user]\n );\n\n const loadLayoutById = useCallback(\n (id) => {\n load(id);\n },\n [load]\n );\n\n return [layout, saveData, loadLayoutById];\n};\n\nexport default useLayoutConfig;\n", "import { MenuRpcResponse } from \"@vuu-ui/vuu-data\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { createContext, ReactElement, ReactNode, useContext } from \"react\";\n\nexport interface ShellContextProps {\n getDefaultColumnConfig?: (\n tableName: string,\n columnName: string\n ) => Partial<ColumnDescriptor>;\n handleRpcResponse?: (response?: MenuRpcResponse) => void;\n}\n\nconst defaultConfig = {};\n\nconst ShellContext = createContext<ShellContextProps>(defaultConfig);\n\nexport interface ShellProviderProps {\n children: ReactNode;\n value?: ShellContextProps;\n}\n\nconst Provider = ({\n children,\n context,\n inheritedContext,\n}: {\n children: ReactNode;\n context?: ShellContextProps;\n inheritedContext?: ShellContextProps;\n}) => {\n // TODO functions provided at multiple levels must be merged\n const mergedContext = {\n ...inheritedContext,\n ...context,\n };\n return (\n <ShellContext.Provider value={mergedContext}>\n {children}\n </ShellContext.Provider>\n );\n};\n\nexport const ShellContextProvider = ({\n children,\n value,\n}: ShellProviderProps): ReactElement => {\n return (\n <ShellContext.Consumer>\n {(context) => (\n <Provider context={value} inheritedContext={context}>\n {children}\n </Provider>\n )}\n </ShellContext.Consumer>\n );\n};\n\nexport const useShellContext = () => {\n return useContext(ShellContext);\n};\n", "import { HTMLAttributes, useCallback } from \"react\";\nimport { VuuUser } from \"../shell\";\nimport { UserProfile } from \"../user-profile\";\nimport { ThemeMode, ThemeSwitch } from \"../theme-switch\";\nimport cx from \"classnames\";\n\nimport \"./AppHeader.css\";\nimport { Density } from \"@salt-ds/core\";\nimport { DensitySwitch } from \"../density-switch\";\n\nconst classBase = \"vuuAppHeader\";\nexport interface AppHeaderProps extends HTMLAttributes<HTMLDivElement> {\n layoutId: string;\n loginUrl?: string;\n onNavigate: (id: string) => void;\n onSwitchTheme?: (mode: ThemeMode) => void;\n themeMode?: ThemeMode;\n onDensitySwitch?: (density: Density) => void;\n density?: Density\n user: VuuUser;\n}\n\nexport const AppHeader = ({\n className: classNameProp,\n layoutId,\n loginUrl,\n onNavigate,\n onSwitchTheme,\n themeMode = \"light\",\n onDensitySwitch,\n density=\"medium\",\n user,\n ...htmlAttributes\n}: AppHeaderProps) => {\n const className = cx(classBase, classNameProp, `salt-density-${density}`);\n const handleSwitchTheme = useCallback(\n (mode: ThemeMode) => onSwitchTheme?.(mode),\n [onSwitchTheme]\n );\n const handleDensitySwitch = useCallback(\n (density: Density) => onDensitySwitch?.(density),\n [onDensitySwitch]\n );\n return (\n <header className={className} {...htmlAttributes}>\n <ThemeSwitch defaultMode={themeMode} onChange={handleSwitchTheme} />\n <DensitySwitch defaultDensity={density} onDensityChange={handleDensitySwitch} />\n <UserProfile\n layoutId={layoutId}\n loginUrl={loginUrl}\n onNavigate={onNavigate}\n user={user}\n />\n </header>\n );\n};\n", "import { Button } from \"@salt-ds/core\";\nimport { DropdownBase } from \"@heswell/salt-lab\";\nimport { UserSolidIcon } from \"@salt-ds/icons\";\nimport { UserPanel } from \"./UserPanel\";\n\nimport \"./UserProfile.css\";\nimport { VuuUser } from \"../shell\";\n\nexport interface UserProfileProps {\n layoutId: string;\n loginUrl?: string;\n onNavigate: (id: string) => void;\n user: VuuUser;\n}\n\nexport const UserProfile = ({\n layoutId,\n loginUrl,\n onNavigate,\n user,\n}: UserProfileProps) => {\n const handleNavigate = (id: string) => {\n onNavigate(id);\n };\n\n return (\n <DropdownBase className=\"vuuUserProfile\" placement=\"bottom-end\">\n <Button variant=\"secondary\">\n <UserSolidIcon />\n </Button>\n <UserPanel\n layoutId={layoutId}\n loginUrl={loginUrl}\n onNavigate={handleNavigate}\n user={user}\n />\n </DropdownBase>\n );\n};\n", "import { formatDate } from \"@vuu-ui/vuu-utils\";\nimport { List, ListItem, ListItemProps } from \"@heswell/salt-lab\";\nimport { Button } from \"@salt-ds/core\";\nimport { ExportIcon } from \"@salt-ds/icons\";\nimport {\n ForwardedRef,\n forwardRef,\n HTMLAttributes,\n useCallback,\n useEffect,\n useState,\n} from \"react\";\nimport { getLayoutHistory, LayoutHistoryItem } from \"../get-layout-history\";\nimport { logout } from \"../login\";\nimport { VuuUser } from \"../shell\";\n\nimport \"./UserPanel.css\";\n\nconst byLastUpdate = (\n { lastUpdate: l1 }: LayoutHistoryItem,\n { lastUpdate: l2 }: LayoutHistoryItem\n) => {\n return l2 === l1 ? 0 : l2 < l1 ? -1 : 1;\n};\n\ntype HistoryEntry = {\n id: string;\n label: string;\n lastUpdate: number;\n};\n\nconst HistoryListItem = (props: ListItemProps<HistoryEntry>) => {\n return <ListItem {...props} />;\n};\n\nexport interface UserPanelProps extends HTMLAttributes<HTMLDivElement> {\n loginUrl?: string;\n onNavigate: (id: string) => void;\n user: VuuUser;\n layoutId: string;\n}\n\nexport const UserPanel = forwardRef(function UserPanel(\n { loginUrl, onNavigate, user, layoutId = \"latest\" }: UserPanelProps,\n forwardedRef: ForwardedRef<HTMLDivElement>\n) {\n const [history, setHistory] = useState<HistoryEntry[]>([]);\n\n useEffect(() => {\n async function getHistory() {\n const history = await getLayoutHistory(user);\n const sortedHistory = history\n .filter((item) => item.id !== \"latest\")\n .sort(byLastUpdate)\n .map<HistoryEntry>(({ id, lastUpdate }) => ({\n lastUpdate,\n id,\n label: `Saved at ${formatDate(new Date(lastUpdate), \"kk:mm:ss\")}`,\n }));\n console.log({ sortedHistory });\n setHistory(sortedHistory);\n }\n\n getHistory();\n }, [user]);\n\n const handleHisorySelected = useCallback(\n (evt, selected) => {\n if (selected) {\n onNavigate(selected.id);\n }\n },\n [onNavigate]\n );\n\n const handleLogout = useCallback(() => {\n logout(loginUrl);\n }, [loginUrl]);\n\n const selected =\n history.length === 0\n ? null\n : layoutId === \"latest\"\n ? history[0]\n : history.find((i) => i.id === layoutId);\n\n return (\n <div className=\"vuuUserPanel\" ref={forwardedRef}>\n <List<HistoryEntry>\n ListItem={HistoryListItem}\n className=\"vuuUserPanel-history\"\n onSelect={handleHisorySelected}\n selected={selected}\n source={history}\n />\n <div className=\"vuuUserPanel-buttonBar\">\n <Button aria-label=\"logout\" onClick={handleLogout}>\n <ExportIcon /> Logout\n </Button>\n </div>\n </div>\n );\n});\n", "import { VuuUser } from \"./shell\";\n\nexport interface LayoutHistoryItem {\n user: string;\n id: string;\n uniqueId: string;\n lastUpdate: number;\n}\n\nexport const getLayoutHistory = async (\n user: VuuUser\n): Promise<LayoutHistoryItem[]> => {\n const history = await fetch(`api/vui/${user.username}`, {})\n .then((response) => {\n return response.ok ? response.json() : null;\n })\n .catch(() => {\n // TODO we should set a layout with a warning here\n console.log(\"error getting history\");\n });\n\n return history;\n};\n", "import {\n ToggleButton,\n ToggleButtonGroup,\n ToggleButtonGroupChangeEventHandler,\n} from \"@heswell/salt-lab\";\nimport cx from \"classnames\";\nimport { useControlled } from \"@salt-ds/core\";\nimport { HTMLAttributes, useCallback } from \"react\";\n\nimport \"./ThemeSwitch.css\";\n\nconst classBase = \"vuuThemeSwitch\";\n\nexport type ThemeMode = \"light\" | \"dark\";\n\nexport interface ThemeSwitchProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n defaultMode?: ThemeMode;\n mode?: ThemeMode;\n onChange: (mode: ThemeMode) => void;\n}\n\nconst modes: ThemeMode[] = [\"light\", \"dark\"];\n\nexport const ThemeSwitch = ({\n className: classNameProp,\n defaultMode: defaultModeProp,\n mode: modeProp,\n onChange,\n ...htmlAttributes\n}: ThemeSwitchProps) => {\n const [mode, setMode] = useControlled<ThemeMode>({\n controlled: modeProp,\n default: defaultModeProp ?? \"light\",\n name: \"ThemeSwitch\",\n state: \"mode\",\n });\n\n const selectedIndex = modes.indexOf(mode);\n\n const handleChangeSecondary: ToggleButtonGroupChangeEventHandler =\n useCallback(\n (_evt, index) => {\n const mode = modes[index];\n setMode(mode);\n onChange(mode);\n },\n [onChange, setMode]\n );\n const className = cx(classBase, classNameProp);\n return (\n <ToggleButtonGroup\n className={className}\n {...htmlAttributes}\n onChange={handleChangeSecondary}\n selectedIndex={selectedIndex}\n >\n <ToggleButton\n aria-label=\"alert\"\n tooltipText=\"Light Theme\"\n data-icon=\"light\"\n />\n <ToggleButton\n aria-label=\"home\"\n tooltipText=\"Dark Theme\"\n data-icon=\"dark\"\n />\n </ToggleButtonGroup>\n );\n};\n", "import { Dropdown, SelectionChangeHandler } from \"@heswell/salt-lab\";\nimport { DEFAULT_DENSITY, Density } from \"@salt-ds/core\";\nimport { HTMLAttributes, useCallback } from \"react\";\nimport cx from \"classnames\";\n\nconst classBase = \"vuuDensitySwitch\";\n\nconst densities:Density[] = [\"high\", \"medium\", \"low\", \"touch\"];\n\nexport interface DensitySwitchProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n defaultDensity?: Density;\n density?: Density;\n onDensityChange: (density: Density) => void;\n}\n\nexport const DensitySwitch = ({\n className: classNameProp,\n defaultDensity=DEFAULT_DENSITY,\n onDensityChange\n}:DensitySwitchProps) => {\n\n const handleSelectionChange:SelectionChangeHandler | string = useCallback((_event, selectedItem) => {\n onDensityChange(selectedItem);\n }, [onDensityChange])\n\n const className = cx(classBase, classNameProp);\n\n return (\n <Dropdown\n className={className}\n source={densities}\n defaultSelected={defaultDensity}\n onSelectionChange={handleSelectionChange}\n />\n )\n}"],
5
- "mappings": "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",
6
- "names": ["React", "useEffect", "useState", "cx", "Fragment", "jsx", "jsxs", "ConnectionStatusIcon", "connectionStatus", "className", "element", "props", "classBase", "setClassBase", "useState", "useEffect", "statusIcon", "React", "cx", "React", "Suspense", "registerComponent", "React", "Fragment", "jsx", "jsxs", "ErrorBoundary", "props", "error", "errorInfo", "jsx", "Loader", "importCSS", "path", "container", "x", "jsx", "RawFeature", "url", "css", "params", "props", "importCSS", "styleSheet", "LazyFeature", "React", "ErrorBoundary", "Suspense", "Loader", "Feature", "registerComponent", "useState", "Button", "FormField", "Input", "jsx", "jsxs", "classBase", "LoginPanel", "onSubmit", "username", "setUserName", "useState", "password", "setPassword", "login", "handleUsername", "_event", "value", "handlePassword", "dataIsValid", "FormField", "Input", "Button", "getCookieValue", "getAuthDetailsFromCookies", "username", "token", "redirectToLogin", "loginUrl", "logout", "connectToServer", "useCallback", "useEffect", "useRef", "useState", "useCallback", "useEffect", "useState", "useLayoutConfig", "user", "defaultLayout", "layout", "_setLayout", "setLayout", "load", "id", "response", "saveData", "data", "loadLayoutById", "use_layout_config_default", "createContext", "useContext", "jsx", "defaultConfig", "ShellContext", "Provider", "children", "context", "inheritedContext", "mergedContext", "ShellContextProvider", "value", "useShellContext", "cx", "Chest", "DraggableLayout", "Drawer", "Flexbox", "LayoutProvider", "View", "useCallback", "Button", "DropdownBase", "UserSolidIcon", "formatDate", "List", "ListItem", "Button", "ExportIcon", "forwardRef", "useCallback", "useEffect", "useState", "getLayoutHistory", "user", "response", "jsx", "jsxs", "byLastUpdate", "l1", "l2", "HistoryListItem", "props", "ListItem", "UserPanel", "forwardRef", "loginUrl", "onNavigate", "user", "layoutId", "forwardedRef", "history", "setHistory", "useState", "useEffect", "getHistory", "sortedHistory", "getLayoutHistory", "item", "id", "lastUpdate", "formatDate", "handleHisorySelected", "useCallback", "evt", "selected", "handleLogout", "logout", "i", "List", "Button", "ExportIcon", "jsx", "jsxs", "UserProfile", "layoutId", "loginUrl", "onNavigate", "user", "DropdownBase", "Button", "UserSolidIcon", "UserPanel", "id", "ToggleButton", "ToggleButtonGroup", "cx", "useControlled", "useCallback", "jsx", "jsxs", "classBase", "modes", "ThemeSwitch", "classNameProp", "defaultModeProp", "modeProp", "onChange", "htmlAttributes", "mode", "setMode", "useControlled", "selectedIndex", "handleChangeSecondary", "useCallback", "_evt", "index", "className", "cx", "ToggleButtonGroup", "ToggleButton", "cx", "Dropdown", "DEFAULT_DENSITY", "useCallback", "cx", "jsx", "classBase", "densities", "DensitySwitch", "classNameProp", "defaultDensity", "onDensityChange", "handleSelectionChange", "_event", "selectedItem", "className", "jsx", "jsxs", "classBase", "AppHeader", "classNameProp", "layoutId", "loginUrl", "onNavigate", "onSwitchTheme", "themeMode", "onDensitySwitch", "density", "user", "htmlAttributes", "className", "cx", "handleSwitchTheme", "useCallback", "mode", "handleDensitySwitch", "ThemeSwitch", "DensitySwitch", "UserProfile", "jsx", "jsxs", "warningLayout", "Shell", "children", "classNameProp", "defaultLayout", "leftSidePanel", "loginUrl", "serverUrl", "user", "htmlAttributes", "rootRef", "useRef", "density", "setDensity", "useState", "paletteView", "open", "setOpen", "layoutId", "layout", "setLayoutConfig", "loadLayoutById", "use_layout_config_default", "handleLayoutChange", "useCallback", "handleSwitchTheme", "mode", "handleDensitySwitch", "handleDrawerClick", "e", "_a", "target", "handleNavigate", "id", "useEffect", "connectToServer", "getDrawers", "drawers", "Drawer", "View", "className", "cx", "ShellContextProvider", "LayoutProvider", "DraggableLayout", "Flexbox", "AppHeader", "Chest"]
3
+ "sources": ["../../../packages/vuu-shell/src/connection-status/ConnectionStatusIcon.tsx", "../../../packages/vuu-shell/src/density-switch/DensitySwitch.tsx", "../../../packages/vuu-shell/src/feature/Feature.tsx", "../../../packages/vuu-shell/src/feature/ErrorBoundary.jsx", "../../../packages/vuu-shell/src/feature/Loader.tsx", "../../../packages/vuu-shell/src/login/LoginPanel.tsx", "../../../packages/vuu-shell/src/login/login-utils.ts", "../../../packages/vuu-shell/src/shell.tsx", "../../../packages/vuu-shell/src/ShellContextProvider.tsx", "../../../packages/vuu-shell/src/use-layout-config.js", "../../../packages/vuu-shell/src/app-header/AppHeader.tsx", "../../../packages/vuu-shell/src/user-profile/UserProfile.tsx", "../../../packages/vuu-shell/src/user-profile/UserPanel.tsx", "../../../packages/vuu-shell/src/get-layout-history.ts", "../../../packages/vuu-shell/src/theme-switch/ThemeSwitch.tsx", "../../../packages/vuu-shell/src/theme-provider/ThemeProvider.tsx"],
4
+ "sourcesContent": ["import React, { useEffect, useState } from 'react';\nimport cx from 'classnames';\nimport './ConnectionStatusIcon.css';\n\ntype connectionStatus = 'connected' | 'reconnected' | 'connecting' | 'disconnected';\n\ninterface ConnectionStatusProps {\n\tconnectionStatus: connectionStatus\n\tclassName?: string;\n\tprops?: unknown;\n\telement?: string;\n}\n\nexport const ConnectionStatusIcon = ({ connectionStatus, className, element = 'span', ...props}: ConnectionStatusProps) => {\n\tconst [classBase, setClassBase] = useState<string>('vuuConnectingStatus');\n\tuseEffect(() => {\n\t\tswitch(connectionStatus) {\n\t\t\tcase 'connected':\n\t\t\tcase 'reconnected':\n\t\t\t\tsetClassBase('vuuActiveStatus');\n\t\t\t\tbreak;\n\t\t\tcase 'connecting':\n\t\t\t\tsetClassBase('vuuConnectingStatus');\n\t\t\t\tbreak;\n\t\t\tcase 'disconnected':\n\t\t\t\tsetClassBase('vuuDisconnectedStatus');\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}, [connectionStatus]);\n\n\tconst statusIcon = React.createElement (\n\t\telement,\n\t\t{\n\t\t\t...props,\n\t\t\tclassName: cx('vuuStatus vuuIcon', classBase, className)\n\t\t},\n\t)\n\n\treturn (\n\t\t<>\n\t\t\t<div className='vuuStatus-container salt-theme'>\n\t\t\t\t{statusIcon}\n\t\t\t\t<div\tclassName='vuuStatus-text'>Status: {connectionStatus.toUpperCase()}</div>\n\t\t\t</div>\n\t\t</>\n\t)\n}", "import { Dropdown } from \"@heswell/salt-lab\";\nimport { Density } from \"@salt-ds/core\";\nimport { HTMLAttributes, useCallback } from \"react\";\nimport cx from \"classnames\";\n\nconst classBase = \"vuuDensitySwitch\";\n\nconst densities:Density[] = [\"high\", \"medium\", \"low\", \"touch\"];\nconst DEFAULT_DENSITY = \"high\";\n\nexport interface DensitySwitchProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n defaultDensity?: Density;\n density?: Density;\n onDensityChange: (density: Density) => void;\n}\n\nexport const DensitySwitch = ({\n className: classNameProp,\n defaultDensity=DEFAULT_DENSITY,\n onDensityChange,\n}:DensitySwitchProps) => {\n const handleSelectionChange = useCallback((_event, selectedItem) => {\n onDensityChange(selectedItem);\n }, [onDensityChange])\n\n const className = cx(classBase, classNameProp);\n\n return (\n <Dropdown\n className={className}\n source={densities}\n defaultSelected={defaultDensity}\n onSelectionChange={handleSelectionChange}\n />\n )\n}", "import React, { Suspense } from \"react\";\nimport { registerComponent } from \"@vuu-ui/vuu-layout\";\nimport { ErrorBoundary } from \"./ErrorBoundary\";\nimport { Loader } from \"./Loader\";\n// import { importCSS } from \"./css-module-loader\";\n\nexport interface FeatureProps<Params extends object | undefined = undefined> {\n height?: number;\n url: string;\n css?: string;\n width?: number;\n params: Params;\n}\n\nfunction RawFeature<Params extends object | undefined>({\n url,\n css,\n params,\n ...props\n}: FeatureProps<Params>) {\n if (css) {\n import(/* @vite-ignore */ css, { assert: { type: \"css\" } }).then(\n (cssModule) => {\n document.adoptedStyleSheets = [\n ...document.adoptedStyleSheets,\n cssModule.default,\n ];\n }\n );\n // Polyfill until vite build supports import assertions\n // Note: already fully supported in esbuild, so vite dev\n // importCSS(css).then((styleSheet) => {\n // document.adoptedStyleSheets = [\n // ...document.adoptedStyleSheets,\n // styleSheet,\n // ];\n // });\n }\n const LazyFeature = React.lazy(() => import(/* @vite-ignore */ url));\n return (\n <ErrorBoundary>\n <Suspense fallback={<Loader />}>\n <LazyFeature {...props} {...params} />\n </Suspense>\n </ErrorBoundary>\n );\n}\n\nexport const Feature = React.memo(RawFeature);\nFeature.displayName = \"Feature\";\nregisterComponent(\"Feature\", Feature, \"view\");\n", "import React from 'react';\n// TODO\nexport class ErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = { errorMessage: null };\n }\n\n static getDerivedStateFromError(error) {\n // Update state so the next render will show the fallback UI.\n return { errorMessage: error.message };\n }\n\n componentDidCatch(error, errorInfo) {\n // You can also log the error to an error reporting service\n console.log(error, errorInfo);\n }\n\n render() {\n if (this.state.errorMessage) {\n return (\n <>\n <h1>Something went wrong.</h1>\n <p>{this.state.errorMessage}</p>\n </>\n );\n }\n\n return this.props.children;\n }\n}\n", "// TODO\nexport const Loader = () => <div className=\"hwLoader\">loading</div>;\n", "import { ChangeEvent, HTMLAttributes, useState } from \"react\";\nimport { Button } from \"@salt-ds/core\";\nimport { FormField, Input } from \"@heswell/salt-lab\";\n\nimport \"./LoginPanel.css\";\n\nconst classBase = \"vuuLoginPanel\";\n\nexport interface LoginPanelProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onSubmit\"> {\n onSubmit: (username: string, password: string) => void;\n}\n\nexport const LoginPanel = ({ onSubmit }: LoginPanelProps) => {\n const [username, setUserName] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n\n const login = () => {\n onSubmit(username, password);\n };\n\n const handleUsername = (\n _event: ChangeEvent<HTMLInputElement>,\n value: string\n ) => {\n setUserName(value);\n };\n\n const handlePassword = (\n _event: ChangeEvent<HTMLInputElement>,\n value: string\n ) => {\n setPassword(value);\n };\n\n const dataIsValid = username.trim() !== \"\" && password.trim() !== \"\";\n\n return (\n <div className={classBase}>\n <FormField label=\"Username\" style={{ width: 200 }}>\n <Input value={username} id=\"text-username\" onChange={handleUsername} />\n </FormField>\n\n <FormField label=\"Password\" style={{ width: 200 }}>\n <Input\n type=\"password\"\n value={password}\n id=\"text-password\"\n onChange={handlePassword}\n />\n </FormField>\n\n <Button\n className={`${classBase}-login`}\n disabled={!dataIsValid}\n onClick={login}\n variant=\"cta\"\n >\n Login\n </Button>\n </div>\n );\n};\n", "import { getCookieValue } from \"@vuu-ui/vuu-utils\";\n\nexport const getAuthDetailsFromCookies = () => {\n const username = getCookieValue(\"vuu-username\");\n const token = getCookieValue(\"vuu-auth-token\");\n return [username, token];\n};\n\nexport const redirectToLogin = (loginUrl = \"/login.html\") => {\n window.location.href = loginUrl;\n};\n\nexport const logout = (loginUrl?: string) => {\n document.cookie = \"vuu-username= ; expires = Thu, 01 Jan 1970 00:00:00 GMT\";\n document.cookie = \"vuu-auth-token= ; expires = Thu, 01 Jan 1970 00:00:00 GMT\";\n redirectToLogin(loginUrl);\n};\n", "import { connectToServer } from \"@vuu-ui/vuu-data\";\nimport cx from \"classnames\";\nimport {\n HTMLAttributes,\n MouseEvent,\n ReactElement,\n ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { ShellContextProvider } from \"./ShellContextProvider\";\nimport useLayoutConfig from \"./use-layout-config\";\nimport {\n DockLayout,\n DraggableLayout,\n Drawer,\n Flexbox,\n LayoutProvider,\n View,\n} from \"@vuu-ui/vuu-layout\";\nimport { LayoutJSON } from \"@vuu-ui/vuu-layout/src/layout-reducer\";\nimport { AppHeader } from \"./app-header\";\nimport { ThemeMode } from \"./theme-provider\";\n\nimport \"./shell.css\";\n\nexport type VuuUser = {\n username: string;\n token: string;\n};\n\nconst warningLayout = {\n type: \"View\",\n props: {\n style: { height: \"calc(100% - 6px)\" },\n },\n children: [\n {\n props: {\n className: \"vuuShell-warningPlaceholder\",\n },\n type: \"Placeholder\",\n },\n ],\n};\n\nexport interface ShellProps extends HTMLAttributes<HTMLDivElement> {\n children?: ReactNode;\n defaultLayout?: LayoutJSON;\n leftSidePanel?: ReactElement;\n loginUrl?: string;\n // paletteConfig: any;\n serverUrl?: string;\n user: VuuUser;\n}\n\nexport const Shell = ({\n children,\n className: classNameProp,\n defaultLayout = warningLayout,\n leftSidePanel,\n loginUrl,\n serverUrl,\n user,\n ...htmlAttributes\n}: ShellProps) => {\n const rootRef = useRef<HTMLDivElement>(null);\n const paletteView = useRef<HTMLDivElement>(null);\n const [open, setOpen] = useState(false);\n const layoutId = useRef(\"latest\");\n\n const [layout, setLayoutConfig, loadLayoutById] = useLayoutConfig(\n user,\n defaultLayout\n );\n\n const handleLayoutChange = useCallback(\n (layout) => {\n setLayoutConfig(layout);\n },\n [setLayoutConfig]\n );\n\n const handleSwitchTheme = useCallback((mode: ThemeMode) => {\n if (rootRef.current) {\n rootRef.current.dataset.mode = mode;\n }\n }, []);\n\n const handleDrawerClick = (e: MouseEvent<HTMLElement>) => {\n const target = e.target as HTMLElement;\n if (!paletteView.current?.contains(target)) {\n setOpen(!open);\n }\n };\n\n const handleNavigate = useCallback(\n (id) => {\n layoutId.current = id;\n loadLayoutById(id);\n },\n [loadLayoutById]\n );\n\n useEffect(() => {\n if (serverUrl && user.token) {\n connectToServer(serverUrl, user.token);\n }\n }, [serverUrl, user.token]);\n\n const getDrawers = () => {\n const drawers: ReactElement[] = [];\n if (leftSidePanel) {\n drawers.push(\n <Drawer\n key=\"left-panel\"\n onClick={handleDrawerClick}\n open={open}\n position=\"left\"\n inline\n peekaboo\n sizeOpen={200}\n toggleButton=\"end\"\n >\n <View\n className=\"vuuShell-palette\"\n id=\"vw-app-palette\"\n key=\"app-palette\"\n ref={paletteView}\n style={{ height: \"100%\" }}\n >\n {leftSidePanel}\n </View>\n </Drawer>\n );\n }\n\n return drawers;\n };\n\n const className = cx(\n \"vuuShell\",\n classNameProp,\n \"salt-theme\",\n \"salt-density-high\"\n );\n\n return (\n // ShellContext TBD\n <ShellContextProvider value={undefined}>\n <LayoutProvider layout={layout} onLayoutChange={handleLayoutChange}>\n <DraggableLayout\n className={className}\n data-mode=\"light\"\n ref={rootRef}\n {...htmlAttributes}\n >\n <Flexbox\n className=\"App\"\n style={{ flexDirection: \"column\", height: \"100%\", width: \"100%\" }}\n >\n <AppHeader\n layoutId={layoutId.current}\n loginUrl={loginUrl}\n user={user}\n onNavigate={handleNavigate}\n onSwitchTheme={handleSwitchTheme}\n />\n <DockLayout style={{ flex: 1 }}>\n {getDrawers().concat(\n <DraggableLayout\n dropTarget\n key=\"main-content\"\n style={{ width: \"100%\", height: \"100%\" }}\n />\n )}\n </DockLayout>\n </Flexbox>\n </DraggableLayout>\n </LayoutProvider>\n {children}\n </ShellContextProvider>\n );\n};\n", "import { MenuRpcResponse } from \"@vuu-ui/vuu-data\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { createContext, ReactElement, ReactNode, useContext } from \"react\";\n\nexport interface ShellContextProps {\n getDefaultColumnConfig?: (\n tableName: string,\n columnName: string\n ) => Partial<ColumnDescriptor>;\n handleRpcResponse?: (response?: MenuRpcResponse) => void;\n}\n\nconst defaultConfig = {};\n\nconst ShellContext = createContext<ShellContextProps>(defaultConfig);\n\nexport interface ShellProviderProps {\n children: ReactNode;\n value?: ShellContextProps;\n}\n\nconst Provider = ({\n children,\n context,\n inheritedContext,\n}: {\n children: ReactNode;\n context?: ShellContextProps;\n inheritedContext?: ShellContextProps;\n}) => {\n // TODO functions provided at multiple levels must be merged\n const mergedContext = {\n ...inheritedContext,\n ...context,\n };\n return (\n <ShellContext.Provider value={mergedContext}>\n {children}\n </ShellContext.Provider>\n );\n};\n\nexport const ShellContextProvider = ({\n children,\n value,\n}: ShellProviderProps): ReactElement => {\n return (\n <ShellContext.Consumer>\n {(context) => (\n <Provider context={value} inheritedContext={context}>\n {children}\n </Provider>\n )}\n </ShellContext.Consumer>\n );\n};\n\nexport const useShellContext = () => {\n return useContext(ShellContext);\n};\n", "import { useCallback, useEffect, useState } from \"react\";\n\nconst useLayoutConfig = (user, defaultLayout) => {\n const [layout, _setLayout] = useState(defaultLayout);\n\n const setLayout = (layout) => {\n _setLayout(layout);\n };\n\n const load = useCallback(\n async (id = \"latest\") => {\n fetch(`api/vui/${user.username}/${id}`, {})\n .then((response) => {\n return response.ok ? response.json() : defaultLayout;\n })\n .then(setLayout)\n .catch(() => {\n // TODO we should set a layout with a warning here\n setLayout(defaultLayout);\n });\n },\n [defaultLayout, user.username]\n );\n\n useEffect(() => {\n load();\n }, [load]);\n\n const saveData = useCallback(\n (data) => {\n fetch(`api/vui/${user.username}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(data),\n }).then((response) => {\n return response.ok ? response.json() : defaultLayout;\n });\n },\n [defaultLayout, user]\n );\n\n const loadLayoutById = useCallback(\n (id) => {\n load(id);\n },\n [load]\n );\n\n return [layout, saveData, loadLayoutById];\n};\n\nexport default useLayoutConfig;\n", "import { HTMLAttributes, useCallback } from \"react\";\nimport { VuuUser } from \"../shell\";\nimport { UserProfile } from \"../user-profile\";\nimport { ThemeSwitch } from \"../theme-switch\";\nimport { ThemeMode } from \"../theme-provider\";\nimport cx from \"classnames\";\n\nimport \"./AppHeader.css\";\n\nconst classBase = \"vuuAppHeader\";\nexport interface AppHeaderProps extends HTMLAttributes<HTMLDivElement> {\n layoutId: string;\n loginUrl?: string;\n onNavigate: (id: string) => void;\n onSwitchTheme?: (mode: ThemeMode) => void;\n themeMode?: ThemeMode;\n user: VuuUser;\n}\n\nexport const AppHeader = ({\n className: classNameProp,\n layoutId,\n loginUrl,\n onNavigate,\n onSwitchTheme,\n themeMode = \"light\",\n user,\n ...htmlAttributes\n}: AppHeaderProps) => {\n const className = cx(classBase, classNameProp);\n const handleSwitchTheme = useCallback(\n (mode: ThemeMode) => onSwitchTheme?.(mode),\n [onSwitchTheme]\n );\n return (\n <header className={className} {...htmlAttributes}>\n <ThemeSwitch defaultMode={themeMode} onChange={handleSwitchTheme} />\n <UserProfile\n layoutId={layoutId}\n loginUrl={loginUrl}\n onNavigate={onNavigate}\n user={user}\n />\n </header>\n );\n};\n", "import { Button } from \"@salt-ds/core\";\nimport { DropdownBase } from \"@heswell/salt-lab\";\nimport { UserSolidIcon } from \"@salt-ds/icons\";\nimport { UserPanel } from \"./UserPanel\";\n\nimport \"./UserProfile.css\";\nimport { VuuUser } from \"../shell\";\n\nexport interface UserProfileProps {\n layoutId: string;\n loginUrl?: string;\n onNavigate: (id: string) => void;\n user: VuuUser;\n}\n\nexport const UserProfile = ({\n layoutId,\n loginUrl,\n onNavigate,\n user,\n}: UserProfileProps) => {\n const handleNavigate = (id: string) => {\n onNavigate(id);\n };\n\n return (\n <DropdownBase className=\"vuuUserProfile\" placement=\"bottom-end\">\n <Button variant=\"secondary\">\n <UserSolidIcon />\n </Button>\n <UserPanel\n layoutId={layoutId}\n loginUrl={loginUrl}\n onNavigate={handleNavigate}\n user={user}\n />\n </DropdownBase>\n );\n};\n", "import { formatDate } from \"@vuu-ui/vuu-utils\";\nimport { List, ListItem, ListItemProps } from \"@heswell/salt-lab\";\nimport { Button } from \"@salt-ds/core\";\nimport { ExportIcon } from \"@salt-ds/icons\";\nimport {\n ForwardedRef,\n forwardRef,\n HTMLAttributes,\n useCallback,\n useEffect,\n useState,\n} from \"react\";\nimport { getLayoutHistory, LayoutHistoryItem } from \"../get-layout-history\";\nimport { logout } from \"../login\";\nimport { VuuUser } from \"../shell\";\n\nimport \"./UserPanel.css\";\n\nconst byLastUpdate = (\n { lastUpdate: l1 }: LayoutHistoryItem,\n { lastUpdate: l2 }: LayoutHistoryItem\n) => {\n return l2 === l1 ? 0 : l2 < l1 ? -1 : 1;\n};\n\ntype HistoryEntry = {\n id: string;\n label: string;\n lastUpdate: number;\n};\n\nconst HistoryListItem = (props: ListItemProps<HistoryEntry>) => {\n return <ListItem {...props} />;\n};\n\nexport interface UserPanelProps extends HTMLAttributes<HTMLDivElement> {\n loginUrl?: string;\n onNavigate: (id: string) => void;\n user: VuuUser;\n layoutId: string;\n}\n\nexport const UserPanel = forwardRef(function UserPanel(\n { loginUrl, onNavigate, user, layoutId = \"latest\" }: UserPanelProps,\n forwardedRef: ForwardedRef<HTMLDivElement>\n) {\n const [history, setHistory] = useState<HistoryEntry[]>([]);\n\n useEffect(() => {\n async function getHistory() {\n const history = await getLayoutHistory(user);\n const sortedHistory = history\n .filter((item) => item.id !== \"latest\")\n .sort(byLastUpdate)\n .map<HistoryEntry>(({ id, lastUpdate }) => ({\n lastUpdate,\n id,\n label: `Saved at ${formatDate(new Date(lastUpdate), \"kk:mm:ss\")}`,\n }));\n console.log({ sortedHistory });\n setHistory(sortedHistory);\n }\n\n getHistory();\n }, [user]);\n\n const handleHisorySelected = useCallback(\n (evt, selected) => {\n if (selected) {\n onNavigate(selected.id);\n }\n },\n [onNavigate]\n );\n\n const handleLogout = useCallback(() => {\n logout(loginUrl);\n }, [loginUrl]);\n\n const selected =\n history.length === 0\n ? null\n : layoutId === \"latest\"\n ? history[0]\n : history.find((i) => i.id === layoutId);\n\n return (\n <div className=\"vuuUserPanel\" ref={forwardedRef}>\n <List<HistoryEntry>\n ListItem={HistoryListItem}\n className=\"vuuUserPanel-history\"\n onSelect={handleHisorySelected}\n selected={selected}\n source={history}\n />\n <div className=\"vuuUserPanel-buttonBar\">\n <Button aria-label=\"logout\" onClick={handleLogout}>\n <ExportIcon /> Logout\n </Button>\n </div>\n </div>\n );\n});\n", "import { VuuUser } from \"./shell\";\n\nexport interface LayoutHistoryItem {\n user: string;\n id: string;\n uniqueId: string;\n lastUpdate: number;\n}\n\nexport const getLayoutHistory = async (\n user: VuuUser\n): Promise<LayoutHistoryItem[]> => {\n const history = await fetch(`api/vui/${user.username}`, {})\n .then((response) => {\n return response.ok ? response.json() : null;\n })\n .catch(() => {\n // TODO we should set a layout with a warning here\n console.log(\"error getting history\");\n });\n\n return history;\n};\n", "import {\n ToggleButton,\n ToggleButtonGroup,\n ToggleButtonGroupChangeEventHandler,\n} from \"@heswell/salt-lab\";\nimport cx from \"classnames\";\nimport { useControlled } from \"@salt-ds/core\";\nimport { HTMLAttributes, useCallback } from \"react\";\n\nimport \"./ThemeSwitch.css\";\nimport { ThemeMode } from \"../theme-provider\";\n\nconst classBase = \"vuuThemeSwitch\";\nexport interface ThemeSwitchProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n defaultMode?: ThemeMode;\n mode?: ThemeMode;\n onChange: (mode: ThemeMode) => void;\n}\n\nconst modes: ThemeMode[] = [\"light\", \"dark\"];\n\nexport const ThemeSwitch = ({\n className: classNameProp,\n defaultMode: defaultModeProp,\n mode: modeProp,\n onChange,\n ...htmlAttributes\n}: ThemeSwitchProps) => {\n const [mode, setMode] = useControlled<ThemeMode>({\n controlled: modeProp,\n default: defaultModeProp ?? \"light\",\n name: \"ThemeSwitch\",\n state: \"mode\",\n });\n\n const selectedIndex = modes.indexOf(mode);\n\n const handleChangeSecondary: ToggleButtonGroupChangeEventHandler =\n useCallback(\n (_evt, index) => {\n const mode = modes[index];\n setMode(mode);\n onChange(mode);\n },\n [onChange, setMode]\n );\n const className = cx(classBase, classNameProp);\n return (\n <ToggleButtonGroup\n className={className}\n {...htmlAttributes}\n onChange={handleChangeSecondary}\n selectedIndex={selectedIndex}\n >\n <ToggleButton\n aria-label=\"alert\"\n tooltipText=\"Light Theme\"\n data-icon=\"light\"\n />\n <ToggleButton\n aria-label=\"home\"\n tooltipText=\"Dark Theme\"\n data-icon=\"dark\"\n />\n </ToggleButtonGroup>\n );\n};\n", "import React, {\n createContext,\n HTMLAttributes,\n ReactNode,\n ReactElement,\n isValidElement,\n cloneElement,\n useContext,\n} from \"react\";\nimport cx from \"classnames\";\n\nexport const DEFAULT_DENSITY: Density = \"medium\";\nexport const DEFAULT_THEME = \"salt-theme\";\nexport const DEFAULT_THEME_MODE: ThemeMode = \"light\";\n\nexport type Density = \"high\" | \"medium\" | \"low\" | \"touch\";\nexport type ThemeMode = \"light\" | \"dark\";\nexport type TargetElement = \"root\" | \"scope\" | \"child\";\n\nexport interface ThemeContextProps {\n density: Density;\n theme: string;\n themeMode: ThemeMode;\n}\n\nexport const ThemeContext = createContext<ThemeContextProps>({\n density: \"high\",\n theme: \"salt-theme\",\n themeMode: \"light\",\n});\n\nconst createThemedChildren = (\n children: ReactNode,\n theme: string,\n themeMode: ThemeMode,\n density: Density\n) => {\n if (isValidElement<HTMLAttributes<HTMLElement>>(children)) {\n return cloneElement(children, {\n className: cx(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n children.props?.className,\n theme,\n `salt-density-${density}`\n ),\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n \"data-mode\": themeMode,\n });\n } else {\n console.warn(\n `\\nThemeProvider can only apply CSS classes for theming to a single nested child element of the ThemeProvider.\n Wrap elements with a single container`\n );\n return children;\n }\n};\n\ninterface ThemeProviderProps {\n children: ReactElement;\n density?: Density;\n theme?: string;\n themeMode?: ThemeMode;\n applyClassesTo?: TargetElement;\n}\n\nexport const ThemeProvider = ({\n children,\n theme: themeProp,\n themeMode: themeModeProp,\n density: densityProp,\n}: ThemeProviderProps) => {\n const {\n density: inheritedDensity,\n themeMode: inheritedThemeMode,\n theme: inheritedTheme,\n } = useContext(ThemeContext);\n\n const density = densityProp ?? inheritedDensity ?? DEFAULT_DENSITY;\n const themeMode = themeModeProp ?? inheritedThemeMode ?? DEFAULT_THEME_MODE;\n const theme = themeProp ?? inheritedTheme ?? DEFAULT_THEME;\n const themedChildren = createThemedChildren(\n children,\n theme,\n themeMode,\n density\n );\n\n return (\n <ThemeContext.Provider value={{ themeMode, density, theme }}>\n {themedChildren}\n </ThemeContext.Provider>\n );\n};\n\nThemeProvider.displayName = \"ThemeProvider\";\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "useEffect", "useState", "cx", "Fragment", "jsx", "jsxs", "ConnectionStatusIcon", "connectionStatus", "className", "element", "props", "classBase", "setClassBase", "useState", "useEffect", "statusIcon", "React", "cx", "Dropdown", "useCallback", "cx", "jsx", "classBase", "densities", "DEFAULT_DENSITY", "DensitySwitch", "classNameProp", "defaultDensity", "onDensityChange", "handleSelectionChange", "_event", "selectedItem", "className", "React", "Suspense", "registerComponent", "React", "Fragment", "jsx", "jsxs", "ErrorBoundary", "props", "error", "errorInfo", "jsx", "Loader", "jsx", "RawFeature", "url", "css", "params", "props", "cssModule", "LazyFeature", "React", "ErrorBoundary", "Suspense", "Loader", "Feature", "registerComponent", "useState", "Button", "FormField", "Input", "jsx", "jsxs", "classBase", "LoginPanel", "onSubmit", "username", "setUserName", "useState", "password", "setPassword", "login", "handleUsername", "_event", "value", "handlePassword", "dataIsValid", "FormField", "Input", "Button", "getCookieValue", "getAuthDetailsFromCookies", "username", "token", "redirectToLogin", "loginUrl", "logout", "connectToServer", "cx", "useCallback", "useEffect", "useRef", "useState", "createContext", "useContext", "jsx", "defaultConfig", "ShellContext", "Provider", "children", "context", "inheritedContext", "mergedContext", "ShellContextProvider", "value", "useShellContext", "useCallback", "useEffect", "useState", "useLayoutConfig", "user", "defaultLayout", "layout", "_setLayout", "setLayout", "load", "id", "response", "saveData", "data", "loadLayoutById", "use_layout_config_default", "DockLayout", "DraggableLayout", "Drawer", "Flexbox", "LayoutProvider", "View", "useCallback", "Button", "DropdownBase", "UserSolidIcon", "formatDate", "List", "ListItem", "Button", "ExportIcon", "forwardRef", "useCallback", "useEffect", "useState", "getLayoutHistory", "user", "response", "jsx", "jsxs", "byLastUpdate", "l1", "l2", "HistoryListItem", "props", "ListItem", "UserPanel", "forwardRef", "loginUrl", "onNavigate", "user", "layoutId", "forwardedRef", "history", "setHistory", "useState", "useEffect", "getHistory", "sortedHistory", "getLayoutHistory", "item", "id", "lastUpdate", "formatDate", "handleHisorySelected", "useCallback", "evt", "selected", "handleLogout", "logout", "i", "List", "Button", "ExportIcon", "jsx", "jsxs", "UserProfile", "layoutId", "loginUrl", "onNavigate", "user", "DropdownBase", "Button", "UserSolidIcon", "UserPanel", "id", "ToggleButton", "ToggleButtonGroup", "cx", "useControlled", "useCallback", "jsx", "jsxs", "classBase", "modes", "ThemeSwitch", "classNameProp", "defaultModeProp", "modeProp", "onChange", "htmlAttributes", "mode", "setMode", "useControlled", "selectedIndex", "handleChangeSecondary", "useCallback", "_evt", "index", "className", "cx", "ToggleButtonGroup", "ToggleButton", "cx", "jsx", "jsxs", "classBase", "AppHeader", "classNameProp", "layoutId", "loginUrl", "onNavigate", "onSwitchTheme", "themeMode", "user", "htmlAttributes", "className", "cx", "handleSwitchTheme", "useCallback", "mode", "ThemeSwitch", "UserProfile", "jsx", "jsxs", "warningLayout", "Shell", "children", "classNameProp", "defaultLayout", "leftSidePanel", "loginUrl", "serverUrl", "user", "htmlAttributes", "rootRef", "useRef", "paletteView", "open", "setOpen", "useState", "layoutId", "layout", "setLayoutConfig", "loadLayoutById", "use_layout_config_default", "handleLayoutChange", "useCallback", "handleSwitchTheme", "mode", "handleDrawerClick", "e", "_a", "target", "handleNavigate", "id", "useEffect", "connectToServer", "getDrawers", "drawers", "Drawer", "View", "className", "cx", "ShellContextProvider", "LayoutProvider", "DraggableLayout", "Flexbox", "AppHeader", "DockLayout", "createContext", "isValidElement", "cloneElement", "useContext", "cx", "jsx", "DEFAULT_DENSITY", "DEFAULT_THEME", "DEFAULT_THEME_MODE", "ThemeContext", "createThemedChildren", "children", "theme", "themeMode", "density", "_a", "ThemeProvider", "themeProp", "themeModeProp", "densityProp", "_b", "_c", "inheritedDensity", "inheritedThemeMode", "inheritedTheme", "themedChildren"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vuu-ui/vuu-shell",
3
- "version": "0.6.25",
3
+ "version": "0.6.26",
4
4
  "description": "VUU UI Shell",
5
5
  "author": "heswell",
6
6
  "license": "Apache-2.0",
@@ -8,9 +8,9 @@
8
8
  "@salt-ds/core": "1.2.0",
9
9
  "@salt-ds/icons": "1.1.0",
10
10
  "@heswell/salt-lab": "1.0.0-alpha.2",
11
- "@vuu-ui/vuu-data": "0.6.25",
12
- "@vuu-ui/vuu-layout": "0.6.25",
13
- "@vuu-ui/vuu-utils": "0.6.25"
11
+ "@vuu-ui/vuu-data": "0.6.26",
12
+ "@vuu-ui/vuu-layout": "0.6.26",
13
+ "@vuu-ui/vuu-utils": "0.6.26"
14
14
  },
15
15
  "peerDependencies": {
16
16
  "classnames": "^2.2.6",
@@ -1,16 +1,13 @@
1
1
  import { HTMLAttributes } from "react";
2
2
  import { VuuUser } from "../shell";
3
- import { ThemeMode } from "../theme-switch";
3
+ import { ThemeMode } from "../theme-provider";
4
4
  import "./AppHeader.css";
5
- import { Density } from "@salt-ds/core";
6
5
  export interface AppHeaderProps extends HTMLAttributes<HTMLDivElement> {
7
6
  layoutId: string;
8
7
  loginUrl?: string;
9
8
  onNavigate: (id: string) => void;
10
9
  onSwitchTheme?: (mode: ThemeMode) => void;
11
10
  themeMode?: ThemeMode;
12
- onDensitySwitch?: (density: Density) => void;
13
- density?: Density;
14
11
  user: VuuUser;
15
12
  }
16
- export declare const AppHeader: ({ className: classNameProp, layoutId, loginUrl, onNavigate, onSwitchTheme, themeMode, onDensitySwitch, density, user, ...htmlAttributes }: AppHeaderProps) => JSX.Element;
13
+ export declare const AppHeader: ({ className: classNameProp, layoutId, loginUrl, onNavigate, onSwitchTheme, themeMode, user, ...htmlAttributes }: AppHeaderProps) => JSX.Element;
@@ -5,4 +5,4 @@ export interface DensitySwitchProps extends Omit<HTMLAttributes<HTMLDivElement>,
5
5
  density?: Density;
6
6
  onDensityChange: (density: Density) => void;
7
7
  }
8
- export declare const DensitySwitch: ({ className: classNameProp, defaultDensity, onDensityChange }: DensitySwitchProps) => JSX.Element;
8
+ export declare const DensitySwitch: ({ className: classNameProp, defaultDensity, onDensityChange, }: DensitySwitchProps) => JSX.Element;
package/types/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  export * from "./connection-status";
2
+ export * from "./density-switch";
2
3
  export * from "./feature";
3
4
  export * from "./login";
4
5
  export * from "./shell";
5
6
  export * from "./shellTypes";
6
7
  export * from "./ShellContextProvider";
8
+ export * from "./theme-provider";
7
9
  export * from "./theme-switch";
@@ -1,18 +1,25 @@
1
1
  import React, { ReactElement } from "react";
2
- export declare const DEFAULT_DENSITY = "medium";
2
+ export declare const DEFAULT_DENSITY: Density;
3
3
  export declare const DEFAULT_THEME = "salt-theme";
4
+ export declare const DEFAULT_THEME_MODE: ThemeMode;
4
5
  export type Density = "high" | "medium" | "low" | "touch";
6
+ export type ThemeMode = "light" | "dark";
7
+ export type TargetElement = "root" | "scope" | "child";
5
8
  export interface ThemeContextProps {
6
- density?: Density;
7
- themes?: string[];
8
- theme?: string;
9
+ density: Density;
10
+ theme: string;
11
+ themeMode: ThemeMode;
9
12
  }
10
13
  export declare const ThemeContext: React.Context<ThemeContextProps>;
11
14
  interface ThemeProviderProps {
12
15
  children: ReactElement;
13
16
  density?: Density;
14
17
  theme?: string;
15
- applyClassesToChild?: true;
18
+ themeMode?: ThemeMode;
19
+ applyClassesTo?: TargetElement;
16
20
  }
17
- export declare const ThemeProvider: ({ children, density: densityProp, theme: themeProp, }: ThemeProviderProps) => JSX.Element;
21
+ export declare const ThemeProvider: {
22
+ ({ children, theme: themeProp, themeMode: themeModeProp, density: densityProp, }: ThemeProviderProps): JSX.Element;
23
+ displayName: string;
24
+ };
18
25
  export {};
@@ -0,0 +1 @@
1
+ export * from "./ThemeProvider";
@@ -1,6 +1,6 @@
1
1
  import { HTMLAttributes } from "react";
2
2
  import "./ThemeSwitch.css";
3
- export type ThemeMode = "light" | "dark";
3
+ import { ThemeMode } from "../theme-provider";
4
4
  export interface ThemeSwitchProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
5
5
  defaultMode?: ThemeMode;
6
6
  mode?: ThemeMode;