@flexkit/studio 0.2.19 → 0.2.20
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/dist/{chat-page-LAK4TFN4.js → chat-page-4G4XQ26P.js} +3 -3
- package/dist/{chat-page-LAK4TFN4.js.map → chat-page-4G4XQ26P.js.map} +1 -1
- package/dist/{chunk-4IEOAKKK.js → chunk-2P2QV3K6.js} +2 -2
- package/dist/{chunk-4IEOAKKK.js.map → chunk-2P2QV3K6.js.map} +1 -1
- package/dist/{chunk-OOYCTZ3C.js → chunk-445XKMAG.js} +3 -3
- package/dist/{chunk-OOYCTZ3C.js.map → chunk-445XKMAG.js.map} +1 -1
- package/dist/{chunk-H2RWSC56.js → chunk-B7QMGBK5.js} +3 -3
- package/dist/{chunk-H2RWSC56.js.map → chunk-B7QMGBK5.js.map} +1 -1
- package/dist/{chunk-ZKA2HKNI.js → chunk-BXN72PW2.js} +2 -2
- package/dist/{chunk-ZKA2HKNI.js.map → chunk-BXN72PW2.js.map} +1 -1
- package/dist/{chunk-HCJAM5LG.js → chunk-F2DT6NRK.js} +2 -2
- package/dist/{chunk-HCJAM5LG.js.map → chunk-F2DT6NRK.js.map} +1 -1
- package/dist/{chunk-DFLAX7EE.js → chunk-HLHLBMLJ.js} +2 -2
- package/dist/{chunk-DFLAX7EE.js.map → chunk-HLHLBMLJ.js.map} +1 -1
- package/dist/{chunk-V6RB45UU.js → chunk-JWBER5NX.js} +2 -2
- package/dist/{chunk-V6RB45UU.js.map → chunk-JWBER5NX.js.map} +1 -1
- package/dist/{chunk-VMWUMFUL.js → chunk-LK67JOQA.js} +3 -3
- package/dist/{chunk-VMWUMFUL.js.map → chunk-LK67JOQA.js.map} +1 -1
- package/dist/{chunk-6RRB47OZ.js → chunk-MKK65RQB.js} +3 -3
- package/dist/{chunk-6RRB47OZ.js.map → chunk-MKK65RQB.js.map} +1 -1
- package/dist/{chunk-XNHSHVG2.js → chunk-NYSQU73M.js} +3 -3
- package/dist/{chunk-XNHSHVG2.js.map → chunk-NYSQU73M.js.map} +1 -1
- package/dist/{chunk-QWQHXMXW.js → chunk-RY6PECIT.js} +2 -2
- package/dist/{chunk-QWQHXMXW.js.map → chunk-RY6PECIT.js.map} +1 -1
- package/dist/{entry-3JSFO4OU.js → entry-XVLXKEQV.js} +2 -2
- package/dist/{entry-3JSFO4OU.js.map → entry-XVLXKEQV.js.map} +1 -1
- package/dist/index.css +3 -0
- package/dist/index.js +2 -2
- package/dist/{list-SY3L2ACH.js → list-4OJMI4CB.js} +3 -3
- package/dist/{list-SY3L2ACH.js.map → list-4OJMI4CB.js.map} +1 -1
- package/dist/{list-Z2C74QDN.js → list-RABV2F3H.js} +2 -2
- package/dist/{list-Z2C74QDN.js.map → list-RABV2F3H.js.map} +1 -1
- package/dist/{pages-INCA54HE.js → pages-7LWBCW2X.js} +3 -3
- package/dist/{pages-INCA54HE.js.map → pages-7LWBCW2X.js.map} +1 -1
- package/dist/{plugin-pages-WO3MCJKC.js → plugin-pages-PQWTH7P5.js} +2 -2
- package/dist/{plugin-pages-WO3MCJKC.js.map → plugin-pages-PQWTH7P5.js.map} +1 -1
- package/dist/{record-links-CTB4SC4J.js → record-links-BFHPBOAL.js} +2 -2
- package/dist/{record-links-CTB4SC4J.js.map → record-links-BFHPBOAL.js.map} +1 -1
- package/dist/{root-XHXX3SZG.js → root-BS6QCYLO.js} +3 -3
- package/dist/{root-XHXX3SZG.js.map → root-BS6QCYLO.js.map} +1 -1
- package/dist/{root-6MSWGFZX.js → root-COI626G2.js} +2 -2
- package/dist/{root-6MSWGFZX.js.map → root-COI626G2.js.map} +1 -1
- package/dist/{root-DOOWSYWY.js → root-FTT4XDCE.js} +3 -3
- package/dist/{root-DOOWSYWY.js.map → root-FTT4XDCE.js.map} +1 -1
- package/dist/{root-OGX4DUTM.js → root-PDSTTPHO.js} +2 -2
- package/dist/{root-OGX4DUTM.js.map → root-PDSTTPHO.js.map} +1 -1
- package/dist/{root-JA2LFGNX.js → root-RXMRNU4M.js} +2 -2
- package/dist/{root-JA2LFGNX.js.map → root-RXMRNU4M.js.map} +1 -1
- package/dist/root-TZYOIXVG.js +2 -0
- package/dist/root-TZYOIXVG.js.map +1 -0
- package/dist/{search-Z4M4R4NJ.js → search-VPS2UHPQ.js} +2 -2
- package/dist/{search-Z4M4R4NJ.js.map → search-VPS2UHPQ.js.map} +1 -1
- package/dist/{skills-pages-TP2XQPCQ.js → skills-pages-G6JK7KKQ.js} +2 -2
- package/dist/{skills-pages-TP2XQPCQ.js.map → skills-pages-G6JK7KKQ.js.map} +1 -1
- package/dist/{source-5J56KIFA.js → source-MNHZQD4T.js} +2 -2
- package/dist/{source-5J56KIFA.js.map → source-MNHZQD4T.js.map} +1 -1
- package/package.json +3 -3
- package/dist/root-B4D3C37Q.js +0 -2
- package/dist/root-B4D3C37Q.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import'./index.css';import {b,c}from'./chunk-
|
|
2
|
-
//# sourceMappingURL=root-
|
|
1
|
+
import'./index.css';import {b,c}from'./chunk-HLHLBMLJ.js';import'./chunk-MKK65RQB.js';import'./chunk-UOR437J2.js';import {a}from'./chunk-BMX4URYN.js';import {g,f as f$1}from'./chunk-DHVKE36X.js';import'./chunk-2P2QV3K6.js';import'./chunk-2NXQF2F7.js';import'./chunk-ZZRA4567.js';import'./chunk-A7XHA2P6.js';import {f}from'./chunk-B7QMGBK5.js';import'./chunk-2HYQVMP3.js';import'./chunk-5CVDMZUI.js';import {K,M,Q,N,S,U as U$1,s as s$1,R,V as V$1,W,X,P}from'./chunk-DGIY4SKN.js';import'./chunk-SZEGGBOC.js';import {b as b$1}from'./chunk-32ZU4MLE.js';import'./chunk-U45E5X3H.js';import'./chunk-HDOIOXMP.js';import'./chunk-USNXQOMJ.js';import'./chunk-6NRQMG26.js';import'./chunk-O2QMYUPS.js';import {Outlet,useLocation,NavLink}from'react-router-dom';import {useState}from'react';import {SearchIcon,XIcon,SquarePenIcon,BellIcon,BotIcon,HistoryIcon,InboxIcon,PlugIcon}from'lucide-react';import T from'swr';import {jsxs,jsx}from'react/jsx-runtime';var U=300,s=NavLink;function V(){let{currentProjectId:a}=f(),{data:e}=T(a?g(a).approvalsCount:null,f$1,{refreshInterval:3e4}),n=e?.pendingCount??0;return n===0?null:jsx(b$1,{className:"fk:ml-auto fk:h-5 fk:min-w-5 fk:justify-center fk:rounded-full fk:bg-amber-500/20 fk:px-1.5 fk:text-[0.6875rem] fk:text-amber-600 fk:border-none fk:corner-squircle",children:n>99?"99+":n.toString()})}function F(){let{currentProjectId:a$1}=f(),e=a(a$1),n=e?.needsActionCount??0,l=n>0?n:e?.unreadCount??0;return l===0?null:jsx(b$1,{className:`fk:ml-auto fk:h-5 fk:min-w-5 fk:justify-center fk:rounded-full fk:px-1.5 fk:text-[0.6875rem] fk:border-none fk:corner-squircle ${n>0?"fk:bg-amber-500/20 fk:text-amber-600":"fk:bg-muted fk:text-muted-foreground"}`,children:l>99?"99+":l.toString()})}function B(){let e=useLocation().pathname.replace(/\/$/,""),n=e.endsWith("/ai/agent"),l=e.endsWith("/ai/runs"),P$1=e.endsWith("/ai/approvals"),R$1=e.endsWith("/ai/activity")||e.includes("/ai/activity/"),W$1=e.includes("/ai/plugins")||e.includes("/ai/skills"),L=e.includes("/ai/automations"),[d,k]=useState(""),E=b(d.trim(),U);return jsxs(N,{collapsible:"icon",variant:"inset",children:[jsx(S,{className:"fk:shrink-0 fk:pb-1.5 fk:group-data-[collapsible=icon]:hidden",children:jsxs(U$1,{className:"fk:relative",children:[jsx(SearchIcon,{className:"fk:absolute fk:left-2 fk:top-1/2 fk:size-3.5 fk:-translate-y-1/2 fk:text-muted-foreground"}),jsx(s$1,{className:"fk:h-8 fk:bg-background fk:pl-7 fk:pr-7 fk:text-sm",placeholder:"Search chats...",value:d,onChange:G=>k(G.target.value)}),d?jsx("button",{"aria-label":"Clear search",className:"fk:absolute fk:right-2 fk:top-1/2 fk:-translate-y-1/2 fk:cursor-pointer fk:text-muted-foreground fk:hover:text-foreground",type:"button",onClick:()=>k(""),children:jsx(XIcon,{className:"fk:size-3.5"})}):null]})}),jsxs(R,{children:[jsx(S,{children:jsxs(V$1,{children:[jsx(W,{children:jsx(X,{asChild:true,isActive:n,tooltip:"New chat",children:jsxs(s,{to:"agent",children:[jsx(SquarePenIcon,{className:"fk:h-4 fk:w-4",strokeWidth:2}),jsx("span",{children:"New chat"})]})})}),jsx(W,{children:jsx(X,{asChild:true,isActive:R$1,tooltip:"Activity",children:jsxs(s,{to:"activity",children:[jsx(BellIcon,{className:"fk:h-4 fk:w-4",strokeWidth:2}),jsx("span",{children:"Activity"}),jsx(F,{})]})})}),jsx(W,{children:jsx(X,{asChild:true,isActive:L,tooltip:"Automations",children:jsxs(s,{to:"automations",children:[jsx(BotIcon,{className:"fk:h-4 fk:w-4",strokeWidth:2}),jsx("span",{children:"Automations"})]})})}),jsx(W,{children:jsx(X,{asChild:true,isActive:l,tooltip:"Run History",children:jsxs(s,{to:"runs",children:[jsx(HistoryIcon,{className:"fk:h-4 fk:w-4",strokeWidth:2}),jsx("span",{children:"Run History"})]})})}),jsx(W,{children:jsx(X,{asChild:true,isActive:P$1,tooltip:"Approvals",children:jsxs(s,{to:"approvals",children:[jsx(InboxIcon,{className:"fk:h-4 fk:w-4",strokeWidth:2}),jsx("span",{children:"Approvals"}),jsx(V,{})]})})}),jsx(W,{children:jsx(X,{asChild:true,isActive:W$1,tooltip:"Plugins",children:jsxs(s,{to:"plugins",children:[jsx(PlugIcon,{className:"fk:size-4"}),jsx("span",{children:"Plugins"})]})})})]})}),jsx(S,{className:"fk:mt-4 fk:group-data-[collapsible=icon]:hidden",children:jsx(U$1,{children:jsx(c,{query:E})})})]}),jsx(P,{})]})}function pt(){let{currentProjectId:a}=f(),e=K();return a?jsxs(M,{className:"fk:h-full",defaultOpen:e,children:[jsx(B,{}),jsx(Q,{className:"fk:min-w-0",children:jsx("div",{className:"fk:flex fk:h-full fk:min-h-0 fk:min-w-0 fk:flex-col fk:overflow-hidden fk:pl-4 fk:pt-3",children:jsx("div",{className:"fk:flex fk:min-h-0 fk:min-w-0 fk:flex-1 fk:flex-col",children:jsx(Outlet,{})})})})]}):jsx("main",{className:"fk:flex fk:h-full fk:flex-1 fk:items-center fk:justify-center fk:p-8 fk:text-sm fk:text-muted-foreground",children:"Select a project to manage automations and skills."})}export{pt as Root};//# sourceMappingURL=root-PDSTTPHO.js.map
|
|
2
|
+
//# sourceMappingURL=root-PDSTTPHO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/ai/sidebar.tsx","../src/apps/ai/root.tsx"],"names":["SEARCH_DEBOUNCE_MS","NavLinkCompat","NavLink","PendingApprovalsBadge","currentProjectId","useConfig","data","useSWR","paths","fetcher","pendingCount","jsx","Badge","ActivityBadge","useActivitySummary","needsAction","count","AutomationsSidebar","pathname","useLocation","isNewChat","isRunHistory","isApprovals","isActivity","isPlugins","isAutomations","query","setQuery","useState","debouncedQuery","useDebouncedValue","jsxs","Sidebar","SidebarGroup","SidebarGroupContent","SearchIcon","Input","event","XIcon","SidebarContent","SidebarMenu","SidebarMenuItem","SidebarMenuButton","SquarePenIcon","BellIcon","BotIcon","HistoryIcon","InboxIcon","PlugIcon","AgentChatsSection","SidebarRail","Root","defaultOpen","readSidebarCookieState","SidebarProvider","SidebarInset","Outlet"],"mappings":"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","file":"root-OGX4DUTM.js","sourcesContent":["import type { JSX } from 'react';\nimport { useState } from 'react';\nimport { BellIcon, BotIcon, PlugIcon, HistoryIcon, InboxIcon, SearchIcon, SquarePenIcon, XIcon } from 'lucide-react';\nimport { NavLink, useLocation } from 'react-router-dom';\nimport useSWR from 'swr';\nimport { useConfig } from '../../core/config/config-context';\nimport {\n Badge,\n Input,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarPanel,\n SidebarRail,\n} from '../../ui';\nimport { fetcher, paths } from './api';\nimport { useActivitySummary } from './activity-nav-button';\nimport { AgentChatsSection, useDebouncedValue } from './agent/chat-list';\nimport type { AutomationApprovals } from './types';\n\nconst SEARCH_DEBOUNCE_MS = 300;\n\nconst NavLinkCompat = NavLink as unknown as React.ComponentType<{\n children?: React.ReactNode;\n to: string;\n}>;\n\nfunction PendingApprovalsBadge(): JSX.Element | null {\n const { currentProjectId } = useConfig();\n const { data } = useSWR<AutomationApprovals>(\n currentProjectId ? paths(currentProjectId).approvalsCount : null,\n fetcher,\n { refreshInterval: 30_000 }\n );\n const pendingCount = data?.pendingCount ?? 0;\n\n if (pendingCount === 0) {\n return null;\n }\n\n return (\n <Badge className=\"fk:ml-auto fk:h-5 fk:min-w-5 fk:justify-center fk:rounded-full fk:bg-amber-500/20 fk:px-1.5 fk:text-[0.6875rem] fk:text-amber-600 fk:border-none fk:corner-squircle\">\n {pendingCount > 99 ? '99+' : pendingCount.toString()}\n </Badge>\n );\n}\n\n/** Open items that wait on the viewer; falls back to the unread count when nothing waits. */\nfunction ActivityBadge(): JSX.Element | null {\n const { currentProjectId } = useConfig();\n const data = useActivitySummary(currentProjectId);\n const needsAction = data?.needsActionCount ?? 0;\n const count = needsAction > 0 ? needsAction : (data?.unreadCount ?? 0);\n\n if (count === 0) {\n return null;\n }\n\n return (\n <Badge\n className={`fk:ml-auto fk:h-5 fk:min-w-5 fk:justify-center fk:rounded-full fk:px-1.5 fk:text-[0.6875rem] fk:border-none fk:corner-squircle ${\n needsAction > 0 ? 'fk:bg-amber-500/20 fk:text-amber-600' : 'fk:bg-muted fk:text-muted-foreground'\n }`}\n >\n {count > 99 ? '99+' : count.toString()}\n </Badge>\n );\n}\n\nexport function AutomationsSidebar(): JSX.Element {\n const location = useLocation();\n const pathname = location.pathname.replace(/\\/$/, '');\n const isNewChat = pathname.endsWith('/ai/agent');\n const isRunHistory = pathname.endsWith('/ai/runs');\n const isApprovals = pathname.endsWith('/ai/approvals');\n const isActivity = pathname.endsWith('/ai/activity') || pathname.includes('/ai/activity/');\n const isPlugins = pathname.includes('/ai/plugins') || pathname.includes('/ai/skills');\n const isAutomations = pathname.includes('/ai/automations');\n const [query, setQuery] = useState('');\n const debouncedQuery = useDebouncedValue(query.trim(), SEARCH_DEBOUNCE_MS);\n\n return (\n <SidebarPanel collapsible=\"icon\" variant=\"inset\">\n <SidebarGroup className=\"fk:shrink-0 fk:pb-1.5 fk:group-data-[collapsible=icon]:hidden\">\n <SidebarGroupContent className=\"fk:relative\">\n <SearchIcon className=\"fk:absolute fk:left-2 fk:top-1/2 fk:size-3.5 fk:-translate-y-1/2 fk:text-muted-foreground\" />\n <Input\n className=\"fk:h-8 fk:bg-background fk:pl-7 fk:pr-7 fk:text-sm\"\n placeholder=\"Search chats...\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n />\n {query ? (\n <button\n aria-label=\"Clear search\"\n className=\"fk:absolute fk:right-2 fk:top-1/2 fk:-translate-y-1/2 fk:cursor-pointer fk:text-muted-foreground fk:hover:text-foreground\"\n type=\"button\"\n onClick={() => setQuery('')}\n >\n <XIcon className=\"fk:size-3.5\" />\n </button>\n ) : null}\n </SidebarGroupContent>\n </SidebarGroup>\n <SidebarContent>\n <SidebarGroup>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isNewChat} tooltip=\"New chat\">\n <NavLinkCompat to=\"agent\">\n <SquarePenIcon className=\"fk:h-4 fk:w-4\" strokeWidth={2} />\n <span>New chat</span>\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isActivity} tooltip=\"Activity\">\n <NavLinkCompat to=\"activity\">\n <BellIcon className=\"fk:h-4 fk:w-4\" strokeWidth={2} />\n <span>Activity</span>\n <ActivityBadge />\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isAutomations} tooltip=\"Automations\">\n <NavLinkCompat to=\"automations\">\n <BotIcon className=\"fk:h-4 fk:w-4\" strokeWidth={2} />\n <span>Automations</span>\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isRunHistory} tooltip=\"Run History\">\n <NavLinkCompat to=\"runs\">\n <HistoryIcon className=\"fk:h-4 fk:w-4\" strokeWidth={2} />\n <span>Run History</span>\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isApprovals} tooltip=\"Approvals\">\n <NavLinkCompat to=\"approvals\">\n <InboxIcon className=\"fk:h-4 fk:w-4\" strokeWidth={2} />\n <span>Approvals</span>\n <PendingApprovalsBadge />\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isPlugins} tooltip=\"Plugins\">\n <NavLinkCompat to=\"plugins\">\n <PlugIcon className=\"fk:size-4\" />\n <span>Plugins</span>\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n <SidebarGroup className=\"fk:mt-4 fk:group-data-[collapsible=icon]:hidden\">\n <SidebarGroupContent>\n <AgentChatsSection query={debouncedQuery} />\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </SidebarPanel>\n );\n}\n","import type { JSX } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useConfig } from '../../core/config/config-context';\nimport { readSidebarCookieState, SidebarInset, SidebarProvider } from '../../ui';\nimport { AutomationsSidebar } from './sidebar';\n\nexport function Root(): JSX.Element {\n const { currentProjectId } = useConfig();\n const defaultOpen = readSidebarCookieState();\n\n if (!currentProjectId) {\n return (\n <main className=\"fk:flex fk:h-full fk:flex-1 fk:items-center fk:justify-center fk:p-8 fk:text-sm fk:text-muted-foreground\">\n Select a project to manage automations and skills.\n </main>\n );\n }\n\n return (\n <SidebarProvider className=\"fk:h-full\" defaultOpen={defaultOpen}>\n <AutomationsSidebar />\n <SidebarInset className=\"fk:min-w-0\">\n <div className=\"fk:flex fk:h-full fk:min-h-0 fk:min-w-0 fk:flex-col fk:overflow-hidden fk:pl-4 fk:pt-3\">\n <div className=\"fk:flex fk:min-h-0 fk:min-w-0 fk:flex-1 fk:flex-col\">\n <Outlet />\n </div>\n </div>\n </SidebarInset>\n </SidebarProvider>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/apps/ai/sidebar.tsx","../src/apps/ai/root.tsx"],"names":["SEARCH_DEBOUNCE_MS","NavLinkCompat","NavLink","PendingApprovalsBadge","currentProjectId","useConfig","data","useSWR","paths","fetcher","pendingCount","jsx","Badge","ActivityBadge","useActivitySummary","needsAction","count","AutomationsSidebar","pathname","useLocation","isNewChat","isRunHistory","isApprovals","isActivity","isPlugins","isAutomations","query","setQuery","useState","debouncedQuery","useDebouncedValue","jsxs","Sidebar","SidebarGroup","SidebarGroupContent","SearchIcon","Input","event","XIcon","SidebarContent","SidebarMenu","SidebarMenuItem","SidebarMenuButton","SquarePenIcon","BellIcon","BotIcon","HistoryIcon","InboxIcon","PlugIcon","AgentChatsSection","SidebarRail","Root","defaultOpen","readSidebarCookieState","SidebarProvider","SidebarInset","Outlet"],"mappings":"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","file":"root-PDSTTPHO.js","sourcesContent":["import type { JSX } from 'react';\nimport { useState } from 'react';\nimport { BellIcon, BotIcon, PlugIcon, HistoryIcon, InboxIcon, SearchIcon, SquarePenIcon, XIcon } from 'lucide-react';\nimport { NavLink, useLocation } from 'react-router-dom';\nimport useSWR from 'swr';\nimport { useConfig } from '../../core/config/config-context';\nimport {\n Badge,\n Input,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarPanel,\n SidebarRail,\n} from '../../ui';\nimport { fetcher, paths } from './api';\nimport { useActivitySummary } from './activity-nav-button';\nimport { AgentChatsSection, useDebouncedValue } from './agent/chat-list';\nimport type { AutomationApprovals } from './types';\n\nconst SEARCH_DEBOUNCE_MS = 300;\n\nconst NavLinkCompat = NavLink as unknown as React.ComponentType<{\n children?: React.ReactNode;\n to: string;\n}>;\n\nfunction PendingApprovalsBadge(): JSX.Element | null {\n const { currentProjectId } = useConfig();\n const { data } = useSWR<AutomationApprovals>(\n currentProjectId ? paths(currentProjectId).approvalsCount : null,\n fetcher,\n { refreshInterval: 30_000 }\n );\n const pendingCount = data?.pendingCount ?? 0;\n\n if (pendingCount === 0) {\n return null;\n }\n\n return (\n <Badge className=\"fk:ml-auto fk:h-5 fk:min-w-5 fk:justify-center fk:rounded-full fk:bg-amber-500/20 fk:px-1.5 fk:text-[0.6875rem] fk:text-amber-600 fk:border-none fk:corner-squircle\">\n {pendingCount > 99 ? '99+' : pendingCount.toString()}\n </Badge>\n );\n}\n\n/** Open items that wait on the viewer; falls back to the unread count when nothing waits. */\nfunction ActivityBadge(): JSX.Element | null {\n const { currentProjectId } = useConfig();\n const data = useActivitySummary(currentProjectId);\n const needsAction = data?.needsActionCount ?? 0;\n const count = needsAction > 0 ? needsAction : (data?.unreadCount ?? 0);\n\n if (count === 0) {\n return null;\n }\n\n return (\n <Badge\n className={`fk:ml-auto fk:h-5 fk:min-w-5 fk:justify-center fk:rounded-full fk:px-1.5 fk:text-[0.6875rem] fk:border-none fk:corner-squircle ${\n needsAction > 0 ? 'fk:bg-amber-500/20 fk:text-amber-600' : 'fk:bg-muted fk:text-muted-foreground'\n }`}\n >\n {count > 99 ? '99+' : count.toString()}\n </Badge>\n );\n}\n\nexport function AutomationsSidebar(): JSX.Element {\n const location = useLocation();\n const pathname = location.pathname.replace(/\\/$/, '');\n const isNewChat = pathname.endsWith('/ai/agent');\n const isRunHistory = pathname.endsWith('/ai/runs');\n const isApprovals = pathname.endsWith('/ai/approvals');\n const isActivity = pathname.endsWith('/ai/activity') || pathname.includes('/ai/activity/');\n const isPlugins = pathname.includes('/ai/plugins') || pathname.includes('/ai/skills');\n const isAutomations = pathname.includes('/ai/automations');\n const [query, setQuery] = useState('');\n const debouncedQuery = useDebouncedValue(query.trim(), SEARCH_DEBOUNCE_MS);\n\n return (\n <SidebarPanel collapsible=\"icon\" variant=\"inset\">\n <SidebarGroup className=\"fk:shrink-0 fk:pb-1.5 fk:group-data-[collapsible=icon]:hidden\">\n <SidebarGroupContent className=\"fk:relative\">\n <SearchIcon className=\"fk:absolute fk:left-2 fk:top-1/2 fk:size-3.5 fk:-translate-y-1/2 fk:text-muted-foreground\" />\n <Input\n className=\"fk:h-8 fk:bg-background fk:pl-7 fk:pr-7 fk:text-sm\"\n placeholder=\"Search chats...\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n />\n {query ? (\n <button\n aria-label=\"Clear search\"\n className=\"fk:absolute fk:right-2 fk:top-1/2 fk:-translate-y-1/2 fk:cursor-pointer fk:text-muted-foreground fk:hover:text-foreground\"\n type=\"button\"\n onClick={() => setQuery('')}\n >\n <XIcon className=\"fk:size-3.5\" />\n </button>\n ) : null}\n </SidebarGroupContent>\n </SidebarGroup>\n <SidebarContent>\n <SidebarGroup>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isNewChat} tooltip=\"New chat\">\n <NavLinkCompat to=\"agent\">\n <SquarePenIcon className=\"fk:h-4 fk:w-4\" strokeWidth={2} />\n <span>New chat</span>\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isActivity} tooltip=\"Activity\">\n <NavLinkCompat to=\"activity\">\n <BellIcon className=\"fk:h-4 fk:w-4\" strokeWidth={2} />\n <span>Activity</span>\n <ActivityBadge />\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isAutomations} tooltip=\"Automations\">\n <NavLinkCompat to=\"automations\">\n <BotIcon className=\"fk:h-4 fk:w-4\" strokeWidth={2} />\n <span>Automations</span>\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isRunHistory} tooltip=\"Run History\">\n <NavLinkCompat to=\"runs\">\n <HistoryIcon className=\"fk:h-4 fk:w-4\" strokeWidth={2} />\n <span>Run History</span>\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isApprovals} tooltip=\"Approvals\">\n <NavLinkCompat to=\"approvals\">\n <InboxIcon className=\"fk:h-4 fk:w-4\" strokeWidth={2} />\n <span>Approvals</span>\n <PendingApprovalsBadge />\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton asChild isActive={isPlugins} tooltip=\"Plugins\">\n <NavLinkCompat to=\"plugins\">\n <PlugIcon className=\"fk:size-4\" />\n <span>Plugins</span>\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n <SidebarGroup className=\"fk:mt-4 fk:group-data-[collapsible=icon]:hidden\">\n <SidebarGroupContent>\n <AgentChatsSection query={debouncedQuery} />\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </SidebarPanel>\n );\n}\n","import type { JSX } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useConfig } from '../../core/config/config-context';\nimport { readSidebarCookieState, SidebarInset, SidebarProvider } from '../../ui';\nimport { AutomationsSidebar } from './sidebar';\n\nexport function Root(): JSX.Element {\n const { currentProjectId } = useConfig();\n const defaultOpen = readSidebarCookieState();\n\n if (!currentProjectId) {\n return (\n <main className=\"fk:flex fk:h-full fk:flex-1 fk:items-center fk:justify-center fk:p-8 fk:text-sm fk:text-muted-foreground\">\n Select a project to manage automations and skills.\n </main>\n );\n }\n\n return (\n <SidebarProvider className=\"fk:h-full\" defaultOpen={defaultOpen}>\n <AutomationsSidebar />\n <SidebarInset className=\"fk:min-w-0\">\n <div className=\"fk:flex fk:h-full fk:min-h-0 fk:min-w-0 fk:flex-col fk:overflow-hidden fk:pl-4 fk:pt-3\">\n <div className=\"fk:flex fk:min-h-0 fk:min-w-0 fk:flex-1 fk:flex-col\">\n <Outlet />\n </div>\n </div>\n </SidebarInset>\n </SidebarProvider>\n );\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import'./index.css';import {c}from'./chunk-2DXR5NJV.js';import {f}from'./chunk-
|
|
2
|
-
//# sourceMappingURL=root-
|
|
1
|
+
import'./index.css';import {c}from'./chunk-2DXR5NJV.js';import {f}from'./chunk-B7QMGBK5.js';import {g}from'./chunk-2HYQVMP3.js';import'./chunk-5CVDMZUI.js';import {K,M,Z,Q}from'./chunk-DGIY4SKN.js';import'./chunk-SZEGGBOC.js';import'./chunk-32ZU4MLE.js';import'./chunk-U45E5X3H.js';import'./chunk-HDOIOXMP.js';import'./chunk-USNXQOMJ.js';import'./chunk-6NRQMG26.js';import'./chunk-O2QMYUPS.js';import {Outlet}from'react-router-dom';import {jsxs,jsx}from'react/jsx-runtime';function P(){let[,u]=g(),{currentProject:r}=f(),c$1=r?.schema??[],p=r?.menuGroups??[],d=c(c$1,u.user?.spaces),f$1=K();return jsxs(M,{defaultOpen:f$1,children:[jsx(Z,{schema:d,menuGroups:p}),jsx(Q,{children:jsx(Outlet,{})})]})}export{P as Root};//# sourceMappingURL=root-RXMRNU4M.js.map
|
|
2
|
+
//# sourceMappingURL=root-RXMRNU4M.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/desk/root.tsx"],"names":["Root","auth","useAuth","currentProject","useConfig","schema","menuGroups","visibleSchema","filterEntitiesForSpaces","defaultOpen","readSidebarCookieState","jsxs","SidebarProvider","jsx","Sidebar","SidebarInset","Outlet"],"mappings":"ydAOO,SAASA,CAAAA,EAAoB,CAClC,GAAM,EAAGC,CAAI,CAAA,CAAIC,CAAAA,EAAQ,CACnB,CAAE,cAAA,CAAAC,CAAe,EAAIC,CAAAA,EAAU,CAC/BC,GAAAA,CAASF,CAAAA,EAAgB,MAAA,EAAU,EAAC,CACpCG,CAAAA,CAAaH,GAAgB,UAAA,EAAc,EAAC,CAG5CI,CAAAA,CAAgBC,CAAAA,CAAwBH,GAAAA,CAAQJ,CAAAA,CAAK,IAAA,EAAM,MAAM,CAAA,CACjEQ,GAAAA,CAAcC,CAAAA,EAAuB,CAE3C,OACEC,IAAAA,CAACC,CAAAA,CAAA,CAAgB,YAAaH,GAAAA,CAC5B,QAAA,CAAA,CAAAI,GAAAA,CAACC,CAAAA,CAAA,CAAQ,MAAA,CAAQP,CAAAA,CAAe,UAAA,CAAYD,EAAY,CAAA,CACxDO,GAAAA,CAACE,CAAAA,CAAA,CACC,SAAAF,GAAAA,CAACG,MAAAA,CAAA,EAAO,CAAA,CACV,GACF,CAEJ","file":"root-
|
|
1
|
+
{"version":3,"sources":["../src/apps/desk/root.tsx"],"names":["Root","auth","useAuth","currentProject","useConfig","schema","menuGroups","visibleSchema","filterEntitiesForSpaces","defaultOpen","readSidebarCookieState","jsxs","SidebarProvider","jsx","Sidebar","SidebarInset","Outlet"],"mappings":"ydAOO,SAASA,CAAAA,EAAoB,CAClC,GAAM,EAAGC,CAAI,CAAA,CAAIC,CAAAA,EAAQ,CACnB,CAAE,cAAA,CAAAC,CAAe,EAAIC,CAAAA,EAAU,CAC/BC,GAAAA,CAASF,CAAAA,EAAgB,MAAA,EAAU,EAAC,CACpCG,CAAAA,CAAaH,GAAgB,UAAA,EAAc,EAAC,CAG5CI,CAAAA,CAAgBC,CAAAA,CAAwBH,GAAAA,CAAQJ,CAAAA,CAAK,IAAA,EAAM,MAAM,CAAA,CACjEQ,GAAAA,CAAcC,CAAAA,EAAuB,CAE3C,OACEC,IAAAA,CAACC,CAAAA,CAAA,CAAgB,YAAaH,GAAAA,CAC5B,QAAA,CAAA,CAAAI,GAAAA,CAACC,CAAAA,CAAA,CAAQ,MAAA,CAAQP,CAAAA,CAAe,UAAA,CAAYD,EAAY,CAAA,CACxDO,GAAAA,CAACE,CAAAA,CAAA,CACC,SAAAF,GAAAA,CAACG,MAAAA,CAAA,EAAO,CAAA,CACV,GACF,CAEJ","file":"root-RXMRNU4M.js","sourcesContent":["import { JSX } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { filterEntitiesForSpaces } from '../../core/spaces';\nimport { useAuth } from '../../auth/auth-context';\nimport { useConfig } from '../../core/config/config-context';\nimport { readSidebarCookieState, Sidebar, SidebarInset, SidebarProvider } from '../../ui';\n\nexport function Root(): JSX.Element {\n const [, auth] = useAuth();\n const { currentProject } = useConfig();\n const schema = currentProject?.schema ?? [];\n const menuGroups = currentProject?.menuGroups ?? [];\n // Space-bound entities are hidden from non-members; the generated\n // @authorization rules block their data server-side either way.\n const visibleSchema = filterEntitiesForSpaces(schema, auth.user?.spaces);\n const defaultOpen = readSidebarCookieState();\n\n return (\n <SidebarProvider defaultOpen={defaultOpen}>\n <Sidebar schema={visibleSchema} menuGroups={menuGroups} />\n <SidebarInset>\n <Outlet />\n </SidebarInset>\n </SidebarProvider>\n );\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import'./index.css';import {a as a$1}from'./chunk-RY6PECIT.js';import {f as f$1,i,g as g$1,v,j,b as b$1,e as e$1,k,t,s,d,a,l,h,o as o$2,m,n,r as r$1,c as c$4,p,q as q$1}from'./chunk-ME55YNBF.js';import {c as c$2}from'./chunk-2DXR5NJV.js';import {c as c$1}from'./chunk-BMO7JFAX.js';import {c}from'./chunk-XMOSCJOI.js';import'./chunk-YDVO6XWD.js';import {a as a$2}from'./chunk-ERDARDGB.js';import {f}from'./chunk-B7QMGBK5.js';import {g}from'./chunk-2HYQVMP3.js';import'./chunk-5CVDMZUI.js';import {K,M,Q,O,qa,N,R,S,s as s$1,T,V,W,X,o,P}from'./chunk-DGIY4SKN.js';import {e as e$2,g as g$2,h as h$1,j as j$1,q,r,s as s$2,o as o$1}from'./chunk-SZEGGBOC.js';import {v as v$1}from'./chunk-32ZU4MLE.js';import {b}from'./chunk-U45E5X3H.js';import'./chunk-HDOIOXMP.js';import {b as b$2,c as c$3,e}from'./chunk-USNXQOMJ.js';import {b as b$3}from'./chunk-6NRQMG26.js';import'./chunk-O2QMYUPS.js';import {useMemo,useRef,useState,useCallback,useEffect,useReducer}from'react';import {useLocation}from'react-router-dom';import Bt from'graphology';import Ft from'graphology-layout-forceatlas2';import Jt from'graphology-layout-forceatlas2/worker';import Yt,{DEFAULT_STYLES}from'sigma';import {jsxs,jsx}from'react/jsx-runtime';import {gql}from'@apollo/client';import {useApolloClient,useQuery}from'@apollo/client/react';import {formatDistance}from'date-fns';import {SearchIcon,ScanIcon,LoaderCircleIcon,ExpandIcon,EyeOffIcon,EraserIcon,XIcon,SquareArrowOutUpRightIcon}from'lucide-react';import {useDebounce}from'use-debounce';function ue(e){return Math.min(2e4,2e3+e*9)}function gt({mean:e,max:t,diagonal:n}){let r=Math.max(.05,n*.0015);return e<r&&t<r*20}var Qt=40,$t=400,Ut=1200,Vt=2;function Zt(e){return 5+Math.min(10,Math.sqrt(e)*2)}function bt(e){return Qt*(.8+Math.sqrt(e)*.6)}function yt(e,t,n){let r=Math.random()*Math.PI*2;return Array.from({length:t},(i,a)=>{let o=r+a/t*Math.PI*2+Math.random()*.3,b=n*(.9+Math.random()*.2);return {x:e.x+Math.cos(o)*b,y:e.y+Math.sin(o)*b}})}function St(e,t){return !Number.isNaN(e.getNodeAttribute(t,"x"))}function Kt(e,t){if(t.length===0)return {center:{x:0,y:0},reach:0};let n=t.reduce((i,a)=>({x:i.x+e.getNodeAttribute(a,"x"),y:i.y+e.getNodeAttribute(a,"y")}),{x:0,y:0});n.x/=t.length,n.y/=t.length;let r=t.reduce((i,a)=>Math.max(i,Math.hypot(e.getNodeAttribute(a,"x")-n.x,e.getNodeAttribute(a,"y")-n.y)),0);return {center:n,reach:r}}function Wt(e,t){let n=new Map;t.forEach(r=>{let i=e.neighbors(r).find(a=>!t.has(a)&&St(e,a))??null;n.set(i,[...n.get(i)??[],r]);}),n.forEach((r,i)=>{let a;if(i){let o={x:e.getNodeAttribute(i,"x"),y:e.getNodeAttribute(i,"y")};a=yt(o,r.length,bt(r.length));}else {let o=e.nodes().filter(A=>!t.has(A)&&St(e,A)),b=Kt(e,o);a=yt(b.center,r.length,b.reach+bt(r.length));}a.forEach((o,b)=>e.mergeNodeAttributes(r[b],o));});}var Ne=class{constructor(t){this.graph=t;this.positions=new Float64Array(t.order*2);let n=0;this.graph.forEachNode((r,i)=>{this.positions[n]=i.x,this.positions[n+1]=i.y,n+=2;});}positions;measure(){let{graph:t,positions:n}=this,r=0,i=0,a=0,o=Number.POSITIVE_INFINITY,b=Number.POSITIVE_INFINITY,A=Number.NEGATIVE_INFINITY,_=Number.NEGATIVE_INFINITY,f=0;return t.forEachNode((s,p)=>{let{x:E,y:S}=p;if(f+1<n.length&&!p.fixed){let x=Math.hypot(E-n[f],S-n[f+1]);r+=x,i=Math.max(i,x),a+=1;}n[f]=E,n[f+1]=S,f+=2,o=Math.min(o,E),b=Math.min(b,S),A=Math.max(A,E),_=Math.max(_,S);}),{mean:a>0?r/a:0,max:i,diagonal:t.order>0?Math.hypot(A-o,_-b):0}}};function en(e,t,n){let r=false,i=new Set,a=e.order>0;return e.forEachNode(o=>{t.nodes[o]||(e.dropNode(o),r=true);}),Object.values(t.nodes).forEach(o=>{e.hasNode(o.key)||(e.addNode(o.key,{entity:o.entity,label:o.label,color:n[o.entity]??"#71717a",size:5,x:Number.NaN,y:Number.NaN}),i.add(o.key),r=true);}),e.forEachEdge(o=>{t.edges[o]||(e.dropEdge(o),r=true);}),Object.values(t.edges).forEach(o=>{e.hasEdge(o.key)||(e.addEdgeWithKey(o.key,o.source,o.target,{size:1}),r=true);}),Wt(e,i),r&&e.forEachNode(o=>{e.setNodeAttribute(o,"size",Zt(e.degree(o)));}),{changed:r,added:i,hadNodes:a}}function xt({scene:e,colors:t,theme:n,apiRef:r,onSelect:i,onContextMenu:a,onExpand:o,onPin:b,onLayoutChange:A}){let _=useRef(null),f=useRef(null),s=useRef(null),p=useRef(null),E=useRef(null),S=useRef(null),x=useRef(null),c=useRef(null),N=useRef(null),d=useRef(new Set),C=useRef(e.pinned);C.current=e.pinned;let w=useRef({key:null,nodes:[]}),T=useRef({onSelect:i,onContextMenu:a,onExpand:o,onPin:b,onLayoutChange:A}),[U,M]=useState(0);T.current={onSelect:i,onContextMenu:a,onExpand:o,onPin:b,onLayoutChange:A},f.current||(f.current=new Bt({type:"undirected",multi:true}));let I=useCallback(()=>{E.current!==null&&(window.clearTimeout(E.current),E.current=null),c.current!==null&&(window.clearInterval(c.current),c.current=null),p.current&&(p.current.kill(),p.current=null,N.current=null,T.current.onLayoutChange(false));let l=f.current;d.current.forEach(g=>{l?.hasNode(g)&&l.setNodeAttribute(g,"fixed",C.current[g]===true);}),d.current=new Set;},[]),L=useCallback((l,g=[])=>{let h=f.current;if(I(),!h||h.order===0)return;if(d.current=new Set(g.filter(k=>h.hasNode(k))),d.current.forEach(k=>h.setNodeAttribute(k,"fixed",true)),!h.someNode((k,P)=>!P.fixed)){I();return}let y=Ft.inferSettings(h),v=new Jt(h,{settings:{...y,adjustSizes:true,gravity:.2,slowDown:(y.slowDown??1)*2},outputReducer:(k,P)=>{let ne=S.current;return ne&&ne.node===k&&(P.x=ne.x,P.y=ne.y),P}}),D=performance.now(),q=new Ne(h),Y=false,z=0;p.current=v,N.current=D+l,v.start(),T.current.onLayoutChange(true);let u=()=>{S.current?(N.current=performance.now()+l,E.current=window.setTimeout(u,l)):I();};E.current=window.setTimeout(u,l),c.current=window.setInterval(()=>{let k=q.measure();if(S.current){z=0;return}Y=Y||k.max>0,z=Y&>(k)?z+1:0,z>=Vt&&performance.now()-D>=Ut&&I();},$t);},[I]),$=useCallback(l=>{let g=f.current,h=s.current;if(!g||!h)return;let y=w.current;if(h.setNodesState(y.nodes.filter(v=>g.hasNode(v)),{isNeighbour:false}),l&&g.hasNode(l)){let v=g.neighbors(l);h.setNodesState(v,{isNeighbour:true}),w.current={key:l,nodes:v};}else w.current={key:null,nodes:[]};},[]);return useEffect(()=>{let l=_.current,g=f.current;if(!l||!g)return;if(l.clientWidth===0||l.clientHeight===0){let u=new ResizeObserver(()=>{l.clientWidth>0&&l.clientHeight>0&&(u.disconnect(),M(k=>k+1));});return u.observe(l),()=>u.disconnect()}let h=n==="dark",y=new Yt(g,l,{customNodeState:{isNeighbour:false},customEdgeState:{},customGraphState:{isDense:g.order>300,isZoomedIn:false},settings:{allowInvalidContainer:true,itemSizesReference:"screen",enableNodeDrag:true,renderEdgeLabels:false,labelRenderedSizeThreshold:7,labelDensity:.1,labelGridCellSize:80},styles:{nodes:[{...DEFAULT_STYLES.nodes,size:{whenState:"isHighlighted",then:u=>u.size+5,else:{whenState:"isHovered",then:u=>u.size+2,else:{attribute:"size"}}},cursor:"pointer",labelColor:h?"#e4e4e7":"#18181b",labelSize:12,labelFont:"ui-sans-serif, system-ui, sans-serif",labelVisibility:(u,k,P)=>k.isHovered||k.isHighlighted?"visible":P.isDense&&!P.isZoomedIn&&!k.isNeighbour?"hidden":"auto",backdropColor:h?"#27272a":"#ffffff",backdropShadowColor:h?"rgba(0, 0, 0, 0.6)":"rgba(0, 0, 0, 0.25)"}],edges:[{...DEFAULT_STYLES.edges,color:h?"#3f3f46":"#d4d4d8",size:1}]}});s.current=y,y.on("clickNode",({node:u})=>{T.current.onSelect(u);}),y.on("clickStage",()=>{T.current.onSelect(null);}),y.on("doubleClickNode",({node:u,event:k})=>{k.preventSigmaDefault(),T.current.onExpand(u);}),y.on("rightClickNode",({node:u,event:k})=>{k.preventSigmaDefault();let P=k.original;P.preventDefault(),T.current.onSelect(u),T.current.onContextMenu(u,{x:P.clientX,y:P.clientY});}),y.on("enterNode",({node:u})=>$(u)),y.on("leaveNode",()=>$(null));let v=u=>{let k=new Set([u,...g.neighbors(u)]);return g.nodes().filter(P=>P===u||!k.has(P))};y.on("nodeDragStart",({node:u})=>{S.current={node:u,x:g.getNodeAttribute(u,"x"),y:g.getNodeAttribute(u,"y")},g.size>0?(L(ue(g.order),v(u)),x.current=p.current):(I(),g.setNodeAttribute(u,"fixed",true));}),y.on("nodeDrag",({node:u})=>{S.current?.node===u&&(S.current.x=g.getNodeAttribute(u,"x"),S.current.y=g.getNodeAttribute(u,"y"));}),y.on("nodeDragEnd",({node:u})=>{let k=S.current!==null&&p.current!==null&&p.current===x.current;S.current=null,x.current=null,T.current.onPin(u),k&&L(ue(g.order),v(u));});let D=y.getCamera(),q=({ratio:u})=>{let k=u<.45;y.getGraphState().isZoomedIn!==k&&y.setGraphState({isZoomedIn:k});};D.on("updated",q);let Y=u=>u.preventDefault();l.addEventListener("contextmenu",Y);let z=new ResizeObserver(()=>{l.clientWidth>0&&l.clientHeight>0&&(y.resize(),y.scheduleRefresh());});return z.observe(l),r.current={fit:()=>{D.reset({duration:300});}},()=>{z.disconnect(),D.off("updated",q),l.removeEventListener("contextmenu",Y),r.current=null,s.current=null,w.current={key:null,nodes:[]},y.kill();}},[n,U,r,L,I,$]),useEffect(()=>{let l=f.current;if(!l)return;I();let{changed:g,added:h,hadNodes:y}=en(l,e,t);if(!g)return;if(s.current?.setGraphState({isDense:l.order>300}),$(l.hasNode(w.current.key??"")?w.current.key:null),l.size===0){I();return}let v=y&&h.size>0?l.nodes().filter(D=>!h.has(D)):[];L(ue(v.length>0?h.size:l.order),v);},[e.version]),useEffect(()=>{let l=f.current;l&&l.forEachNode((g,h)=>{l.setNodeAttribute(g,"color",t[h.entity]??"#71717a");});},[t]),useEffect(()=>{let l=f.current,g=s.current;if(!l||!g)return;let h=new Set(e.hiddenEntities),y=false;l.forEachNode((v,D)=>{g.setNodeState(v,{isHidden:h.has(D.entity),isHighlighted:v===e.selected});let q=e.pinned[v]===true||d.current.has(v);(D.fixed??false)!==q&&(l.setNodeAttribute(v,"fixed",q),y=true);}),y&&N.current!==null&&L(Math.max(500,N.current-performance.now()),[...d.current]),l.forEachEdge((v,D,q,Y)=>{g.setEdgeState(v,{isHidden:h.has(l.getNodeAttribute(q,"entity"))||h.has(l.getNodeAttribute(Y,"entity"))});});},[e.hiddenEntities,e.selected,e.pinned,e.version,U,n,L]),useEffect(()=>I,[I]),jsx("div",{className:"fk:h-full fk:w-full fk:min-h-0",ref:_})}function Nt({menu:e,relationships:t,isPinned:n,onClose:r$1,onExpandAll:i,onExpandAttribute:a,onHide:o,onHideOthers:b,onTogglePin:A,onOpenRecord:_}){let f=e?.key??"";return jsxs(e$2,{onOpenChange:s=>{s||r$1();},open:e!==null,children:[jsx(g$2,{asChild:true,children:jsx("span",{"aria-hidden":"true",className:"fk:fixed fk:size-0",style:{left:e?.x??0,top:e?.y??0}})}),jsxs(h$1,{align:"start",className:"fk:w-52","data-testid":"graph-context-menu",side:"bottom",children:[jsx(j$1,{onSelect:()=>i(f),children:"Expand all"}),t.length>0?jsxs(q,{children:[jsx(r,{children:"Expand"}),jsx(s$2,{className:"fk:max-h-80 fk:overflow-y-auto",children:t.map(s=>jsx(j$1,{onSelect:()=>a(f,s),children:s.label},s.name))})]}):null,jsx(o$1,{}),jsx(j$1,{onSelect:()=>o(f),children:"Hide"}),jsx(j$1,{onSelect:()=>b(f),children:"Hide others"}),jsx(j$1,{onSelect:()=>A(f),children:n?"Unpin position":"Pin position"}),jsx(o$1,{}),jsx(j$1,{onSelect:()=>_(f),children:"Open record"})]})]})}var ve={nodes:{},edges:{},counts:{},fetched:{},hiddenEntities:[],pinned:{},selected:null,notice:null,version:0};function nn(e,t){if(!t)return e;let n={...e};return Object.entries(t).forEach(([r,i])=>{n[r]={...n[r],...i};}),n}function rn(e,t){if(!t)return e;let n={...e};return Object.entries(t).forEach(([r,i])=>{let a={...n[r]};Object.entries(i).forEach(([o,b])=>{a[o]=Math.max(a[o]??0,b);}),n[r]=a;}),n}function Et(e,t){let n=Object.fromEntries(Object.entries(e.nodes).filter(([a])=>!t.has(a))),r=Object.fromEntries(Object.entries(e.edges).filter(([,a])=>!t.has(a.source)&&!t.has(a.target))),i=Object.fromEntries(Object.entries(e.pinned).filter(([a])=>!t.has(a)));return {...e,nodes:n,edges:r,pinned:i,selected:e.selected&&t.has(e.selected)?null:e.selected,version:e.version+1}}function vt(e,t){switch(t.type){case "merge":{let n={...e.nodes},r=Object.keys(n).length,i=0;t.data.nodes.forEach(o=>{if(!n[o.key]){if(r>=c$4){i+=1;return}n[o.key]=o,r+=1;}});let a={...e.edges};return t.data.edges.forEach(o=>{n[o.source]&&n[o.target]&&(a[o.key]=o);}),{...e,nodes:n,edges:a,counts:nn(e.counts,t.data.counts),fetched:rn(e.fetched,t.fetched),notice:i>0?`The canvas holds ${c$4.toLocaleString()} nodes at most; ${i.toLocaleString()} were left out. Hide some nodes to make room.`:e.notice,version:e.version+1}}case "remove":return Et(e,new Set(t.keys));case "keepOnly":{let n=new Set(t.keys);return Et(e,new Set(Object.keys(e.nodes).filter(r=>!n.has(r))))}case "clear":return {...ve,hiddenEntities:e.hiddenEntities,version:e.version+1};case "toggleEntity":return {...e,hiddenEntities:e.hiddenEntities.includes(t.entity)?e.hiddenEntities.filter(n=>n!==t.entity):[...e.hiddenEntities,t.entity]};case "select":return e.selected===t.key?e:{...e,selected:t.key};case "togglePin":{let n={...e.pinned};return n[t.key]?delete n[t.key]:n[t.key]=true,{...e,pinned:n}}case "notice":return {...e,notice:t.message};default:return e}}function At(e){return Object.values(e.nodes).reduce((t,n)=>(t[n.entity]=(t[n.entity]??0)+1,t),{})}function Ct(e,t){return Object.values(e.edges).reduce((n,r)=>(r.source===t?n[r.sourceAttribute]=(n[r.sourceAttribute]??0)+1:r.target===t&&(n[r.targetAttribute]=(n[r.targetAttribute]??0)+1),n),{})}function wt(e,t){return Object.values(e.edges).flatMap(n=>n.source===t?[n.target]:n.target===t?[n.source]:[])}function un(e){let[t,n,r]=[1,3,5].map(a=>{let o=parseInt(e.slice(a,a+2),16)/255;return o<=.03928?o/12.92:((o+.055)/1.055)**2.4});return .2126*t+.7152*n+.0722*r>.3?"#0a0a0a":"#ffffff"}function Tt({node:e$2,schema:t,scope:n$1,scene:r,colors:i,isLoading:a,onClose:o,onOpenRecord:b,onExpandAll:A,onExpandAttribute:_,onHide:f}){let s=g$1(t,e$2.entity),p=useMemo(()=>gql(s?o$2({entity:s,scope:n$1}):"query GraphDetails { __typename }"),[s,n$1]),E=useMemo(()=>gql(s?m({entity:s}):"query GraphCounts { __typename }"),[s]),S=useQuery(p,{variables:{id:e$2.id},skip:!s}),x=useQuery(E,{variables:{id:e$2.id},skip:!s}),c=s?S.data?.[s.plural]?.[0]:void 0,N=s?x.data?.[s.plural]?.[0]:void 0,d=useMemo(()=>Ct(r,e$2.key),[r,e$2.key]),C=s?e$1(s):[],w=s?n(s):[],T=c?._updatedAt?new Date(c._updatedAt):null,U=i[e$2.entity]??"#71717a";return jsxs("aside",{"aria-label":"Selected record",className:"fk:flex fk:w-72 fk:shrink-0 fk:flex-col fk:gap-5 fk:overflow-y-auto fk:border-l fk:bg-background fk:p-4 fk:text-sm","data-testid":"graph-inspector",children:[jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsxs("div",{className:"fk:flex fk:items-center fk:justify-between fk:gap-2",children:[jsx("span",{className:"fk:inline-flex fk:items-center fk:rounded-full fk:px-2 fk:py-0.5 fk:text-xs fk:font-medium",style:{backgroundColor:U,color:un(U)},children:s?h(s):e$2.entity}),jsx(b$3,{"aria-label":"Close",className:"fk:size-7",onClick:o,size:"icon",variant:"ghost",children:jsx(XIcon,{className:"fk:size-4"})})]}),jsx("h2",{className:"fk:text-base fk:font-semibold fk:leading-snug fk:break-words",children:e$2.label}),jsxs("div",{className:"fk:flex fk:gap-1.5",children:[jsxs(b$3,{onClick:()=>b(e$2.key),size:"xs",children:[jsx(SquareArrowOutUpRightIcon,{}),"Open record"]}),jsxs(b$2,{children:[jsx(c$3,{asChild:true,children:jsxs(b$3,{"aria-label":"Expand every relationship",disabled:a,onClick:()=>A(e$2.key),size:"xs",variant:"outline",children:[a?jsx(LoaderCircleIcon,{className:"fk:animate-spin"}):jsx(ExpandIcon,{}),"Expand"]})}),jsx(e,{children:"Load the first related records of every relationship"})]}),jsxs(b$3,{"aria-label":"Hide this node",onClick:()=>f(e$2.key),size:"xs",variant:"outline",children:[jsx(EyeOffIcon,{}),"Hide"]})]})]}),jsxs("section",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx("h3",{className:"fk:text-xs fk:font-medium fk:text-muted-foreground",children:"Attributes"}),S.loading&&!c?jsx("span",{className:"fk:text-muted-foreground",children:"Loading\u2026"}):jsxs("dl",{className:"fk:grid fk:grid-cols-[minmax(0,2fr)_minmax(0,3fr)] fk:gap-x-3 fk:gap-y-1.5",children:[w.map(M=>jsxs("div",{className:"fk:contents",children:[jsx("dt",{className:"fk:truncate fk:text-muted-foreground",title:M.label,children:M.label}),jsx("dd",{className:"fk:min-w-0 fk:break-words",children:c&&r$1(c[M.name],n$1)||"\u2014"})]},M.name)),T?jsxs("div",{className:"fk:contents",children:[jsx("dt",{className:"fk:text-muted-foreground",children:"Updated"}),jsx("dd",{children:formatDistance(T,new Date,{addSuffix:true})})]}):null]})]}),C.length>0?jsxs("section",{className:"fk:flex fk:flex-col fk:gap-1",children:[jsx("h3",{className:"fk:mb-1 fk:text-xs fk:font-medium fk:text-muted-foreground",children:"Relationships"}),C.map(M=>{let I=g$1(t,M.relationship?.entity??""),L=N?.[`${M.name}Connection`]?.aggregate?.count?.nodes,$=d[M.name]??0,l=r.fetched[e$2.key]?.[M.name]??0,g=typeof L=="number"&&l>=L;return jsxs("div",{className:"fk:flex fk:h-8 fk:items-center fk:gap-2",children:[jsx("span",{"aria-hidden":"true",className:"fk:size-2 fk:shrink-0 fk:rounded-full",style:{backgroundColor:i[M.relationship?.entity??""]??"#71717a"}}),jsx("span",{className:"fk:min-w-0 fk:flex-1 fk:truncate",title:I?h(I):void 0,children:M.label}),jsx("span",{className:"fk:text-xs fk:text-muted-foreground",children:typeof L=="number"?`${$} of ${L.toLocaleString()}`:$}),L===0||g?null:jsx(b$3,{className:"fk:h-6 fk:px-2 fk:text-xs",disabled:a,onClick:()=>_(e$2.key,M),size:"xs",variant:"outline",children:l>0?"More":"Expand"})]},M.name)})]}):null]})}var kn=250,bn=5;function yn(e,t){let n=t.trim();return !n||e.length===0?null:{searchRequests:{searches:e.map(r=>({collection:r.plural}))},commonParams:{q:n,limit:bn}}}function Sn(e){let t=useMemo(()=>p(e),[e]),n=useMemo(()=>gql(t.length>0?q$1(t):"query GraphTotals { __typename }"),[t]),{data:r}=useQuery(n,{skip:t.length===0});return useMemo(()=>Object.fromEntries(t.map(i=>[i.plural,r?.[`${i.plural}Total`]]).filter(i=>typeof i[1]=="number")),[t,r])}function Gt({projectId:e,entities:t,colors:n,onCanvas:r,hiddenEntities:i,onStart:a,onHit:o$1,onToggleEntity:b}){let[A,_]=useState(""),[f]=useDebounce(A,kn),s=useMemo(()=>t.filter(d=>d.attributes.some(C=>C.searchable)),[t]),p=useMemo(()=>yn(s,f),[s,f]),{results:E,isLoading:S$1}=a$1(e,p),x=Sn(t),c=useMemo(()=>new Map(t.map(d=>[d.name,d])),[t]),N$1=Object.keys(r).sort();return jsxs(N,{collapsible:"icon",variant:"inset",children:[jsxs(R,{children:[jsxs(S,{className:"fk:group-data-[collapsible=icon]:hidden",children:[jsxs("div",{className:"fk:relative",children:[jsx(SearchIcon,{className:"fk:pointer-events-none fk:absolute fk:left-2 fk:top-1/2 fk:size-4 fk:-translate-y-1/2 fk:text-muted-foreground"}),jsx(s$1,{"aria-label":"Search records to add to the canvas",className:"fk:h-8 fk:bg-background fk:pl-8 fk:shadow-none",onChange:d=>_(d.target.value),placeholder:s.length>0?"Search records\u2026":"No searchable entity",disabled:s.length===0,value:A})]}),p?jsxs("ul",{className:"fk:mt-2 fk:flex fk:flex-col fk:gap-0.5","data-testid":"graph-search-results",children:[E.map(d=>{let C=c.get(d._entityName),w=d[a$2(C)?.name??""];return jsx("li",{children:jsxs("button",{className:"fk:flex fk:w-full fk:items-center fk:gap-2 fk:rounded-md fk:px-2 fk:py-1.5 fk:text-left fk:text-sm fk:hover:bg-sidebar-accent",onClick:()=>o$1(d._entityName,d._id),type:"button",children:[jsx("span",{"aria-hidden":"true",className:"fk:size-2.5 fk:shrink-0 fk:rounded-full",style:{backgroundColor:n[d._entityName]??"#71717a"}}),jsx("span",{className:"fk:min-w-0 fk:flex-1 fk:truncate",children:String(w??d._id)})]})},`${d._entityName}:${d._id}`)}),!S$1&&E.length===0?jsx("li",{className:"fk:px-2 fk:py-1.5 fk:text-sm fk:text-muted-foreground",children:"Nothing found"}):null]}):null]}),jsxs(S,{children:[jsx(T,{children:"Nodes"}),jsx(V,{children:t.map(d=>jsx(W,{children:jsxs(X,{onClick:()=>a(d),tooltip:h(d),children:[jsx("span",{"aria-hidden":"true",className:"fk:size-2.5 fk:shrink-0 fk:rounded-full",style:{backgroundColor:n[d.name]??"#71717a"}}),jsx("span",{className:"fk:truncate",children:h(d)}),x[d.plural]!==void 0?jsx("span",{className:"fk:ml-auto fk:text-xs fk:text-muted-foreground",children:x[d.plural]?.toLocaleString()}):null]})},d.name))})]}),N$1.length>0?jsxs(S,{className:"fk:group-data-[collapsible=icon]:hidden",children:[jsx(T,{children:"On canvas"}),jsx("ul",{className:"fk:flex fk:flex-col","data-testid":"graph-legend",children:N$1.map(d=>{let C=c.get(d),w=!i.includes(d),T=`graph-legend-${d}`;return jsxs("li",{className:"fk:flex fk:h-8 fk:items-center fk:gap-2 fk:px-2 fk:text-sm",children:[jsx("span",{"aria-hidden":"true",className:"fk:size-2.5 fk:shrink-0 fk:rounded-full",style:{backgroundColor:n[d]??"#71717a",opacity:w?1:.35}}),jsx("label",{className:"fk:min-w-0 fk:flex-1 fk:cursor-pointer fk:truncate",htmlFor:T,children:C?h(C):d}),jsx("span",{className:"fk:text-xs fk:text-muted-foreground",children:r[d]?.toLocaleString()}),jsx(o,{"aria-label":`Show ${C?h(C):d}`,checked:w,id:T,onCheckedChange:()=>b(d)})]},d)})})]}):null]}),jsx(P,{})]})}function fe({label:e$1,icon:t,disabled:n,onClick:r}){return jsxs(b$2,{children:[jsx(c$3,{asChild:true,children:jsxs(b$3,{className:"fk:h-8 fk:gap-1.5 fk:px-2.5",disabled:n,onClick:r,size:"sm",variant:"ghost",children:[t,jsx("span",{className:"fk:text-xs",children:e$1})]})}),jsx(e,{children:e$1})]})}function It({hasSelection:e,hasNodes:t,isLoading:n,onFit:r,onExpand:i,onHide:a,onClear:o}){return jsxs("div",{className:"fk:flex fk:items-center fk:gap-0.5 fk:rounded-lg fk:border fk:bg-background fk:p-1 fk:shadow-xs","data-testid":"graph-toolbar",children:[jsx(fe,{disabled:!t,icon:jsx(ScanIcon,{className:"fk:size-3.5"}),label:"Fit",onClick:r}),jsx(v$1,{className:"fk:mx-0.5 fk:h-4",orientation:"vertical"}),jsx(fe,{disabled:!e||n,icon:n?jsx(LoaderCircleIcon,{className:"fk:size-3.5 fk:animate-spin"}):jsx(ExpandIcon,{className:"fk:size-3.5"}),label:"Expand",onClick:i}),jsx(fe,{disabled:!e,icon:jsx(EyeOffIcon,{className:"fk:size-3.5"}),label:"Hide",onClick:a}),jsx(v$1,{className:"fk:mx-0.5 fk:h-4",orientation:"vertical"}),jsx(fe,{disabled:!t,icon:jsx(EraserIcon,{className:"fk:size-3.5"}),label:"Clear",onClick:o})]})}function Pt(e){return e instanceof Error?e.message:"The records could not be loaded."}function Ot({schema:e,scope:t$1}){let n=useApolloClient(),[r,i]=useReducer(vt,ve),[a$1,o]=useState(0),b=useCallback(async(f,s$1)=>{let p="ids"in s$1?s$1.ids:void 0,E="ids"in s$1?s$1.expand:false,S="limit"in s$1?s$1.limit:p?.length;o(x=>x+1);try{let c=(await n.query({query:gql(k({entity:f,schema:e,scope:t$1,expand:E})),variables:{where:p?{_id:{in:p}}:void 0,limit:S},fetchPolicy:"network-only"})).data?.[f.plural]??[];return i({type:"merge",data:s({records:c,entity:f,schema:e,scope:t$1}),fetched:t(c,f)}),c.map(N=>d(f.name,N._id))}catch(x){return qa.error(Pt(x)),[]}finally{o(x=>x-1);}},[n,e,t$1]),A=useCallback(async f=>{let s=r.nodes[f],p=s?g$1(e,s.entity):void 0;!s||!p||await b(p,{ids:[s.id],expand:true});},[b,e,r.nodes]),_=useCallback(async(f,s$1)=>{let p=r.nodes[f],E=p?g$1(e,p.entity):void 0;if(!p||!E)return;let S=r.fetched[f]?.[s$1.name]??0;o(x=>x+1);try{let c=(await n.query({query:gql(l({entity:E,schema:e,scope:t$1,attribute:s$1})),variables:{id:p.id,offset:S,limit:a},fetchPolicy:"network-only"})).data?.[E.plural]??[],N=c.reduce((d,C)=>{let w=C[s$1.name];return d+(Array.isArray(w)?w.length:0)},0);i({type:"merge",data:s({records:c,entity:E,schema:e,scope:t$1}),fetched:{[f]:{[s$1.name]:S+N}}});}catch(x){qa.error(Pt(x));}finally{o(x=>x-1);}},[n,e,t$1,r.fetched,r.nodes]);return {state:r,dispatch:i,isLoading:a$1>0,loadRecords:b,expandAll:A,expandAttribute:_}}function jr(){let{currentProjectId:e$2,currentProject:t,currentProjectSchema:n}=f(),[,r]=g(),{scope:i$1}=c(),{resolvedTheme:a}=b(),o=useLocation(),b$3=c$1(),A=a==="dark"?"dark":"light",_=t?.scopes?.find(m=>m.isDefault)?.name??"default",f$2=i$1||_,s=r.user?.spaces,p=useMemo(()=>c$2(n,s),[n,s]),E=useMemo(()=>f$1(p),[p]),S=useMemo(()=>i(p,A),[p,A]),x=Ot({schema:p,scope:f$2}),{state:c$4,dispatch:N,isLoading:d,loadRecords:C,expandAll:w,expandAttribute:T}=x,U=useRef(null),[M$1,I]=useState(null),[L,$]=useState(false),l=useRef(null),g$2=useMemo(()=>At(c$4),[c$4]),h=c$4.selected?c$4.nodes[c$4.selected]:void 0,y=M$1?c$4.nodes[M$1.key]:void 0,v$1=y?g$1(p,y.entity):void 0,D=Object.keys(c$4.nodes).length,q=Object.keys(c$4.edges).length,Y=K(),z=useCallback(m=>N({type:"select",key:m}),[N]),u=useCallback(m=>{let O=c$4.nodes[m],ee=O?g$1(p,O.entity):void 0;O&&ee&&b$3({type:"EditEntity",payload:{entityId:O.id,entityNamePlural:ee.plural}});},[b$3,p,c$4.nodes]),k=useCallback(m=>N({type:"remove",keys:[m]}),[N]),P=useCallback(m=>N({type:"keepOnly",keys:[m,...wt(c$4,m)]}),[N,c$4]),ne=useCallback(m=>N({type:"togglePin",key:m}),[N]),zt=useCallback(m=>{c$4.pinned[m]||N({type:"togglePin",key:m});},[N,c$4.pinned]),Ht=useCallback(async(m,O)=>{let ee=g$1(p,m);if(!ee)return;let[ae]=await C(ee,{ids:[O],expand:true});ae&&z(ae);},[C,p,z]),jt=useCallback((m,O)=>{I(null),T(m,O);},[T]);return useEffect(()=>{let m=v(o.search);if(!m||l.current===o.key)return;let O=g$1(p,m.entity);if(!O||p.length===0)return;l.current=o.key;let ee=m.ids.length>0?{ids:m.ids,expand:m.ids.length<=j}:{limit:b$1};C(O,ee).then(ae=>{m.ids.length===1&&ae[0]&&z(ae[0]);});},[o.key,o.search,p,C,z]),e$2?jsxs(M,{className:"fk:h-full",defaultOpen:Y,children:[jsx(Gt,{colors:S,entities:E,hiddenEntities:c$4.hiddenEntities,onCanvas:g$2,onHit:(m,O)=>{Ht(m,O);},onStart:m=>{C(m,{limit:b$1});},onToggleEntity:m=>N({type:"toggleEntity",entity:m}),projectId:e$2}),jsx(Q,{className:"fk:min-w-0",children:jsxs("div",{className:"fk:flex fk:h-full fk:min-h-0 fk:min-w-0","data-testid":"graph-app",children:[jsxs("div",{className:"fk:relative fk:min-w-0 fk:flex-1 fk:overflow-hidden fk:bg-background",children:[jsxs("div",{className:"fk:absolute fk:left-3 fk:top-3 fk:z-10 fk:flex fk:items-center fk:gap-2",children:[jsxs(b$2,{children:[jsx(c$3,{asChild:true,children:jsx(O,{className:"fk:h-8 fk:w-8 fk:rounded-lg fk:hover:bg-transparent fk:dark:hover:bg-transparent"})}),jsx(e,{children:"Toggle Sidebar"})]}),jsx(It,{hasNodes:D>0,hasSelection:h!==void 0,isLoading:d,onClear:()=>N({type:"clear"}),onExpand:()=>{c$4.selected&&w(c$4.selected);},onFit:()=>U.current?.fit(),onHide:()=>{c$4.selected&&k(c$4.selected);}})]}),D>0?null:jsx("div",{className:"fk:pointer-events-none fk:absolute fk:inset-0 fk:flex fk:items-center fk:justify-center fk:p-8 fk:text-center fk:text-sm fk:text-muted-foreground",children:d?"Loading records\u2026":"Search a record or start from an entity to draw its graph."}),jsx(xt,{apiRef:U,colors:S,onContextMenu:(m,O)=>I({key:m,...O}),onExpand:m=>{w(m);},onLayoutChange:$,onPin:zt,onSelect:z,scene:c$4,theme:A}),jsxs("div",{className:"fk:absolute fk:bottom-3 fk:left-3 fk:flex fk:max-w-[calc(100%-1.5rem)] fk:items-center fk:gap-2 fk:rounded-lg fk:border fk:bg-background fk:px-2.5 fk:py-1.5 fk:text-xs fk:text-muted-foreground fk:shadow-xs","data-testid":"graph-status",children:[jsxs("span",{children:[D.toLocaleString()," ",D===1?"node":"nodes"," \xB7 ",q.toLocaleString()," ",q===1?"relationship":"relationships"]}),L?jsx("span",{children:"\xB7 laying out\u2026"}):null,c$4.notice?jsxs("span",{className:"fk:truncate fk:text-foreground",children:["\xB7 ",c$4.notice]}):null]}),jsx(Nt,{isPinned:M$1?c$4.pinned[M$1.key]===true:false,menu:M$1,onClose:()=>I(null),onExpandAll:m=>{w(m);},onExpandAttribute:jt,onHide:k,onHideOthers:P,onOpenRecord:u,onTogglePin:ne,relationships:v$1?e$1(v$1):[]})]}),h?jsx(Tt,{colors:S,isLoading:d,node:h,onClose:()=>z(null),onExpandAll:m=>{w(m);},onExpandAttribute:(m,O)=>{T(m,O);},onHide:k,onOpenRecord:u,scene:c$4,schema:p,scope:f$2}):null]})})]}):jsx("main",{className:"fk:flex fk:h-full fk:flex-1 fk:items-center fk:justify-center fk:p-8 fk:text-sm fk:text-muted-foreground",children:"Select a project to explore its graph."})}export{jr as Root};//# sourceMappingURL=root-TZYOIXVG.js.map
|
|
2
|
+
//# sourceMappingURL=root-TZYOIXVG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/apps/graph/layout.ts","../src/apps/graph/canvas.tsx","../src/apps/graph/context-menu.tsx","../src/apps/graph/scene.ts","../src/apps/graph/inspector.tsx","../src/apps/graph/sidebar.tsx","../src/apps/graph/toolbar.tsx","../src/apps/graph/use-scene.ts","../src/apps/graph/root.tsx"],"names":["layoutBudget","order","isSettled","mean","max","diagonal","threshold","PLACEMENT_RADIUS","SETTLE_INTERVAL_MS","SETTLE_MIN_MS","SETTLE_QUIET_SAMPLES","nodeSize","degree","ringRadius","count","ringPositions","center","radius","phase","_","index","angle","distance","isPositioned","graph","key","placedExtent","placed","sum","reach","placeNewNodes","added","groups","anchor","neighbour","keys","positions","extent","position","PositionTracker","cursor","_key","attributes","total","free","minX","minY","maxX","maxY","x","y","moved","syncGraph","scene","colors","changed","hadNodes","node","edge","GraphCanvas","theme","apiRef","onSelect","onContextMenu","onExpand","onPin","onLayoutChange","containerRef","useRef","graphRef","rendererRef","layoutRef","layoutTimerRef","dragRef","dragLayoutRef","settleTimerRef","layoutDeadlineRef","heldRef","pinnedRef","hoverRef","callbacksRef","mountAttempt","setMountAttempt","useState","Graph","stopLayout","useCallback","startLayout","budgetMs","hold","inferred","forceAtlas2","layout","FA2LayoutSupervisor","drag","startedAt","tracker","hasMoved","quietSamples","onBudget","movement","applyHover","renderer","previous","nodes","useEffect","container","observer","attempt","isDark","Sigma","DEFAULT_STYLES","_attributes","state","graphState","event","original","holdAllBut","wasRunning","camera","handleCameraUpdate","ratio","isZoomedIn","preventContextMenu","sizeObserver","hidden","pinsChanged","fixed","source","target","jsx","GraphContextMenu","menu","relationships","isPinned","onClose","onExpandAll","onExpandAttribute","onHide","onHideOthers","onTogglePin","onOpenRecord","jsxs","DropdownMenu","open","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuItem","DropdownMenuSub","DropdownMenuSubTrigger","DropdownMenuSubContent","attribute","DropdownMenuSeparator","EMPTY_SCENE","mergeCounts","current","incoming","next","perAttribute","mergeFetched","merged","offset","withoutNodes","dropped","edges","pinned","sceneReducer","action","MAX_NODES","kept","entity","countNodesByEntity","result","countEdgesByAttribute","neighbourKeys","getTextColorOn","hex","r","g","b","channel","GraphInspector","schema","scope","isLoading","getEntity","detailsDocument","useMemo","gql","buildDetailsQuery","countsDocument","buildCountsQuery","details","useQuery","counts","record","countRecord","onCanvas","getRelationshipAttributes","getDetailAttributes","updatedAt","color","getEntityLabel","Button","XIcon","SquareArrowOutUpRightIcon","Tooltip","TooltipTrigger","LoaderCircleIcon","ExpandIcon","TooltipContent","EyeOffIcon","formatDetailValue","formatDistance","relatedEntity","shown","fetched","exhausted","SEARCH_DEBOUNCE_MS","SEARCH_HITS_PER_ENTITY","buildSearchRequest","entities","q","trimmed","useTotals","countable","getTotalEntities","document","buildTotalsQuery","data","pair","GraphSidebar","projectId","hiddenEntities","onStart","onHit","onToggleEntity","query","setQuery","debouncedQuery","useDebounce","searchable","request","results","useSearch","totals","entityByName","onCanvasEntities","Sidebar","SidebarContent","SidebarGroup","SearchIcon","Input","hit","label","getDisplayAttribute","SidebarGroupLabel","SidebarMenu","SidebarMenuItem","SidebarMenuButton","name","checked","id","Checkbox","SidebarRail","ToolbarButton","icon","disabled","onClick","GraphToolbar","hasSelection","hasNodes","onFit","onClear","ScanIcon","Separator","EraserIcon","errorMessage","error","useScene","client","useApolloClient","dispatch","useReducer","pending","setPending","loadRecords","selection","ids","expand","limit","records","buildRecordsQuery","graphFromRecords","fetchedFromRecords","nodeKey","toast","expandAll","expandAttribute","buildExpandQuery","EXPAND_PAGE","received","related","Root","currentProjectId","currentProject","currentProjectSchema","useConfig","auth","useAuth","useAppContext","resolvedTheme","useTheme","location","useLocation","dispatchAction","useDispatch","defaultScope","item","scopeField","userSpaces","filterEntitiesForSpaces","getGraphEntities","getEntityColors","canvasApi","setMenu","isLayoutRunning","setIsLayoutRunning","loadedSearchRef","selectedNode","menuNode","menuEntity","nodeCount","edgeCount","defaultOpen","readSidebarCookieState","select","openRecord","hide","hideOthers","togglePin","pin","addRecord","entityName","expandAttributeAndClose","params","parseGraphParams","EXPAND_HOP_MAX_RECORDS","SAMPLE_LIMIT","SidebarProvider","SidebarInset","SidebarTrigger"],"mappings":"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","file":"root-TZYOIXVG.js","sourcesContent":["/**\n * Pure layout rules of the canvas: how long the force layout may run, when\n * it counts as settled, and when a graph is too dense for labels everywhere.\n */\n\n/** Above this many nodes, labels show only around the pointer and the selection unless zoomed in. */\nexport const DENSE_NODES = 300;\n\n/** Camera ratio below which a dense graph shows labels again (1 = the whole graph in view). */\nexport const ZOOMED_IN_RATIO = 0.45;\n\n/** The longest the force layout runs after a change: 2 s for a few nodes, 20 s at the cap. */\nexport function layoutBudget(order: number): number {\n return Math.min(20000, 2000 + order * 9);\n}\n\n/** How much the free nodes moved since the last sample, and the graph's extent. */\nexport interface LayoutMovement {\n /** Mean move of the nodes the layout may move. */\n mean: number;\n /** Largest move of any of them: a few new nodes still flying in keep the layout going. */\n max: number;\n /** Bounding-box diagonal of the whole graph. */\n diagonal: number;\n}\n\n/**\n * Whether the layout has settled: the mean move per free node is a sliver\n * of the graph's extent and no node is still travelling, with a floor so a\n * tiny graph settles too.\n */\nexport function isSettled({ mean, max, diagonal }: LayoutMovement): boolean {\n const threshold = Math.max(0.05, diagonal * 0.0015);\n\n return mean < threshold && max < threshold * 20;\n}\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { JSX, MutableRefObject } from 'react';\nimport Graph from 'graphology';\nimport type { Attributes } from 'graphology-types';\nimport forceAtlas2 from 'graphology-layout-forceatlas2';\nimport FA2LayoutSupervisor from 'graphology-layout-forceatlas2/worker';\nimport Sigma, { DEFAULT_STYLES } from 'sigma';\nimport { DENSE_NODES, isSettled, layoutBudget, ZOOMED_IN_RATIO, type LayoutMovement } from './layout';\nimport type { SceneState } from './scene';\n\ntype NodeAttributes = {\n entity: string;\n label: string;\n color: string;\n size: number;\n x: number;\n y: number;\n fixed?: boolean;\n};\ntype EdgeAttributes = { size: number };\n/** A neighbour of the hovered node, for its label. */\ntype NodeState = { isNeighbour: boolean };\ntype EdgeState = Record<string, never>;\n/** Too many nodes for labels everywhere; zoomed in far enough to show them anyway. */\ntype GraphState = { isDense: boolean; isZoomedIn: boolean };\ntype Renderer = Sigma<NodeAttributes, EdgeAttributes, Attributes, NodeState, EdgeState, GraphState>;\n\nexport interface GraphCanvasApi {\n /** Brings the whole graph into view. */\n fit: () => void;\n}\n\nexport interface GraphCanvasProps {\n scene: SceneState;\n colors: { [entity: string]: string };\n theme: 'light' | 'dark';\n apiRef: MutableRefObject<GraphCanvasApi | null>;\n onSelect: (key: string | null) => void;\n onContextMenu: (key: string, position: { x: number; y: number }) => void;\n onExpand: (key: string) => void;\n onPin: (key: string) => void;\n onLayoutChange: (running: boolean) => void;\n}\n\n/** Spread of new nodes around the node they came from, in graph units. */\nconst PLACEMENT_RADIUS = 40;\n/** How often the layout is checked for movement. */\nconst SETTLE_INTERVAL_MS = 400;\n/** The layout runs at least this long before it may be called settled. */\nconst SETTLE_MIN_MS = 1200;\n/** Two quiet samples in a row, after the worker first moved something, end the layout. */\nconst SETTLE_QUIET_SAMPLES = 2;\n\nfunction nodeSize(degree: number): number {\n return 5 + Math.min(10, Math.sqrt(degree) * 2);\n}\n\ntype Point = { x: number; y: number };\n\n/** The ring new nodes start on: wider the more of them share an anchor, so they do not explode apart. */\nfunction ringRadius(count: number): number {\n return PLACEMENT_RADIUS * (0.8 + Math.sqrt(count) * 0.6);\n}\n\n/**\n * Evenly spaced positions on a ring, with a little jitter so no two coincide\n * and a random phase so a lone newcomer can land on any side of its anchor.\n */\nfunction ringPositions(center: Point, count: number, radius: number): Point[] {\n const phase = Math.random() * Math.PI * 2;\n\n return Array.from({ length: count }, (_, index) => {\n const angle = phase + (index / count) * Math.PI * 2 + Math.random() * 0.3;\n const distance = radius * (0.9 + Math.random() * 0.2);\n\n return { x: center.x + Math.cos(angle) * distance, y: center.y + Math.sin(angle) * distance };\n });\n}\n\nfunction isPositioned(graph: Graph<NodeAttributes, EdgeAttributes>, key: string): boolean {\n return !Number.isNaN(graph.getNodeAttribute(key, 'x'));\n}\n\n/** Centre and reach of the nodes already placed, to put unanchored newcomers beyond them. */\nfunction placedExtent(\n graph: Graph<NodeAttributes, EdgeAttributes>,\n placed: string[]\n): { center: Point; reach: number } {\n if (placed.length === 0) {\n return { center: { x: 0, y: 0 }, reach: 0 };\n }\n\n const center = placed.reduce(\n (sum, key) => ({ x: sum.x + graph.getNodeAttribute(key, 'x'), y: sum.y + graph.getNodeAttribute(key, 'y') }),\n { x: 0, y: 0 }\n );\n center.x /= placed.length;\n center.y /= placed.length;\n const reach = placed.reduce(\n (max, key) =>\n Math.max(\n max,\n Math.hypot(graph.getNodeAttribute(key, 'x') - center.x, graph.getNodeAttribute(key, 'y') - center.y)\n ),\n 0\n );\n\n return { center, reach };\n}\n\n/**\n * Places new nodes: those sharing an anchor already on the canvas go on a\n * ring around it, the rest on a ring beyond everything placed so far.\n */\nfunction placeNewNodes(graph: Graph<NodeAttributes, EdgeAttributes>, added: Set<string>): void {\n const groups = new Map<string | null, string[]>();\n added.forEach((key) => {\n const anchor =\n graph.neighbors(key).find((neighbour) => !added.has(neighbour) && isPositioned(graph, neighbour)) ?? null;\n groups.set(anchor, [...(groups.get(anchor) ?? []), key]);\n });\n groups.forEach((keys, anchor) => {\n let positions: Point[];\n\n if (anchor) {\n const center = { x: graph.getNodeAttribute(anchor, 'x'), y: graph.getNodeAttribute(anchor, 'y') };\n positions = ringPositions(center, keys.length, ringRadius(keys.length));\n } else {\n const placed = graph.nodes().filter((key) => !added.has(key) && isPositioned(graph, key));\n const extent = placedExtent(graph, placed);\n positions = ringPositions(extent.center, keys.length, extent.reach + ringRadius(keys.length));\n }\n\n positions.forEach((position, index) => graph.mergeNodeAttributes(keys[index]!, position));\n });\n}\n\n/**\n * Positions of every node, kept in one typed array the layout's movement is\n * measured against: one pass per sample, no allocation.\n */\nclass PositionTracker {\n private positions: Float64Array;\n\n constructor(private readonly graph: Graph<NodeAttributes, EdgeAttributes>) {\n this.positions = new Float64Array(graph.order * 2);\n let cursor = 0;\n this.graph.forEachNode((_key, attributes) => {\n this.positions[cursor] = attributes.x;\n this.positions[cursor + 1] = attributes.y;\n cursor += 2;\n });\n }\n\n /** Movement since the last call, then remembers the current positions. */\n measure(): LayoutMovement {\n const { graph, positions } = this;\n let total = 0;\n let max = 0;\n let free = 0;\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n let index = 0;\n graph.forEachNode((_key, attributes) => {\n const { x, y } = attributes;\n\n if (index + 1 < positions.length && !attributes.fixed) {\n const moved = Math.hypot(x - positions[index]!, y - positions[index + 1]!);\n total += moved;\n max = Math.max(max, moved);\n free += 1;\n }\n\n positions[index] = x;\n positions[index + 1] = y;\n index += 2;\n minX = Math.min(minX, x);\n minY = Math.min(minY, y);\n maxX = Math.max(maxX, x);\n maxY = Math.max(maxY, y);\n });\n\n return {\n mean: free > 0 ? total / free : 0,\n max,\n diagonal: graph.order > 0 ? Math.hypot(maxX - minX, maxY - minY) : 0,\n };\n }\n}\n\n/**\n * Adds the scene's new nodes and edges to the graph, drops the removed ones\n * and places new nodes around what is already on the canvas. Reports what\n * was added and whether anything was placed before.\n */\nfunction syncGraph(\n graph: Graph<NodeAttributes, EdgeAttributes>,\n scene: SceneState,\n colors: { [entity: string]: string }\n): { changed: boolean; added: Set<string>; hadNodes: boolean } {\n let changed = false;\n const added = new Set<string>();\n const hadNodes = graph.order > 0;\n\n graph.forEachNode((key) => {\n if (!scene.nodes[key]) {\n graph.dropNode(key);\n changed = true;\n }\n });\n Object.values(scene.nodes).forEach((node) => {\n if (graph.hasNode(node.key)) {\n return;\n }\n\n graph.addNode(node.key, {\n entity: node.entity,\n label: node.label,\n color: colors[node.entity] ?? '#71717a',\n size: 5,\n x: Number.NaN,\n y: Number.NaN,\n });\n added.add(node.key);\n changed = true;\n });\n graph.forEachEdge((key) => {\n if (!scene.edges[key]) {\n graph.dropEdge(key);\n changed = true;\n }\n });\n // A multigraph: two relationships between the same records are two edges.\n Object.values(scene.edges).forEach((edge) => {\n if (!graph.hasEdge(edge.key)) {\n graph.addEdgeWithKey(edge.key, edge.source, edge.target, { size: 1 });\n changed = true;\n }\n });\n\n placeNewNodes(graph, added);\n\n if (changed) {\n graph.forEachNode((key) => {\n graph.setNodeAttribute(key, 'size', nodeSize(graph.degree(key)));\n });\n }\n\n return { changed, added, hadNodes };\n}\n\n/**\n * The WebGL canvas: a graphology graph that lives as long as the component,\n * rendered by sigma and laid out by ForceAtlas2 in a web worker until it\n * settles after every change. Selection, hover, entity visibility and pins\n * are sigma states and node attributes; the scene stays the source of truth.\n */\nexport function GraphCanvas({\n scene,\n colors,\n theme,\n apiRef,\n onSelect,\n onContextMenu,\n onExpand,\n onPin,\n onLayoutChange,\n}: GraphCanvasProps): JSX.Element {\n const containerRef = useRef<HTMLDivElement>(null);\n const graphRef = useRef<Graph<NodeAttributes, EdgeAttributes> | null>(null);\n const rendererRef = useRef<Renderer | null>(null);\n const layoutRef = useRef<FA2LayoutSupervisor | null>(null);\n const layoutTimerRef = useRef<number | null>(null);\n /** The node under the pointer while one is dragged, with the pointer's graph position. */\n const dragRef = useRef<{ node: string; x: number; y: number } | null>(null);\n /** The layout a drag started, so a drop restarts only that one. */\n const dragLayoutRef = useRef<FA2LayoutSupervisor | null>(null);\n const settleTimerRef = useRef<number | null>(null);\n const layoutDeadlineRef = useRef<number | null>(null);\n /** Nodes held still for the running layout so only newcomers move. */\n const heldRef = useRef<Set<string>>(new Set());\n const pinnedRef = useRef<SceneState['pinned']>(scene.pinned);\n pinnedRef.current = scene.pinned;\n /** The hovered node and the neighbours marked around it. */\n const hoverRef = useRef<{ key: string | null; nodes: string[] }>({ key: null, nodes: [] });\n const callbacksRef = useRef({ onSelect, onContextMenu, onExpand, onPin, onLayoutChange });\n const [mountAttempt, setMountAttempt] = useState(0);\n callbacksRef.current = { onSelect, onContextMenu, onExpand, onPin, onLayoutChange };\n\n if (!graphRef.current) {\n graphRef.current = new Graph<NodeAttributes, EdgeAttributes>({ type: 'undirected', multi: true });\n }\n\n const stopLayout = useCallback((): void => {\n if (layoutTimerRef.current !== null) {\n window.clearTimeout(layoutTimerRef.current);\n layoutTimerRef.current = null;\n }\n\n if (settleTimerRef.current !== null) {\n window.clearInterval(settleTimerRef.current);\n settleTimerRef.current = null;\n }\n\n if (layoutRef.current) {\n layoutRef.current.kill();\n layoutRef.current = null;\n layoutDeadlineRef.current = null;\n callbacksRef.current.onLayoutChange(false);\n }\n\n const graph = graphRef.current;\n heldRef.current.forEach((key) => {\n if (graph?.hasNode(key)) {\n graph.setNodeAttribute(key, 'fixed', pinnedRef.current[key] === true);\n }\n });\n heldRef.current = new Set();\n }, []);\n\n // The worker reads `fixed` only when it (re)builds its matrices, so a new\n // supervisor is needed whenever pins change while a layout runs. The\n // layout stops once the nodes stop moving, or at the budget. Nodes in\n // `hold` stay where they are, so adding to a settled canvas moves only\n // the newcomers instead of shaking everything.\n const startLayout = useCallback(\n (budgetMs: number, hold: string[] = []): void => {\n const graph = graphRef.current;\n stopLayout();\n\n if (!graph || graph.order === 0) {\n return;\n }\n\n heldRef.current = new Set(hold.filter((key) => graph.hasNode(key)));\n heldRef.current.forEach((key) => graph.setNodeAttribute(key, 'fixed', true));\n\n // Nothing free to move (say, a dragged node without neighbours): a run would never settle.\n if (!graph.someNode((_key, attributes) => !attributes.fixed)) {\n stopLayout();\n\n return;\n }\n\n const inferred = forceAtlas2.inferSettings(graph);\n const layout = new FA2LayoutSupervisor(graph, {\n // Gentle gravity keeps loose parts near the rest; the extra slowdown keeps the motion calm.\n settings: { ...inferred, adjustSizes: true, gravity: 0.2, slowDown: (inferred.slowDown ?? 1) * 2 },\n // A dragged node stays under the pointer: the worker's positions are\n // overridden for it, and with a reducer set the supervisor reads the\n // graph's positions back into the worker, so the neighbours follow.\n outputReducer: (key: string, attributes: NodeAttributes): NodeAttributes => {\n const drag = dragRef.current;\n\n if (drag && drag.node === key) {\n attributes.x = drag.x;\n attributes.y = drag.y;\n }\n\n return attributes;\n },\n });\n const startedAt = performance.now();\n const tracker = new PositionTracker(graph);\n let hasMoved = false;\n let quietSamples = 0;\n layoutRef.current = layout;\n layoutDeadlineRef.current = startedAt + budgetMs;\n layout.start();\n callbacksRef.current.onLayoutChange(true);\n // While a node is dragged the layout runs on: the budget is extended and settling does not stop it.\n const onBudget = (): void => {\n if (dragRef.current) {\n layoutDeadlineRef.current = performance.now() + budgetMs;\n layoutTimerRef.current = window.setTimeout(onBudget, budgetMs);\n } else {\n stopLayout();\n }\n };\n layoutTimerRef.current = window.setTimeout(onBudget, budgetMs);\n settleTimerRef.current = window.setInterval(() => {\n const movement = tracker.measure();\n\n if (dragRef.current) {\n quietSamples = 0;\n\n return;\n }\n\n // The worker needs a moment to spawn; quiet samples before its first\n // positions arrive say nothing about the layout.\n hasMoved = hasMoved || movement.max > 0;\n quietSamples = hasMoved && isSettled(movement) ? quietSamples + 1 : 0;\n\n if (quietSamples >= SETTLE_QUIET_SAMPLES && performance.now() - startedAt >= SETTLE_MIN_MS) {\n stopLayout();\n }\n }, SETTLE_INTERVAL_MS);\n },\n [stopLayout]\n );\n\n /**\n * Marks the hovered node's neighbours so their labels show, clearing the\n * previous marks first. Re-run after the graph changes so nodes added\n * under the pointer are marked too, and marks of dropped nodes go away.\n */\n const applyHover = useCallback((key: string | null): void => {\n const graph = graphRef.current;\n const renderer = rendererRef.current;\n\n if (!graph || !renderer) {\n return;\n }\n\n const previous = hoverRef.current;\n renderer.setNodesState(\n previous.nodes.filter((node) => graph.hasNode(node)),\n { isNeighbour: false }\n );\n\n if (key && graph.hasNode(key)) {\n const nodes = graph.neighbors(key);\n renderer.setNodesState(nodes, { isNeighbour: true });\n hoverRef.current = { key, nodes };\n } else {\n hoverRef.current = { key: null, nodes: [] };\n }\n }, []);\n\n // The renderer: created per theme (styles are fixed at construction) over\n // the persistent graph.\n useEffect(() => {\n const container = containerRef.current;\n const graph = graphRef.current;\n\n if (!container || !graph) {\n return undefined;\n }\n\n // Sigma throws when the container has no size yet (first paint of a lazy\n // route, hidden app); wait for the box to get one before mounting.\n if (container.clientWidth === 0 || container.clientHeight === 0) {\n const observer = new ResizeObserver(() => {\n if (container.clientWidth > 0 && container.clientHeight > 0) {\n observer.disconnect();\n setMountAttempt((attempt) => attempt + 1);\n }\n });\n observer.observe(container);\n\n return () => observer.disconnect();\n }\n\n const isDark = theme === 'dark';\n const renderer: Renderer = new Sigma<NodeAttributes, EdgeAttributes, Attributes, NodeState, EdgeState, GraphState>(\n graph,\n container,\n {\n customNodeState: { isNeighbour: false },\n customEdgeState: {},\n customGraphState: { isDense: graph.order > DENSE_NODES, isZoomedIn: false },\n settings: {\n // Every render starts with a resize, which would throw while the\n // app is hidden but kept mounted; a hidden canvas renders at 1 px\n // instead and the size observer restores it when it shows again.\n allowInvalidContainer: true,\n itemSizesReference: 'screen',\n enableNodeDrag: true,\n renderEdgeLabels: false,\n labelRenderedSizeThreshold: 7,\n labelDensity: 0.1,\n labelGridCellSize: 80,\n },\n styles: {\n nodes: [\n {\n ...DEFAULT_STYLES.nodes,\n size: {\n whenState: 'isHighlighted',\n then: (attributes: NodeAttributes) => attributes.size + 5,\n else: {\n whenState: 'isHovered',\n then: (attributes: NodeAttributes) => attributes.size + 2,\n else: { attribute: 'size' },\n },\n },\n cursor: 'pointer',\n labelColor: isDark ? '#e4e4e7' : '#18181b',\n labelSize: 12,\n labelFont: 'ui-sans-serif, system-ui, sans-serif',\n // Dense graphs label only the pointer's surroundings and the\n // selection until zoomed in. Neighbours always go through the\n // label grid: a hub's many neighbours would otherwise pile up.\n labelVisibility: (_attributes, state, graphState) => {\n if (state.isHovered || state.isHighlighted) {\n return 'visible';\n }\n\n return graphState.isDense && !graphState.isZoomedIn && !state.isNeighbour ? 'hidden' : 'auto';\n },\n backdropColor: isDark ? '#27272a' : '#ffffff',\n backdropShadowColor: isDark ? 'rgba(0, 0, 0, 0.6)' : 'rgba(0, 0, 0, 0.25)',\n },\n ],\n edges: [\n {\n ...DEFAULT_STYLES.edges,\n color: isDark ? '#3f3f46' : '#d4d4d8',\n size: 1,\n },\n ],\n },\n }\n );\n rendererRef.current = renderer;\n\n renderer.on('clickNode', ({ node }) => {\n callbacksRef.current.onSelect(node);\n });\n renderer.on('clickStage', () => {\n callbacksRef.current.onSelect(null);\n });\n renderer.on('doubleClickNode', ({ node, event }) => {\n event.preventSigmaDefault();\n callbacksRef.current.onExpand(node);\n });\n renderer.on('rightClickNode', ({ node, event }) => {\n event.preventSigmaDefault();\n const original = event.original as MouseEvent;\n original.preventDefault();\n callbacksRef.current.onSelect(node);\n callbacksRef.current.onContextMenu(node, { x: original.clientX, y: original.clientY });\n });\n renderer.on('enterNode', ({ node }) => applyHover(node));\n renderer.on('leaveNode', () => applyHover(null));\n // Dragging a node pulls its neighbours along: the layout runs while the\n // drag lasts with the node held under the pointer, so a cluster can be\n // pulled apart. Everything else is held, so the rest of the canvas\n // stays still, and a canvas without relationships has nothing to pull on.\n const holdAllBut = (node: string): string[] => {\n const free = new Set([node, ...graph.neighbors(node)]);\n\n return graph.nodes().filter((key) => key === node || !free.has(key));\n };\n renderer.on('nodeDragStart', ({ node }) => {\n dragRef.current = { node, x: graph.getNodeAttribute(node, 'x'), y: graph.getNodeAttribute(node, 'y') };\n\n if (graph.size > 0) {\n startLayout(layoutBudget(graph.order), holdAllBut(node));\n dragLayoutRef.current = layoutRef.current;\n } else {\n stopLayout();\n graph.setNodeAttribute(node, 'fixed', true);\n }\n });\n renderer.on('nodeDrag', ({ node }) => {\n if (dragRef.current?.node === node) {\n dragRef.current.x = graph.getNodeAttribute(node, 'x');\n dragRef.current.y = graph.getNodeAttribute(node, 'y');\n }\n });\n renderer.on('nodeDragEnd', ({ node }) => {\n // A scene change during the drag replaced its layout with one settling\n // newcomers; that one keeps running, with the drop pinned by the scene.\n const wasRunning =\n dragRef.current !== null && layoutRef.current !== null && layoutRef.current === dragLayoutRef.current;\n dragRef.current = null;\n dragLayoutRef.current = null;\n callbacksRef.current.onPin(node);\n\n // The node stays where it was dropped while its neighbours settle around it.\n if (wasRunning) {\n startLayout(layoutBudget(graph.order), holdAllBut(node));\n }\n });\n\n const camera = renderer.getCamera();\n const handleCameraUpdate = ({ ratio }: { ratio: number }): void => {\n const isZoomedIn = ratio < ZOOMED_IN_RATIO;\n\n if (renderer.getGraphState().isZoomedIn !== isZoomedIn) {\n renderer.setGraphState({ isZoomedIn });\n }\n };\n camera.on('updated', handleCameraUpdate);\n\n const preventContextMenu = (event: MouseEvent): void => event.preventDefault();\n container.addEventListener('contextmenu', preventContextMenu);\n\n // Sigma only watches the window: the canvases must follow the container\n // when a pane opens beside it, or they keep their size and overflow it.\n const sizeObserver = new ResizeObserver(() => {\n if (container.clientWidth > 0 && container.clientHeight > 0) {\n renderer.resize();\n renderer.scheduleRefresh();\n }\n });\n sizeObserver.observe(container);\n\n apiRef.current = {\n fit: () => {\n void camera.reset({ duration: 300 });\n },\n };\n\n return () => {\n sizeObserver.disconnect();\n camera.off('updated', handleCameraUpdate);\n container.removeEventListener('contextmenu', preventContextMenu);\n apiRef.current = null;\n rendererRef.current = null;\n hoverRef.current = { key: null, nodes: [] };\n renderer.kill();\n };\n }, [theme, mountAttempt, apiRef, startLayout, stopLayout, applyHover]);\n\n // Scene changes: sync the graph, then let the layout settle the new nodes.\n useEffect(() => {\n const graph = graphRef.current;\n\n if (!graph) {\n return;\n }\n\n // The layout's supervisor respawns its worker on every graph change, on\n // a timer that outlives `kill()`: stop it before the graph is touched.\n stopLayout();\n const { changed, added, hadNodes } = syncGraph(graph, scene, colors);\n\n if (!changed) {\n return;\n }\n\n rendererRef.current?.setGraphState({ isDense: graph.order > DENSE_NODES });\n // Nodes added under the pointer get their hover marks; marks of dropped nodes go.\n applyHover(graph.hasNode(hoverRef.current.key ?? '') ? hoverRef.current.key : null);\n\n // Nothing to pull on: a bare sample stays on its ring.\n if (graph.size === 0) {\n stopLayout();\n\n return;\n }\n\n // Adding to a placed canvas: hold what is there, settle the newcomers.\n const hold = hadNodes && added.size > 0 ? graph.nodes().filter((key) => !added.has(key)) : [];\n startLayout(layoutBudget(hold.length > 0 ? added.size : graph.order), hold);\n // Nodes and edges only change with the scene version; colours are applied by their own effect.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- see above\n }, [scene.version]);\n\n // Theme change: recolour the nodes.\n useEffect(() => {\n const graph = graphRef.current;\n\n if (!graph) {\n return;\n }\n\n graph.forEachNode((key, attributes) => {\n graph.setNodeAttribute(key, 'color', colors[attributes.entity] ?? '#71717a');\n });\n }, [colors]);\n\n // Selection, switched-off entities and pins.\n useEffect(() => {\n const graph = graphRef.current;\n const renderer = rendererRef.current;\n\n if (!graph || !renderer) {\n return;\n }\n\n const hidden = new Set(scene.hiddenEntities);\n let pinsChanged = false;\n graph.forEachNode((key, attributes) => {\n renderer.setNodeState(key, { isHidden: hidden.has(attributes.entity), isHighlighted: key === scene.selected });\n const fixed = scene.pinned[key] === true || heldRef.current.has(key);\n\n if ((attributes.fixed ?? false) !== fixed) {\n graph.setNodeAttribute(key, 'fixed', fixed);\n pinsChanged = true;\n }\n });\n\n // A pin change during a run restarts it with the same hold, so the\n // nodes kept still for it stay still.\n if (pinsChanged && layoutDeadlineRef.current !== null) {\n startLayout(Math.max(500, layoutDeadlineRef.current - performance.now()), [...heldRef.current]);\n }\n graph.forEachEdge((key, _attributes, source, target) => {\n renderer.setEdgeState(key, {\n isHidden:\n hidden.has(graph.getNodeAttribute(source, 'entity')) || hidden.has(graph.getNodeAttribute(target, 'entity')),\n });\n });\n }, [scene.hiddenEntities, scene.selected, scene.pinned, scene.version, mountAttempt, theme, startLayout]);\n\n // Unmount: stop the worker.\n useEffect(() => stopLayout, [stopLayout]);\n\n return <div className=\"fk:h-full fk:w-full fk:min-h-0\" ref={containerRef} />;\n}\n","'use client';\n\nimport type { JSX } from 'react';\nimport type { Attribute } from '../../core/types';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from '../../ui';\n\nexport interface GraphContextMenuState {\n key: string;\n x: number;\n y: number;\n}\n\nexport interface GraphContextMenuProps {\n menu: GraphContextMenuState | null;\n relationships: Attribute[];\n isPinned: boolean;\n onClose: () => void;\n onExpandAll: (key: string) => void;\n onExpandAttribute: (key: string, attribute: Attribute) => void;\n onHide: (key: string) => void;\n onHideOthers: (key: string) => void;\n onTogglePin: (key: string) => void;\n onOpenRecord: (key: string) => void;\n}\n\n/** The right-click menu of a node, anchored at the pointer. */\nexport function GraphContextMenu({\n menu,\n relationships,\n isPinned,\n onClose,\n onExpandAll,\n onExpandAttribute,\n onHide,\n onHideOthers,\n onTogglePin,\n onOpenRecord,\n}: GraphContextMenuProps): JSX.Element {\n const key = menu?.key ?? '';\n\n return (\n <DropdownMenu\n onOpenChange={(open) => {\n if (!open) {\n onClose();\n }\n }}\n open={menu !== null}\n >\n <DropdownMenuTrigger asChild>\n <span\n aria-hidden=\"true\"\n className=\"fk:fixed fk:size-0\"\n style={{ left: menu?.x ?? 0, top: menu?.y ?? 0 }}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"fk:w-52\" data-testid=\"graph-context-menu\" side=\"bottom\">\n <DropdownMenuItem onSelect={() => onExpandAll(key)}>Expand all</DropdownMenuItem>\n {relationships.length > 0 ? (\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>Expand</DropdownMenuSubTrigger>\n <DropdownMenuSubContent className=\"fk:max-h-80 fk:overflow-y-auto\">\n {relationships.map((attribute) => (\n <DropdownMenuItem key={attribute.name} onSelect={() => onExpandAttribute(key, attribute)}>\n {attribute.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n ) : null}\n <DropdownMenuSeparator />\n <DropdownMenuItem onSelect={() => onHide(key)}>Hide</DropdownMenuItem>\n <DropdownMenuItem onSelect={() => onHideOthers(key)}>Hide others</DropdownMenuItem>\n <DropdownMenuItem onSelect={() => onTogglePin(key)}>{isPinned ? 'Unpin position' : 'Pin position'}</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem onSelect={() => onOpenRecord(key)}>Open record</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import { MAX_NODES, type GraphCounts, type GraphData, type GraphEdge, type GraphNode } from './graph';\n\n/**\n * The scene is what the canvas draws: the nodes and edges loaded so far,\n * which entities are switched off, which nodes are pinned, the selection.\n * A pure reducer so every rule is unit-tested; the canvas syncs to it.\n */\n\nexport interface SceneState {\n nodes: { [key: string]: GraphNode };\n edges: { [key: string]: GraphEdge };\n /** Total related records per relationship of a node, when the API told us. */\n counts: GraphCounts;\n /** Related records fetched so far per relationship of a node: the next page's offset. */\n fetched: GraphCounts;\n hiddenEntities: string[];\n pinned: { [key: string]: true };\n selected: string | null;\n /** A message for the status line, such as the node cap being reached. */\n notice: string | null;\n /** Bumped whenever nodes or edges change, so the canvas knows to sync. */\n version: number;\n}\n\nexport type SceneAction =\n | { type: 'merge'; data: GraphData; fetched?: GraphCounts }\n | { type: 'remove'; keys: string[] }\n | { type: 'keepOnly'; keys: string[] }\n | { type: 'clear' }\n | { type: 'toggleEntity'; entity: string }\n | { type: 'select'; key: string | null }\n | { type: 'togglePin'; key: string }\n | { type: 'notice'; message: string | null };\n\nexport const EMPTY_SCENE: SceneState = {\n nodes: {},\n edges: {},\n counts: {},\n fetched: {},\n hiddenEntities: [],\n pinned: {},\n selected: null,\n notice: null,\n version: 0,\n};\n\nfunction mergeCounts(current: GraphCounts, incoming: GraphCounts | undefined): GraphCounts {\n if (!incoming) {\n return current;\n }\n\n const next = { ...current };\n Object.entries(incoming).forEach(([key, perAttribute]) => {\n next[key] = { ...next[key], ...perAttribute };\n });\n\n return next;\n}\n\n/** Fetched offsets only move forward: a fresh first page never rewinds paging. */\nfunction mergeFetched(current: GraphCounts, incoming: GraphCounts | undefined): GraphCounts {\n if (!incoming) {\n return current;\n }\n\n const next = { ...current };\n Object.entries(incoming).forEach(([key, perAttribute]) => {\n const merged = { ...next[key] };\n Object.entries(perAttribute).forEach(([attribute, offset]) => {\n merged[attribute] = Math.max(merged[attribute] ?? 0, offset);\n });\n next[key] = merged;\n });\n\n return next;\n}\n\nfunction withoutNodes(state: SceneState, dropped: Set<string>): SceneState {\n const nodes = Object.fromEntries(Object.entries(state.nodes).filter(([key]) => !dropped.has(key)));\n const edges = Object.fromEntries(\n Object.entries(state.edges).filter(([, edge]) => !dropped.has(edge.source) && !dropped.has(edge.target))\n );\n const pinned = Object.fromEntries(Object.entries(state.pinned).filter(([key]) => !dropped.has(key)));\n\n return {\n ...state,\n nodes,\n edges,\n pinned,\n selected: state.selected && dropped.has(state.selected) ? null : state.selected,\n version: state.version + 1,\n };\n}\n\nexport function sceneReducer(state: SceneState, action: SceneAction): SceneState {\n switch (action.type) {\n case 'merge': {\n const nodes = { ...state.nodes };\n let count = Object.keys(nodes).length;\n let dropped = 0;\n\n action.data.nodes.forEach((node) => {\n if (nodes[node.key]) {\n return;\n }\n\n if (count >= MAX_NODES) {\n dropped += 1;\n\n return;\n }\n\n nodes[node.key] = node;\n count += 1;\n });\n\n const edges = { ...state.edges };\n action.data.edges.forEach((edge) => {\n if (nodes[edge.source] && nodes[edge.target]) {\n edges[edge.key] = edge;\n }\n });\n\n return {\n ...state,\n nodes,\n edges,\n counts: mergeCounts(state.counts, action.data.counts),\n fetched: mergeFetched(state.fetched, action.fetched),\n notice:\n dropped > 0\n ? `The canvas holds ${MAX_NODES.toLocaleString()} nodes at most; ${dropped.toLocaleString()} were left out. Hide some nodes to make room.`\n : state.notice,\n version: state.version + 1,\n };\n }\n case 'remove':\n return withoutNodes(state, new Set(action.keys));\n case 'keepOnly': {\n const kept = new Set(action.keys);\n\n return withoutNodes(state, new Set(Object.keys(state.nodes).filter((key) => !kept.has(key))));\n }\n case 'clear':\n return { ...EMPTY_SCENE, hiddenEntities: state.hiddenEntities, version: state.version + 1 };\n case 'toggleEntity':\n return {\n ...state,\n hiddenEntities: state.hiddenEntities.includes(action.entity)\n ? state.hiddenEntities.filter((entity) => entity !== action.entity)\n : [...state.hiddenEntities, action.entity],\n };\n case 'select':\n return state.selected === action.key ? state : { ...state, selected: action.key };\n case 'togglePin': {\n const pinned = { ...state.pinned };\n\n if (pinned[action.key]) {\n delete pinned[action.key];\n } else {\n pinned[action.key] = true;\n }\n\n return { ...state, pinned };\n }\n case 'notice':\n return { ...state, notice: action.message };\n default:\n return state;\n }\n}\n\n/** Nodes on the canvas per entity, for the legend. */\nexport function countNodesByEntity(state: SceneState): { [entity: string]: number } {\n return Object.values(state.nodes).reduce<{ [entity: string]: number }>((result, node) => {\n result[node.entity] = (result[node.entity] ?? 0) + 1;\n\n return result;\n }, {});\n}\n\n/** Related nodes of one node per relationship attribute that are on the canvas. */\nexport function countEdgesByAttribute(state: SceneState, key: string): { [attribute: string]: number } {\n return Object.values(state.edges).reduce<{ [attribute: string]: number }>((result, edge) => {\n if (edge.source === key) {\n result[edge.sourceAttribute] = (result[edge.sourceAttribute] ?? 0) + 1;\n } else if (edge.target === key) {\n result[edge.targetAttribute] = (result[edge.targetAttribute] ?? 0) + 1;\n }\n\n return result;\n }, {});\n}\n\n/** Keys of the nodes joined to one node by an edge. */\nexport function neighbourKeys(state: SceneState, key: string): string[] {\n return Object.values(state.edges).flatMap((edge) => {\n if (edge.source === key) {\n return [edge.target];\n }\n\n if (edge.target === key) {\n return [edge.source];\n }\n\n return [];\n });\n}\n","'use client';\n\nimport { useMemo } from 'react';\nimport type { JSX } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { formatDistance } from 'date-fns';\nimport { EyeOffIcon, ExpandIcon, LoaderCircleIcon, SquareArrowOutUpRightIcon, XIcon } from 'lucide-react';\nimport type { Attribute, Entity } from '../../core/types';\nimport { Button, Tooltip, TooltipContent, TooltipTrigger } from '../../ui';\nimport {\n buildCountsQuery,\n buildDetailsQuery,\n formatDetailValue,\n getDetailAttributes,\n getEntity,\n getEntityLabel,\n getRelationshipAttributes,\n type GraphNode,\n type GraphRecord,\n} from './graph';\nimport { countEdgesByAttribute, type SceneState } from './scene';\n\nexport interface GraphInspectorProps {\n node: GraphNode;\n schema: Entity[];\n scope: string;\n scene: SceneState;\n colors: { [entity: string]: string };\n isLoading: boolean;\n onClose: () => void;\n onOpenRecord: (key: string) => void;\n onExpandAll: (key: string) => void;\n onExpandAttribute: (key: string, attribute: Attribute) => void;\n onHide: (key: string) => void;\n}\n\ntype ConnectionCount = { aggregate?: { count?: { nodes?: number } } };\n\n/**\n * Black or white, whichever reads better on a palette color (`#rrggbb`): the\n * yellows and greens are too light for white text.\n */\nfunction getTextColorOn(hex: string): string {\n const [r, g, b] = [1, 3, 5].map((offset) => {\n const channel = parseInt(hex.slice(offset, offset + 2), 16) / 255;\n\n return channel <= 0.03928 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;\n });\n const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;\n\n return luminance > 0.3 ? '#0a0a0a' : '#ffffff';\n}\ntype DetailsResult = { [plural: string]: (GraphRecord & { _updatedAt?: string })[] };\n\n/**\n * The selected node: its scalar attributes in the current scope and each\n * relationship with how many related records are on the canvas out of the\n * total, with a button to fetch the next page.\n */\nexport function GraphInspector({\n node,\n schema,\n scope,\n scene,\n colors,\n isLoading,\n onClose,\n onOpenRecord,\n onExpandAll,\n onExpandAttribute,\n onHide,\n}: GraphInspectorProps): JSX.Element {\n const entity = getEntity(schema, node.entity);\n const detailsDocument = useMemo(\n () => gql(entity ? buildDetailsQuery({ entity, scope }) : 'query GraphDetails { __typename }'),\n [entity, scope]\n );\n const countsDocument = useMemo(\n () => gql(entity ? buildCountsQuery({ entity }) : 'query GraphCounts { __typename }'),\n [entity]\n );\n const details = useQuery<DetailsResult>(detailsDocument, { variables: { id: node.id }, skip: !entity });\n const counts = useQuery<{ [plural: string]: { [field: string]: ConnectionCount }[] }>(countsDocument, {\n variables: { id: node.id },\n skip: !entity,\n });\n const record = entity ? details.data?.[entity.plural]?.[0] : undefined;\n const countRecord = entity ? counts.data?.[entity.plural]?.[0] : undefined;\n const onCanvas = useMemo(() => countEdgesByAttribute(scene, node.key), [scene, node.key]);\n const relationships = entity ? getRelationshipAttributes(entity) : [];\n const attributes = entity ? getDetailAttributes(entity) : [];\n const updatedAt = record?._updatedAt ? new Date(record._updatedAt) : null;\n const color = colors[node.entity] ?? '#71717a';\n\n return (\n <aside\n aria-label=\"Selected record\"\n className=\"fk:flex fk:w-72 fk:shrink-0 fk:flex-col fk:gap-5 fk:overflow-y-auto fk:border-l fk:bg-background fk:p-4 fk:text-sm\"\n data-testid=\"graph-inspector\"\n >\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <div className=\"fk:flex fk:items-center fk:justify-between fk:gap-2\">\n <span\n className=\"fk:inline-flex fk:items-center fk:rounded-full fk:px-2 fk:py-0.5 fk:text-xs fk:font-medium\"\n style={{ backgroundColor: color, color: getTextColorOn(color) }}\n >\n {entity ? getEntityLabel(entity) : node.entity}\n </span>\n <Button aria-label=\"Close\" className=\"fk:size-7\" onClick={onClose} size=\"icon\" variant=\"ghost\">\n <XIcon className=\"fk:size-4\" />\n </Button>\n </div>\n <h2 className=\"fk:text-base fk:font-semibold fk:leading-snug fk:break-words\">{node.label}</h2>\n <div className=\"fk:flex fk:gap-1.5\">\n <Button onClick={() => onOpenRecord(node.key)} size=\"xs\">\n <SquareArrowOutUpRightIcon />\n Open record\n </Button>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n aria-label=\"Expand every relationship\"\n disabled={isLoading}\n onClick={() => onExpandAll(node.key)}\n size=\"xs\"\n variant=\"outline\"\n >\n {isLoading ? <LoaderCircleIcon className=\"fk:animate-spin\" /> : <ExpandIcon />}\n Expand\n </Button>\n </TooltipTrigger>\n <TooltipContent>Load the first related records of every relationship</TooltipContent>\n </Tooltip>\n <Button aria-label=\"Hide this node\" onClick={() => onHide(node.key)} size=\"xs\" variant=\"outline\">\n <EyeOffIcon />\n Hide\n </Button>\n </div>\n </div>\n\n <section className=\"fk:flex fk:flex-col fk:gap-2\">\n <h3 className=\"fk:text-xs fk:font-medium fk:text-muted-foreground\">Attributes</h3>\n {details.loading && !record ? (\n <span className=\"fk:text-muted-foreground\">Loading…</span>\n ) : (\n <dl className=\"fk:grid fk:grid-cols-[minmax(0,2fr)_minmax(0,3fr)] fk:gap-x-3 fk:gap-y-1.5\">\n {attributes.map((attribute) => (\n <div className=\"fk:contents\" key={attribute.name}>\n <dt className=\"fk:truncate fk:text-muted-foreground\" title={attribute.label}>\n {attribute.label}\n </dt>\n <dd className=\"fk:min-w-0 fk:break-words\">{record ? formatDetailValue(record[attribute.name], scope) || '—' : '—'}</dd>\n </div>\n ))}\n {updatedAt ? (\n <div className=\"fk:contents\">\n <dt className=\"fk:text-muted-foreground\">Updated</dt>\n <dd>{formatDistance(updatedAt, new Date(), { addSuffix: true })}</dd>\n </div>\n ) : null}\n </dl>\n )}\n </section>\n\n {relationships.length > 0 ? (\n <section className=\"fk:flex fk:flex-col fk:gap-1\">\n <h3 className=\"fk:mb-1 fk:text-xs fk:font-medium fk:text-muted-foreground\">Relationships</h3>\n {relationships.map((attribute) => {\n const relatedEntity = getEntity(schema, attribute.relationship?.entity ?? '');\n const total = countRecord?.[`${attribute.name}Connection`]?.aggregate?.count?.nodes;\n const shown = onCanvas[attribute.name] ?? 0;\n const fetched = scene.fetched[node.key]?.[attribute.name] ?? 0;\n const exhausted = typeof total === 'number' && fetched >= total;\n\n return (\n <div className=\"fk:flex fk:h-8 fk:items-center fk:gap-2\" key={attribute.name}>\n <span\n aria-hidden=\"true\"\n className=\"fk:size-2 fk:shrink-0 fk:rounded-full\"\n style={{ backgroundColor: colors[attribute.relationship?.entity ?? ''] ?? '#71717a' }}\n />\n <span className=\"fk:min-w-0 fk:flex-1 fk:truncate\" title={relatedEntity ? getEntityLabel(relatedEntity) : undefined}>\n {attribute.label}\n </span>\n <span className=\"fk:text-xs fk:text-muted-foreground\">\n {typeof total === 'number' ? `${shown} of ${total.toLocaleString()}` : shown}\n </span>\n {total === 0 || exhausted ? null : (\n <Button\n className=\"fk:h-6 fk:px-2 fk:text-xs\"\n disabled={isLoading}\n onClick={() => onExpandAttribute(node.key, attribute)}\n size=\"xs\"\n variant=\"outline\"\n >\n {fetched > 0 ? 'More' : 'Expand'}\n </Button>\n )}\n </div>\n );\n })}\n </section>\n ) : null}\n </aside>\n );\n}\n","'use client';\n\nimport { useMemo, useState } from 'react';\nimport type { JSX } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { SearchIcon } from 'lucide-react';\nimport { useDebounce } from 'use-debounce';\nimport { getDisplayAttribute } from '../../core/get-display-attribute';\nimport { useSearch } from '../../core/use-search';\nimport type { Entity, SearchRequestProps } from '../../core/types';\nimport {\n Checkbox,\n Input,\n SidebarContent,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarPanel,\n SidebarRail,\n} from '../../ui';\nimport { buildTotalsQuery, getEntityLabel, getTotalEntities } from './graph';\n\nconst SEARCH_DEBOUNCE_MS = 250;\nconst SEARCH_HITS_PER_ENTITY = 5;\n\nexport interface GraphSidebarProps {\n projectId: string;\n entities: Entity[];\n colors: { [entity: string]: string };\n /** Nodes on the canvas per entity. */\n onCanvas: { [entity: string]: number };\n hiddenEntities: string[];\n onStart: (entity: Entity) => void;\n onHit: (entityName: string, id: string) => void;\n onToggleEntity: (entityName: string) => void;\n}\n\nfunction buildSearchRequest(entities: Entity[], q: string): SearchRequestProps | null {\n const trimmed = q.trim();\n\n if (!trimmed || entities.length === 0) {\n return null;\n }\n\n return {\n searchRequests: { searches: entities.map((entity) => ({ collection: entity.plural })) },\n commonParams: { q: trimmed, limit: SEARCH_HITS_PER_ENTITY },\n };\n}\n\n/** Count-store totals per entity for the \"Nodes\" list; absent for space-bound entities. */\nfunction useTotals(entities: Entity[]): { [plural: string]: number } {\n const countable = useMemo(() => getTotalEntities(entities), [entities]);\n const document = useMemo(() => gql(countable.length > 0 ? buildTotalsQuery(countable) : 'query GraphTotals { __typename }'), [countable]);\n const { data } = useQuery<{ [field: string]: number }>(document, { skip: countable.length === 0 });\n\n return useMemo(\n () =>\n Object.fromEntries(\n countable\n .map((entity) => [entity.plural, data?.[`${entity.plural}Total`]] as const)\n .filter((pair): pair is readonly [string, number] => typeof pair[1] === 'number')\n ),\n [countable, data]\n );\n}\n\n/**\n * Search a record to add it to the canvas, start from a whole entity, and the\n * legend of what is on the canvas with a switch per entity.\n */\nexport function GraphSidebar({\n projectId,\n entities,\n colors,\n onCanvas,\n hiddenEntities,\n onStart,\n onHit,\n onToggleEntity,\n}: GraphSidebarProps): JSX.Element {\n const [query, setQuery] = useState('');\n const [debouncedQuery] = useDebounce(query, SEARCH_DEBOUNCE_MS);\n const searchable = useMemo(\n () => entities.filter((entity) => entity.attributes.some((attribute) => attribute.searchable)),\n [entities]\n );\n const request = useMemo(() => buildSearchRequest(searchable, debouncedQuery), [searchable, debouncedQuery]);\n const { results, isLoading } = useSearch(projectId, request);\n const totals = useTotals(entities);\n const entityByName = useMemo(() => new Map(entities.map((entity) => [entity.name, entity])), [entities]);\n const onCanvasEntities = Object.keys(onCanvas).sort();\n\n return (\n <SidebarPanel collapsible=\"icon\" variant=\"inset\">\n <SidebarContent>\n <SidebarGroup className=\"fk:group-data-[collapsible=icon]:hidden\">\n <div className=\"fk:relative\">\n <SearchIcon className=\"fk:pointer-events-none fk:absolute fk:left-2 fk:top-1/2 fk:size-4 fk:-translate-y-1/2 fk:text-muted-foreground\" />\n <Input\n aria-label=\"Search records to add to the canvas\"\n className=\"fk:h-8 fk:bg-background fk:pl-8 fk:shadow-none\"\n onChange={(event) => setQuery(event.target.value)}\n placeholder={searchable.length > 0 ? 'Search records…' : 'No searchable entity'}\n disabled={searchable.length === 0}\n value={query}\n />\n </div>\n {request ? (\n <ul className=\"fk:mt-2 fk:flex fk:flex-col fk:gap-0.5\" data-testid=\"graph-search-results\">\n {results.map((hit) => {\n const entity = entityByName.get(hit._entityName);\n const label = hit[getDisplayAttribute(entity)?.name ?? ''];\n\n return (\n <li key={`${hit._entityName}:${hit._id}`}>\n <button\n className=\"fk:flex fk:w-full fk:items-center fk:gap-2 fk:rounded-md fk:px-2 fk:py-1.5 fk:text-left fk:text-sm fk:hover:bg-sidebar-accent\"\n onClick={() => onHit(hit._entityName, hit._id)}\n type=\"button\"\n >\n <span\n aria-hidden=\"true\"\n className=\"fk:size-2.5 fk:shrink-0 fk:rounded-full\"\n style={{ backgroundColor: colors[hit._entityName] ?? '#71717a' }}\n />\n <span className=\"fk:min-w-0 fk:flex-1 fk:truncate\">{String(label ?? hit._id)}</span>\n </button>\n </li>\n );\n })}\n {!isLoading && results.length === 0 ? (\n <li className=\"fk:px-2 fk:py-1.5 fk:text-sm fk:text-muted-foreground\">Nothing found</li>\n ) : null}\n </ul>\n ) : null}\n </SidebarGroup>\n\n <SidebarGroup>\n <SidebarGroupLabel>Nodes</SidebarGroupLabel>\n <SidebarMenu>\n {entities.map((entity) => (\n <SidebarMenuItem key={entity.name}>\n <SidebarMenuButton onClick={() => onStart(entity)} tooltip={getEntityLabel(entity)}>\n <span\n aria-hidden=\"true\"\n className=\"fk:size-2.5 fk:shrink-0 fk:rounded-full\"\n style={{ backgroundColor: colors[entity.name] ?? '#71717a' }}\n />\n <span className=\"fk:truncate\">{getEntityLabel(entity)}</span>\n {totals[entity.plural] !== undefined ? (\n <span className=\"fk:ml-auto fk:text-xs fk:text-muted-foreground\">\n {totals[entity.plural]?.toLocaleString()}\n </span>\n ) : null}\n </SidebarMenuButton>\n </SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroup>\n\n {onCanvasEntities.length > 0 ? (\n <SidebarGroup className=\"fk:group-data-[collapsible=icon]:hidden\">\n <SidebarGroupLabel>On canvas</SidebarGroupLabel>\n <ul className=\"fk:flex fk:flex-col\" data-testid=\"graph-legend\">\n {onCanvasEntities.map((name) => {\n const entity = entityByName.get(name);\n const checked = !hiddenEntities.includes(name);\n const id = `graph-legend-${name}`;\n\n return (\n <li className=\"fk:flex fk:h-8 fk:items-center fk:gap-2 fk:px-2 fk:text-sm\" key={name}>\n <span\n aria-hidden=\"true\"\n className=\"fk:size-2.5 fk:shrink-0 fk:rounded-full\"\n style={{ backgroundColor: colors[name] ?? '#71717a', opacity: checked ? 1 : 0.35 }}\n />\n <label className=\"fk:min-w-0 fk:flex-1 fk:cursor-pointer fk:truncate\" htmlFor={id}>\n {entity ? getEntityLabel(entity) : name}\n </label>\n <span className=\"fk:text-xs fk:text-muted-foreground\">{onCanvas[name]?.toLocaleString()}</span>\n <Checkbox\n aria-label={`Show ${entity ? getEntityLabel(entity) : name}`}\n checked={checked}\n id={id}\n onCheckedChange={() => onToggleEntity(name)}\n />\n </li>\n );\n })}\n </ul>\n </SidebarGroup>\n ) : null}\n </SidebarContent>\n <SidebarRail />\n </SidebarPanel>\n );\n}\n","'use client';\n\nimport type { JSX } from 'react';\nimport { EraserIcon, ExpandIcon, EyeOffIcon, LoaderCircleIcon, ScanIcon } from 'lucide-react';\nimport { Button, Separator, Tooltip, TooltipContent, TooltipTrigger } from '../../ui';\n\nexport interface GraphToolbarProps {\n hasSelection: boolean;\n hasNodes: boolean;\n isLoading: boolean;\n onFit: () => void;\n onExpand: () => void;\n onHide: () => void;\n onClear: () => void;\n}\n\nfunction ToolbarButton({\n label,\n icon,\n disabled,\n onClick,\n}: {\n label: string;\n icon: JSX.Element;\n disabled?: boolean;\n onClick: () => void;\n}): JSX.Element {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button className=\"fk:h-8 fk:gap-1.5 fk:px-2.5\" disabled={disabled} onClick={onClick} size=\"sm\" variant=\"ghost\">\n {icon}\n <span className=\"fk:text-xs\">{label}</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent>{label}</TooltipContent>\n </Tooltip>\n );\n}\n\n/** The floating actions over the canvas. */\nexport function GraphToolbar({\n hasSelection,\n hasNodes,\n isLoading,\n onFit,\n onExpand,\n onHide,\n onClear,\n}: GraphToolbarProps): JSX.Element {\n return (\n <div\n className=\"fk:flex fk:items-center fk:gap-0.5 fk:rounded-lg fk:border fk:bg-background fk:p-1 fk:shadow-xs\"\n data-testid=\"graph-toolbar\"\n >\n <ToolbarButton disabled={!hasNodes} icon={<ScanIcon className=\"fk:size-3.5\" />} label=\"Fit\" onClick={onFit} />\n <Separator className=\"fk:mx-0.5 fk:h-4\" orientation=\"vertical\" />\n <ToolbarButton\n disabled={!hasSelection || isLoading}\n icon={isLoading ? <LoaderCircleIcon className=\"fk:size-3.5 fk:animate-spin\" /> : <ExpandIcon className=\"fk:size-3.5\" />}\n label=\"Expand\"\n onClick={onExpand}\n />\n <ToolbarButton disabled={!hasSelection} icon={<EyeOffIcon className=\"fk:size-3.5\" />} label=\"Hide\" onClick={onHide} />\n <Separator className=\"fk:mx-0.5 fk:h-4\" orientation=\"vertical\" />\n <ToolbarButton disabled={!hasNodes} icon={<EraserIcon className=\"fk:size-3.5\" />} label=\"Clear\" onClick={onClear} />\n </div>\n );\n}\n","'use client';\n\nimport { useCallback, useReducer, useState } from 'react';\nimport type { Dispatch } from 'react';\nimport { gql } from '@apollo/client';\nimport { useApolloClient } from '@apollo/client/react';\nimport { toast } from '../../ui';\nimport type { Attribute, Entity } from '../../core/types';\nimport {\n buildExpandQuery,\n buildRecordsQuery,\n EXPAND_PAGE,\n fetchedFromRecords,\n getEntity,\n graphFromRecords,\n nodeKey,\n type GraphRecord,\n} from './graph';\nimport { EMPTY_SCENE, sceneReducer, type SceneAction, type SceneState } from './scene';\n\n/** Which records to load: given ids (with their first hop when `expand`), or a sample. */\nexport type RecordSelection = { ids: string[]; expand: boolean } | { limit: number };\n\nexport interface SceneApi {\n state: SceneState;\n dispatch: Dispatch<SceneAction>;\n isLoading: boolean;\n /** Loads records, with the first page of each relationship when asked; resolves to their node keys. */\n loadRecords: (entity: Entity, selection: RecordSelection) => Promise<string[]>;\n /** Loads the first page of every relationship of a node. */\n expandAll: (key: string) => Promise<void>;\n /** Loads the next page of one relationship of a node. */\n expandAttribute: (key: string, attribute: Attribute) => Promise<void>;\n}\n\ntype RecordsResult = { [plural: string]: GraphRecord[] };\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : 'The records could not be loaded.';\n}\n\n/**\n * The scene plus the loaders that grow it through the project GraphQL API,\n * so the roles and spaces of the signed-in member apply to every node.\n */\nexport function useScene({ schema, scope }: { schema: Entity[]; scope: string }): SceneApi {\n const client = useApolloClient();\n const [state, dispatch] = useReducer(sceneReducer, EMPTY_SCENE);\n const [pending, setPending] = useState(0);\n\n const loadRecords = useCallback(\n async (entity: Entity, selection: RecordSelection): Promise<string[]> => {\n const ids = 'ids' in selection ? selection.ids : undefined;\n const expand = 'ids' in selection ? selection.expand : false;\n const limit = 'limit' in selection ? selection.limit : ids?.length;\n setPending((count) => count + 1);\n\n try {\n const result = await client.query<RecordsResult>({\n query: gql(buildRecordsQuery({ entity, schema, scope, expand })),\n variables: {\n where: ids ? { _id: { in: ids } } : undefined,\n limit,\n },\n fetchPolicy: 'network-only',\n });\n const records = result.data?.[entity.plural] ?? [];\n dispatch({\n type: 'merge',\n data: graphFromRecords({ records, entity, schema, scope }),\n fetched: fetchedFromRecords(records, entity),\n });\n\n return records.map((record) => nodeKey(entity.name, record._id));\n } catch (error) {\n toast.error(errorMessage(error));\n\n return [];\n } finally {\n setPending((count) => count - 1);\n }\n },\n [client, schema, scope]\n );\n\n const expandAll = useCallback(\n async (key: string): Promise<void> => {\n const node = state.nodes[key];\n const entity = node ? getEntity(schema, node.entity) : undefined;\n\n if (!node || !entity) {\n return;\n }\n\n await loadRecords(entity, { ids: [node.id], expand: true });\n },\n [loadRecords, schema, state.nodes]\n );\n\n const expandAttribute = useCallback(\n async (key: string, attribute: Attribute): Promise<void> => {\n const node = state.nodes[key];\n const entity = node ? getEntity(schema, node.entity) : undefined;\n\n if (!node || !entity) {\n return;\n }\n\n const offset = state.fetched[key]?.[attribute.name] ?? 0;\n setPending((count) => count + 1);\n\n try {\n const result = await client.query<RecordsResult>({\n query: gql(buildExpandQuery({ entity, schema, scope, attribute })),\n variables: { id: node.id, offset, limit: EXPAND_PAGE },\n fetchPolicy: 'network-only',\n });\n const records = result.data?.[entity.plural] ?? [];\n const received = records.reduce((sum, record) => {\n const related = record[attribute.name];\n\n return sum + (Array.isArray(related) ? related.length : 0);\n }, 0);\n dispatch({\n type: 'merge',\n data: graphFromRecords({ records, entity, schema, scope }),\n fetched: { [key]: { [attribute.name]: offset + received } },\n });\n } catch (error) {\n toast.error(errorMessage(error));\n } finally {\n setPending((count) => count - 1);\n }\n },\n [client, schema, scope, state.fetched, state.nodes]\n );\n\n return { state, dispatch, isLoading: pending > 0, loadRecords, expandAll, expandAttribute };\n}\n","'use client';\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { JSX } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { useAuth } from '../../auth/auth-context';\nimport { useAppContext } from '../../core/app-context';\nimport { useConfig } from '../../core/config/config-context';\nimport { filterEntitiesForSpaces } from '../../core/spaces';\nimport type { Attribute } from '../../core/types';\nimport { useDispatch } from '../../entities/actions-context';\nimport {\n readSidebarCookieState,\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '../../ui';\nimport { useTheme } from '../../ui/theme-context';\nimport { GraphCanvas, type GraphCanvasApi } from './canvas';\nimport { GraphContextMenu, type GraphContextMenuState } from './context-menu';\nimport {\n EXPAND_HOP_MAX_RECORDS,\n getEntity,\n getEntityColors,\n getGraphEntities,\n getRelationshipAttributes,\n parseGraphParams,\n SAMPLE_LIMIT,\n} from './graph';\nimport { GraphInspector } from './inspector';\nimport { countNodesByEntity, neighbourKeys } from './scene';\nimport { GraphSidebar } from './sidebar';\nimport { GraphToolbar } from './toolbar';\nimport { useScene } from './use-scene';\n\n/**\n * The Graph app: explore records as nodes and relationships. The sidebar\n * adds records, the canvas draws them, the inspector details the selection.\n * Other apps open it with `?entity=<name>&ids=<id,id>` to show those records\n * expanded one hop.\n */\nexport function Root(): JSX.Element {\n const { currentProjectId, currentProject, currentProjectSchema } = useConfig();\n const [, auth] = useAuth();\n const { scope } = useAppContext();\n const { resolvedTheme } = useTheme();\n const location = useLocation();\n const dispatchAction = useDispatch();\n const theme = resolvedTheme === 'dark' ? 'dark' : 'light';\n const defaultScope = currentProject?.scopes?.find((item) => item.isDefault)?.name ?? 'default';\n const scopeField = scope || defaultScope;\n // Space-bound entities are hidden from non-members, as in Desk; the API\n // rejects their data either way.\n const userSpaces = auth.user?.spaces;\n const schema = useMemo(() => filterEntitiesForSpaces(currentProjectSchema, userSpaces), [currentProjectSchema, userSpaces]);\n const entities = useMemo(() => getGraphEntities(schema), [schema]);\n const colors = useMemo(() => getEntityColors(schema, theme), [schema, theme]);\n const scene = useScene({ schema, scope: scopeField });\n const { state, dispatch, isLoading, loadRecords, expandAll, expandAttribute } = scene;\n const canvasApi = useRef<GraphCanvasApi | null>(null);\n const [menu, setMenu] = useState<GraphContextMenuState | null>(null);\n const [isLayoutRunning, setIsLayoutRunning] = useState(false);\n const loadedSearchRef = useRef<string | null>(null);\n const onCanvas = useMemo(() => countNodesByEntity(state), [state]);\n const selectedNode = state.selected ? state.nodes[state.selected] : undefined;\n const menuNode = menu ? state.nodes[menu.key] : undefined;\n const menuEntity = menuNode ? getEntity(schema, menuNode.entity) : undefined;\n const nodeCount = Object.keys(state.nodes).length;\n const edgeCount = Object.keys(state.edges).length;\n const defaultOpen = readSidebarCookieState();\n\n const select = useCallback((key: string | null) => dispatch({ type: 'select', key }), [dispatch]);\n\n const openRecord = useCallback(\n (key: string) => {\n const node = state.nodes[key];\n const entity = node ? getEntity(schema, node.entity) : undefined;\n\n if (node && entity) {\n dispatchAction({ type: 'EditEntity', payload: { entityId: node.id, entityNamePlural: entity.plural } });\n }\n },\n [dispatchAction, schema, state.nodes]\n );\n\n const hide = useCallback((key: string) => dispatch({ type: 'remove', keys: [key] }), [dispatch]);\n\n const hideOthers = useCallback(\n (key: string) => dispatch({ type: 'keepOnly', keys: [key, ...neighbourKeys(state, key)] }),\n [dispatch, state]\n );\n\n const togglePin = useCallback((key: string) => dispatch({ type: 'togglePin', key }), [dispatch]);\n\n const pin = useCallback(\n (key: string) => {\n if (!state.pinned[key]) {\n dispatch({ type: 'togglePin', key });\n }\n },\n [dispatch, state.pinned]\n );\n\n const addRecord = useCallback(\n async (entityName: string, id: string) => {\n const entity = getEntity(schema, entityName);\n\n if (!entity) {\n return;\n }\n\n const [key] = await loadRecords(entity, { ids: [id], expand: true });\n\n if (key) {\n select(key);\n }\n },\n [loadRecords, schema, select]\n );\n\n const expandAttributeAndClose = useCallback(\n (key: string, attribute: Attribute) => {\n setMenu(null);\n void expandAttribute(key, attribute);\n },\n [expandAttribute]\n );\n\n // Records another app asked for: `?entity=product&ids=a,b` loads those\n // records, expanded one hop when they are few, `?entity=product` a sample.\n useEffect(() => {\n const params = parseGraphParams(location.search);\n\n // Keyed on the navigation, not the query string: opening the same\n // records again after a Clear must load them again.\n if (!params || loadedSearchRef.current === location.key) {\n return;\n }\n\n const entity = getEntity(schema, params.entity);\n\n if (!entity || schema.length === 0) {\n return;\n }\n\n loadedSearchRef.current = location.key;\n const selection =\n params.ids.length > 0\n ? { ids: params.ids, expand: params.ids.length <= EXPAND_HOP_MAX_RECORDS }\n : { limit: SAMPLE_LIMIT };\n void loadRecords(entity, selection).then((keys) => {\n if (params.ids.length === 1 && keys[0]) {\n select(keys[0]);\n }\n });\n }, [location.key, location.search, schema, loadRecords, select]);\n\n if (!currentProjectId) {\n return (\n <main className=\"fk:flex fk:h-full fk:flex-1 fk:items-center fk:justify-center fk:p-8 fk:text-sm fk:text-muted-foreground\">\n Select a project to explore its graph.\n </main>\n );\n }\n\n return (\n <SidebarProvider className=\"fk:h-full\" defaultOpen={defaultOpen}>\n <GraphSidebar\n colors={colors}\n entities={entities}\n hiddenEntities={state.hiddenEntities}\n onCanvas={onCanvas}\n onHit={(entityName, id) => void addRecord(entityName, id)}\n onStart={(entity) => void loadRecords(entity, { limit: SAMPLE_LIMIT })}\n onToggleEntity={(entityName) => dispatch({ type: 'toggleEntity', entity: entityName })}\n projectId={currentProjectId}\n />\n <SidebarInset className=\"fk:min-w-0\">\n <div className=\"fk:flex fk:h-full fk:min-h-0 fk:min-w-0\" data-testid=\"graph-app\">\n <div className=\"fk:relative fk:min-w-0 fk:flex-1 fk:overflow-hidden fk:bg-background\">\n <div className=\"fk:absolute fk:left-3 fk:top-3 fk:z-10 fk:flex fk:items-center fk:gap-2\">\n <Tooltip>\n <TooltipTrigger asChild>\n <SidebarTrigger className=\"fk:h-8 fk:w-8 fk:rounded-lg fk:hover:bg-transparent fk:dark:hover:bg-transparent\" />\n </TooltipTrigger>\n <TooltipContent>Toggle Sidebar</TooltipContent>\n </Tooltip>\n <GraphToolbar\n hasNodes={nodeCount > 0}\n hasSelection={selectedNode !== undefined}\n isLoading={isLoading}\n onClear={() => dispatch({ type: 'clear' })}\n onExpand={() => {\n if (state.selected) {\n void expandAll(state.selected);\n }\n }}\n onFit={() => canvasApi.current?.fit()}\n onHide={() => {\n if (state.selected) {\n hide(state.selected);\n }\n }}\n />\n </div>\n {nodeCount > 0 ? null : (\n <div className=\"fk:pointer-events-none fk:absolute fk:inset-0 fk:flex fk:items-center fk:justify-center fk:p-8 fk:text-center fk:text-sm fk:text-muted-foreground\">\n {isLoading ? 'Loading records…' : 'Search a record or start from an entity to draw its graph.'}\n </div>\n )}\n <GraphCanvas\n apiRef={canvasApi}\n colors={colors}\n onContextMenu={(key, position) => setMenu({ key, ...position })}\n onExpand={(key) => void expandAll(key)}\n onLayoutChange={setIsLayoutRunning}\n onPin={pin}\n onSelect={select}\n scene={state}\n theme={theme}\n />\n <div\n className=\"fk:absolute fk:bottom-3 fk:left-3 fk:flex fk:max-w-[calc(100%-1.5rem)] fk:items-center fk:gap-2 fk:rounded-lg fk:border fk:bg-background fk:px-2.5 fk:py-1.5 fk:text-xs fk:text-muted-foreground fk:shadow-xs\"\n data-testid=\"graph-status\"\n >\n <span>\n {nodeCount.toLocaleString()} {nodeCount === 1 ? 'node' : 'nodes'} · {edgeCount.toLocaleString()}{' '}\n {edgeCount === 1 ? 'relationship' : 'relationships'}\n </span>\n {isLayoutRunning ? <span>· laying out…</span> : null}\n {state.notice ? <span className=\"fk:truncate fk:text-foreground\">· {state.notice}</span> : null}\n </div>\n <GraphContextMenu\n isPinned={menu ? state.pinned[menu.key] === true : false}\n menu={menu}\n onClose={() => setMenu(null)}\n onExpandAll={(key) => void expandAll(key)}\n onExpandAttribute={expandAttributeAndClose}\n onHide={hide}\n onHideOthers={hideOthers}\n onOpenRecord={openRecord}\n onTogglePin={togglePin}\n relationships={menuEntity ? getRelationshipAttributes(menuEntity) : []}\n />\n </div>\n {selectedNode ? (\n <GraphInspector\n colors={colors}\n isLoading={isLoading}\n node={selectedNode}\n onClose={() => select(null)}\n onExpandAll={(key) => void expandAll(key)}\n onExpandAttribute={(key, attribute) => void expandAttribute(key, attribute)}\n onHide={hide}\n onOpenRecord={openRecord}\n scene={state}\n schema={schema}\n scope={scopeField}\n />\n ) : null}\n </div>\n </SidebarInset>\n </SidebarProvider>\n );\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import'./index.css';import {a}from'./chunk-
|
|
2
|
-
//# sourceMappingURL=search-
|
|
1
|
+
import'./index.css';import {a}from'./chunk-RY6PECIT.js';import'./chunk-XMOSCJOI.js';import'./chunk-ERDARDGB.js';import'./chunk-B7QMGBK5.js';import'./chunk-2HYQVMP3.js';import'./chunk-5CVDMZUI.js';import {z,m,w,q,p,r,t,b as b$1}from'./chunk-32ZU4MLE.js';import'./chunk-U45E5X3H.js';import {a as a$1,d,c,e,g}from'./chunk-HDOIOXMP.js';import {b}from'./chunk-6NRQMG26.js';import {a as a$2}from'./chunk-O2QMYUPS.js';import {useState,useMemo,useRef}from'react';import {useDebounce}from'use-debounce';import {LoaderCircle,Search,X}from'lucide-react';import {Command}from'cmdk';import {useNavigate}from'react-router-dom';import {jsxs,jsx}from'react/jsx-runtime';var s="all",ne=200,oe=2,ae=8,le=25;function se(t){let n=t.replace(/([A-Z])/g," $1");return n.charAt(0).toUpperCase()+n.slice(1).trim()}function ie(t){return t.filter(n=>n.attributes.some(o=>o.searchable))}function fe(t,n){return n===s?t.map(o=>o.plural):t.filter(o=>o.plural===n).map(o=>o.plural)}function ce(t,n){return n===s?s:t.some(o=>o.plural===n)?n:s}function ue(t,n){let o=n.trim();return o.length<oe?null:{searchRequests:{searches:t.map(m=>({collection:m}))},commonParams:{q:o,limit:t.length>1?ae:le}}}function me(t){return t.menu?.label??se(t.plural)}function Ee({onSelect:t$1,searchPlaceholder:n="Search...",noResultsMsg:o="Nothing found",className:m$1,onSearchChange:S,projectId:G,schema:C}){let[V,l]=useState(false),[i,N]=useState(""),[U,X$1]=useState(s),f=useMemo(()=>ie(C),[C]),k=ce(f,U),I=useMemo(()=>fe(f,k),[f,k]),[d$1]=useDebounce(i,ne),w$1=useMemo(()=>ue(I,d$1),[I,d$1]),c$1=useRef(null),{results:p$1,isLoading:j}=a(G,w$1),h=j||d$1!==i,z$1=V&&w$1!==null&&(p$1.length>0||!h),H=useNavigate();function F(e){N(e),e.length>0&&l(true),e.length===0&&l(false),S&&S(e);}function J(e){X$1(e),i.length>0&&l(true);}function Q(){N(""),l(false),c$1.current&&(c$1.current.value="");let e=new URL(window.location.href);e.searchParams.has("id")&&(e.searchParams.delete("id"),H(e.pathname+e.search));}return jsxs(z,{children:[jsxs(a$1,{onValueChange:J,value:k,children:[jsx(d,{"aria-label":"Filter search by entity",className:"fk:w-36 fk:h-9 fk:py-1 fk:rounded-r-none fk:border-border fk:shadow-none fk:corner-squircle",children:jsx(c,{})}),jsxs(e,{children:[jsx(g,{value:s,children:"All"}),f.map(e=>jsx(g,{value:e.plural,children:me(e)},e.plural))]})]}),jsxs(m,{className:"fk:relative fk:overflow-visible fk:h-auto fk:justify-center fk:rounded-none fk:bg-transparent fk:corner-squircle",onBlur:()=>{setTimeout(()=>{l(false);},300);},onKeyDown:e=>{e.key==="Escape"&&(e.preventDefault(),l(false));},shouldFilter:false,children:[jsxs("div",{className:a$2("fk:flex fk:items-center fk:border-y fk:border-r fk:border-border fk:rounded-r-md fk:bg-background fk:pl-3 fk:pr-2 fk:h-9 fk:md:w-25 fk:lg:w-75 fk:corner-squircle","fk:outline-none fk:transition-[color,box-shadow] fk:has-[input:focus-visible]:border-ring fk:has-[input:focus-visible]:ring-[3px] fk:has-[input:focus-visible]:ring-ring/50"),children:[h?jsx(LoaderCircle,{className:"fk:mr-2 fk:h-4 fk:w-4 fk:shrink-0 fk:opacity-50 fk:animate-spin"}):jsx(Search,{className:"fk:mr-2 fk:h-4 fk:w-4 fk:shrink-0 fk:opacity-50"}),jsx(Command.Input,{className:a$2("fk:flex fk:h-9 fk:w-full fk:rounded-none fk:bg-transparent fk:py-1 fk:text-sm fk:outline-hidden fk:placeholder:text-muted-foreground fk:disabled:cursor-not-allowed fk:disabled:opacity-50 fk:corner-squircle",m$1),placeholder:n,onMouseDown:()=>{(c$1.current?.value.length??0)>0&&l(true);},onValueChange:F,ref:c$1,value:i}),i&&jsx(b,{"aria-label":"Clear search",className:"fk:flex fk:items-center fk:justify-center fk:ml-2 fk:h-6 fk:w-6 fk:text-muted-foreground fk:hover:text-foreground fk:hover:bg-foreground/10 fk:cursor-pointer fk:rounded-full fk:bg-transparent fk:corner-squircle",onClick:Q,type:"button",children:jsx(X,{className:"fk:h-4 fk:w-4"})})]}),jsx("div",{className:"fk:relative fk:max-w-150",children:jsx("div",{className:a$2("fk:mt-1 fk:animate-in fk:fade-in-0 fk:zoom-in-95 fk:absolute fk:top-0 fk:z-50 fk:w-full fk:rounded-md fk:bg-popover fk:outline-hidden fk:drop-shadow-md fk:border fk:border-border fk:corner-squircle",z$1?"fk:block":"fk:hidden"),children:jsxs(w,{className:"fk:max-h-55 fk:overflow-auto",children:[!h&&jsx(q,{children:o}),jsx(p,{children:jsxs(r,{children:[p$1.length>0&&jsx(t,{"aria-hidden":"true",className:"fk:hidden!",value:"-"}),p$1.map(e=>jsxs(t,{className:"fk:flex",value:e._id,onSelect:K=>{t$1({entityName:e._entityName,entityNamePlural:e._entityNamePlural,entityId:K});},children:[jsx("span",{className:"fk:basis-full",children:e[Object.keys(e)[3]]}),jsx(b$1,{className:"fk:py-px fk:text-[0.6875rem] fk:leading-3 fk:bg-teal-400",children:e._entityName})]},e._id))]})})]})})})]})]})}export{Ee as Search};//# sourceMappingURL=search-VPS2UHPQ.js.map
|
|
2
|
+
//# sourceMappingURL=search-VPS2UHPQ.js.map
|