@leverege/imaginarium-ui 1.2.2 → 1.4.0
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/lib/ImaginariumApp-D7jCl_VH.js +514 -0
- package/lib/ImaginariumApp-D7jCl_VH.js.map +1 -0
- package/lib/ImaginariumApp-DeLr4nad.cjs +2 -0
- package/lib/ImaginariumApp-DeLr4nad.cjs.map +1 -0
- package/lib/MarkdownPageDoc-BZF02iL5.cjs +2 -0
- package/lib/MarkdownPageDoc-BZF02iL5.cjs.map +1 -0
- package/lib/MarkdownPageDoc-DR1FmNpF.js +157 -0
- package/lib/MarkdownPageDoc-DR1FmNpF.js.map +1 -0
- package/lib/PluginSetup-BJlPsEwp.cjs +116 -0
- package/lib/PluginSetup-BJlPsEwp.cjs.map +1 -0
- package/lib/{PluginSetup-BQk4FFh9.js → PluginSetup-Bi8huSsp.js} +980 -835
- package/lib/PluginSetup-Bi8huSsp.js.map +1 -0
- package/lib/{PluginSetup-NL8jYfpN.js → PluginSetup-CTRJO5hU.js} +164 -118
- package/lib/PluginSetup-CTRJO5hU.js.map +1 -0
- package/lib/PluginSetup-CuLezaDw.cjs +45 -0
- package/lib/PluginSetup-CuLezaDw.cjs.map +1 -0
- package/lib/{PluginSetup-Co-WnS3V.js → PluginSetup-DNKri9P1.js} +2 -2
- package/lib/{PluginSetup-Co-WnS3V.js.map → PluginSetup-DNKri9P1.js.map} +1 -1
- package/lib/{PluginSetup-CQPpS_Js.cjs → PluginSetup-De9E1hRC.cjs} +2 -2
- package/lib/{PluginSetup-CQPpS_Js.cjs.map → PluginSetup-De9E1hRC.cjs.map} +1 -1
- package/lib/PluginTypes-BmYA5_B9.cjs +2 -0
- package/lib/PluginTypes-BmYA5_B9.cjs.map +1 -0
- package/lib/PluginTypes-mZ4TjxPV.js +9 -0
- package/lib/PluginTypes-mZ4TjxPV.js.map +1 -0
- package/lib/docs/DocsPanel.d.ts +15 -0
- package/lib/docs/DocsPanel.d.ts.map +1 -0
- package/lib/docs/MarkdownPageDoc.d.ts +8 -0
- package/lib/docs/MarkdownPageDoc.d.ts.map +1 -0
- package/lib/docs/PageDoc.d.ts +9 -0
- package/lib/docs/PageDoc.d.ts.map +1 -0
- package/lib/docs/PageDocsContext.d.ts +12 -0
- package/lib/docs/PageDocsContext.d.ts.map +1 -0
- package/lib/docs/index.d.ts +5 -0
- package/lib/docs/index.d.ts.map +1 -0
- package/lib/docs/mdComponents.d.ts +21 -0
- package/lib/docs/mdComponents.d.ts.map +1 -0
- package/lib/imp/release/ImpPageDoc.d.ts +3 -0
- package/lib/imp/release/ImpPageDoc.d.ts.map +1 -0
- package/lib/imp/release/PluginSetup.d.ts.map +1 -1
- package/lib/imp/release/TranslationsTab.d.ts.map +1 -1
- package/lib/imp/release/sortConfigIdsByName.d.ts +6 -0
- package/lib/imp/release/sortConfigIdsByName.d.ts.map +1 -0
- package/lib/index.cjs +1 -1
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +75 -72
- package/lib/mdComponents-BiOJ7Epf.cjs +16 -0
- package/lib/mdComponents-BiOJ7Epf.cjs.map +1 -0
- package/lib/mdComponents-kPa8Rxqz.js +6792 -0
- package/lib/mdComponents-kPa8Rxqz.js.map +1 -0
- package/lib/plugins/PluginTypes.d.ts +1 -0
- package/lib/plugins/PluginTypes.d.ts.map +1 -1
- package/lib/plugins/registry.d.ts +3 -1
- package/lib/plugins/registry.d.ts.map +1 -1
- package/lib/plugins/types.d.ts +5 -0
- package/lib/plugins/types.d.ts.map +1 -1
- package/lib/plugins.cjs +1 -1
- package/lib/plugins.js +2 -2
- package/lib/registry-Bq42i86Q.cjs +2 -0
- package/lib/registry-Bq42i86Q.cjs.map +1 -0
- package/lib/registry-CMZCG8pH.js +44 -0
- package/lib/registry-CMZCG8pH.js.map +1 -0
- package/lib/release.cjs +1 -1
- package/lib/release.js +1 -1
- package/lib/secret.cjs +1 -1
- package/lib/secret.js +1 -1
- package/lib/shell/Shell.d.ts.map +1 -1
- package/lib/shell.cjs +1 -1
- package/lib/shell.js +1 -1
- package/lib/system/PluginSetup.d.ts.map +1 -1
- package/lib/system/SystemPageDoc.d.ts +3 -0
- package/lib/system/SystemPageDoc.d.ts.map +1 -0
- package/lib/system.cjs +1 -1
- package/lib/system.js +2 -2
- package/package.json +2 -1
- package/src/docs/DocsPanel.tsx +80 -0
- package/src/docs/MarkdownPageDoc.tsx +35 -0
- package/src/docs/PageDoc.ts +12 -0
- package/src/docs/PageDocsContext.tsx +37 -0
- package/src/docs/index.ts +4 -0
- package/src/docs/mdComponents.tsx +75 -0
- package/src/imp/release/ImpPageDoc.ts +117 -0
- package/src/imp/release/PluginSetup.ts +3 -0
- package/src/imp/release/TranslationsTab.tsx +76 -54
- package/src/imp/release/sortConfigIdsByName.ts +12 -0
- package/src/index.ts +4 -0
- package/src/plugins/PluginTypes.ts +1 -0
- package/src/plugins/registry.ts +13 -2
- package/src/plugins/types.ts +6 -0
- package/src/shell/Shell.tsx +48 -14
- package/src/system/PluginSetup.ts +4 -0
- package/src/system/SystemPageDoc.ts +49 -0
- package/lib/ImaginariumApp-Bp1toCAd.js +0 -437
- package/lib/ImaginariumApp-Bp1toCAd.js.map +0 -1
- package/lib/ImaginariumApp-DpQNMjG_.cjs +0 -2
- package/lib/ImaginariumApp-DpQNMjG_.cjs.map +0 -1
- package/lib/PluginSetup-3m6kjRze.cjs +0 -2
- package/lib/PluginSetup-3m6kjRze.cjs.map +0 -1
- package/lib/PluginSetup-BQk4FFh9.js.map +0 -1
- package/lib/PluginSetup-DoIf-dYR.cjs +0 -5
- package/lib/PluginSetup-DoIf-dYR.cjs.map +0 -1
- package/lib/PluginSetup-NL8jYfpN.js.map +0 -1
- package/lib/PluginTypes-C4a2lmPj.cjs +0 -2
- package/lib/PluginTypes-C4a2lmPj.cjs.map +0 -1
- package/lib/PluginTypes-DsLT43Y8.js +0 -8
- package/lib/PluginTypes-DsLT43Y8.js.map +0 -1
- package/lib/SystemConfigsContext-D0hXRSH-.js +0 -128
- package/lib/SystemConfigsContext-D0hXRSH-.js.map +0 -1
- package/lib/SystemConfigsContext-yOuS10VO.cjs +0 -2
- package/lib/SystemConfigsContext-yOuS10VO.cjs.map +0 -1
- package/lib/registry-8kQ494RA.js +0 -36
- package/lib/registry-8kQ494RA.js.map +0 -1
- package/lib/registry-CHzOVHAg.cjs +0 -2
- package/lib/registry-CHzOVHAg.cjs.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const e=require("react/jsx-runtime"),d=require("react"),T=require("@tanstack/react-query"),p=require("@leverege/plugin"),J=require("./Tooltip-DQn1fHhM.cjs"),a=require("./Card-CHVaz_7u.cjs"),K=require("@radix-ui/react-toast"),X=require("class-variance-authority"),S=require("lucide-react"),w=require("./registry-Bq42i86Q.cjs"),h=require("wouter"),D=require("./mdComponents-BiOJ7Epf.cjs");function _(t){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const n in t)if(n!=="default"){const o=Object.getOwnPropertyDescriptor(t,n);Object.defineProperty(r,n,o.get?o:{enumerable:!0,get:()=>t[n]})}}return r.default=t,Object.freeze(r)}const v=_(d),u=_(K),A=d.createContext({tabMarkdown:null,setTabMarkdown:()=>{}});function Y({children:t}){const[r,n]=d.useState(null);return e.jsx(A.Provider,{value:{tabMarkdown:r,setTabMarkdown:n},children:t})}function Z(t){const{setTabMarkdown:r}=d.useContext(A);d.useEffect(()=>(r(t),()=>{r(null)}),[t,r])}function ee(){return d.useContext(A).tabMarkdown}const M=t=>a.cn("flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs font-medium transition-colors",t?"border-primary/50 bg-primary/10 text-primary":"border-border bg-card text-muted-foreground hover:border-primary/30 hover:text-foreground"),O=()=>e.jsx("span",{className:"flex h-3.5 w-3.5 items-center justify-center rounded-full border border-current text-[9px] font-bold leading-none",children:"i"});function L({href:t,open:r=!1,onToggle:n}){return t!=null?e.jsx("div",{children:e.jsxs("a",{href:t,target:"_blank",rel:"noopener noreferrer",className:M(!1),children:[e.jsx(O,{}),"Docs"]})}):e.jsx("div",{children:e.jsxs("button",{onClick:n,className:M(r),children:[e.jsx(O,{}),"Docs"]})})}function te({pageDocs:t,tabMarkdown:r,onClose:n}){const o=t.path.replace(/^\//,"")||"docs",s=t.component;return e.jsxs("aside",{className:"absolute right-0 top-0 bottom-0 z-20 w-[26rem] border-l border-border bg-card flex flex-col overflow-hidden shadow-xl",children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-border",children:[e.jsx("span",{className:"text-sm font-semibold text-foreground",children:o}),e.jsx("button",{onClick:n,className:"text-xs text-muted-foreground hover:text-foreground transition-colors","aria-label":"Close docs panel",children:"✕"})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto px-4 py-4",children:[r!=null&&e.jsxs(e.Fragment,{children:[e.jsx(D.Markdown,{components:D.mdComponents,children:r}),e.jsx("hr",{className:"border-border my-3"})]}),s!=null&&e.jsx(s,{})]})]})}function re(t){const{element:r}=t;return d.isValidElement(r)?r:typeof r=="function"?d.createElement(r):r}function V({fallback:t,children:r}){return e.jsx(Y,{children:e.jsx(ne,{fallback:t,children:r})})}function ne({fallback:t,children:r}){const n=w.getPages(),[o,s]=d.useState(!1),[c]=h.useLocation(),i=w.getPageDocs(c);d.useEffect(()=>{s(!1)},[c]);const x=ee();return e.jsxs("div",{className:"relative flex flex-1 overflow-hidden",children:[e.jsxs("main",{className:"relative flex-1 overflow-y-auto",children:[i!=null&&e.jsx("div",{className:"flex justify-end px-6 pt-4",children:i.href!=null?e.jsx(L,{href:i.href}):e.jsx(L,{open:o,onToggle:()=>s(m=>!m)})}),e.jsxs("div",{className:"px-6 pb-6 pt-4",children:[r,e.jsxs(h.Switch,{children:[n.map(m=>e.jsx(h.Route,{path:m.path,children:re(m)},m.path)),e.jsx(h.Route,{children:t??e.jsx("div",{className:"p-8 text-muted-foreground",children:"Not found"})})]})]})]}),o&&i!=null&&i.href==null&&e.jsx(te,{pageDocs:i,tabMarkdown:x,onClose:()=>s(!1)})]})}function se(t){const r=[],n=new Map;for(const s of t){if(!s.section){r.push(s);continue}n.has(s.section)||n.set(s.section,{label:s.section,sectionSort:s.sectionSort??s.sort??0,items:[]}),n.get(s.section).items.push(s)}r.sort((s,c)=>(s.sort??0)-(c.sort??0));const o=Array.from(n.values());for(const s of o)s.items.sort((c,i)=>(c.sort??0)-(i.sort??0));return o.sort((s,c)=>{const i=s.sectionSort-c.sectionSort;return i!==0?i:s.label.localeCompare(c.label)}),{ungrouped:r,sections:o}}const B="imaginarium.ui.sidebar.collapsed",$="imaginarium.ui.sidebar.sections";function oe(t,r){try{const n=localStorage.getItem(t);return n===null?r:n==="true"}catch{return r}}function ae(){try{const t=localStorage.getItem($);if(!t)return new Set;const r=JSON.parse(t);return new Set(Array.isArray(r)?r:[])}catch{return new Set}}const ie=/^(https?:|data:|blob:|\/|\.\/|\.\.\/)/;function ce(t,r){if(!t)return null;if(typeof t=="string")return ie.test(t)?e.jsx("img",{src:t,alt:"",className:r}):e.jsx("span",{className:`${t} ${r}`,"aria-hidden":"true"});const n=t;return e.jsx(n,{className:r})}function z({title:t="Imaginarium",titleIcon:r,rightSlot:n}){const[o]=h.useLocation(),[s,c]=d.useState(()=>oe(B,!1)),[i,x]=d.useState(ae);d.useEffect(()=>{try{localStorage.setItem(B,String(s))}catch{}},[s]),d.useEffect(()=>{try{localStorage.setItem($,JSON.stringify(Array.from(i)))}catch{}},[i]);const m=d.useCallback(()=>c(l=>!l),[]),j=d.useCallback(l=>{x(g=>{const f=new Set(g);return f.has(l)?f.delete(l):f.add(l),f})},[]),{ungrouped:b,sections:N}=se(w.getNavItems()),C=w.getTopBarItems();return e.jsxs("aside",{className:a.cn("flex flex-col flex-shrink-0 border-r bg-background transition-[width] duration-200 ease-in-out overflow-hidden",s?"w-[52px]":"w-[220px]"),children:[e.jsxs("div",{className:"flex h-[52px] flex-shrink-0 items-center border-b px-2.5 gap-2",children:[!s&&ce(r,"h-6 w-6"),!s&&e.jsx("span",{className:"flex-1 truncate text-sm font-semibold",children:t}),e.jsx("button",{onClick:m,"aria-label":s?"Expand sidebar":"Collapse sidebar",className:a.cn("flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md border text-muted-foreground","hover:bg-accent hover:text-accent-foreground transition-colors",s&&"mx-auto border-transparent"),children:e.jsx(S.ChevronLeft,{className:a.cn("h-4 w-4 transition-transform duration-200",s&&"rotate-180")})})]}),e.jsxs("nav",{className:"flex flex-1 flex-col gap-0.5 overflow-y-auto overflow-x-hidden p-1.5",children:[b.map(({path:l,label:g,icon:f})=>{const y=o===l||o.startsWith(`${l}/`);return e.jsxs(h.Link,{href:l,title:s?g:void 0,className:a.cn("relative flex items-center gap-2.5 rounded-md px-2 py-1.5 text-sm text-muted-foreground","hover:bg-accent hover:text-accent-foreground transition-colors whitespace-nowrap",y&&"bg-accent/50 text-accent-foreground font-medium",s&&"justify-center px-2"),children:[f&&e.jsx(f,{className:"h-4 w-4 flex-shrink-0"}),!s&&e.jsx("span",{children:g})]},l)}),N.map(l=>{const g=!s&&i.has(l.label);return e.jsxs("div",{className:"flex flex-col",children:[e.jsx("div",{className:"my-1.5 h-px bg-border"}),!s&&e.jsxs("button",{onClick:()=>j(l.label),className:a.cn("flex items-center justify-between px-2 pb-1 pt-2.5","text-[10px] font-semibold uppercase tracking-widest text-muted-foreground","hover:text-foreground transition-colors cursor-pointer rounded-sm"),children:[l.label,e.jsx(S.ChevronDown,{className:a.cn("h-3 w-3 transition-transform duration-200",g&&"-rotate-90")})]}),e.jsx("div",{className:a.cn("flex flex-col gap-0.5 overflow-hidden transition-all duration-200",g?"max-h-0 opacity-0":"max-h-screen opacity-100"),children:l.items.map(({path:f,label:y,icon:q})=>{const W=o===f||o.startsWith(`${f}/`);return e.jsxs(h.Link,{href:f,title:s?y:void 0,className:a.cn("relative flex items-center gap-2.5 rounded-md px-2 py-1.5 text-sm text-muted-foreground","hover:bg-accent hover:text-accent-foreground transition-colors whitespace-nowrap",W&&"bg-accent/50 text-accent-foreground font-medium",s&&"justify-center px-2"),children:[q&&e.jsx(q,{className:"h-4 w-4 flex-shrink-0"}),!s&&e.jsx("span",{children:y})]},f)})})]},l.label)})]}),e.jsxs("div",{className:a.cn("flex flex-shrink-0 items-center border-t p-1.5",s?"flex-col gap-1":"flex-row justify-end gap-0.5"),children:[!s&&n,C.map(l=>{const g=l.component;return e.jsx(g,{},l.id)})]})]})}const F=u.Provider,k=v.forwardRef(({className:t,...r},n)=>e.jsx(u.Viewport,{ref:n,className:a.cn("fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",t),...r}));k.displayName=u.Viewport.displayName;const le=X.cva("group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",{variants:{variant:{default:"border bg-background text-foreground",destructive:"destructive group border-destructive bg-destructive text-destructive-foreground"}},defaultVariants:{variant:"default"}}),P=v.forwardRef(({className:t,variant:r,...n},o)=>e.jsx(u.Root,{ref:o,className:a.cn(le({variant:r}),t),...n}));P.displayName=u.Root.displayName;const G=v.forwardRef(({className:t,...r},n)=>e.jsx(u.Action,{ref:n,className:a.cn("inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",t),...r}));G.displayName=u.Action.displayName;const I=v.forwardRef(({className:t,...r},n)=>e.jsx(u.Close,{ref:n,className:a.cn("absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100",t),"toast-close":"",...r,children:e.jsx(S.X,{className:"h-4 w-4"})}));I.displayName=u.Close.displayName;const R=v.forwardRef(({className:t,...r},n)=>e.jsx(u.Title,{ref:n,className:a.cn("text-sm font-semibold",t),...r}));R.displayName=u.Title.displayName;const E=v.forwardRef(({className:t,...r},n)=>e.jsx(u.Description,{ref:n,className:a.cn("text-sm opacity-90",t),...r}));E.displayName=u.Description.displayName;function Q(){const{toasts:t}=a.useToast();return e.jsxs(F,{children:[t.map(({id:r,title:n,description:o,action:s,...c})=>e.jsxs(P,{...c,children:[e.jsxs("div",{className:"grid gap-1",children:[n&&e.jsx(R,{children:n}),o&&e.jsx(E,{children:o})]}),s,e.jsx(I,{})]},r)),e.jsx(k,{})]})}function de({className:t}){return e.jsxs("svg",{viewBox:"0 0 24 24",className:t,"aria-hidden":"true",children:[e.jsx("path",{fill:"#4285F4",d:"M23.49 12.27c0-.79-.07-1.54-.19-2.27H12v4.51h6.16c-.27 1.4-1.04 2.59-2.21 3.41v2.77h3.59c2.08-1.92 3.95-4.74 3.95-8.42z"}),e.jsx("path",{fill:"#34A853",d:"M12 24c2.97 0 5.46-.98 7.28-2.66l-3.59-2.77c-.98.66-2.23 1.06-3.69 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 21.53 7.7 24 12 24z"}),e.jsx("path",{fill:"#FBBC05",d:"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"}),e.jsx("path",{fill:"#EA4335",d:"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"})]})}const ue={auth_failed:"Sign-in failed. Please try again."};function fe(){if(typeof window>"u")return;const t=new URLSearchParams(window.location.search).get("error");if(t)return ue[t]??`Sign-in error: ${t}`}function H({loginPath:t,title:r="Sign in",subtitle:n,buttonLabel:o="Sign in with Google",backgroundUrl:s,errorMessage:c}){const i=c??fe(),x=!!s;return e.jsx("div",{className:"min-h-screen flex items-center justify-center bg-background bg-cover bg-center px-4",style:x?{backgroundImage:`url(${s})`}:void 0,children:e.jsxs(a.Card,{className:`w-full max-w-md ${x?"backdrop-blur-sm bg-card/90":""}`,children:[e.jsxs(a.CardHeader,{className:"text-center",children:[e.jsx(a.CardTitle,{children:r}),n&&e.jsx(a.CardDescription,{children:n})]}),e.jsxs(a.CardContent,{className:"space-y-4",children:[i&&e.jsx("div",{className:"rounded-md border border-destructive bg-destructive/10 px-4 py-2 text-sm text-destructive",children:i}),e.jsxs(a.Button,{className:"w-full",variant:"outline",onClick:()=>{window.location.href=t},children:[e.jsx(de,{className:"h-5 w-5 mr-2"}),o]})]})]})})}function U({children:t}){const{fetchJson:r}=a.useImaginariumApi(),n=p.Config.get("ImaginariumApp","userPath","/auth/user"),{isPending:o,isError:s}=T.useQuery({queryKey:["imaginarium","auth","user",n],queryFn:()=>r(n),retry:!1,refetchOnWindowFocus:!1});if(o)return e.jsx("div",{className:"p-8 text-muted-foreground",children:"Checking sign-in…"});if(s){const c=p.Config.get("ImaginariumApp","loginPage",H),i=p.Config.get("ImaginariumApp","loginTitle",void 0),x=p.Config.get("ImaginariumApp","loginSubtitle",void 0),m=p.Config.get("ImaginariumApp","loginButtonLabel",void 0),j=p.Config.get("ImaginariumApp","loginPath","/api/login"),b=p.Config.get("ImaginariumApp","loginBackgroundUrl",void 0),N=p.Config.get("ImaginariumApp","title","Imaginarium"),C=i??`Sign in to ${N}`;return d.createElement(c,{loginPath:j,title:C,subtitle:x,buttonLabel:m,backgroundUrl:b})}return e.jsx(e.Fragment,{children:t})}function me(t){const r=w.getProviders();let n=t;for(const{component:o}of r)n=e.jsx(o,{children:n});return n}const xe=new T.QueryClient({defaultOptions:{queries:{retry:!1,refetchOnWindowFocus:!1}}});function pe({title:t,titleIcon:r,navRightSlot:n,shellFallback:o,children:s}){return me(e.jsxs("div",{className:"flex h-screen overflow-hidden bg-background text-foreground",children:[e.jsx(z,{title:t,titleIcon:r,rightSlot:n}),e.jsx(V,{fallback:o,children:s})]}))}function ge({apiBaseUrl:t="/api",queryClient:r,title:n,titleIcon:o,navRightSlot:s,shellFallback:c,children:i}){const x=d.useMemo(()=>r??xe,[r]),m=p.Config.get("ImaginariumApp","requireAuth",!0),j=o??p.Config.get("ImaginariumApp","titleIcon",void 0),b=e.jsx(pe,{title:n,titleIcon:j,navRightSlot:s,shellFallback:c,children:i});return e.jsx(T.QueryClientProvider,{client:x,children:e.jsx(J.TooltipProvider,{children:e.jsxs(a.ImaginariumApiProvider,{apiBaseUrl:t,children:[m?e.jsx(U,{children:b}):b,e.jsx(Q,{})]})})})}exports.AppSidebar=z;exports.ImaginariumApp=ge;exports.LoginPage=H;exports.RequireAuth=U;exports.Shell=V;exports.Toast=P;exports.ToastAction=G;exports.ToastClose=I;exports.ToastDescription=E;exports.ToastProvider=F;exports.ToastTitle=R;exports.ToastViewport=k;exports.Toaster=Q;exports.useRegisterTabDocs=Z;
|
|
2
|
+
//# sourceMappingURL=ImaginariumApp-DeLr4nad.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImaginariumApp-DeLr4nad.cjs","sources":["../src/docs/PageDocsContext.tsx","../src/docs/DocsPanel.tsx","../src/shell/Shell.tsx","../src/shell/groupNavItems.ts","../src/shell/AppSidebar.tsx","../src/components/ui/Toast.tsx","../src/components/ui/Toaster.tsx","../src/auth/LoginPage.tsx","../src/auth/RequireAuth.tsx","../src/shell/ImaginariumApp.tsx"],"sourcesContent":["import { createContext, useContext, useEffect, useState, type ReactNode } from 'react'\n\ninterface PageDocsContextValue {\n tabMarkdown: string | null\n setTabMarkdown: ( markdown: string | null ) => void\n}\n\nconst PageDocsContext = createContext<PageDocsContextValue>( {\n tabMarkdown: null,\n setTabMarkdown: () => {},\n} )\n\nexport function PageDocsProvider( { children }: { children: ReactNode } ) {\n const [ tabMarkdown, setTabMarkdown ] = useState<string | null>( null )\n return (\n <PageDocsContext.Provider value={{ tabMarkdown, setTabMarkdown }}>\n {children}\n </PageDocsContext.Provider>\n )\n}\n\n/**\n * Call inside a page component to register tab-specific docs.\n * When the component unmounts or markdown changes, the panel falls back\n * to the page-level docs registered via addPageDocs().\n */\nexport function useRegisterTabDocs( markdown: string ) {\n const { setTabMarkdown } = useContext( PageDocsContext )\n useEffect( () => {\n setTabMarkdown( markdown )\n return () => { setTabMarkdown( null ) }\n }, [ markdown, setTabMarkdown ] )\n}\n\nexport function useActiveTabDocs(): string | null {\n return useContext( PageDocsContext ).tabMarkdown\n}\n","import ReactMarkdown from 'react-markdown'\nimport { cn } from '../lib/utils'\nimport type { PageDocsPlugin } from '../plugins/types'\nimport { mdComponents } from './mdComponents'\n\ninterface DocsTriggerProps {\n href?: string\n open?: boolean\n onToggle?: () => void\n}\n\nconst triggerClass = ( active: boolean ) => cn(\n 'flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs font-medium transition-colors',\n active\n ? 'border-primary/50 bg-primary/10 text-primary'\n : 'border-border bg-card text-muted-foreground hover:border-primary/30 hover:text-foreground'\n)\n\nconst TriggerIcon = () => (\n <span className=\"flex h-3.5 w-3.5 items-center justify-center rounded-full border border-current text-[9px] font-bold leading-none\">\n i\n </span>\n)\n\nexport function DocsTrigger( { href, open = false, onToggle }: DocsTriggerProps ) {\n if ( href != null ) {\n return (\n <div>\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" className={triggerClass( false )}>\n <TriggerIcon />\n Docs\n </a>\n </div>\n )\n }\n return (\n <div>\n <button onClick={onToggle} className={triggerClass( open )}>\n <TriggerIcon />\n Docs\n </button>\n </div>\n )\n}\n\ninterface DocsSidePanelProps {\n pageDocs: PageDocsPlugin\n tabMarkdown: string | null\n onClose: () => void\n}\n\nexport function DocsSidePanel( { pageDocs, tabMarkdown, onClose }: DocsSidePanelProps ) {\n const title = pageDocs.path.replace( /^\\//, '' ) || 'docs'\n const Component = pageDocs.component\n\n return (\n <aside className=\"absolute right-0 top-0 bottom-0 z-20 w-[26rem] border-l border-border bg-card flex flex-col overflow-hidden shadow-xl\">\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border\">\n <span className=\"text-sm font-semibold text-foreground\">{title}</span>\n <button\n onClick={onClose}\n className=\"text-xs text-muted-foreground hover:text-foreground transition-colors\"\n aria-label=\"Close docs panel\"\n >\n ✕\n </button>\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-4 py-4\">\n {tabMarkdown != null && (\n <>\n <ReactMarkdown components={mdComponents}>{tabMarkdown}</ReactMarkdown>\n <hr className=\"border-border my-3\" />\n </>\n )}\n {Component != null && <Component />}\n </div>\n </aside>\n )\n}\n","import { isValidElement, createElement, useState, useEffect, type ReactNode } from 'react'\nimport { Route, Switch, useLocation } from 'wouter'\n\nimport { getPageDocs, getPages } from '../plugins/registry'\nimport { PageDocsProvider, useActiveTabDocs } from '../docs/PageDocsContext'\nimport { DocsTrigger, DocsSidePanel } from '../docs/DocsPanel'\nimport type { PagePlugin } from '../plugins/types'\n\nfunction renderPageElement( plugin: PagePlugin ): ReactNode {\n const { element } = plugin\n if ( isValidElement( element ) ) { return element }\n if ( typeof element === 'function' ) {\n return createElement( element as React.ComponentType )\n }\n return element as ReactNode\n}\n\nexport interface ShellProps {\n fallback?: ReactNode\n children?: ReactNode\n}\n\nexport function Shell( { fallback, children }: ShellProps ) {\n return (\n <PageDocsProvider>\n <ShellContent fallback={fallback}>{children}</ShellContent>\n </PageDocsProvider>\n )\n}\n\nfunction ShellContent( { fallback, children }: ShellProps ) {\n const pages = getPages()\n const [ open, setOpen ] = useState( false )\n const [ location ] = useLocation()\n const pageDocs = getPageDocs( location )\n\n useEffect( () => { setOpen( false ) }, [ location ] )\n const tabMarkdown = useActiveTabDocs()\n\n return (\n <div className=\"relative flex flex-1 overflow-hidden\">\n <main className=\"relative flex-1 overflow-y-auto\">\n {pageDocs != null && (\n <div className=\"flex justify-end px-6 pt-4\">\n {pageDocs.href != null\n ? <DocsTrigger href={pageDocs.href} />\n : <DocsTrigger open={open} onToggle={() => setOpen( ( o ) => !o )} />}\n </div>\n )}\n <div className=\"px-6 pb-6 pt-4\">\n {children}\n <Switch>\n {pages.map( ( page ) => (\n <Route key={page.path} path={page.path}>\n {renderPageElement( page )}\n </Route>\n ) )}\n <Route>{fallback ?? <div className=\"p-8 text-muted-foreground\">Not found</div>}</Route>\n </Switch>\n </div>\n </main>\n {open && pageDocs != null && pageDocs.href == null && (\n <DocsSidePanel\n pageDocs={pageDocs}\n tabMarkdown={tabMarkdown}\n onClose={() => setOpen( false )}\n />\n )}\n </div>\n )\n}\n","import type { NavItemPlugin } from '../plugins/types'\n\nexport interface NavSection {\n label: string\n sectionSort: number\n items: NavItemPlugin[]\n}\n\nexport interface GroupedNav {\n ungrouped: NavItemPlugin[]\n sections: NavSection[]\n}\n\nexport function groupNavItems( items: NavItemPlugin[] ): GroupedNav {\n const ungrouped: NavItemPlugin[] = []\n const sectionMap = new Map<string, NavSection>()\n\n for ( const item of items ) {\n if ( !item.section ) {\n ungrouped.push( item )\n continue\n }\n if ( !sectionMap.has( item.section ) ) {\n sectionMap.set( item.section, {\n label : item.section,\n sectionSort : item.sectionSort ?? item.sort ?? 0,\n items : [],\n } )\n }\n sectionMap.get( item.section )!.items.push( item )\n }\n\n ungrouped.sort( ( a, b ) => ( a.sort ?? 0 ) - ( b.sort ?? 0 ) )\n\n const sections = Array.from( sectionMap.values() )\n for ( const s of sections ) {\n s.items.sort( ( a, b ) => ( a.sort ?? 0 ) - ( b.sort ?? 0 ) )\n }\n sections.sort( ( a, b ) => {\n const d = a.sectionSort - b.sectionSort\n return d !== 0 ? d : a.label.localeCompare( b.label )\n } )\n\n return { ungrouped, sections }\n}\n","import { useState, useEffect, useCallback } from 'react'\nimport { Link, useLocation } from 'wouter'\nimport { ChevronLeft, ChevronDown } from 'lucide-react'\nimport { cn } from '../lib/utils'\nimport { getNavItems, getTopBarItems } from '../plugins/registry'\nimport { groupNavItems } from './groupNavItems'\nimport type { ComponentType } from 'react'\n\n/**\n * Accepted icon forms (anywhere we render an inline icon):\n * - React component: `Settings` from lucide-react\n * - URL string: `/logo.png`, `https://...`, `data:image/...`, `blob:...`\n * - CSS class string: `fa-solid fa-gear`, `material-icons` (rendered on a <span>)\n */\nexport type IconRef = ComponentType<{ className?: string }> | string\n\nconst STORAGE_COLLAPSED = 'imaginarium.ui.sidebar.collapsed'\nconst STORAGE_SECTIONS = 'imaginarium.ui.sidebar.sections'\n\nfunction readBool( key: string, fallback: boolean ): boolean {\n try {\n const v = localStorage.getItem( key )\n return v === null ? fallback : v === 'true'\n } catch { return fallback }\n}\n\nfunction readSections(): Set<string> {\n try {\n const v = localStorage.getItem( STORAGE_SECTIONS )\n if ( !v ) { return new Set() }\n const parsed = JSON.parse( v )\n return new Set( Array.isArray( parsed ) ? parsed as string[] : [] )\n } catch { return new Set() }\n}\n\nconst URL_RE = /^(https?:|data:|blob:|\\/|\\.\\/|\\.\\.\\/)/\n\nfunction renderIcon( icon: IconRef | undefined, className: string ) {\n if ( !icon ) { return null }\n if ( typeof icon === 'string' ) {\n if ( URL_RE.test( icon ) ) { return <img src={icon} alt=\"\" className={className} /> }\n return <span className={`${icon} ${className}`} aria-hidden=\"true\" />\n }\n const Icon = icon\n return <Icon className={className} />\n}\n\nexport interface AppSidebarProps {\n title?: string\n titleIcon?: IconRef\n rightSlot?: React.ReactNode\n}\n\nexport function AppSidebar( { title = 'Imaginarium', titleIcon, rightSlot }: AppSidebarProps ) {\n const [ location ] = useLocation()\n const [ collapsed, setCollapsed ] = useState( () => readBool( STORAGE_COLLAPSED, false ) )\n const [ collapsedSections, setCollapsedSections ] = useState<Set<string>>( readSections )\n\n useEffect( () => {\n try { localStorage.setItem( STORAGE_COLLAPSED, String( collapsed ) ) } catch { /* ignore */ }\n }, [ collapsed ] )\n\n useEffect( () => {\n try {\n localStorage.setItem( STORAGE_SECTIONS, JSON.stringify( Array.from( collapsedSections ) ) )\n } catch { /* ignore */ }\n }, [ collapsedSections ] )\n\n const toggleSidebar = useCallback( () => setCollapsed( v => !v ), [] )\n\n const toggleSection = useCallback( ( label: string ) => {\n setCollapsedSections( prev => {\n const next = new Set( prev )\n next.has( label ) ? next.delete( label ) : next.add( label )\n return next\n } )\n }, [] )\n\n const { ungrouped, sections } = groupNavItems( getNavItems() )\n const topBarItems = getTopBarItems()\n\n return (\n <aside\n className={cn(\n 'flex flex-col flex-shrink-0 border-r bg-background transition-[width] duration-200 ease-in-out overflow-hidden',\n collapsed ? 'w-[52px]' : 'w-[220px]',\n )}\n >\n {/* Header */}\n <div className=\"flex h-[52px] flex-shrink-0 items-center border-b px-2.5 gap-2\">\n {!collapsed && renderIcon( titleIcon, 'h-6 w-6' )}\n {!collapsed && (\n <span className=\"flex-1 truncate text-sm font-semibold\">{title}</span>\n )}\n <button\n onClick={toggleSidebar}\n aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}\n className={cn(\n 'flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md border text-muted-foreground',\n 'hover:bg-accent hover:text-accent-foreground transition-colors',\n collapsed && 'mx-auto border-transparent',\n )}\n >\n <ChevronLeft\n className={cn( 'h-4 w-4 transition-transform duration-200', collapsed && 'rotate-180' )}\n />\n </button>\n </div>\n\n {/* Nav */}\n <nav className=\"flex flex-1 flex-col gap-0.5 overflow-y-auto overflow-x-hidden p-1.5\">\n {/* Ungrouped items */}\n {ungrouped.map( ( { path, label, icon: Icon } ) => {\n const isActive = location === path || location.startsWith( `${path}/` )\n return (\n <Link\n key={path}\n href={path}\n title={collapsed ? label : undefined}\n className={cn(\n 'relative flex items-center gap-2.5 rounded-md px-2 py-1.5 text-sm text-muted-foreground',\n 'hover:bg-accent hover:text-accent-foreground transition-colors whitespace-nowrap',\n isActive && 'bg-accent/50 text-accent-foreground font-medium',\n collapsed && 'justify-center px-2',\n )}\n >\n {Icon && <Icon className=\"h-4 w-4 flex-shrink-0\" />}\n {!collapsed && <span>{label}</span>}\n </Link>\n )\n } )}\n\n {/* Sections */}\n {sections.map( ( section ) => {\n const isSectionCollapsed = !collapsed && collapsedSections.has( section.label )\n return (\n <div key={section.label} className=\"flex flex-col\">\n {/* Section divider + header */}\n <div className=\"my-1.5 h-px bg-border\" />\n {!collapsed && (\n <button\n onClick={() => toggleSection( section.label )}\n className={cn(\n 'flex items-center justify-between px-2 pb-1 pt-2.5',\n 'text-[10px] font-semibold uppercase tracking-widest text-muted-foreground',\n 'hover:text-foreground transition-colors cursor-pointer rounded-sm',\n )}\n >\n {section.label}\n <ChevronDown\n className={cn(\n 'h-3 w-3 transition-transform duration-200',\n isSectionCollapsed && '-rotate-90',\n )}\n />\n </button>\n )}\n\n {/* Section items */}\n <div\n className={cn(\n 'flex flex-col gap-0.5 overflow-hidden transition-all duration-200',\n isSectionCollapsed ? 'max-h-0 opacity-0' : 'max-h-screen opacity-100',\n )}\n >\n {section.items.map( ( { path, label, icon: Icon } ) => {\n const isActive = location === path || location.startsWith( `${path}/` )\n return (\n <Link\n key={path}\n href={path}\n title={collapsed ? label : undefined}\n className={cn(\n 'relative flex items-center gap-2.5 rounded-md px-2 py-1.5 text-sm text-muted-foreground',\n 'hover:bg-accent hover:text-accent-foreground transition-colors whitespace-nowrap',\n isActive && 'bg-accent/50 text-accent-foreground font-medium',\n collapsed && 'justify-center px-2',\n )}\n >\n {Icon && <Icon className=\"h-4 w-4 flex-shrink-0\" />}\n {!collapsed && <span>{label}</span>}\n </Link>\n )\n } )}\n </div>\n </div>\n )\n } )}\n </nav>\n\n {/* Footer: rightSlot + TopBarItems */}\n <div className={cn(\n 'flex flex-shrink-0 items-center border-t p-1.5',\n collapsed ? 'flex-col gap-1' : 'flex-row justify-end gap-0.5',\n )}>\n {!collapsed && rightSlot}\n {topBarItems.map( ( item ) => {\n const C = item.component\n return <C key={item.id} />\n } )}\n </div>\n </aside>\n )\n}\n","import * as React from 'react'\nimport * as ToastPrimitives from '@radix-ui/react-toast'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { X } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\n\nconst ToastProvider = ToastPrimitives.Provider\n\nconst ToastViewport = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Viewport>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>\n>( ( { className, ...props }, ref ) => (\n <ToastPrimitives.Viewport\n ref={ref}\n className={cn(\n 'fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]',\n className,\n )}\n {...props}\n />\n) )\nToastViewport.displayName = ToastPrimitives.Viewport.displayName\n\nconst toastVariants = cva(\n 'group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',\n {\n variants: {\n variant: {\n default: 'border bg-background text-foreground',\n destructive: 'destructive group border-destructive bg-destructive text-destructive-foreground',\n },\n },\n defaultVariants: { variant: 'default' },\n },\n)\n\nconst Toast = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Root>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> & VariantProps<typeof toastVariants>\n>( ( { className, variant, ...props }, ref ) => (\n <ToastPrimitives.Root ref={ref} className={cn( toastVariants( { variant } ), className )} {...props} />\n) )\nToast.displayName = ToastPrimitives.Root.displayName\n\nconst ToastAction = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Action>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>\n>( ( { className, ...props }, ref ) => (\n <ToastPrimitives.Action\n ref={ref}\n className={cn(\n 'inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',\n className,\n )}\n {...props}\n />\n) )\nToastAction.displayName = ToastPrimitives.Action.displayName\n\nconst ToastClose = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Close>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>\n>( ( { className, ...props }, ref ) => (\n <ToastPrimitives.Close\n ref={ref}\n className={cn(\n 'absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100',\n className,\n )}\n toast-close=\"\"\n {...props}\n >\n <X className=\"h-4 w-4\" />\n </ToastPrimitives.Close>\n) )\nToastClose.displayName = ToastPrimitives.Close.displayName\n\nconst ToastTitle = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Title>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>\n>( ( { className, ...props }, ref ) => (\n <ToastPrimitives.Title ref={ref} className={cn( 'text-sm font-semibold', className )} {...props} />\n) )\nToastTitle.displayName = ToastPrimitives.Title.displayName\n\nconst ToastDescription = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Description>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>\n>( ( { className, ...props }, ref ) => (\n <ToastPrimitives.Description ref={ref} className={cn( 'text-sm opacity-90', className )} {...props} />\n) )\nToastDescription.displayName = ToastPrimitives.Description.displayName\n\nexport type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>\nexport type ToastActionElement = React.ReactElement<typeof ToastAction>\n\nexport {\n ToastProvider,\n ToastViewport,\n Toast,\n ToastTitle,\n ToastDescription,\n ToastClose,\n ToastAction,\n}\n","import { useToast } from '../../hooks/useToast'\nimport {\n Toast,\n ToastClose,\n ToastDescription,\n ToastProvider,\n ToastTitle,\n ToastViewport,\n} from './Toast'\n\nexport function Toaster() {\n const { toasts } = useToast()\n\n return (\n <ToastProvider>\n {toasts.map( ( { id, title, description, action, ...props } ) => (\n <Toast key={id} {...props}>\n <div className=\"grid gap-1\">\n {title && <ToastTitle>{title}</ToastTitle>}\n {description && <ToastDescription>{description}</ToastDescription>}\n </div>\n {action}\n <ToastClose />\n </Toast>\n ) )}\n <ToastViewport />\n </ToastProvider>\n )\n}\n","import { Button } from '../components/ui/Button'\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '../components/ui/Card'\n\nexport interface LoginPageProps {\n loginPath: string\n title?: string\n subtitle?: string\n buttonLabel?: string\n /** URL of an image to show behind the sign-in card. Empty/null skips it. */\n backgroundUrl?: string\n /** Optional message shown above the button (e.g. an error from a failed prior attempt). */\n errorMessage?: string\n}\n\nfunction GoogleGlyph( { className }: { className?: string } ) {\n return (\n <svg viewBox=\"0 0 24 24\" className={className} aria-hidden=\"true\">\n <path fill=\"#4285F4\" d=\"M23.49 12.27c0-.79-.07-1.54-.19-2.27H12v4.51h6.16c-.27 1.4-1.04 2.59-2.21 3.41v2.77h3.59c2.08-1.92 3.95-4.74 3.95-8.42z\" />\n <path fill=\"#34A853\" d=\"M12 24c2.97 0 5.46-.98 7.28-2.66l-3.59-2.77c-.98.66-2.23 1.06-3.69 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 21.53 7.7 24 12 24z\" />\n <path fill=\"#FBBC05\" d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\" />\n <path fill=\"#EA4335\" d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\" />\n </svg>\n )\n}\n\nconst ERROR_MESSAGES: Record<string, string> = {\n auth_failed : 'Sign-in failed. Please try again.',\n}\n\nfunction readUrlError(): string | undefined {\n if ( typeof window === 'undefined' ) { \n return undefined \n }\n const code = new URLSearchParams( window.location.search ).get( 'error' )\n if ( !code ) { \n return undefined \n }\n return ERROR_MESSAGES[code] ?? `Sign-in error: ${code}`\n}\n\nexport function LoginPage( {\n loginPath,\n title = 'Sign in',\n subtitle,\n buttonLabel = 'Sign in with Google',\n backgroundUrl,\n errorMessage,\n}: LoginPageProps ) {\n const message = errorMessage ?? readUrlError()\n const hasBackground = Boolean( backgroundUrl )\n\n return (\n <div\n className=\"min-h-screen flex items-center justify-center bg-background bg-cover bg-center px-4\"\n style={hasBackground ? { backgroundImage: `url(${backgroundUrl})` } : undefined}\n >\n <Card className={`w-full max-w-md ${hasBackground ? 'backdrop-blur-sm bg-card/90' : ''}`}>\n <CardHeader className=\"text-center\">\n <CardTitle>{title}</CardTitle>\n {subtitle && <CardDescription>{subtitle}</CardDescription>}\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {message && (\n <div className=\"rounded-md border border-destructive bg-destructive/10 px-4 py-2 text-sm text-destructive\">\n {message}\n </div>\n )}\n <Button\n className=\"w-full\"\n variant=\"outline\"\n onClick={() => { window.location.href = loginPath }}\n >\n <GoogleGlyph className=\"h-5 w-5 mr-2\" />\n {buttonLabel}\n </Button>\n </CardContent>\n </Card>\n </div>\n )\n}\n\nexport default LoginPage\n","import { createElement, type ComponentType, type ReactNode } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { Config } from '@leverege/plugin'\n\nimport { useImaginariumApi } from '../api/ImaginariumApiContext'\nimport { LoginPage, type LoginPageProps } from './LoginPage'\n\nexport interface RequireAuthProps {\n children: ReactNode\n}\n\n/**\n * Wraps `children` with an authentication gate. On mount, fetches\n * `Config.get('ImaginariumApp', 'userPath', '/auth/user')` from the configured\n * API base URL. While loading, renders a small placeholder. On error, renders\n * the configured login component (defaults to the bundled `LoginPage`). On\n * success, renders `children`.\n *\n * Recognized config keys (under `'ImaginariumApp'`):\n * - `userPath` endpoint to check (default `/auth/user`)\n * - `loginPath` URL the login button navigates to (default `/api/login`)\n * - `loginPage` component to render when unauthenticated\n * - `loginTitle` default page heading\n * - `loginSubtitle` default page subtitle\n * - `loginButtonLabel` default button label\n * - `loginBackgroundUrl` URL of an image to show behind the sign-in card\n */\nexport function RequireAuth( { children }: RequireAuthProps ) {\n const { fetchJson } = useImaginariumApi()\n const userPath = Config.get<string>( 'ImaginariumApp', 'userPath', '/auth/user' )\n\n const { isPending, isError } = useQuery( {\n queryKey: [ 'imaginarium', 'auth', 'user', userPath ],\n queryFn: () => fetchJson( userPath ),\n retry: false,\n refetchOnWindowFocus: false,\n } )\n\n if ( isPending ) {\n return <div className=\"p-8 text-muted-foreground\">Checking sign-in…</div>\n }\n\n if ( isError ) {\n const LoginComponent = Config.get<ComponentType<LoginPageProps>>(\n 'ImaginariumApp', 'loginPage', LoginPage,\n )\n const title = Config.get<string | undefined>( 'ImaginariumApp', 'loginTitle', undefined )\n const subtitle = Config.get<string | undefined>( 'ImaginariumApp', 'loginSubtitle', undefined )\n const buttonLabel = Config.get<string | undefined>(\n 'ImaginariumApp', 'loginButtonLabel', undefined,\n )\n const loginPath = Config.get<string>( 'ImaginariumApp', 'loginPath', '/api/login' )\n const backgroundUrl = Config.get<string | undefined>(\n 'ImaginariumApp', 'loginBackgroundUrl', undefined,\n )\n\n const appTitle = Config.get<string>( 'ImaginariumApp', 'title', 'Imaginarium' )\n const resolvedTitle = title ?? `Sign in to ${appTitle}`\n\n return createElement( LoginComponent, {\n loginPath,\n title: resolvedTitle,\n subtitle,\n buttonLabel,\n backgroundUrl,\n } )\n }\n\n return <>{children}</>\n}\n\nexport default RequireAuth\n","import { useMemo, type ReactNode } from 'react'\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'\nimport { Config } from '@leverege/plugin'\n\nimport { TooltipProvider } from '../components/ui/Tooltip'\nimport { Toaster } from '../components/ui/Toaster'\nimport { ImaginariumApiProvider } from '../api/ImaginariumApiContext'\nimport { RequireAuth } from '../auth/RequireAuth'\nimport { getProviders } from '../plugins/registry'\nimport { AppSidebar, type AppSidebarProps, type IconRef } from './AppSidebar'\nimport { Shell, type ShellProps } from './Shell'\n\nfunction withProviders( tree: ReactNode ): ReactNode {\n const providers = getProviders()\n let wrapped = tree\n for ( const { component: Provider } of providers ) {\n wrapped = <Provider>{wrapped}</Provider>\n }\n return wrapped\n}\n\nexport interface ImaginariumAppProps {\n apiBaseUrl?: string\n queryClient?: QueryClient\n title?: string\n titleIcon?: IconRef\n navRightSlot?: AppSidebarProps['rightSlot']\n shellFallback?: ShellProps['fallback']\n children?: ReactNode\n}\n\nconst defaultQueryClient = new QueryClient( {\n defaultOptions: {\n queries: { retry: false, refetchOnWindowFocus: false },\n },\n} )\n\nfunction GatedShell( { title, titleIcon, navRightSlot, shellFallback, children }: {\n title?: string\n titleIcon?: IconRef\n navRightSlot?: AppSidebarProps['rightSlot']\n shellFallback?: ShellProps['fallback']\n children?: ReactNode\n} ) {\n return withProviders(\n <div className=\"flex h-screen overflow-hidden bg-background text-foreground\">\n <AppSidebar title={title} titleIcon={titleIcon} rightSlot={navRightSlot} />\n <Shell fallback={shellFallback}>{children}</Shell>\n </div>,\n )\n}\n\nexport function ImaginariumApp( {\n apiBaseUrl = '/api',\n queryClient,\n title,\n titleIcon,\n navRightSlot,\n shellFallback,\n children,\n}: ImaginariumAppProps ) {\n const qc = useMemo( () => queryClient ?? defaultQueryClient, [ queryClient ] )\n const requireAuth = Config.get<boolean>( 'ImaginariumApp', 'requireAuth', true )\n const resolvedTitleIcon = titleIcon\n ?? Config.get<IconRef | undefined>( 'ImaginariumApp', 'titleIcon', undefined )\n\n const gated = (\n <GatedShell\n title={title}\n titleIcon={resolvedTitleIcon}\n navRightSlot={navRightSlot}\n shellFallback={shellFallback}\n >\n {children}\n </GatedShell>\n )\n\n return (\n <QueryClientProvider client={qc}>\n <TooltipProvider>\n <ImaginariumApiProvider apiBaseUrl={apiBaseUrl}>\n {requireAuth ? <RequireAuth>{gated}</RequireAuth> : gated}\n <Toaster />\n </ImaginariumApiProvider>\n </TooltipProvider>\n </QueryClientProvider>\n )\n}\n"],"names":["PageDocsContext","createContext","PageDocsProvider","children","tabMarkdown","setTabMarkdown","useState","jsx","useRegisterTabDocs","markdown","useContext","useEffect","useActiveTabDocs","triggerClass","active","cn","TriggerIcon","DocsTrigger","href","open","onToggle","jsxs","DocsSidePanel","pageDocs","onClose","title","Component","Fragment","ReactMarkdown","mdComponents","renderPageElement","plugin","element","isValidElement","createElement","Shell","fallback","ShellContent","pages","getPages","setOpen","location","useLocation","getPageDocs","o","Switch","page","Route","groupNavItems","items","ungrouped","sectionMap","item","a","b","sections","d","STORAGE_COLLAPSED","STORAGE_SECTIONS","readBool","key","v","readSections","parsed","URL_RE","renderIcon","icon","className","Icon","AppSidebar","titleIcon","rightSlot","collapsed","setCollapsed","collapsedSections","setCollapsedSections","toggleSidebar","useCallback","toggleSection","label","prev","next","getNavItems","topBarItems","getTopBarItems","ChevronLeft","path","isActive","Link","section","isSectionCollapsed","ChevronDown","C","ToastProvider","ToastPrimitives","ToastViewport","React","props","ref","toastVariants","cva","Toast","variant","ToastAction","ToastClose","X","ToastTitle","ToastDescription","Toaster","toasts","useToast","id","description","action","GoogleGlyph","ERROR_MESSAGES","readUrlError","code","LoginPage","loginPath","subtitle","buttonLabel","backgroundUrl","errorMessage","message","hasBackground","Card","CardHeader","CardTitle","CardDescription","CardContent","Button","RequireAuth","fetchJson","useImaginariumApi","userPath","Config","isPending","isError","useQuery","LoginComponent","appTitle","resolvedTitle","withProviders","tree","providers","getProviders","wrapped","Provider","defaultQueryClient","QueryClient","GatedShell","navRightSlot","shellFallback","ImaginariumApp","apiBaseUrl","queryClient","qc","useMemo","requireAuth","resolvedTitleIcon","gated","QueryClientProvider","TooltipProvider","ImaginariumApiProvider"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const d=require("react/jsx-runtime"),n=require("react"),M=require("@tanstack/react-query"),j=require("@leverege/plugin"),O=require("./Card-CHVaz_7u.cjs"),I=require("./PluginTypes-BmYA5_B9.cjs"),f=require("./mdComponents-BiOJ7Epf.cjs"),v=n.createContext(null);function x(t,o){const s=new Set(t);for(const e of o)e&&s.add(e);const r=Array.from(s).sort();return r.length===t.length&&r.every((e,i)=>e===t[i])?t:r}function w(t,o){const s=t.indexOf(o);if(s===-1){const r=[...t,o];return r.sort(),r}return t.filter((r,e)=>e!==s)}function L({children:t}){const[o,s]=n.useState(!0),[r,e]=n.useState([]),[i,a]=n.useState([]),[u,m]=n.useState([]),[c,q]=n.useState([]),[y,D]=n.useState(0),C=n.useCallback(g=>{e(l=>w(l,g))},[]),p=n.useCallback(g=>{a(l=>w(l,g))},[]),h=n.useCallback(g=>{m(l=>x(l,g))},[]),S=n.useCallback(g=>{q(l=>x(l,g))},[]),T=n.useCallback(()=>{e([]),a([])},[]),E=n.useMemo(()=>({showDev:o,setShowDev:s,hiddenSystemConfigTypes:r,toggleSystemConfigType:C,hiddenSystemConfigTags:i,toggleSystemConfigTag:p,knownSystemConfigTypes:u,registerSystemConfigTypes:h,knownSystemConfigTags:c,registerSystemConfigTags:S,filteredOutCount:y,setFilteredOutCount:D,clearHidden:T}),[o,r,C,i,p,u,h,c,S,y,T]);return d.jsx(v.Provider,{value:E,children:t})}function b(){const t=n.useContext(v);if(!t)throw new Error("useFilters must be used inside FilterProvider");return t}function P(t){const o=t.displayName.toLowerCase(),s=t.baseUrl.toLowerCase();return o.includes("dev")||o.includes("staging")||s.includes("dev-")||s.includes("stg-")}function F(t,o){const s=new Set(o.hiddenSystemConfigTypes),r=new Set(o.hiddenSystemConfigTags);return t.filter(e=>!(!o.showDev&&P(e)||e.type&&s.has(e.type)||e.tags&&e.tags.length>0&&e.tags.every(i=>r.has(i))))}const k=n.createContext(null);function A({children:t}){const{fetchJson:o}=O.useImaginariumApi(),s=j.Config.get("ImagineSystemConfig","apiPath","/configs"),r=n.useMemo(()=>["imaginarium","system-configs",s],[s]),e=b(),i=M.useQuery({queryKey:r,queryFn:async()=>{const c=await o(s);return Array.isArray(c)?c:(c==null?void 0:c.items)??[]}}),a=n.useMemo(()=>i.data??[],[i.data]),u=n.useMemo(()=>F(a,e),[a,e]);n.useEffect(()=>{e.registerSystemConfigTypes(a.map(c=>c.type)),e.registerSystemConfigTags(a.flatMap(c=>c.tags??[]))},[a,e.registerSystemConfigTypes,e.registerSystemConfigTags]),n.useEffect(()=>{e.setFilteredOutCount(a.length-u.length)},[a.length,u.length,e.setFilteredOutCount]),n.useEffect(()=>()=>e.setFilteredOutCount(0),[e.setFilteredOutCount]);const m=n.useMemo(()=>({configs:a,filtered:u,isLoading:i.isLoading,isError:i.isError,error:i.error,refetch:i.refetch,apiPath:s,queryKey:r}),[a,u,i.isLoading,i.isError,i.error,i.refetch,s,r]);return d.jsx(k.Provider,{value:m,children:t})}function H(){const t=n.useContext(k);if(!t)throw new Error("useSystemConfigs must be used inside SystemConfigsProvider");return t}class B{static register(o,s){o.addPlugin(I.PageDocsType,s)}}class K{static create({path:o,markdown:s}){const r=f.extractH2s(s),e=a=>{var u;(u=document.getElementById(a))==null||u.scrollIntoView({behavior:"smooth",block:"start"})};return{path:o,component:()=>d.jsxs(d.Fragment,{children:[r.length>1&&d.jsx("div",{className:"flex flex-wrap gap-1.5 mb-4",children:r.map(({text:a,slug:u})=>d.jsx("button",{onClick:()=>e(u),className:"rounded-full border border-border bg-muted px-2.5 py-0.5 text-[11px] text-muted-foreground hover:border-primary/40 hover:text-foreground transition-colors",children:f.toTitleCase(a)},u))}),d.jsx(f.Markdown,{components:f.mdComponents,children:s})]})}}}exports.FilterProvider=L;exports.MarkdownPageDoc=K;exports.PageDoc=B;exports.SystemConfigsProvider=A;exports.applyConfigFilters=F;exports.isDevConfig=P;exports.useFilters=b;exports.useSystemConfigs=H;
|
|
2
|
+
//# sourceMappingURL=MarkdownPageDoc-BZF02iL5.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownPageDoc-BZF02iL5.cjs","sources":["../src/filters/FilterContext.tsx","../src/filters/applyConfigFilters.ts","../src/system/SystemConfigsContext.tsx","../src/docs/PageDoc.ts","../src/docs/MarkdownPageDoc.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useMemo, useState, type ReactNode } from 'react'\n\nexport interface FilterContextValue {\n showDev : boolean\n setShowDev : ( v: boolean ) => void\n\n // Anything in this set is filtered out\n hiddenSystemConfigTypes : string[]\n toggleSystemConfigType : ( type: string ) => void\n\n hiddenSystemConfigTags : string[]\n toggleSystemConfigTag : ( tag: string ) => void\n\n // Known values, populated by pages as they fetch\n knownSystemConfigTypes : string[]\n registerSystemConfigTypes : ( types: ( string | null | undefined )[] ) => void\n\n knownSystemConfigTags : string[]\n registerSystemConfigTags : ( tags: ( string | null | undefined )[] ) => void\n\n // Number of system configs currently being filtered out, reported by the\n // page that owns the data (ImagineSystemView). The dropdown reads this to\n // render a badge next to the filter icon. Reset to 0 when the page unmounts.\n filteredOutCount : number\n setFilteredOutCount : ( n: number ) => void\n\n // Quick action — clears both hidden sets, leaves showDev untouched\n clearHidden : () => void\n}\n\nconst FilterCtx = createContext<FilterContextValue | null>( null )\n\nfunction registerInto( prev: string[], incoming: ( string | null | undefined )[] ): string[] {\n const next = new Set( prev )\n for ( const t of incoming ) {\n if ( t ) { next.add( t ) }\n }\n const arr = Array.from( next ).sort()\n if ( arr.length === prev.length && arr.every( ( t, i ) => t === prev[i] ) ) {\n return prev\n }\n return arr\n}\n\nfunction toggleIn( prev: string[], value: string ): string[] {\n const idx = prev.indexOf( value )\n if ( idx === -1 ) {\n const next = [ ...prev, value ]\n next.sort()\n return next\n }\n return prev.filter( ( _, i ) => i !== idx )\n}\n\nexport function FilterProvider( { children }: { children: ReactNode } ) {\n const [ showDev, setShowDev ] = useState( true )\n const [ hiddenTypes, setHiddenTypes ] = useState<string[]>( [] )\n const [ hiddenTags, setHiddenTags ] = useState<string[]>( [] )\n const [ knownTypes, setKnownTypes ] = useState<string[]>( [] )\n const [ knownTags, setKnownTags ] = useState<string[]>( [] )\n const [ filteredOutCount, setFilteredOutCount ] = useState( 0 )\n\n const toggleSystemConfigType = useCallback( ( type: string ) => {\n setHiddenTypes( ( prev ) => toggleIn( prev, type ) )\n }, [] )\n\n const toggleSystemConfigTag = useCallback( ( tag: string ) => {\n setHiddenTags( ( prev ) => toggleIn( prev, tag ) )\n }, [] )\n\n const registerSystemConfigTypes = useCallback( ( types: ( string | null | undefined )[] ) => {\n setKnownTypes( ( prev ) => registerInto( prev, types ) )\n }, [] )\n\n const registerSystemConfigTags = useCallback( ( tags: ( string | null | undefined )[] ) => {\n setKnownTags( ( prev ) => registerInto( prev, tags ) )\n }, [] )\n\n const clearHidden = useCallback( () => {\n setHiddenTypes( [] )\n setHiddenTags( [] )\n }, [] )\n\n const value = useMemo<FilterContextValue>( () => ( {\n showDev,\n setShowDev,\n hiddenSystemConfigTypes : hiddenTypes,\n toggleSystemConfigType,\n hiddenSystemConfigTags : hiddenTags,\n toggleSystemConfigTag,\n knownSystemConfigTypes : knownTypes,\n registerSystemConfigTypes,\n knownSystemConfigTags : knownTags,\n registerSystemConfigTags,\n filteredOutCount,\n setFilteredOutCount,\n clearHidden,\n } ), [\n showDev,\n hiddenTypes,\n toggleSystemConfigType,\n hiddenTags,\n toggleSystemConfigTag,\n knownTypes,\n registerSystemConfigTypes,\n knownTags,\n registerSystemConfigTags,\n filteredOutCount,\n clearHidden,\n ] )\n\n return <FilterCtx.Provider value={value}>{children}</FilterCtx.Provider>\n}\n\nexport function useFilters(): FilterContextValue {\n const v = useContext( FilterCtx )\n if ( !v ) {\n throw new Error( 'useFilters must be used inside FilterProvider' )\n }\n return v\n}\n","export interface ImagineSystemConfigLike {\n displayName : string\n baseUrl : string\n type? : string | null\n tags? : string[]\n}\n\nexport function isDevConfig( c: ImagineSystemConfigLike ): boolean {\n const name = c.displayName.toLowerCase()\n const url = c.baseUrl.toLowerCase()\n return name.includes( 'dev' )\n || name.includes( 'staging' )\n || url.includes( 'dev-' )\n || url.includes( 'stg-' )\n}\n\nexport interface ConfigFilterOptions {\n showDev : boolean\n hiddenSystemConfigTypes : string[]\n hiddenSystemConfigTags : string[]\n}\n\nexport function applyConfigFilters<T extends ImagineSystemConfigLike>(\n configs: T[],\n filters: ConfigFilterOptions,\n): T[] {\n const typeBlocked = new Set( filters.hiddenSystemConfigTypes )\n const tagBlocked = new Set( filters.hiddenSystemConfigTags )\n\n return configs.filter( ( c ) => {\n if ( !filters.showDev && isDevConfig( c ) ) { return false }\n if ( c.type && typeBlocked.has( c.type ) ) { return false }\n // Tags: show if at least one tag is still visible. Hide only when the\n // config has tags and every one of them is in the hidden set.\n if ( c.tags && c.tags.length > 0 && c.tags.every( ( t ) => tagBlocked.has( t ) ) ) {\n return false\n }\n return true\n } )\n}\n","import { createContext, useContext, useEffect, useMemo, type ReactNode } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { Config } from '@leverege/plugin'\n\nimport { useImaginariumApi } from '../api/ImaginariumApiContext'\nimport { useFilters } from '../filters/FilterContext'\nimport { applyConfigFilters } from '../filters/applyConfigFilters'\nimport type { ImagineSystemConfig, ImagineSystemConfigListResponse } from './types'\n\nexport interface SystemConfigsContextValue {\n /** Raw list as returned by the server (before filters). */\n configs : ImagineSystemConfig[]\n /** Filter-applied view of `configs`. */\n filtered : ImagineSystemConfig[]\n isLoading : boolean\n isError : boolean\n error : unknown\n refetch : () => Promise<unknown>\n /** API path being polled (relative to apiBaseUrl). */\n apiPath : string\n /** React Query key — share this with mutations to invalidate the cache. */\n queryKey : readonly unknown[]\n}\n\nconst Ctx = createContext<SystemConfigsContextValue | null>( null )\n\nexport function SystemConfigsProvider( { children }: { children: ReactNode } ) {\n const { fetchJson } = useImaginariumApi()\n const apiPath = Config.get<string>( 'ImagineSystemConfig', 'apiPath', '/configs' )\n const queryKey = useMemo(\n () => [ 'imaginarium', 'system-configs', apiPath ] as const,\n [ apiPath ],\n )\n const filters = useFilters()\n\n const query = useQuery<ImagineSystemConfig[]>( {\n queryKey,\n queryFn: async () => {\n const res = await fetchJson<ImagineSystemConfigListResponse | ImagineSystemConfig[]>( apiPath )\n return Array.isArray( res ) ? res : ( res?.items ?? [] )\n },\n } )\n\n const configs = useMemo( () => query.data ?? [], [ query.data ] )\n const filtered = useMemo( () => applyConfigFilters( configs, filters ), [ configs, filters ] )\n\n // Surface available types/tags so the global filter dropdown can render them.\n useEffect( () => {\n filters.registerSystemConfigTypes( configs.map( ( c ) => c.type ) )\n filters.registerSystemConfigTags( configs.flatMap( ( c ) => c.tags ?? [] ) )\n }, [ configs, filters.registerSystemConfigTypes, filters.registerSystemConfigTags ] )\n\n // Surface how many configs are currently being filtered out (badge on filter button).\n useEffect( () => {\n filters.setFilteredOutCount( configs.length - filtered.length )\n }, [ configs.length, filtered.length, filters.setFilteredOutCount ] )\n\n useEffect( () => {\n return () => filters.setFilteredOutCount( 0 )\n }, [ filters.setFilteredOutCount ] )\n\n const value = useMemo<SystemConfigsContextValue>( () => ( {\n configs,\n filtered,\n isLoading : query.isLoading,\n isError : query.isError,\n error : query.error,\n refetch : query.refetch,\n apiPath,\n queryKey,\n } ), [\n configs,\n filtered,\n query.isLoading,\n query.isError,\n query.error,\n query.refetch,\n apiPath,\n queryKey,\n ] )\n\n return <Ctx.Provider value={value}>{children}</Ctx.Provider>\n}\n\nexport function useSystemConfigs(): SystemConfigsContextValue {\n const v = useContext( Ctx )\n if ( !v ) {\n throw new Error( 'useSystemConfigs must be used inside SystemConfigsProvider' )\n }\n return v\n}\n","import { PageDocsType } from '../plugins/PluginTypes'\nimport type { PageDocsPlugin } from '../plugins/types'\n\ninterface RegistryLike {\n addPlugin( type: string, plugin: unknown ): void\n}\n\nexport class PageDoc {\n static register( plg: RegistryLike, pageDoc: PageDocsPlugin ) {\n plg.addPlugin( PageDocsType, pageDoc )\n }\n}\n","import type { ComponentType } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport type { PageDocsPlugin } from '../plugins/types'\nimport { mdComponents, extractH2s, toTitleCase } from './mdComponents'\n\nexport class MarkdownPageDoc {\n static create( { path, markdown }: { path: string; markdown: string } ): PageDocsPlugin {\n const sections = extractH2s( markdown )\n\n const scrollTo = ( slug: string ) => {\n document.getElementById( slug )?.scrollIntoView( { behavior: 'smooth', block: 'start' } )\n }\n\n const Component: ComponentType = () => (\n <>\n {sections.length > 1 && (\n <div className=\"flex flex-wrap gap-1.5 mb-4\">\n {sections.map( ( { text, slug } ) => (\n <button\n key={slug}\n onClick={() => scrollTo( slug )}\n className=\"rounded-full border border-border bg-muted px-2.5 py-0.5 text-[11px] text-muted-foreground hover:border-primary/40 hover:text-foreground transition-colors\"\n >\n {toTitleCase( text )}\n </button>\n ) )}\n </div>\n )}\n <ReactMarkdown components={mdComponents}>{markdown}</ReactMarkdown>\n </>\n )\n\n return { path, component: Component }\n }\n}\n"],"names":["FilterCtx","createContext","registerInto","prev","incoming","next","t","arr","toggleIn","value","idx","_","i","FilterProvider","children","showDev","setShowDev","useState","hiddenTypes","setHiddenTypes","hiddenTags","setHiddenTags","knownTypes","setKnownTypes","knownTags","setKnownTags","filteredOutCount","setFilteredOutCount","toggleSystemConfigType","useCallback","type","toggleSystemConfigTag","tag","registerSystemConfigTypes","types","registerSystemConfigTags","tags","clearHidden","useMemo","jsx","useFilters","v","useContext","isDevConfig","c","name","url","applyConfigFilters","configs","filters","typeBlocked","tagBlocked","Ctx","SystemConfigsProvider","fetchJson","useImaginariumApi","apiPath","Config","queryKey","query","useQuery","res","filtered","useEffect","useSystemConfigs","PageDoc","plg","pageDoc","PageDocsType","MarkdownPageDoc","path","markdown","sections","extractH2s","scrollTo","slug","_a","jsxs","Fragment","text","ReactMarkdown","mdComponents"],"mappings":"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"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { jsx as m, jsxs as M, Fragment as L } from "react/jsx-runtime";
|
|
2
|
+
import { createContext as F, useState as d, useCallback as f, useMemo as l, useContext as P, useEffect as C } from "react";
|
|
3
|
+
import { useQuery as A } from "@tanstack/react-query";
|
|
4
|
+
import { Config as H } from "@leverege/plugin";
|
|
5
|
+
import { a as q } from "./Card-D2LdIJwJ.js";
|
|
6
|
+
import { b as B } from "./PluginTypes-mZ4TjxPV.js";
|
|
7
|
+
import { e as K, t as N, M as j, m as J } from "./mdComponents-kPa8Rxqz.js";
|
|
8
|
+
const k = F(null);
|
|
9
|
+
function v(t, n) {
|
|
10
|
+
const s = new Set(t);
|
|
11
|
+
for (const e of n)
|
|
12
|
+
e && s.add(e);
|
|
13
|
+
const o = Array.from(s).sort();
|
|
14
|
+
return o.length === t.length && o.every((e, r) => e === t[r]) ? t : o;
|
|
15
|
+
}
|
|
16
|
+
function b(t, n) {
|
|
17
|
+
const s = t.indexOf(n);
|
|
18
|
+
if (s === -1) {
|
|
19
|
+
const o = [...t, n];
|
|
20
|
+
return o.sort(), o;
|
|
21
|
+
}
|
|
22
|
+
return t.filter((o, e) => e !== s);
|
|
23
|
+
}
|
|
24
|
+
function Z({ children: t }) {
|
|
25
|
+
const [n, s] = d(!0), [o, e] = d([]), [r, i] = d([]), [a, y] = d([]), [g, E] = d([]), [p, O] = d(0), h = f((c) => {
|
|
26
|
+
e((u) => b(u, c));
|
|
27
|
+
}, []), S = f((c) => {
|
|
28
|
+
i((u) => b(u, c));
|
|
29
|
+
}, []), T = f((c) => {
|
|
30
|
+
y((u) => v(u, c));
|
|
31
|
+
}, []), w = f((c) => {
|
|
32
|
+
E((u) => v(u, c));
|
|
33
|
+
}, []), x = f(() => {
|
|
34
|
+
e([]), i([]);
|
|
35
|
+
}, []), I = l(() => ({
|
|
36
|
+
showDev: n,
|
|
37
|
+
setShowDev: s,
|
|
38
|
+
hiddenSystemConfigTypes: o,
|
|
39
|
+
toggleSystemConfigType: h,
|
|
40
|
+
hiddenSystemConfigTags: r,
|
|
41
|
+
toggleSystemConfigTag: S,
|
|
42
|
+
knownSystemConfigTypes: a,
|
|
43
|
+
registerSystemConfigTypes: T,
|
|
44
|
+
knownSystemConfigTags: g,
|
|
45
|
+
registerSystemConfigTags: w,
|
|
46
|
+
filteredOutCount: p,
|
|
47
|
+
setFilteredOutCount: O,
|
|
48
|
+
clearHidden: x
|
|
49
|
+
}), [
|
|
50
|
+
n,
|
|
51
|
+
o,
|
|
52
|
+
h,
|
|
53
|
+
r,
|
|
54
|
+
S,
|
|
55
|
+
a,
|
|
56
|
+
T,
|
|
57
|
+
g,
|
|
58
|
+
w,
|
|
59
|
+
p,
|
|
60
|
+
x
|
|
61
|
+
]);
|
|
62
|
+
return /* @__PURE__ */ m(k.Provider, { value: I, children: t });
|
|
63
|
+
}
|
|
64
|
+
function Q() {
|
|
65
|
+
const t = P(k);
|
|
66
|
+
if (!t)
|
|
67
|
+
throw new Error("useFilters must be used inside FilterProvider");
|
|
68
|
+
return t;
|
|
69
|
+
}
|
|
70
|
+
function U(t) {
|
|
71
|
+
const n = t.displayName.toLowerCase(), s = t.baseUrl.toLowerCase();
|
|
72
|
+
return n.includes("dev") || n.includes("staging") || s.includes("dev-") || s.includes("stg-");
|
|
73
|
+
}
|
|
74
|
+
function V(t, n) {
|
|
75
|
+
const s = new Set(n.hiddenSystemConfigTypes), o = new Set(n.hiddenSystemConfigTags);
|
|
76
|
+
return t.filter((e) => !(!n.showDev && U(e) || e.type && s.has(e.type) || e.tags && e.tags.length > 0 && e.tags.every((r) => o.has(r))));
|
|
77
|
+
}
|
|
78
|
+
const D = F(null);
|
|
79
|
+
function $({ children: t }) {
|
|
80
|
+
const { fetchJson: n } = q(), s = H.get("ImagineSystemConfig", "apiPath", "/configs"), o = l(
|
|
81
|
+
() => ["imaginarium", "system-configs", s],
|
|
82
|
+
[s]
|
|
83
|
+
), e = Q(), r = A({
|
|
84
|
+
queryKey: o,
|
|
85
|
+
queryFn: async () => {
|
|
86
|
+
const g = await n(s);
|
|
87
|
+
return Array.isArray(g) ? g : (g == null ? void 0 : g.items) ?? [];
|
|
88
|
+
}
|
|
89
|
+
}), i = l(() => r.data ?? [], [r.data]), a = l(() => V(i, e), [i, e]);
|
|
90
|
+
C(() => {
|
|
91
|
+
e.registerSystemConfigTypes(i.map((g) => g.type)), e.registerSystemConfigTags(i.flatMap((g) => g.tags ?? []));
|
|
92
|
+
}, [i, e.registerSystemConfigTypes, e.registerSystemConfigTags]), C(() => {
|
|
93
|
+
e.setFilteredOutCount(i.length - a.length);
|
|
94
|
+
}, [i.length, a.length, e.setFilteredOutCount]), C(() => () => e.setFilteredOutCount(0), [e.setFilteredOutCount]);
|
|
95
|
+
const y = l(() => ({
|
|
96
|
+
configs: i,
|
|
97
|
+
filtered: a,
|
|
98
|
+
isLoading: r.isLoading,
|
|
99
|
+
isError: r.isError,
|
|
100
|
+
error: r.error,
|
|
101
|
+
refetch: r.refetch,
|
|
102
|
+
apiPath: s,
|
|
103
|
+
queryKey: o
|
|
104
|
+
}), [
|
|
105
|
+
i,
|
|
106
|
+
a,
|
|
107
|
+
r.isLoading,
|
|
108
|
+
r.isError,
|
|
109
|
+
r.error,
|
|
110
|
+
r.refetch,
|
|
111
|
+
s,
|
|
112
|
+
o
|
|
113
|
+
]);
|
|
114
|
+
return /* @__PURE__ */ m(D.Provider, { value: y, children: t });
|
|
115
|
+
}
|
|
116
|
+
function ee() {
|
|
117
|
+
const t = P(D);
|
|
118
|
+
if (!t)
|
|
119
|
+
throw new Error("useSystemConfigs must be used inside SystemConfigsProvider");
|
|
120
|
+
return t;
|
|
121
|
+
}
|
|
122
|
+
class te {
|
|
123
|
+
static register(n, s) {
|
|
124
|
+
n.addPlugin(B, s);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
class se {
|
|
128
|
+
static create({ path: n, markdown: s }) {
|
|
129
|
+
const o = K(s), e = (i) => {
|
|
130
|
+
var a;
|
|
131
|
+
(a = document.getElementById(i)) == null || a.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
132
|
+
};
|
|
133
|
+
return { path: n, component: () => /* @__PURE__ */ M(L, { children: [
|
|
134
|
+
o.length > 1 && /* @__PURE__ */ m("div", { className: "flex flex-wrap gap-1.5 mb-4", children: o.map(({ text: i, slug: a }) => /* @__PURE__ */ m(
|
|
135
|
+
"button",
|
|
136
|
+
{
|
|
137
|
+
onClick: () => e(a),
|
|
138
|
+
className: "rounded-full border border-border bg-muted px-2.5 py-0.5 text-[11px] text-muted-foreground hover:border-primary/40 hover:text-foreground transition-colors",
|
|
139
|
+
children: N(i)
|
|
140
|
+
},
|
|
141
|
+
a
|
|
142
|
+
)) }),
|
|
143
|
+
/* @__PURE__ */ m(j, { components: J, children: s })
|
|
144
|
+
] }) };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
export {
|
|
148
|
+
Z as F,
|
|
149
|
+
se as M,
|
|
150
|
+
te as P,
|
|
151
|
+
$ as S,
|
|
152
|
+
Q as a,
|
|
153
|
+
V as b,
|
|
154
|
+
U as i,
|
|
155
|
+
ee as u
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=MarkdownPageDoc-DR1FmNpF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownPageDoc-DR1FmNpF.js","sources":["../src/filters/FilterContext.tsx","../src/filters/applyConfigFilters.ts","../src/system/SystemConfigsContext.tsx","../src/docs/PageDoc.ts","../src/docs/MarkdownPageDoc.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useMemo, useState, type ReactNode } from 'react'\n\nexport interface FilterContextValue {\n showDev : boolean\n setShowDev : ( v: boolean ) => void\n\n // Anything in this set is filtered out\n hiddenSystemConfigTypes : string[]\n toggleSystemConfigType : ( type: string ) => void\n\n hiddenSystemConfigTags : string[]\n toggleSystemConfigTag : ( tag: string ) => void\n\n // Known values, populated by pages as they fetch\n knownSystemConfigTypes : string[]\n registerSystemConfigTypes : ( types: ( string | null | undefined )[] ) => void\n\n knownSystemConfigTags : string[]\n registerSystemConfigTags : ( tags: ( string | null | undefined )[] ) => void\n\n // Number of system configs currently being filtered out, reported by the\n // page that owns the data (ImagineSystemView). The dropdown reads this to\n // render a badge next to the filter icon. Reset to 0 when the page unmounts.\n filteredOutCount : number\n setFilteredOutCount : ( n: number ) => void\n\n // Quick action — clears both hidden sets, leaves showDev untouched\n clearHidden : () => void\n}\n\nconst FilterCtx = createContext<FilterContextValue | null>( null )\n\nfunction registerInto( prev: string[], incoming: ( string | null | undefined )[] ): string[] {\n const next = new Set( prev )\n for ( const t of incoming ) {\n if ( t ) { next.add( t ) }\n }\n const arr = Array.from( next ).sort()\n if ( arr.length === prev.length && arr.every( ( t, i ) => t === prev[i] ) ) {\n return prev\n }\n return arr\n}\n\nfunction toggleIn( prev: string[], value: string ): string[] {\n const idx = prev.indexOf( value )\n if ( idx === -1 ) {\n const next = [ ...prev, value ]\n next.sort()\n return next\n }\n return prev.filter( ( _, i ) => i !== idx )\n}\n\nexport function FilterProvider( { children }: { children: ReactNode } ) {\n const [ showDev, setShowDev ] = useState( true )\n const [ hiddenTypes, setHiddenTypes ] = useState<string[]>( [] )\n const [ hiddenTags, setHiddenTags ] = useState<string[]>( [] )\n const [ knownTypes, setKnownTypes ] = useState<string[]>( [] )\n const [ knownTags, setKnownTags ] = useState<string[]>( [] )\n const [ filteredOutCount, setFilteredOutCount ] = useState( 0 )\n\n const toggleSystemConfigType = useCallback( ( type: string ) => {\n setHiddenTypes( ( prev ) => toggleIn( prev, type ) )\n }, [] )\n\n const toggleSystemConfigTag = useCallback( ( tag: string ) => {\n setHiddenTags( ( prev ) => toggleIn( prev, tag ) )\n }, [] )\n\n const registerSystemConfigTypes = useCallback( ( types: ( string | null | undefined )[] ) => {\n setKnownTypes( ( prev ) => registerInto( prev, types ) )\n }, [] )\n\n const registerSystemConfigTags = useCallback( ( tags: ( string | null | undefined )[] ) => {\n setKnownTags( ( prev ) => registerInto( prev, tags ) )\n }, [] )\n\n const clearHidden = useCallback( () => {\n setHiddenTypes( [] )\n setHiddenTags( [] )\n }, [] )\n\n const value = useMemo<FilterContextValue>( () => ( {\n showDev,\n setShowDev,\n hiddenSystemConfigTypes : hiddenTypes,\n toggleSystemConfigType,\n hiddenSystemConfigTags : hiddenTags,\n toggleSystemConfigTag,\n knownSystemConfigTypes : knownTypes,\n registerSystemConfigTypes,\n knownSystemConfigTags : knownTags,\n registerSystemConfigTags,\n filteredOutCount,\n setFilteredOutCount,\n clearHidden,\n } ), [\n showDev,\n hiddenTypes,\n toggleSystemConfigType,\n hiddenTags,\n toggleSystemConfigTag,\n knownTypes,\n registerSystemConfigTypes,\n knownTags,\n registerSystemConfigTags,\n filteredOutCount,\n clearHidden,\n ] )\n\n return <FilterCtx.Provider value={value}>{children}</FilterCtx.Provider>\n}\n\nexport function useFilters(): FilterContextValue {\n const v = useContext( FilterCtx )\n if ( !v ) {\n throw new Error( 'useFilters must be used inside FilterProvider' )\n }\n return v\n}\n","export interface ImagineSystemConfigLike {\n displayName : string\n baseUrl : string\n type? : string | null\n tags? : string[]\n}\n\nexport function isDevConfig( c: ImagineSystemConfigLike ): boolean {\n const name = c.displayName.toLowerCase()\n const url = c.baseUrl.toLowerCase()\n return name.includes( 'dev' )\n || name.includes( 'staging' )\n || url.includes( 'dev-' )\n || url.includes( 'stg-' )\n}\n\nexport interface ConfigFilterOptions {\n showDev : boolean\n hiddenSystemConfigTypes : string[]\n hiddenSystemConfigTags : string[]\n}\n\nexport function applyConfigFilters<T extends ImagineSystemConfigLike>(\n configs: T[],\n filters: ConfigFilterOptions,\n): T[] {\n const typeBlocked = new Set( filters.hiddenSystemConfigTypes )\n const tagBlocked = new Set( filters.hiddenSystemConfigTags )\n\n return configs.filter( ( c ) => {\n if ( !filters.showDev && isDevConfig( c ) ) { return false }\n if ( c.type && typeBlocked.has( c.type ) ) { return false }\n // Tags: show if at least one tag is still visible. Hide only when the\n // config has tags and every one of them is in the hidden set.\n if ( c.tags && c.tags.length > 0 && c.tags.every( ( t ) => tagBlocked.has( t ) ) ) {\n return false\n }\n return true\n } )\n}\n","import { createContext, useContext, useEffect, useMemo, type ReactNode } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { Config } from '@leverege/plugin'\n\nimport { useImaginariumApi } from '../api/ImaginariumApiContext'\nimport { useFilters } from '../filters/FilterContext'\nimport { applyConfigFilters } from '../filters/applyConfigFilters'\nimport type { ImagineSystemConfig, ImagineSystemConfigListResponse } from './types'\n\nexport interface SystemConfigsContextValue {\n /** Raw list as returned by the server (before filters). */\n configs : ImagineSystemConfig[]\n /** Filter-applied view of `configs`. */\n filtered : ImagineSystemConfig[]\n isLoading : boolean\n isError : boolean\n error : unknown\n refetch : () => Promise<unknown>\n /** API path being polled (relative to apiBaseUrl). */\n apiPath : string\n /** React Query key — share this with mutations to invalidate the cache. */\n queryKey : readonly unknown[]\n}\n\nconst Ctx = createContext<SystemConfigsContextValue | null>( null )\n\nexport function SystemConfigsProvider( { children }: { children: ReactNode } ) {\n const { fetchJson } = useImaginariumApi()\n const apiPath = Config.get<string>( 'ImagineSystemConfig', 'apiPath', '/configs' )\n const queryKey = useMemo(\n () => [ 'imaginarium', 'system-configs', apiPath ] as const,\n [ apiPath ],\n )\n const filters = useFilters()\n\n const query = useQuery<ImagineSystemConfig[]>( {\n queryKey,\n queryFn: async () => {\n const res = await fetchJson<ImagineSystemConfigListResponse | ImagineSystemConfig[]>( apiPath )\n return Array.isArray( res ) ? res : ( res?.items ?? [] )\n },\n } )\n\n const configs = useMemo( () => query.data ?? [], [ query.data ] )\n const filtered = useMemo( () => applyConfigFilters( configs, filters ), [ configs, filters ] )\n\n // Surface available types/tags so the global filter dropdown can render them.\n useEffect( () => {\n filters.registerSystemConfigTypes( configs.map( ( c ) => c.type ) )\n filters.registerSystemConfigTags( configs.flatMap( ( c ) => c.tags ?? [] ) )\n }, [ configs, filters.registerSystemConfigTypes, filters.registerSystemConfigTags ] )\n\n // Surface how many configs are currently being filtered out (badge on filter button).\n useEffect( () => {\n filters.setFilteredOutCount( configs.length - filtered.length )\n }, [ configs.length, filtered.length, filters.setFilteredOutCount ] )\n\n useEffect( () => {\n return () => filters.setFilteredOutCount( 0 )\n }, [ filters.setFilteredOutCount ] )\n\n const value = useMemo<SystemConfigsContextValue>( () => ( {\n configs,\n filtered,\n isLoading : query.isLoading,\n isError : query.isError,\n error : query.error,\n refetch : query.refetch,\n apiPath,\n queryKey,\n } ), [\n configs,\n filtered,\n query.isLoading,\n query.isError,\n query.error,\n query.refetch,\n apiPath,\n queryKey,\n ] )\n\n return <Ctx.Provider value={value}>{children}</Ctx.Provider>\n}\n\nexport function useSystemConfigs(): SystemConfigsContextValue {\n const v = useContext( Ctx )\n if ( !v ) {\n throw new Error( 'useSystemConfigs must be used inside SystemConfigsProvider' )\n }\n return v\n}\n","import { PageDocsType } from '../plugins/PluginTypes'\nimport type { PageDocsPlugin } from '../plugins/types'\n\ninterface RegistryLike {\n addPlugin( type: string, plugin: unknown ): void\n}\n\nexport class PageDoc {\n static register( plg: RegistryLike, pageDoc: PageDocsPlugin ) {\n plg.addPlugin( PageDocsType, pageDoc )\n }\n}\n","import type { ComponentType } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport type { PageDocsPlugin } from '../plugins/types'\nimport { mdComponents, extractH2s, toTitleCase } from './mdComponents'\n\nexport class MarkdownPageDoc {\n static create( { path, markdown }: { path: string; markdown: string } ): PageDocsPlugin {\n const sections = extractH2s( markdown )\n\n const scrollTo = ( slug: string ) => {\n document.getElementById( slug )?.scrollIntoView( { behavior: 'smooth', block: 'start' } )\n }\n\n const Component: ComponentType = () => (\n <>\n {sections.length > 1 && (\n <div className=\"flex flex-wrap gap-1.5 mb-4\">\n {sections.map( ( { text, slug } ) => (\n <button\n key={slug}\n onClick={() => scrollTo( slug )}\n className=\"rounded-full border border-border bg-muted px-2.5 py-0.5 text-[11px] text-muted-foreground hover:border-primary/40 hover:text-foreground transition-colors\"\n >\n {toTitleCase( text )}\n </button>\n ) )}\n </div>\n )}\n <ReactMarkdown components={mdComponents}>{markdown}</ReactMarkdown>\n </>\n )\n\n return { path, component: Component }\n }\n}\n"],"names":["FilterCtx","createContext","registerInto","prev","incoming","next","t","arr","i","toggleIn","value","idx","_","FilterProvider","children","showDev","setShowDev","useState","hiddenTypes","setHiddenTypes","hiddenTags","setHiddenTags","knownTypes","setKnownTypes","knownTags","setKnownTags","filteredOutCount","setFilteredOutCount","toggleSystemConfigType","useCallback","type","toggleSystemConfigTag","tag","registerSystemConfigTypes","types","registerSystemConfigTags","tags","clearHidden","useMemo","jsx","useFilters","v","useContext","isDevConfig","c","name","url","applyConfigFilters","configs","filters","typeBlocked","tagBlocked","Ctx","SystemConfigsProvider","fetchJson","useImaginariumApi","apiPath","Config","queryKey","query","useQuery","res","filtered","useEffect","useSystemConfigs","PageDoc","plg","pageDoc","PageDocsType","MarkdownPageDoc","path","markdown","sections","extractH2s","scrollTo","slug","_a","jsxs","Fragment","text","ReactMarkdown","mdComponents"],"mappings":"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"}
|