@flexkit/studio 0.2.40 → 0.2.41
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-I2IFVZA3.js → chat-page-DM5R7DEJ.js} +3 -3
- package/dist/{chat-page-I2IFVZA3.js.map → chat-page-DM5R7DEJ.js.map} +1 -1
- package/dist/{chunk-L62VVHKS.js → chunk-2MNG5HBI.js} +2 -2
- package/dist/{chunk-L62VVHKS.js.map → chunk-2MNG5HBI.js.map} +1 -1
- package/dist/{chunk-4JG3OWQW.js → chunk-3DT7IQLS.js} +2 -2
- package/dist/{chunk-4JG3OWQW.js.map → chunk-3DT7IQLS.js.map} +1 -1
- package/dist/{chunk-NPO7ISWV.js → chunk-3V7VAQBP.js} +2 -2
- package/dist/{chunk-NPO7ISWV.js.map → chunk-3V7VAQBP.js.map} +1 -1
- package/dist/{chunk-LO37DY2Z.js → chunk-JHYLYOJJ.js} +2 -2
- package/dist/{chunk-LO37DY2Z.js.map → chunk-JHYLYOJJ.js.map} +1 -1
- package/dist/{chunk-GPMBBJHK.js → chunk-KGNQ6P6R.js} +3 -3
- package/dist/{chunk-GPMBBJHK.js.map → chunk-KGNQ6P6R.js.map} +1 -1
- package/dist/{chunk-X5QKLF63.js → chunk-KL2NENPM.js} +3 -3
- package/dist/{chunk-X5QKLF63.js.map → chunk-KL2NENPM.js.map} +1 -1
- package/dist/{chunk-HOAVEDVI.js → chunk-NHNJNPF5.js} +3 -3
- package/dist/{chunk-HOAVEDVI.js.map → chunk-NHNJNPF5.js.map} +1 -1
- package/dist/{chunk-E3KO5NGM.js → chunk-NS4FHGIC.js} +2 -2
- package/dist/{chunk-E3KO5NGM.js.map → chunk-NS4FHGIC.js.map} +1 -1
- package/dist/{chunk-NPMBADZL.js → chunk-NVQANITJ.js} +3 -3
- package/dist/{chunk-NPMBADZL.js.map → chunk-NVQANITJ.js.map} +1 -1
- package/dist/{chunk-2IJWBRN2.js → chunk-OXJJX6QV.js} +2 -2
- package/dist/{chunk-2IJWBRN2.js.map → chunk-OXJJX6QV.js.map} +1 -1
- package/dist/{chunk-DAXVPJJS.js → chunk-T7IAVZCX.js} +4 -4
- package/dist/{chunk-DAXVPJJS.js.map → chunk-T7IAVZCX.js.map} +1 -1
- package/dist/{chunk-GPTSQ2WH.js → chunk-TATNK4AH.js} +3 -3
- package/dist/{chunk-GPTSQ2WH.js.map → chunk-TATNK4AH.js.map} +1 -1
- package/dist/{chunk-HUG2NGZI.js → chunk-VS7RDMW2.js} +2 -2
- package/dist/{chunk-HUG2NGZI.js.map → chunk-VS7RDMW2.js.map} +1 -1
- package/dist/{chunk-53GVTCXC.js → chunk-VT476KKC.js} +3 -3
- package/dist/{chunk-53GVTCXC.js.map → chunk-VT476KKC.js.map} +1 -1
- package/dist/{chunk-DFOPVG7I.js → chunk-VUGISMZA.js} +2 -2
- package/dist/{chunk-DFOPVG7I.js.map → chunk-VUGISMZA.js.map} +1 -1
- package/dist/{chunk-CQS6AIOX.js → chunk-VXRA33F4.js} +2 -2
- package/dist/{chunk-CQS6AIOX.js.map → chunk-VXRA33F4.js.map} +1 -1
- package/dist/{chunk-LWI3HNJL.js → chunk-XRZBQA6H.js} +3 -3
- package/dist/{chunk-LWI3HNJL.js.map → chunk-XRZBQA6H.js.map} +1 -1
- package/dist/{chunk-Y7VBTUNI.js → chunk-YGG43LHF.js} +3 -3
- package/dist/{chunk-Y7VBTUNI.js.map → chunk-YGG43LHF.js.map} +1 -1
- package/dist/{entry-NCKQ45MI.js → entry-4OP3BASI.js} +2 -2
- package/dist/{entry-NCKQ45MI.js.map → entry-4OP3BASI.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/{list-VWN4IJYC.js → list-4XKSEBGT.js} +3 -3
- package/dist/{list-VWN4IJYC.js.map → list-4XKSEBGT.js.map} +1 -1
- package/dist/{list-UHHDZ3DM.js → list-KPKWXWZZ.js} +2 -2
- package/dist/{list-UHHDZ3DM.js.map → list-KPKWXWZZ.js.map} +1 -1
- package/dist/pages-JYXHLRSZ.js +5 -0
- package/dist/pages-JYXHLRSZ.js.map +1 -0
- package/dist/{plugin-pages-LLJPZJWL.js → plugin-pages-5PNAZGCO.js} +2 -2
- package/dist/{plugin-pages-LLJPZJWL.js.map → plugin-pages-5PNAZGCO.js.map} +1 -1
- package/dist/{project-selector-K3T6H77F.js → project-selector-6VHU5KVQ.js} +2 -2
- package/dist/{project-selector-K3T6H77F.js.map → project-selector-6VHU5KVQ.js.map} +1 -1
- package/dist/record-links-KRMGWWLU.js +2 -0
- package/dist/{record-links-CILZYRSE.js.map → record-links-KRMGWWLU.js.map} +1 -1
- package/dist/{root-PY5SBJ4F.js → root-4F6MS4T7.js} +3 -3
- package/dist/{root-PY5SBJ4F.js.map → root-4F6MS4T7.js.map} +1 -1
- package/dist/{root-XTF6EH63.js → root-7UPTEL7G.js} +3 -3
- package/dist/{root-XTF6EH63.js.map → root-7UPTEL7G.js.map} +1 -1
- package/dist/{root-ADEORVTL.js → root-HYB5RRH4.js} +2 -2
- package/dist/{root-ADEORVTL.js.map → root-HYB5RRH4.js.map} +1 -1
- package/dist/{root-LSBCX6AE.js → root-ILUM4ZHH.js} +2 -2
- package/dist/{root-LSBCX6AE.js.map → root-ILUM4ZHH.js.map} +1 -1
- package/dist/{root-CE6LNBBW.js → root-KYXGSM45.js} +3 -3
- package/dist/{root-CE6LNBBW.js.map → root-KYXGSM45.js.map} +1 -1
- package/dist/{root-Y3D2FTDR.js → root-WOUYFOQO.js} +2 -2
- package/dist/{root-Y3D2FTDR.js.map → root-WOUYFOQO.js.map} +1 -1
- package/dist/{search-MGY3OWZQ.js → search-HV4MXIKW.js} +2 -2
- package/dist/{search-MGY3OWZQ.js.map → search-HV4MXIKW.js.map} +1 -1
- package/dist/{skills-pages-7QYBKBSB.js → skills-pages-C4OOTCLS.js} +2 -2
- package/dist/{skills-pages-7QYBKBSB.js.map → skills-pages-C4OOTCLS.js.map} +1 -1
- package/dist/{source-M746FR3B.js → source-EGHZGVN4.js} +2 -2
- package/dist/{source-M746FR3B.js.map → source-EGHZGVN4.js.map} +1 -1
- package/package.json +5 -5
- package/dist/pages-LZEKCA4W.js +0 -5
- package/dist/pages-LZEKCA4W.js.map +0 -1
- package/dist/record-links-CILZYRSE.js +0 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import'./index.css';import {c,e}from'./chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import'./index.css';import {c,e}from'./chunk-OXJJX6QV.js';import {b}from'./chunk-NHNJNPF5.js';import {f}from'./chunk-YGG43LHF.js';import {d}from'./chunk-MBBE4RND.js';import {useMemo}from'react';import I from'swr';import {find,propEq}from'ramda';function $(n,o){let{scope:l}=c(),{currentProject:e$1}=f(),a=useMemo(()=>e$1?.schema??[],[e$1]),m=e$1?.scopes,u=e(m),t=o?.commonParams.q?JSON.stringify(o):null,{data:r,error:s,isLoading:y}=I(t,()=>fetch(d(n).search,{headers:{"Content-Type":"application/json"},body:JSON.stringify(o),method:"POST",mode:"cors"}).then(i=>i.json()),{keepPreviousData:true});return {results:useMemo(()=>t?O(r?.results??[],n,a,l,u)??[]:[],[r,u,n,a,l,t]),error:s,isLoading:y}}function O(n,o,l,e,a){return n?.filter(m=>m?.hits?.length>0).map(m=>{let u=m,t=u.collection.replace(`${o}_`,"").replace(/_\d+$/,""),r=find(propEq(t,"plural"))(l);if(!r)return [];let s=b(r)?.name??"",y=r?.name??t;return u.hits.map(({document:c})=>{let i=c[s],N=(i&&typeof i!="string"?i[e]??i[a]:null)??c[s],_=Object.entries(c).reduce((h,[p,f])=>{if(p!==s&&p!=="id"&&p!=="_updatedAt"){let A=typeof f!="string"?f[e]??f[a]:f;h[p]=A;}return h},{});return {_id:c.id,_entityName:y,_entityNamePlural:t,[s]:N,..._}})}).flat()}export{$ as a};//# sourceMappingURL=chunk-2MNG5HBI.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-2MNG5HBI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/use-search.tsx"],"names":["useSearch","projectId","searchRequest","scope","useAppContext","currentProject","useConfig","schema","useMemo","scopes","defaultScope","defaultScopeName","swrKey","data","error","isLoading","useSWR","apiPaths","res","mapResults","results","result","item","entityNamePlural","entitySchema","find","propEq","primaryAttributeName","getDisplayAttribute","entityName","document","primaryAttribute","primaryAttributeValue","attributes","acc","key","value","scopedValue"],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/core/use-search.tsx"],"names":["useSearch","projectId","searchRequest","scope","useAppContext","currentProject","useConfig","schema","useMemo","scopes","defaultScope","defaultScopeName","swrKey","data","error","isLoading","useSWR","apiPaths","res","mapResults","results","result","item","entityNamePlural","entitySchema","find","propEq","primaryAttributeName","getDisplayAttribute","entityName","document","primaryAttribute","primaryAttributeValue","attributes","acc","key","value","scopedValue"],"mappings":"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","file":"chunk-2MNG5HBI.js","sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\nimport { defaultScopeName } from './default-scope';\nimport useSWR from 'swr';\nimport { find, propEq } from 'ramda';\nimport { apiPaths } from './api-paths';\nimport { useAppContext } from './app-context';\nimport { useConfig } from './config/config-context';\nimport { getDisplayAttribute } from './get-display-attribute';\nimport type { Entity, RawResultItem, RawSearchResultItems, SearchRequestProps, SearchResultItem } from './types';\n\nexport function useSearch(\n projectId: string,\n searchRequest: SearchRequestProps | null\n): { results: SearchResultItem[] | []; error: Error; isLoading: boolean } {\n const { scope } = useAppContext();\n const { currentProject } = useConfig();\n const schema = useMemo(() => currentProject?.schema ?? [], [currentProject]);\n const scopes = currentProject?.scopes;\n const defaultScope = defaultScopeName(scopes);\n const swrKey = searchRequest?.commonParams.q ? JSON.stringify(searchRequest) : null;\n const { data, error, isLoading } = useSWR(\n swrKey,\n () =>\n fetch(apiPaths(projectId).search, {\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(searchRequest),\n method: 'POST',\n mode: 'cors',\n }).then((res) => res.json() as Promise<{ results: RawSearchResultItems }>),\n // Show the previous hits until the next request lands instead of flashing an empty list per keystroke.\n { keepPreviousData: true }\n );\n const results = useMemo(\n // SWR keeps the previous key's data while a new key loads, and also after the key becomes null.\n // Callers treat an empty query as \"no search\", so return no hits once there is nothing to search for.\n () => (swrKey ? (mapResults(data?.results ?? [], projectId, schema, scope, defaultScope) ?? []) : []),\n [data, defaultScope, projectId, schema, scope, swrKey]\n );\n\n return { results, error, isLoading };\n}\n\nfunction mapResults(\n results: RawSearchResultItems | undefined,\n projectId: string,\n schema: Entity[],\n scope: string,\n defaultScope: string\n): SearchResultItem[] | undefined {\n return results\n ?.filter((result) => (result as RawResultItem)?.hits?.length > 0)\n .map((result) => {\n const item = result as RawResultItem;\n const entityNamePlural = item.collection.replace(`${projectId}_`, '').replace(/_\\d+$/, '');\n const entitySchema = find<Entity>(propEq(entityNamePlural, 'plural'))(schema);\n\n if (!entitySchema) {\n return [];\n }\n\n const primaryAttributeName = getDisplayAttribute(entitySchema)?.name ?? '';\n const entityName = entitySchema?.name ?? entityNamePlural;\n\n // iterate over the hits and return an object with the primary attribute value first and then the rest of the attributes.\n return item.hits.map(({ document }) => {\n const primaryAttribute = document[primaryAttributeName];\n const scopedPrimaryAttribute =\n primaryAttribute && typeof primaryAttribute !== 'string'\n ? (primaryAttribute[scope] ?? primaryAttribute[defaultScope])\n : null;\n const primaryAttributeValue = scopedPrimaryAttribute ?? document[primaryAttributeName];\n const attributes = Object.entries(document).reduce(\n (acc: Omit<SearchResultItem, '_id' | '_entityName' | '_entityNamePlural'>, [key, value]) => {\n if (key !== primaryAttributeName && key !== 'id' && key !== '_updatedAt') {\n const scopedValue = typeof value !== 'string' ? (value[scope] ?? value[defaultScope]) : value;\n\n acc[key] = scopedValue;\n }\n\n return acc;\n },\n {}\n );\n\n return {\n _id: document.id,\n _entityName: entityName,\n _entityNamePlural: entityNamePlural,\n [primaryAttributeName]: primaryAttributeValue as string,\n ...attributes,\n };\n });\n })\n .flat();\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import'./index.css';import {a,c as c$1,d,f as f$1,g as g$1,e as e$1,i,h as h$2}from'./chunk-4ZWQ44NZ.js';import {b as b$1}from'./chunk-DSLPTDZX.js';import {h}from'./chunk-7KLXWCDS.js';import {f}from'./chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import'./index.css';import {a,c as c$1,d,f as f$1,g as g$1,e as e$1,i,h as h$2}from'./chunk-4ZWQ44NZ.js';import {b as b$1}from'./chunk-DSLPTDZX.js';import {h}from'./chunk-7KLXWCDS.js';import {f}from'./chunk-YGG43LHF.js';import {ma}from'./chunk-RULCANNM.js';import {e,g,h as h$1,j as j$1,o,n}from'./chunk-A4DPLZZF.js';import {b}from'./chunk-5JUG4BEF.js';import {c}from'./chunk-X3SHNHHM.js';import {put}from'@vercel/blob/client';import {useMemo,useRef,useEffect,useState}from'react';import {LoaderCircle,EllipsisVerticalIcon,DownloadIcon,ExternalLinkIcon,Trash2Icon}from'lucide-react';import {mutate}from'swr';import {Document}from'@untitledui/file-icons/dist/solid/document.mjs';import {Docx}from'@untitledui/file-icons/dist/solid/docx.mjs';import {Html}from'@untitledui/file-icons/dist/solid/html.mjs';import {Pdf}from'@untitledui/file-icons/dist/solid/pdf.mjs';import {Pptx}from'@untitledui/file-icons/dist/solid/pptx.mjs';import {Txt}from'@untitledui/file-icons/dist/solid/txt.mjs';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var u=class extends Error{code;status;constructor(n,t,r=null){super(t),this.name="KnowledgeApiError",this.code=r,this.status=n;}},k=class extends Error{status;constructor(n,t="Request failed"){super(t),this.name="FetcherError",this.status=n;}},fe=async e=>{let n=await fetch(e,{credentials:"include"});if(!n.ok)throw new k(n.status);return await n.json()};function j(e){let n=`/api/flexkit/${e}/knowledge`;return {entitySources:t=>`${n}/entities/${encodeURIComponent(t)}/sources`,file:t=>`${n}/sources/${encodeURIComponent(t)}/file`,job:t=>`${n}/jobs/${encodeURIComponent(t)}`,links:t=>`${n}/sources/${encodeURIComponent(t)}/links`,passages:(t,{from:r,to:o})=>`${n}/sources/${encodeURIComponent(t)}/passages?from=${String(r)}&to=${String(o)}`,recordSources:({entity:t,recordId:r})=>`${n}/records/${encodeURIComponent(t)}/${encodeURIComponent(r)}/sources`,source:t=>`${n}/sources/${encodeURIComponent(t)}`,sources:(t={})=>{let{limit:r=25,offset:o=0,search:i,status:a}=t,l=new URLSearchParams({limit:r.toString(),offset:o.toString()}),c=i?.trim();return c&&l.set("q",c),a&&l.set("status",a),`${n}/sources?${l.toString()}`},spaces:`/api/flexkit/${e}/spaces`}}function N(e){return typeof e=="string"&&e.includes("/knowledge/sources?")}function J(e){return typeof e=="string"&&(e.includes("/knowledge/records/")||e.includes("/knowledge/entities/")||e.includes("/knowledge/sources/")&&e.endsWith("/links"))}async function L(e,n){let t={};try{t=await e.json();}catch{}return new u(e.status,t.error?String(t.error):n,t.code??null)}function O(e){let n=`/api/flexkit/${e}/knowledge`;async function t(o,i){let{fallback:a,...l}=i,c=await fetch(o,{credentials:"include",headers:{"Content-Type":"application/json",...l.headers??{}},...l});if(!c.ok)throw await L(c,a);return await c.json()}function r(o){return t(`${n}/sources`,{body:JSON.stringify(o),fallback:"The document could not be added.",method:"POST"})}return {addFile:async(o,i)=>{let a=await fetch(`${n}/uploads`,{body:JSON.stringify({filename:o.name,mediaType:o.type||null,sizeBytes:o.size}),credentials:"include",headers:{"Content-Type":"application/json"},method:"POST",signal:i?.signal});if(!a.ok)throw await L(a,"The file could not be uploaded.");let l=await a.json();if(!l.pathname||!l.token||!l.mediaType)throw new u(a.status,"The file could not be uploaded.");return await put(l.pathname,o,{abortSignal:i?.signal,access:"public",contentType:l.mediaType,token:l.token}),r({kind:"upload",pathname:l.pathname})},addUrl:({title:o,url:i})=>r({kind:"url",url:i,...o?{title:o}:{}}),addChatAttachment:({filename:o,url:i})=>r({filename:o,kind:"chat-attachment",url:i}),deleteSource:o=>t(`${n}/sources/${encodeURIComponent(o)}`,{fallback:"The document could not be removed.",method:"DELETE"}),linkSource:(o,i)=>t(`${n}/sources/${encodeURIComponent(o)}/links`,{body:JSON.stringify(i),fallback:"The document could not be attached.",method:"POST"}),reingestSource:o=>t(`${n}/sources/${encodeURIComponent(o)}/reingest`,{fallback:"The document could not be re-indexed.",method:"POST"}),unlinkSource:(o,{entity:i,recordId:a})=>t(`${n}/sources/${encodeURIComponent(o)}/links/${encodeURIComponent(i)}${a===void 0?"":`/${encodeURIComponent(a)}`}`,{fallback:"The document could not be detached.",method:"DELETE"}),updateSource:(o,i)=>t(`${n}/sources/${encodeURIComponent(o)}`,{body:JSON.stringify(i),fallback:"The document could not be updated.",method:"PATCH"})}}var ae={busy:"fk:bg-amber-500/15 fk:text-amber-700 fk:dark:text-amber-400",error:"fk:bg-destructive/15 fk:text-destructive",muted:"fk:bg-muted fk:text-muted-foreground",ready:"fk:bg-emerald-500/15 fk:text-emerald-700 fk:dark:text-emerald-400"};function le(){let{currentProjectId:e}=f();return {api:useMemo(()=>e?O(e):null,[e]),projectId:e}}function de(){return mutate(N,void 0,{revalidate:true})}function Pe(){return mutate(J,void 0,{revalidate:true})}function ce(e,n){return e instanceof u||e instanceof Error?e.message:n}function Ee(e,n){if(e.duplicate){ma.info(`"${e.source.title}" is already in Knowledge.`);return}ma.success(`Added ${n}. Indexing starts now.`);}function _e({children:e}){return jsx("div",{className:"fk:rounded-md fk:border fk:border-dashed fk:p-8 fk:text-center fk:text-sm fk:text-muted-foreground fk:corner-squircle",children:e})}function Me({label:e,tone:n}){return jsxs(b,{className:`fk:border-none fk:corner-squircle ${ae[n]}`,variant:"outline",children:[n==="busy"?jsx(LoaderCircle,{className:"fk:size-3 fk:animate-spin"}):null,e]})}var ue={document:Document,docx:Docx,html:Html,pdf:Pdf,pptx:Pptx,txt:Txt};function ge({className:e="",size:n=24,source:t}){let r=h(t),o=ue[r.icon];return jsx("span",{"aria-label":r.label,className:`fk:flex fk:shrink-0 fk:items-center fk:justify-center ${e}`,"data-knowledge-type":r.icon,role:"img",children:jsx(o,{size:n})})}function Ue({source:e}){return jsx(ge,{size:40,source:e})}function Le({onVisible:e}){let n=useRef(null),t=useRef(e);return t.current=e,useEffect(()=>{let r=n.current;if(!r)return;let o=new IntersectionObserver(i=>{i.some(a=>a.isIntersecting)&&t.current();});return o.observe(r),()=>{o.disconnect();}},[]),jsx("div",{"aria-hidden":true,className:"fk:h-px",ref:n})}function je({isBusy:e$2=false,onOpen:n$1,onRemoved:t,source:r,trigger:o$1="row"}){let{api:i$1,projectId:a$1}=le(),l=b$1(),[c$2,p]=useState(false),[f,b]=useState(false);if(!i$1||!a$1)return null;let X=i$1;async function H(){b(true);try{await X.deleteSource(r.id),ma.success(`Removed "${r.title}".`),p(!1),t(),de();}catch(w){ma.error(ce(w,"The document could not be removed."));}finally{b(false);}}return jsxs(Fragment,{children:[jsxs(e,{children:[jsx(g,{asChild:true,children:jsx(c,{"aria-label":`Actions for ${r.title}`,className:o$1==="row"?"fk:size-8 fk:shrink-0 fk:text-muted-foreground":void 0,"data-knowledge-menu":true,size:"icon-sm",variant:o$1==="row"?"ghost":"outline",children:jsx(EllipsisVerticalIcon,{className:"fk:size-4"})})}),jsxs(h$1,{align:"end",children:[n$1?jsx(j$1,{onSelect:n$1,children:"Open"}):null,r.path?jsx(j$1,{asChild:true,children:jsxs("a",{href:j(a$1).file(r.id),children:[jsx(DownloadIcon,{}),"Download"]})}):null,r.originUrl?jsx(j$1,{asChild:true,children:jsxs("a",{href:r.originUrl,rel:"noreferrer",target:"_blank",children:[jsx(ExternalLinkIcon,{}),"Open page"]})}):null,n$1||r.path||r.originUrl?jsx(o,{}):null,jsxs(j$1,{disabled:!l||e$2,variant:"destructive",onSelect:()=>p(true),children:[jsx(Trash2Icon,{}),"Remove"]}),l?null:jsx(n,{className:"fk:max-w-56 fk:whitespace-normal fk:text-xs fk:font-normal fk:text-muted-foreground",children:"Your member role cannot remove documents."})]})]}),jsx(a,{open:c$2,onOpenChange:p,children:jsxs(c$1,{children:[jsxs(d,{children:[jsx(f$1,{children:"Remove this document?"}),jsxs(g$1,{children:['"',r.title,'" and its indexed passages are deleted for everyone. Answers the agent gave earlier keep their citations, but the document can no longer be opened.']})]}),jsxs(e$1,{children:[jsx(i,{disabled:f,children:"Cancel"}),jsxs(h$2,{disabled:f,onClick:w=>{w.preventDefault(),H();},children:[f?jsx(LoaderCircle,{className:"fk:animate-spin"}):null,"Remove document"]})]})]})})]})}export{k as a,fe as b,j as c,O as d,le as e,de as f,Pe as g,ce as h,Ee as i,_e as j,Me as k,ge as l,Ue as m,Le as n,je as o};//# sourceMappingURL=chunk-3DT7IQLS.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-3DT7IQLS.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/knowledge/api.ts","../src/apps/knowledge/shared.tsx"],"names":["KnowledgeApiError","status","message","code","FetcherError","fetcher","url","response","knowledgePaths","projectId","basePath","entity","sourceId","jobId","from","to","recordId","options","limit","offset","search","params","trimmedSearch","isKnowledgeListKey","key","isKnowledgeLinkKey","readError","fallback","data","createKnowledgeApi","request","init","requestInit","register","body","file","tokenResponse","tokenData","put","title","filename","target","patch","STATUS_TONE_CLASSES","useProjectKnowledge","currentProjectId","useConfig","useMemo","invalidateKnowledgeLists","mutateGlobal","invalidateKnowledgeLinks","describeApiError","error","announceRegistered","result","name","toast","PageMessage","children","jsx","StatusBadge","label","tone","jsxs","Badge","LoaderCircle","FILE_ICONS","Document","Docx","Html","Pdf","Pptx","Txt","KnowledgeTypeIcon","className","size","source","format","getKnowledgeFormat","Icon","SourceIcon","InfiniteScrollSentinel","onVisible","sentinelRef","useRef","onVisibleRef","useEffect","node","observer","entries","entry","SourceActionsMenu","isBusy","onOpen","onRemoved","trigger","api","canMutate","useCanMutate","isConfirmingRemoval","setIsConfirmingRemoval","useState","isRemoving","setIsRemoving","knowledgeApi","remove","removeError","Fragment","DropdownMenu","DropdownMenuTrigger","Button","EllipsisVerticalIcon","DropdownMenuContent","DropdownMenuItem","DownloadIcon","ExternalLinkIcon","DropdownMenuSeparator","Trash2Icon","DropdownMenuLabel","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","event"],"mappings":"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","file":"chunk-4JG3OWQW.js","sourcesContent":["import { put } from '@vercel/blob/client';\nimport type {\n KnowledgeJob,\n KnowledgeLinkTarget,\n KnowledgeRecordRef,\n KnowledgeSource,\n KnowledgeSourcePatch,\n KnowledgeSourceStatus,\n RegisterKnowledgeSourceResult,\n} from './knowledge';\n\n/** The platform refused a knowledge request; `code` lets the UI tailor the message. */\nexport class KnowledgeApiError extends Error {\n code: string | null;\n status: number;\n\n constructor(status: number, message: string, code: string | null = null) {\n super(message);\n this.name = 'KnowledgeApiError';\n this.code = code;\n this.status = status;\n }\n}\n\nexport interface ProjectSpace {\n code: string;\n id: string;\n label: string;\n}\n\nexport interface KnowledgeApi {\n /** Uploads a document to the file store, then registers it; resolves once indexing is queued or the file was already there. */\n addFile: (_file: File, _options?: { signal?: AbortSignal }) => Promise<RegisterKnowledgeSourceResult>;\n addUrl: (_input: { title?: string; url: string }) => Promise<RegisterKnowledgeSourceResult>;\n /** Promotes a file the caller attached to a chat: the platform copies it into the knowledge folder. */\n addChatAttachment: (_input: { filename: string; url: string }) => Promise<RegisterKnowledgeSourceResult>;\n deleteSource: (_sourceId: string) => Promise<{ deleted: true }>;\n /** Attaches the document to a record, or to every record of an entity type; `linked` is false when it already was. */\n linkSource: (_sourceId: string, _target: KnowledgeLinkTarget) => Promise<{ linked: boolean }>;\n reingestSource: (_sourceId: string) => Promise<{ job: KnowledgeJob }>;\n unlinkSource: (_sourceId: string, _target: KnowledgeLinkTarget) => Promise<{ unlinked: boolean }>;\n updateSource: (_sourceId: string, _patch: KnowledgeSourcePatch) => Promise<{ source: KnowledgeSource }>;\n}\n\nexport class FetcherError extends Error {\n status: number;\n\n constructor(status: number, message = 'Request failed') {\n super(message);\n this.name = 'FetcherError';\n this.status = status;\n }\n}\n\nexport const fetcher = async <T>(url: string): Promise<T> => {\n const response = await fetch(url, { credentials: 'include' });\n\n if (!response.ok) {\n throw new FetcherError(response.status);\n }\n\n return (await response.json()) as T;\n};\n\nexport function knowledgePaths(projectId: string): {\n /** The documents attached to every record of an entity type. */\n entitySources: (_entity: string) => string;\n /** The original file of an uploaded document, served under its name. */\n file: (_sourceId: string) => string;\n job: (_jobId: string) => string;\n /** The records a document is attached to, and the entity types it applies to. */\n links: (_sourceId: string) => string;\n passages: (_sourceId: string, _options: { from: number; to: number }) => string;\n /** The documents attached to a record. */\n recordSources: (_record: KnowledgeRecordRef) => string;\n source: (_sourceId: string) => string;\n sources: (_options?: { limit?: number; offset?: number; search?: string; status?: KnowledgeSourceStatus }) => string;\n spaces: string;\n} {\n const basePath = `/api/flexkit/${projectId}/knowledge`;\n\n return {\n entitySources: (entity) => `${basePath}/entities/${encodeURIComponent(entity)}/sources`,\n file: (sourceId) => `${basePath}/sources/${encodeURIComponent(sourceId)}/file`,\n job: (jobId) => `${basePath}/jobs/${encodeURIComponent(jobId)}`,\n links: (sourceId) => `${basePath}/sources/${encodeURIComponent(sourceId)}/links`,\n passages: (sourceId, { from, to }) =>\n `${basePath}/sources/${encodeURIComponent(sourceId)}/passages?from=${String(from)}&to=${String(to)}`,\n recordSources: ({ entity, recordId }) =>\n `${basePath}/records/${encodeURIComponent(entity)}/${encodeURIComponent(recordId)}/sources`,\n source: (sourceId) => `${basePath}/sources/${encodeURIComponent(sourceId)}`,\n sources: (options = {}) => {\n const { limit = 25, offset = 0, search, status } = options;\n const params = new URLSearchParams({ limit: limit.toString(), offset: offset.toString() });\n const trimmedSearch = search?.trim();\n\n if (trimmedSearch) {\n params.set('q', trimmedSearch);\n }\n\n if (status) {\n params.set('status', status);\n }\n\n return `${basePath}/sources?${params.toString()}`;\n },\n spaces: `/api/flexkit/${projectId}/spaces`,\n };\n}\n\n/** Whether an SWR key is a page of the document list, whatever its filters. */\nexport function isKnowledgeListKey(key: unknown): boolean {\n return typeof key === 'string' && key.includes('/knowledge/sources?');\n}\n\n/** Whether an SWR key lists the documents of a record or an entity type, or the links of a document. */\nexport function isKnowledgeLinkKey(key: unknown): boolean {\n return (\n typeof key === 'string' &&\n (key.includes('/knowledge/records/') ||\n key.includes('/knowledge/entities/') ||\n (key.includes('/knowledge/sources/') && key.endsWith('/links')))\n );\n}\n\nasync function readError(response: Response, fallback: string): Promise<KnowledgeApiError> {\n let data: { code?: string; error?: string } = {};\n\n try {\n data = (await response.json()) as { code?: string; error?: string };\n } catch {\n // Non-JSON error bodies keep the fallback message.\n }\n\n return new KnowledgeApiError(response.status, data.error ? String(data.error) : fallback, data.code ?? null);\n}\n\nexport function createKnowledgeApi(projectId: string): KnowledgeApi {\n const basePath = `/api/flexkit/${projectId}/knowledge`;\n\n async function request<T>(url: string, init: RequestInit & { fallback: string }): Promise<T> {\n const { fallback, ...requestInit } = init;\n const response = await fetch(url, {\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...(requestInit.headers ?? {}) },\n ...requestInit,\n });\n\n if (!response.ok) {\n throw await readError(response, fallback);\n }\n\n return (await response.json()) as T;\n }\n\n function register(body: Record<string, unknown>): Promise<RegisterKnowledgeSourceResult> {\n return request<RegisterKnowledgeSourceResult>(`${basePath}/sources`, {\n body: JSON.stringify(body),\n fallback: 'The document could not be added.',\n method: 'POST',\n });\n }\n\n return {\n addFile: async (file, options) => {\n // The platform issues a token pinned to one pathname, type and size; the\n // browser writes the bytes to the store itself, so a 20 MB document never\n // crosses the API function body limit. Registration then hashes the blob.\n const tokenResponse = await fetch(`${basePath}/uploads`, {\n body: JSON.stringify({ filename: file.name, mediaType: file.type || null, sizeBytes: file.size }),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n signal: options?.signal,\n });\n\n if (!tokenResponse.ok) {\n throw await readError(tokenResponse, 'The file could not be uploaded.');\n }\n\n const tokenData = (await tokenResponse.json()) as { mediaType?: string; pathname?: string; token?: string };\n\n if (!tokenData.pathname || !tokenData.token || !tokenData.mediaType) {\n throw new KnowledgeApiError(tokenResponse.status, 'The file could not be uploaded.');\n }\n\n await put(tokenData.pathname, file, {\n abortSignal: options?.signal,\n access: 'public',\n contentType: tokenData.mediaType,\n token: tokenData.token,\n });\n\n return register({ kind: 'upload', pathname: tokenData.pathname });\n },\n addUrl: ({ title, url }) => register({ kind: 'url', url, ...(title ? { title } : {}) }),\n addChatAttachment: ({ filename, url }) => register({ filename, kind: 'chat-attachment', url }),\n deleteSource: (sourceId) =>\n request<{ deleted: true }>(`${basePath}/sources/${encodeURIComponent(sourceId)}`, {\n fallback: 'The document could not be removed.',\n method: 'DELETE',\n }),\n linkSource: (sourceId, target) =>\n request<{ linked: boolean }>(`${basePath}/sources/${encodeURIComponent(sourceId)}/links`, {\n body: JSON.stringify(target),\n fallback: 'The document could not be attached.',\n method: 'POST',\n }),\n reingestSource: (sourceId) =>\n request<{ job: KnowledgeJob }>(`${basePath}/sources/${encodeURIComponent(sourceId)}/reingest`, {\n fallback: 'The document could not be re-indexed.',\n method: 'POST',\n }),\n unlinkSource: (sourceId, { entity, recordId }) =>\n request<{ unlinked: boolean }>(\n `${basePath}/sources/${encodeURIComponent(sourceId)}/links/${encodeURIComponent(entity)}${\n recordId === undefined ? '' : `/${encodeURIComponent(recordId)}`\n }`,\n { fallback: 'The document could not be detached.', method: 'DELETE' }\n ),\n updateSource: (sourceId, patch) =>\n request<{ source: KnowledgeSource }>(`${basePath}/sources/${encodeURIComponent(sourceId)}`, {\n body: JSON.stringify(patch),\n fallback: 'The document could not be updated.',\n method: 'PATCH',\n }),\n };\n}\n","import type { JSX, MouseEvent } from 'react';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { DownloadIcon, EllipsisVerticalIcon, ExternalLinkIcon, LoaderCircle, Trash2Icon } from 'lucide-react';\nimport { mutate as mutateGlobal } from 'swr';\n// File type icons: Untitled UI's free file icons, Solid variant. The set is\n// published as the MIT package `@untitledui/file-icons`; the page below shows\n// every icon and offers each as SVG or JSX should another format need one.\n// https://www.untitledui.com/resources/file-icons\nimport { Document } from '@untitledui/file-icons/dist/solid/document.mjs';\nimport { Docx } from '@untitledui/file-icons/dist/solid/docx.mjs';\nimport { Html } from '@untitledui/file-icons/dist/solid/html.mjs';\nimport { Pdf } from '@untitledui/file-icons/dist/solid/pdf.mjs';\nimport { Pptx } from '@untitledui/file-icons/dist/solid/pptx.mjs';\nimport { Txt } from '@untitledui/file-icons/dist/solid/txt.mjs';\nimport { useConfig } from '../../core/config/config-context';\nimport { useCanMutate } from '../../core/permissions';\nimport {\n Badge,\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n toast,\n} from '../../ui';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '../../ui/primitives/alert-dialog';\nimport {\n createKnowledgeApi,\n isKnowledgeLinkKey,\n isKnowledgeListKey,\n KnowledgeApiError,\n knowledgePaths,\n type KnowledgeApi,\n} from './api';\nimport {\n getKnowledgeFormat,\n type KnowledgeFileIcon,\n type KnowledgeSource,\n type KnowledgeStatusTone,\n type RegisterKnowledgeSourceResult,\n} from './knowledge';\n\nconst STATUS_TONE_CLASSES: { [tone in KnowledgeStatusTone]: string } = {\n busy: 'fk:bg-amber-500/15 fk:text-amber-700 fk:dark:text-amber-400',\n error: 'fk:bg-destructive/15 fk:text-destructive',\n muted: 'fk:bg-muted fk:text-muted-foreground',\n ready: 'fk:bg-emerald-500/15 fk:text-emerald-700 fk:dark:text-emerald-400',\n};\n\nexport function useProjectKnowledge(): { api: KnowledgeApi | null; projectId: string | undefined } {\n const { currentProjectId } = useConfig();\n const api = useMemo(() => (currentProjectId ? createKnowledgeApi(currentProjectId) : null), [currentProjectId]);\n\n return { api, projectId: currentProjectId };\n}\n\n/** Drops every cached page of the document list, so the next visit fetches it afresh. */\nexport function invalidateKnowledgeLists(): Promise<unknown> {\n return mutateGlobal(isKnowledgeListKey, undefined, { revalidate: true });\n}\n\n/** Drops every cached link listing (a record's documents, a document's records) after a link changed. */\nexport function invalidateKnowledgeLinks(): Promise<unknown> {\n return mutateGlobal(isKnowledgeLinkKey, undefined, { revalidate: true });\n}\n\nexport function describeApiError(error: unknown, fallback: string): string {\n if (error instanceof KnowledgeApiError) {\n return error.message;\n }\n\n return error instanceof Error ? error.message : fallback;\n}\n\n/** What the user hears once a document was registered. */\nexport function announceRegistered(result: RegisterKnowledgeSourceResult, name: string): void {\n if (result.duplicate) {\n toast.info(`\"${result.source.title}\" is already in Knowledge.`);\n\n return;\n }\n\n toast.success(`Added ${name}. Indexing starts now.`);\n}\n\nexport function PageMessage({ children }: { children: string }): JSX.Element {\n return (\n <div className=\"fk:rounded-md fk:border fk:border-dashed fk:p-8 fk:text-center fk:text-sm fk:text-muted-foreground fk:corner-squircle\">\n {children}\n </div>\n );\n}\n\nexport function StatusBadge({ label, tone }: { label: string; tone: KnowledgeStatusTone }): JSX.Element {\n return (\n <Badge className={`fk:border-none fk:corner-squircle ${STATUS_TONE_CLASSES[tone]}`} variant=\"outline\">\n {tone === 'busy' ? <LoaderCircle className=\"fk:size-3 fk:animate-spin\" /> : null}\n {label}\n </Badge>\n );\n}\n\nconst FILE_ICONS: { [icon in KnowledgeFileIcon]: typeof Pdf } = {\n document: Document,\n docx: Docx,\n html: Html,\n pdf: Pdf,\n pptx: Pptx,\n txt: Txt,\n};\n\n/** The document's format as its file icon; the format's name is what a screen reader hears. */\nexport function KnowledgeTypeIcon({\n className = '',\n size = 24,\n source,\n}: {\n className?: string;\n size?: number;\n source: Pick<KnowledgeSource, 'kind' | 'mimeType'>;\n}): JSX.Element {\n const format = getKnowledgeFormat(source);\n const Icon = FILE_ICONS[format.icon];\n\n return (\n <span\n aria-label={format.label}\n className={`fk:flex fk:shrink-0 fk:items-center fk:justify-center ${className}`}\n data-knowledge-type={format.icon}\n role=\"img\"\n >\n <Icon size={size} />\n </span>\n );\n}\n\n/** The larger file icon of the document page and the record panel: the same icon as the list, at 40px. */\nexport function SourceIcon({ source }: { source: Pick<KnowledgeSource, 'kind' | 'mimeType'> }): JSX.Element {\n return <KnowledgeTypeIcon size={40} source={source} />;\n}\n\nexport function InfiniteScrollSentinel({ onVisible }: { onVisible: () => void }): JSX.Element {\n const sentinelRef = useRef<HTMLDivElement>(null);\n const onVisibleRef = useRef(onVisible);\n\n onVisibleRef.current = onVisible;\n\n useEffect(() => {\n const node = sentinelRef.current;\n\n if (!node) {\n return;\n }\n\n const observer = new IntersectionObserver((entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n onVisibleRef.current();\n }\n });\n\n observer.observe(node);\n\n return () => {\n observer.disconnect();\n };\n }, []);\n\n return <div aria-hidden className=\"fk:h-px\" ref={sentinelRef} />;\n}\n\n/**\n * The actions of one document, behind a three-dots button: open (lists\n * only), download the original file (web pages open their address instead)\n * and remove, behind one confirmation. The list and the document page share\n * it so the copy, the download link and the busy rules stay the same.\n */\nexport function SourceActionsMenu({\n isBusy = false,\n onOpen,\n onRemoved,\n source,\n trigger = 'row',\n}: {\n /** Another action on the document is in flight; removing waits for it. */\n isBusy?: boolean;\n /** Offered as the first item when given (the document page is already open). */\n onOpen?: () => void;\n /** The document is gone: drop it from the list, or leave its page. The list invalidation is done here. */\n onRemoved: () => void;\n source: KnowledgeSource;\n /** How the button looks: a quiet icon in a row or card, an outlined one next to page actions. */\n trigger?: 'row' | 'page';\n}): JSX.Element | null {\n const { api, projectId } = useProjectKnowledge();\n const canMutate = useCanMutate();\n const [isConfirmingRemoval, setIsConfirmingRemoval] = useState(false);\n const [isRemoving, setIsRemoving] = useState(false);\n\n if (!api || !projectId) {\n return null;\n }\n\n const knowledgeApi = api;\n\n async function remove(): Promise<void> {\n setIsRemoving(true);\n\n try {\n await knowledgeApi.deleteSource(source.id);\n toast.success(`Removed \"${source.title}\".`);\n setIsConfirmingRemoval(false);\n onRemoved();\n void invalidateKnowledgeLists();\n } catch (removeError) {\n toast.error(describeApiError(removeError, 'The document could not be removed.'));\n } finally {\n setIsRemoving(false);\n }\n }\n\n return (\n <>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n aria-label={`Actions for ${source.title}`}\n className={trigger === 'row' ? 'fk:size-8 fk:shrink-0 fk:text-muted-foreground' : undefined}\n data-knowledge-menu\n size=\"icon-sm\"\n variant={trigger === 'row' ? 'ghost' : 'outline'}\n >\n <EllipsisVerticalIcon className=\"fk:size-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {onOpen ? <DropdownMenuItem onSelect={onOpen}>Open</DropdownMenuItem> : null}\n {source.path ? (\n <DropdownMenuItem asChild>\n <a href={knowledgePaths(projectId).file(source.id)}>\n <DownloadIcon />\n Download\n </a>\n </DropdownMenuItem>\n ) : null}\n {source.originUrl ? (\n <DropdownMenuItem asChild>\n <a href={source.originUrl} rel=\"noreferrer\" target=\"_blank\">\n <ExternalLinkIcon />\n Open page\n </a>\n </DropdownMenuItem>\n ) : null}\n {onOpen || source.path || source.originUrl ? <DropdownMenuSeparator /> : null}\n <DropdownMenuItem\n disabled={!canMutate || isBusy}\n variant=\"destructive\"\n onSelect={() => setIsConfirmingRemoval(true)}\n >\n <Trash2Icon />\n Remove\n </DropdownMenuItem>\n {canMutate ? null : (\n <DropdownMenuLabel className=\"fk:max-w-56 fk:whitespace-normal fk:text-xs fk:font-normal fk:text-muted-foreground\">\n Your member role cannot remove documents.\n </DropdownMenuLabel>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n <AlertDialog open={isConfirmingRemoval} onOpenChange={setIsConfirmingRemoval}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Remove this document?</AlertDialogTitle>\n <AlertDialogDescription>\n \"{source.title}\" and its indexed passages are deleted for everyone. Answers the agent gave earlier keep\n their citations, but the document can no longer be opened.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isRemoving}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n disabled={isRemoving}\n onClick={(event: MouseEvent) => {\n event.preventDefault();\n void remove();\n }}\n >\n {isRemoving ? <LoaderCircle className=\"fk:animate-spin\" /> : null}\n Remove document\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/apps/knowledge/api.ts","../src/apps/knowledge/shared.tsx"],"names":["KnowledgeApiError","status","message","code","FetcherError","fetcher","url","response","knowledgePaths","projectId","basePath","entity","sourceId","jobId","from","to","recordId","options","limit","offset","search","params","trimmedSearch","isKnowledgeListKey","key","isKnowledgeLinkKey","readError","fallback","data","createKnowledgeApi","request","init","requestInit","register","body","file","tokenResponse","tokenData","put","title","filename","target","patch","STATUS_TONE_CLASSES","useProjectKnowledge","currentProjectId","useConfig","useMemo","invalidateKnowledgeLists","mutateGlobal","invalidateKnowledgeLinks","describeApiError","error","announceRegistered","result","name","toast","PageMessage","children","jsx","StatusBadge","label","tone","jsxs","Badge","LoaderCircle","FILE_ICONS","Document","Docx","Html","Pdf","Pptx","Txt","KnowledgeTypeIcon","className","size","source","format","getKnowledgeFormat","Icon","SourceIcon","InfiniteScrollSentinel","onVisible","sentinelRef","useRef","onVisibleRef","useEffect","node","observer","entries","entry","SourceActionsMenu","isBusy","onOpen","onRemoved","trigger","api","canMutate","useCanMutate","isConfirmingRemoval","setIsConfirmingRemoval","useState","isRemoving","setIsRemoving","knowledgeApi","remove","removeError","Fragment","DropdownMenu","DropdownMenuTrigger","Button","EllipsisVerticalIcon","DropdownMenuContent","DropdownMenuItem","DownloadIcon","ExternalLinkIcon","DropdownMenuSeparator","Trash2Icon","DropdownMenuLabel","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","event"],"mappings":"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","file":"chunk-3DT7IQLS.js","sourcesContent":["import { put } from '@vercel/blob/client';\nimport type {\n KnowledgeJob,\n KnowledgeLinkTarget,\n KnowledgeRecordRef,\n KnowledgeSource,\n KnowledgeSourcePatch,\n KnowledgeSourceStatus,\n RegisterKnowledgeSourceResult,\n} from './knowledge';\n\n/** The platform refused a knowledge request; `code` lets the UI tailor the message. */\nexport class KnowledgeApiError extends Error {\n code: string | null;\n status: number;\n\n constructor(status: number, message: string, code: string | null = null) {\n super(message);\n this.name = 'KnowledgeApiError';\n this.code = code;\n this.status = status;\n }\n}\n\nexport interface ProjectSpace {\n code: string;\n id: string;\n label: string;\n}\n\nexport interface KnowledgeApi {\n /** Uploads a document to the file store, then registers it; resolves once indexing is queued or the file was already there. */\n addFile: (_file: File, _options?: { signal?: AbortSignal }) => Promise<RegisterKnowledgeSourceResult>;\n addUrl: (_input: { title?: string; url: string }) => Promise<RegisterKnowledgeSourceResult>;\n /** Promotes a file the caller attached to a chat: the platform copies it into the knowledge folder. */\n addChatAttachment: (_input: { filename: string; url: string }) => Promise<RegisterKnowledgeSourceResult>;\n deleteSource: (_sourceId: string) => Promise<{ deleted: true }>;\n /** Attaches the document to a record, or to every record of an entity type; `linked` is false when it already was. */\n linkSource: (_sourceId: string, _target: KnowledgeLinkTarget) => Promise<{ linked: boolean }>;\n reingestSource: (_sourceId: string) => Promise<{ job: KnowledgeJob }>;\n unlinkSource: (_sourceId: string, _target: KnowledgeLinkTarget) => Promise<{ unlinked: boolean }>;\n updateSource: (_sourceId: string, _patch: KnowledgeSourcePatch) => Promise<{ source: KnowledgeSource }>;\n}\n\nexport class FetcherError extends Error {\n status: number;\n\n constructor(status: number, message = 'Request failed') {\n super(message);\n this.name = 'FetcherError';\n this.status = status;\n }\n}\n\nexport const fetcher = async <T>(url: string): Promise<T> => {\n const response = await fetch(url, { credentials: 'include' });\n\n if (!response.ok) {\n throw new FetcherError(response.status);\n }\n\n return (await response.json()) as T;\n};\n\nexport function knowledgePaths(projectId: string): {\n /** The documents attached to every record of an entity type. */\n entitySources: (_entity: string) => string;\n /** The original file of an uploaded document, served under its name. */\n file: (_sourceId: string) => string;\n job: (_jobId: string) => string;\n /** The records a document is attached to, and the entity types it applies to. */\n links: (_sourceId: string) => string;\n passages: (_sourceId: string, _options: { from: number; to: number }) => string;\n /** The documents attached to a record. */\n recordSources: (_record: KnowledgeRecordRef) => string;\n source: (_sourceId: string) => string;\n sources: (_options?: { limit?: number; offset?: number; search?: string; status?: KnowledgeSourceStatus }) => string;\n spaces: string;\n} {\n const basePath = `/api/flexkit/${projectId}/knowledge`;\n\n return {\n entitySources: (entity) => `${basePath}/entities/${encodeURIComponent(entity)}/sources`,\n file: (sourceId) => `${basePath}/sources/${encodeURIComponent(sourceId)}/file`,\n job: (jobId) => `${basePath}/jobs/${encodeURIComponent(jobId)}`,\n links: (sourceId) => `${basePath}/sources/${encodeURIComponent(sourceId)}/links`,\n passages: (sourceId, { from, to }) =>\n `${basePath}/sources/${encodeURIComponent(sourceId)}/passages?from=${String(from)}&to=${String(to)}`,\n recordSources: ({ entity, recordId }) =>\n `${basePath}/records/${encodeURIComponent(entity)}/${encodeURIComponent(recordId)}/sources`,\n source: (sourceId) => `${basePath}/sources/${encodeURIComponent(sourceId)}`,\n sources: (options = {}) => {\n const { limit = 25, offset = 0, search, status } = options;\n const params = new URLSearchParams({ limit: limit.toString(), offset: offset.toString() });\n const trimmedSearch = search?.trim();\n\n if (trimmedSearch) {\n params.set('q', trimmedSearch);\n }\n\n if (status) {\n params.set('status', status);\n }\n\n return `${basePath}/sources?${params.toString()}`;\n },\n spaces: `/api/flexkit/${projectId}/spaces`,\n };\n}\n\n/** Whether an SWR key is a page of the document list, whatever its filters. */\nexport function isKnowledgeListKey(key: unknown): boolean {\n return typeof key === 'string' && key.includes('/knowledge/sources?');\n}\n\n/** Whether an SWR key lists the documents of a record or an entity type, or the links of a document. */\nexport function isKnowledgeLinkKey(key: unknown): boolean {\n return (\n typeof key === 'string' &&\n (key.includes('/knowledge/records/') ||\n key.includes('/knowledge/entities/') ||\n (key.includes('/knowledge/sources/') && key.endsWith('/links')))\n );\n}\n\nasync function readError(response: Response, fallback: string): Promise<KnowledgeApiError> {\n let data: { code?: string; error?: string } = {};\n\n try {\n data = (await response.json()) as { code?: string; error?: string };\n } catch {\n // Non-JSON error bodies keep the fallback message.\n }\n\n return new KnowledgeApiError(response.status, data.error ? String(data.error) : fallback, data.code ?? null);\n}\n\nexport function createKnowledgeApi(projectId: string): KnowledgeApi {\n const basePath = `/api/flexkit/${projectId}/knowledge`;\n\n async function request<T>(url: string, init: RequestInit & { fallback: string }): Promise<T> {\n const { fallback, ...requestInit } = init;\n const response = await fetch(url, {\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...(requestInit.headers ?? {}) },\n ...requestInit,\n });\n\n if (!response.ok) {\n throw await readError(response, fallback);\n }\n\n return (await response.json()) as T;\n }\n\n function register(body: Record<string, unknown>): Promise<RegisterKnowledgeSourceResult> {\n return request<RegisterKnowledgeSourceResult>(`${basePath}/sources`, {\n body: JSON.stringify(body),\n fallback: 'The document could not be added.',\n method: 'POST',\n });\n }\n\n return {\n addFile: async (file, options) => {\n // The platform issues a token pinned to one pathname, type and size; the\n // browser writes the bytes to the store itself, so a 20 MB document never\n // crosses the API function body limit. Registration then hashes the blob.\n const tokenResponse = await fetch(`${basePath}/uploads`, {\n body: JSON.stringify({ filename: file.name, mediaType: file.type || null, sizeBytes: file.size }),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n signal: options?.signal,\n });\n\n if (!tokenResponse.ok) {\n throw await readError(tokenResponse, 'The file could not be uploaded.');\n }\n\n const tokenData = (await tokenResponse.json()) as { mediaType?: string; pathname?: string; token?: string };\n\n if (!tokenData.pathname || !tokenData.token || !tokenData.mediaType) {\n throw new KnowledgeApiError(tokenResponse.status, 'The file could not be uploaded.');\n }\n\n await put(tokenData.pathname, file, {\n abortSignal: options?.signal,\n access: 'public',\n contentType: tokenData.mediaType,\n token: tokenData.token,\n });\n\n return register({ kind: 'upload', pathname: tokenData.pathname });\n },\n addUrl: ({ title, url }) => register({ kind: 'url', url, ...(title ? { title } : {}) }),\n addChatAttachment: ({ filename, url }) => register({ filename, kind: 'chat-attachment', url }),\n deleteSource: (sourceId) =>\n request<{ deleted: true }>(`${basePath}/sources/${encodeURIComponent(sourceId)}`, {\n fallback: 'The document could not be removed.',\n method: 'DELETE',\n }),\n linkSource: (sourceId, target) =>\n request<{ linked: boolean }>(`${basePath}/sources/${encodeURIComponent(sourceId)}/links`, {\n body: JSON.stringify(target),\n fallback: 'The document could not be attached.',\n method: 'POST',\n }),\n reingestSource: (sourceId) =>\n request<{ job: KnowledgeJob }>(`${basePath}/sources/${encodeURIComponent(sourceId)}/reingest`, {\n fallback: 'The document could not be re-indexed.',\n method: 'POST',\n }),\n unlinkSource: (sourceId, { entity, recordId }) =>\n request<{ unlinked: boolean }>(\n `${basePath}/sources/${encodeURIComponent(sourceId)}/links/${encodeURIComponent(entity)}${\n recordId === undefined ? '' : `/${encodeURIComponent(recordId)}`\n }`,\n { fallback: 'The document could not be detached.', method: 'DELETE' }\n ),\n updateSource: (sourceId, patch) =>\n request<{ source: KnowledgeSource }>(`${basePath}/sources/${encodeURIComponent(sourceId)}`, {\n body: JSON.stringify(patch),\n fallback: 'The document could not be updated.',\n method: 'PATCH',\n }),\n };\n}\n","import type { JSX, MouseEvent } from 'react';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { DownloadIcon, EllipsisVerticalIcon, ExternalLinkIcon, LoaderCircle, Trash2Icon } from 'lucide-react';\nimport { mutate as mutateGlobal } from 'swr';\n// File type icons: Untitled UI's free file icons, Solid variant. The set is\n// published as the MIT package `@untitledui/file-icons`; the page below shows\n// every icon and offers each as SVG or JSX should another format need one.\n// https://www.untitledui.com/resources/file-icons\nimport { Document } from '@untitledui/file-icons/dist/solid/document.mjs';\nimport { Docx } from '@untitledui/file-icons/dist/solid/docx.mjs';\nimport { Html } from '@untitledui/file-icons/dist/solid/html.mjs';\nimport { Pdf } from '@untitledui/file-icons/dist/solid/pdf.mjs';\nimport { Pptx } from '@untitledui/file-icons/dist/solid/pptx.mjs';\nimport { Txt } from '@untitledui/file-icons/dist/solid/txt.mjs';\nimport { useConfig } from '../../core/config/config-context';\nimport { useCanMutate } from '../../core/permissions';\nimport {\n Badge,\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n toast,\n} from '../../ui';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '../../ui/primitives/alert-dialog';\nimport {\n createKnowledgeApi,\n isKnowledgeLinkKey,\n isKnowledgeListKey,\n KnowledgeApiError,\n knowledgePaths,\n type KnowledgeApi,\n} from './api';\nimport {\n getKnowledgeFormat,\n type KnowledgeFileIcon,\n type KnowledgeSource,\n type KnowledgeStatusTone,\n type RegisterKnowledgeSourceResult,\n} from './knowledge';\n\nconst STATUS_TONE_CLASSES: { [tone in KnowledgeStatusTone]: string } = {\n busy: 'fk:bg-amber-500/15 fk:text-amber-700 fk:dark:text-amber-400',\n error: 'fk:bg-destructive/15 fk:text-destructive',\n muted: 'fk:bg-muted fk:text-muted-foreground',\n ready: 'fk:bg-emerald-500/15 fk:text-emerald-700 fk:dark:text-emerald-400',\n};\n\nexport function useProjectKnowledge(): { api: KnowledgeApi | null; projectId: string | undefined } {\n const { currentProjectId } = useConfig();\n const api = useMemo(() => (currentProjectId ? createKnowledgeApi(currentProjectId) : null), [currentProjectId]);\n\n return { api, projectId: currentProjectId };\n}\n\n/** Drops every cached page of the document list, so the next visit fetches it afresh. */\nexport function invalidateKnowledgeLists(): Promise<unknown> {\n return mutateGlobal(isKnowledgeListKey, undefined, { revalidate: true });\n}\n\n/** Drops every cached link listing (a record's documents, a document's records) after a link changed. */\nexport function invalidateKnowledgeLinks(): Promise<unknown> {\n return mutateGlobal(isKnowledgeLinkKey, undefined, { revalidate: true });\n}\n\nexport function describeApiError(error: unknown, fallback: string): string {\n if (error instanceof KnowledgeApiError) {\n return error.message;\n }\n\n return error instanceof Error ? error.message : fallback;\n}\n\n/** What the user hears once a document was registered. */\nexport function announceRegistered(result: RegisterKnowledgeSourceResult, name: string): void {\n if (result.duplicate) {\n toast.info(`\"${result.source.title}\" is already in Knowledge.`);\n\n return;\n }\n\n toast.success(`Added ${name}. Indexing starts now.`);\n}\n\nexport function PageMessage({ children }: { children: string }): JSX.Element {\n return (\n <div className=\"fk:rounded-md fk:border fk:border-dashed fk:p-8 fk:text-center fk:text-sm fk:text-muted-foreground fk:corner-squircle\">\n {children}\n </div>\n );\n}\n\nexport function StatusBadge({ label, tone }: { label: string; tone: KnowledgeStatusTone }): JSX.Element {\n return (\n <Badge className={`fk:border-none fk:corner-squircle ${STATUS_TONE_CLASSES[tone]}`} variant=\"outline\">\n {tone === 'busy' ? <LoaderCircle className=\"fk:size-3 fk:animate-spin\" /> : null}\n {label}\n </Badge>\n );\n}\n\nconst FILE_ICONS: { [icon in KnowledgeFileIcon]: typeof Pdf } = {\n document: Document,\n docx: Docx,\n html: Html,\n pdf: Pdf,\n pptx: Pptx,\n txt: Txt,\n};\n\n/** The document's format as its file icon; the format's name is what a screen reader hears. */\nexport function KnowledgeTypeIcon({\n className = '',\n size = 24,\n source,\n}: {\n className?: string;\n size?: number;\n source: Pick<KnowledgeSource, 'kind' | 'mimeType'>;\n}): JSX.Element {\n const format = getKnowledgeFormat(source);\n const Icon = FILE_ICONS[format.icon];\n\n return (\n <span\n aria-label={format.label}\n className={`fk:flex fk:shrink-0 fk:items-center fk:justify-center ${className}`}\n data-knowledge-type={format.icon}\n role=\"img\"\n >\n <Icon size={size} />\n </span>\n );\n}\n\n/** The larger file icon of the document page and the record panel: the same icon as the list, at 40px. */\nexport function SourceIcon({ source }: { source: Pick<KnowledgeSource, 'kind' | 'mimeType'> }): JSX.Element {\n return <KnowledgeTypeIcon size={40} source={source} />;\n}\n\nexport function InfiniteScrollSentinel({ onVisible }: { onVisible: () => void }): JSX.Element {\n const sentinelRef = useRef<HTMLDivElement>(null);\n const onVisibleRef = useRef(onVisible);\n\n onVisibleRef.current = onVisible;\n\n useEffect(() => {\n const node = sentinelRef.current;\n\n if (!node) {\n return;\n }\n\n const observer = new IntersectionObserver((entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n onVisibleRef.current();\n }\n });\n\n observer.observe(node);\n\n return () => {\n observer.disconnect();\n };\n }, []);\n\n return <div aria-hidden className=\"fk:h-px\" ref={sentinelRef} />;\n}\n\n/**\n * The actions of one document, behind a three-dots button: open (lists\n * only), download the original file (web pages open their address instead)\n * and remove, behind one confirmation. The list and the document page share\n * it so the copy, the download link and the busy rules stay the same.\n */\nexport function SourceActionsMenu({\n isBusy = false,\n onOpen,\n onRemoved,\n source,\n trigger = 'row',\n}: {\n /** Another action on the document is in flight; removing waits for it. */\n isBusy?: boolean;\n /** Offered as the first item when given (the document page is already open). */\n onOpen?: () => void;\n /** The document is gone: drop it from the list, or leave its page. The list invalidation is done here. */\n onRemoved: () => void;\n source: KnowledgeSource;\n /** How the button looks: a quiet icon in a row or card, an outlined one next to page actions. */\n trigger?: 'row' | 'page';\n}): JSX.Element | null {\n const { api, projectId } = useProjectKnowledge();\n const canMutate = useCanMutate();\n const [isConfirmingRemoval, setIsConfirmingRemoval] = useState(false);\n const [isRemoving, setIsRemoving] = useState(false);\n\n if (!api || !projectId) {\n return null;\n }\n\n const knowledgeApi = api;\n\n async function remove(): Promise<void> {\n setIsRemoving(true);\n\n try {\n await knowledgeApi.deleteSource(source.id);\n toast.success(`Removed \"${source.title}\".`);\n setIsConfirmingRemoval(false);\n onRemoved();\n void invalidateKnowledgeLists();\n } catch (removeError) {\n toast.error(describeApiError(removeError, 'The document could not be removed.'));\n } finally {\n setIsRemoving(false);\n }\n }\n\n return (\n <>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n aria-label={`Actions for ${source.title}`}\n className={trigger === 'row' ? 'fk:size-8 fk:shrink-0 fk:text-muted-foreground' : undefined}\n data-knowledge-menu\n size=\"icon-sm\"\n variant={trigger === 'row' ? 'ghost' : 'outline'}\n >\n <EllipsisVerticalIcon className=\"fk:size-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {onOpen ? <DropdownMenuItem onSelect={onOpen}>Open</DropdownMenuItem> : null}\n {source.path ? (\n <DropdownMenuItem asChild>\n <a href={knowledgePaths(projectId).file(source.id)}>\n <DownloadIcon />\n Download\n </a>\n </DropdownMenuItem>\n ) : null}\n {source.originUrl ? (\n <DropdownMenuItem asChild>\n <a href={source.originUrl} rel=\"noreferrer\" target=\"_blank\">\n <ExternalLinkIcon />\n Open page\n </a>\n </DropdownMenuItem>\n ) : null}\n {onOpen || source.path || source.originUrl ? <DropdownMenuSeparator /> : null}\n <DropdownMenuItem\n disabled={!canMutate || isBusy}\n variant=\"destructive\"\n onSelect={() => setIsConfirmingRemoval(true)}\n >\n <Trash2Icon />\n Remove\n </DropdownMenuItem>\n {canMutate ? null : (\n <DropdownMenuLabel className=\"fk:max-w-56 fk:whitespace-normal fk:text-xs fk:font-normal fk:text-muted-foreground\">\n Your member role cannot remove documents.\n </DropdownMenuLabel>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n <AlertDialog open={isConfirmingRemoval} onOpenChange={setIsConfirmingRemoval}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Remove this document?</AlertDialogTitle>\n <AlertDialogDescription>\n \"{source.title}\" and its indexed passages are deleted for everyone. Answers the agent gave earlier keep\n their citations, but the document can no longer be opened.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isRemoving}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n disabled={isRemoving}\n onClick={(event: MouseEvent) => {\n event.preventDefault();\n void remove();\n }}\n >\n {isRemoving ? <LoaderCircle className=\"fk:animate-spin\" /> : null}\n Remove document\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </>\n );\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import'./index.css';import {e,d,a,c,b as b$1}from'./chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import'./index.css';import {e,d,a,c,b as b$1}from'./chunk-KL2NENPM.js';import {f}from'./chunk-OXJJX6QV.js';import {r,s,i,k,j}from'./chunk-NHNJNPF5.js';import {b}from'./chunk-YGG43LHF.js';import {useState,useRef,useMemo,useEffect,useCallback}from'react';import {uniqBy,prop}from'ramda';import {gql,NetworkStatus}from'@apollo/client';import {useQuery}from'@apollo/client/react';var q=null,Y=new Set,St=[],N=new Set,W=new Set,X=new Set;function $t(t,e){if(t==="_asset"||t==="_assets")return `Get${r(b.plural)}`;let r$1=e.find(o=>o.plural===t),n=e.find(o=>o.name===t),i=r$1?.plural??n?.plural??t;return `Get${r(i)}`}function Qt(t){return N.add(t),()=>{N.delete(t);}}function Pt(t){return W.add(t),()=>{W.delete(t);}}function Tt(t){return X.add(t),()=>{X.delete(t);}}function zt(t,e,r){let n=new Set(r.filter(Boolean));if(n.size>0)for(let i of W)i(e,n);return qt(t,e)}function Yt(t,e){let r=e.filter(n=>!!n._id);if(r.length!==0)for(let n of X)n(t,r);}function qt(t,e){return Y.add(e),new Promise((r,n)=>{St.push({resolve:r,reject:n}),q&&clearTimeout(q),q=setTimeout(()=>{let i=new Set(Y),o=St.splice(0);Y.clear(),q=null,Promise.all([...N].map(s=>Promise.resolve(s(i)))).then(()=>{for(let{resolve:s}of o)s();}).catch(s=>{console.error("Error refreshing entity lists:",s);for(let{reject:h}of o)h(s);});},50);})}function ie({entityNamePlural:t,schema:e$1,scope:r$1,variables:n,isForm:i$1,selection:o="full",includeCount:s$1=true,fetchPolicy:h}){let[b,l]=useState({count:0,results:[]}),[_,O]=useState(false),[U,tt]=useState(false),[et,kt]=useState(null),v=useRef(false),P=useRef(false),m=useRef(0),T=useRef(null),M=useRef(null),c$1=f(),A=`${t}Total`,wt=s(e$1,t),V=n?.where===void 0&&(wt?.spaces?.length??0)===0&&(et?.field!==A||et.schema!==e$1)?"total":"aggregate",jt=useMemo(()=>gql(i(t,r$1,e$1,{selection:o,countMode:V,includeCount:s$1,defaultScope:c$1}).query),[t,r$1,e$1,o,V,s$1,c$1]),rt=useMemo(()=>gql(i(t,r$1,e$1,{selection:o,includeCount:false,defaultScope:c$1}).query),[t,r$1,e$1,o,c$1]),{schemaErrorMessage:J,setSchemaErrorMessage:G}=e(),{loading:I,data:E,fetchMore:nt,refetch:st,error:ot,networkStatus:x}=useQuery(jt,{variables:n,notifyOnNetworkStatusChange:true,fetchPolicy:h}),it=useRef(nt),K=useRef(st),ut=useRef(rt),ct=useRef(x),at=useRef(n);it.current=nt,K.current=st,ut.current=rt,at.current=n;let H=s$1&&d(ot,A),lt=V==="total"&&H,R=H?void 0:ot,k=H&&!E?.[t],C=a(R),S=c(R),Dt=C?.statusCode===403&&b$1(C.bodyText)?.code==="PROJECT_HIBERNATED",{isProjectDisabled:_t,isProjectReadOnly:At}=(()=>{if(C?.statusCode===403){let u=b$1(C.bodyText);if(u&&typeof u.code=="string"){if(u.code==="PROJECT_PAUSED"||u.code==="PROJECT_HIBERNATED")return {isProjectDisabled:true,isProjectReadOnly:false};if(u.code==="READ_ONLY_MODE")return {isProjectDisabled:false,isProjectReadOnly:true}}return {isProjectDisabled:true,isProjectReadOnly:false}}return {isProjectDisabled:false,isProjectReadOnly:false}})();useEffect(()=>{lt&&kt({field:A,schema:e$1});},[e$1,lt,A]);let It=useCallback(u=>{if(v.current||P.current)return;v.current=true,O(true);let{limit:d}=u.variables,y=m.current;it.current({...u,query:ut.current,variables:{...at.current,...u.variables,offset:y,limit:d}}).then(({data:Q})=>{let f=D({data:Q,entityNamePlural:t,isForm:i$1,schema:e$1,scope:r$1,defaultScope:c$1}),p=f.results.length;m.current=y+(p===0?0:Math.min(p,d)),l(a=>{let L=uniqBy(prop("_id"),[...a.results,...f.results]);return L.length===a.results.length?{count:a.results.length,results:a.results}:{count:f.count||a.count,results:L}});}).catch(Q=>{console.error("Error fetching more data:",Q);}).finally(()=>{v.current=false,O(false);});},[c$1,t,i$1,e$1,r$1]),Ct=useCallback(u=>{if(P.current)return Promise.resolve();let d=u?.preserve===true;return P.current=true,v.current=false,O(false),d||(T.current=null,M.current=null,m.current=0,tt(true),l({count:0,results:[]})),K.current().then(({data:y})=>{let Q=JSON.stringify({entityNamePlural:t,scope:r$1,selection:o,includeCount:s$1,variables:n}),f=D({data:y,entityNamePlural:t,isForm:i$1,schema:e$1,scope:r$1,defaultScope:c$1});T.current=Q,M.current=null,m.current=B(n)+f.results.length,l(f);}).catch(y=>{console.error("Error reloading data:",y);}).finally(()=>{P.current=false,tt(false);})},[c$1,t,i$1,e$1,r$1,o,s$1,n]);return useEffect(()=>{if(S){G(S);return}E&&J&&!R&&G(null);},[E,R,J,S,G]),useEffect(()=>{if(R||S||k)return;let u=JSON.stringify({entityNamePlural:t,scope:r$1,selection:o,includeCount:s$1,variables:n});if(T.current===u)return;if(I&&M.current!==u){M.current=u,m.current=0,l({count:0,results:[]});return}if(I)return;let d=D({data:E,entityNamePlural:t,isForm:i$1,schema:e$1,scope:r$1,defaultScope:c$1});T.current=u,M.current=null,m.current=B(n)+d.results.length,l(d);},[c$1,E,R,t,i$1,I,k,e$1,S,r$1,o,s$1,n]),useEffect(()=>{let u=ct.current;if(ct.current=x,R||S||P.current||k||u!==NetworkStatus.refetch||x!==NetworkStatus.ready||!E)return;let d=JSON.stringify({entityNamePlural:t,scope:r$1,selection:o,includeCount:s$1,variables:n}),y=D({data:E,entityNamePlural:t,isForm:i$1,schema:e$1,scope:r$1,defaultScope:c$1});T.current=d,M.current=null,m.current=B(n)+y.results.length,l(y);},[c$1,E,R,t,i$1,k,x,e$1,S,r$1,o,s$1,n]),useEffect(()=>{if(i$1)return;let u=`Get${r(t)}`,d=Qt(f=>{if(!(!f.has(u)||v.current||P.current))return K.current().then(({data:p})=>{let a=JSON.stringify({entityNamePlural:t,scope:r$1,selection:o,includeCount:s$1,variables:n}),L=D({data:p,entityNamePlural:t,isForm:i$1,schema:e$1,scope:r$1,defaultScope:c$1});T.current=a,M.current=null,m.current=B(n)+L.results.length,l(L);}).catch(p=>{console.error("Error soft-refreshing entity list:",p);})}),y=Pt((f,p)=>{f===u&&l(a=>{let L=a.results.filter(dt=>{let yt=typeof dt._id=="string"?dt._id:void 0;return !yt||!p.has(yt)}),ft=a.results.length-L.length;return ft===0?a:{count:Math.max(0,a.count-ft),results:L}});}),Q=Tt((f,p)=>{f===u&&l(a=>Vt(a,p,n?.sort));});return ()=>{d(),y(),Q();}},[c$1,t,i$1,e$1,r$1,o,s$1,n]),{isLoading:I&&x!==NetworkStatus.refetch||U||k,isLoadingMore:_,fetchMore:It,reload:Ct,count:b.count,data:b.results,isProjectDisabled:_t,isProjectHibernated:Dt,isProjectReadOnly:At,schemaErrorMessage:J}}function B(t){let e=t?.offset;return typeof e=="number"&&Number.isFinite(e)?e:0}function D(t){let e=t.entityNamePlural;return t.data?.[e]?t.isForm?k(t.entityNamePlural,t.scope,t.data,t.schema,t.defaultScope):j(t.entityNamePlural,t.scope,t.data,t.schema):{count:0,results:[]}}function Vt(t,e,r){let n=new Map(e.map(s=>[s._id,s])),i=false,o=t.results.map(s=>{let h=typeof s._id=="string"?s._id:void 0;if(!h)return s;let b=n.get(h);return b?(i=true,{...s,...b.attributes}):s});return i?{count:t.count,results:Jt(o,r)}:t}function Jt(t,e){if(!Array.isArray(e)||e.length===0)return t;let[r]=e;if(!r||typeof r!="object")return t;let[n]=Object.entries(r),[i,o]=n??[];if(!i||o!=="ASC"&&o!=="DESC")return t;let s=o==="DESC"?-1:1;return [...t].sort((h,b)=>{let l=h[i],_=b[i],O=typeof l=="string"?l:"",U=typeof _=="string"?_:"";return O.localeCompare(U)*s})}export{$t as a,zt as b,Yt as c,qt as d,ie as e};//# sourceMappingURL=chunk-3V7VAQBP.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-3V7VAQBP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graphql-client/refetch-entity-lists.ts","../src/graphql-client/use-entity-query.ts"],"names":["refetchTimer","pendingQueryNames","pendingResolvers","listeners","removalListeners","patchListeners","getEntityListQueryName","entityNameOrPlural","schema","getOperationEntityName","assetSchema","byPlural","entity","byName","plural","subscribeEntityListRefetch","listener","subscribeEntityListRemoval","subscribeEntityListPatch","scheduleEntityListRemoval","apolloClient","queryName","entityIds","ids","scheduleEntityListRefetch","scheduleEntityListPatch","patches","nextPatches","patch","_apolloClient","resolve","reject","names","resolvers","finish","error","fail","useEntityQuery","entityNamePlural","scope","variables","isForm","selection","includeCount","fetchPolicy","result","setResult","useState","isLoadingMore","setIsLoadingMore","isReloading","setIsReloading","unsupportedTotalCount","setUnsupportedTotalCount","isLoadingMoreRef","useRef","isReloadingRef","nextOffsetRef","syncedQueryKeyRef","pendingQueryKeyRef","defaultScope","useDefaultScope","totalCountField","entitySchema","getEntitySchema","countMode","queryDocument","useMemo","gql","getEntityQuery","fetchMoreDocument","schemaErrorMessage","setSchemaErrorMessage","useGraphQLError","isLoading","data","fetchNextPage","refetch","networkStatus","useQuery","fetchNextPageRef","refetchRef","fetchMoreDocumentRef","previousNetworkStatusRef","variablesRef","isMissingTotalCountField","isMissingGraphQLFieldError","shouldFallbackToAggregate","effectiveError","isTotalCountFallbackLoading","serverError","getServerError","schemaMismatchMessage","getGraphQLSchemaMismatchMessage","isProjectHibernated","parseErrorBody","isProjectDisabled","isProjectReadOnly","responseBody","useEffect","fetchMore","useCallback","args","limit","offset","res","mappedFetchMoreResults","mapResults","pageLength","prevRows","merged","uniqBy","prop","fetchError","reload","options","preserve","queryKey","mapped","getVariablesOffset","previousStatus","NetworkStatus","listQueryName","unsubscribeRefetch","queryNames","unsubscribeRemoval","prev","nextResults","row","rowId","removedCount","unsubscribePatch","applyEntityListPatches","mapQueryResultForFormFields","mapQueryResult","sort","patchById","didPatch","sortEntityListResults","results","primarySort","primarySortEntry","sortField","sortDirection","direction","left","right","leftValue","rightValue","leftText","rightText"],"mappings":"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","file":"chunk-NPO7ISWV.js","sourcesContent":["import type { ApolloClient } from '@apollo/client';\nimport type { Schema } from '../core/types';\nimport { assetSchema } from '../entities/assets-schema';\nimport { getOperationEntityName } from './queries';\n\ntype EntityListRefreshListener = (queryNames: ReadonlySet<string>) => void | Promise<void>;\ntype EntityListRemovalListener = (queryName: string, entityIds: ReadonlySet<string>) => void;\ntype EntityListPatchListener = (queryName: string, patches: EntityListRowPatch[]) => void;\n\nexport type EntityListRowPatch = {\n _id: string;\n attributes: { [key: string]: string };\n};\n\nlet refetchTimer: ReturnType<typeof setTimeout> | null = null;\nconst pendingQueryNames = new Set<string>();\nconst pendingResolvers: Array<{ resolve: () => void; reject: (error: unknown) => void }> = [];\nconst listeners = new Set<EntityListRefreshListener>();\nconst removalListeners = new Set<EntityListRemovalListener>();\nconst patchListeners = new Set<EntityListPatchListener>();\n\nexport function getEntityListQueryName(entityNameOrPlural: string, schema: Schema): string {\n if (entityNameOrPlural === '_asset' || entityNameOrPlural === '_assets') {\n return `Get${getOperationEntityName(assetSchema.plural)}`;\n }\n\n const byPlural = schema.find((entity) => entity.plural === entityNameOrPlural);\n const byName = schema.find((entity) => entity.name === entityNameOrPlural);\n const plural = byPlural?.plural ?? byName?.plural ?? entityNameOrPlural;\n\n return `Get${getOperationEntityName(plural)}`;\n}\n\n/**\n * Subscribe to soft list refreshes. Listeners should refetch their own query and\n * remap local paginated state (useEntityQuery ignores Apollo cache writes after sync).\n */\nexport function subscribeEntityListRefetch(listener: EntityListRefreshListener): () => void {\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n}\n\n/**\n * Subscribe to optimistic row removals (e.g. after delete) before the soft-refetch lands.\n */\nexport function subscribeEntityListRemoval(listener: EntityListRemovalListener): () => void {\n removalListeners.add(listener);\n\n return () => {\n removalListeners.delete(listener);\n };\n}\n\n/**\n * Subscribe to in-place row patches (e.g. tag connect/disconnect) without a full list refetch.\n */\nexport function subscribeEntityListPatch(listener: EntityListPatchListener): () => void {\n patchListeners.add(listener);\n\n return () => {\n patchListeners.delete(listener);\n };\n}\n\n/**\n * Immediately drop rows from mounted lists, then soft-refetch to sync counts/pages.\n */\nexport function scheduleEntityListRemoval(\n apolloClient: ApolloClient,\n queryName: string,\n entityIds: string[]\n): Promise<void> {\n const ids = new Set(entityIds.filter(Boolean));\n\n if (ids.size > 0) {\n for (const listener of removalListeners) {\n listener(queryName, ids);\n }\n }\n\n return scheduleEntityListRefetch(apolloClient, queryName);\n}\n\n/**\n * Patch mounted list rows in place. Use when a mutation cannot change list cardinality\n * (e.g. tag connect/disconnect) so we avoid a full GetAssets soft-refetch.\n */\nexport function scheduleEntityListPatch(queryName: string, patches: EntityListRowPatch[]): void {\n const nextPatches = patches.filter((patch) => Boolean(patch._id));\n\n if (nextPatches.length === 0) {\n return;\n }\n\n for (const listener of patchListeners) {\n listener(queryName, nextPatches);\n }\n}\n\n/**\n * Ask mounted entity lists to soft-refresh. Debounced so batch deletes coalesce.\n */\nexport function scheduleEntityListRefetch(_apolloClient: ApolloClient, queryName: string): Promise<void> {\n pendingQueryNames.add(queryName);\n\n return new Promise<void>((resolve, reject) => {\n pendingResolvers.push({ resolve, reject });\n\n if (refetchTimer) {\n clearTimeout(refetchTimer);\n }\n\n refetchTimer = setTimeout(() => {\n const names = new Set(pendingQueryNames);\n const resolvers = pendingResolvers.splice(0);\n pendingQueryNames.clear();\n refetchTimer = null;\n\n void Promise.all([...listeners].map((listener) => Promise.resolve(listener(names))))\n .then(() => {\n for (const { resolve: finish } of resolvers) {\n finish();\n }\n })\n .catch((error: unknown) => {\n console.error('Error refreshing entity lists:', error);\n\n for (const { reject: fail } of resolvers) {\n fail(error);\n }\n });\n }, 50);\n });\n}\n","import { useDefaultScope } from '../core/default-scope';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { prop, uniqBy } from 'ramda';\nimport { gql, NetworkStatus } from '@apollo/client';\nimport type { OperationVariables } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport {\n getGraphQLSchemaMismatchMessage,\n getServerError,\n isMissingGraphQLFieldError,\n parseErrorBody,\n} from './error-utils';\nimport {\n getEntityQuery,\n getEntitySchema,\n getOperationEntityName,\n mapQueryResult,\n mapQueryResultForFormFields,\n} from './queries';\nimport {\n subscribeEntityListPatch,\n subscribeEntityListRefetch,\n subscribeEntityListRemoval,\n type EntityListRowPatch,\n} from './refetch-entity-lists';\nimport { useGraphQLError } from './graphql-context';\nimport type {\n EntityQueryAggregate,\n EntityQueryResults,\n FormEntityItem,\n MappedEntityQueryResults,\n MappedEntityItem,\n MappedFormEntityQueryResults,\n UseEntityQueryParams,\n ImageValue,\n} from './types';\n\ntype FetchMoreOptions = {\n // `offset` is accepted for call-site compatibility but overridden by nextOffsetRef.\n // `where`/`sort` are inherited from the active query unless overridden here.\n variables: OperationVariables & { offset: number; limit: number };\n};\ntype Results = (MappedEntityQueryResults | MappedFormEntityQueryResults) | { count: 0; results: [] };\n\nexport function useEntityQuery({\n entityNamePlural,\n schema,\n scope,\n variables,\n isForm,\n selection = 'full',\n includeCount = true,\n fetchPolicy,\n}: UseEntityQueryParams): {\n count: number;\n data: MappedEntityItem[] | FormEntityItem[] | ImageValue[] | undefined;\n fetchMore: (args: FetchMoreOptions) => void;\n isLoading: boolean;\n isLoadingMore: boolean;\n isProjectDisabled: boolean;\n /** Disabled because the Free project is hibernated (also sets isProjectDisabled). */\n isProjectHibernated: boolean;\n isProjectReadOnly: boolean;\n reload: (options?: { preserve?: boolean }) => Promise<void>;\n schemaErrorMessage: string | null;\n} {\n const [result, setResult] = useState<Results>({\n count: 0,\n results: [],\n });\n const [isLoadingMore, setIsLoadingMore] = useState(false);\n const [isReloading, setIsReloading] = useState(false);\n const [unsupportedTotalCount, setUnsupportedTotalCount] = useState<{\n field: string;\n schema: UseEntityQueryParams['schema'];\n } | null>(null);\n const isLoadingMoreRef = useRef(false);\n const isReloadingRef = useRef(false);\n // Next offset for fetchMore — advanced by each requested page window, not by the\n // deduplicated row count. Using unique rows.length as offset collapses when pages\n // overlap (unstable sorts / tied timestamps) into irregular steps like 25→35→42.\n const nextOffsetRef = useRef(0);\n // Tracks the query identity we last synced into local result state.\n // fetchMore updates Apollo `data` without changing this identity; syncing those\n // updates would wipe accumulated pages and retrigger infinite load-more.\n // Must include entity/scope — variables alone collide across entity navigations.\n const syncedQueryKeyRef = useRef<string | null>(null);\n const pendingQueryKeyRef = useRef<string | null>(null);\n const defaultScope = useDefaultScope();\n const totalCountField = `${entityNamePlural}Total`;\n const entitySchema = getEntitySchema(schema, entityNamePlural);\n const canUseTotalCount =\n variables?.where === undefined &&\n (entitySchema?.spaces?.length ?? 0) === 0 &&\n (unsupportedTotalCount?.field !== totalCountField || unsupportedTotalCount.schema !== schema);\n const countMode = canUseTotalCount ? 'total' : 'aggregate';\n const queryDocument = useMemo(\n () =>\n gql(getEntityQuery(entityNamePlural, scope, schema, { selection, countMode, includeCount, defaultScope }).query),\n [entityNamePlural, scope, schema, selection, countMode, includeCount, defaultScope]\n );\n // fetchMore pages skip the top-level aggregate count (a filtered label scan\n // on the server); the total from the first page still stands.\n const fetchMoreDocument = useMemo(\n () => gql(getEntityQuery(entityNamePlural, scope, schema, { selection, includeCount: false, defaultScope }).query),\n [entityNamePlural, scope, schema, selection, defaultScope]\n );\n const { schemaErrorMessage, setSchemaErrorMessage } = useGraphQLError();\n const {\n loading: isLoading,\n data,\n fetchMore: fetchNextPage,\n refetch,\n error,\n networkStatus,\n } = useQuery<EntityQueryResults & EntityQueryAggregate>(queryDocument, {\n variables,\n notifyOnNetworkStatusChange: true,\n fetchPolicy,\n });\n const fetchNextPageRef = useRef(fetchNextPage);\n const refetchRef = useRef(refetch);\n const fetchMoreDocumentRef = useRef(fetchMoreDocument);\n const previousNetworkStatusRef = useRef(networkStatus);\n const variablesRef = useRef(variables);\n fetchNextPageRef.current = fetchNextPage;\n refetchRef.current = refetch;\n fetchMoreDocumentRef.current = fetchMoreDocument;\n variablesRef.current = variables;\n\n // Parse 403 error response to determine the specific error code\n const isMissingTotalCountField = includeCount && isMissingGraphQLFieldError(error, totalCountField);\n const shouldFallbackToAggregate = countMode === 'total' && isMissingTotalCountField;\n const effectiveError = isMissingTotalCountField ? undefined : error;\n const isTotalCountFallbackLoading = isMissingTotalCountField && !data?.[entityNamePlural];\n const serverError = getServerError(effectiveError);\n const schemaMismatchMessage = getGraphQLSchemaMismatchMessage(effectiveError);\n\n const isProjectHibernated =\n serverError?.statusCode === 403 &&\n parseErrorBody<{ code?: string }>(serverError.bodyText)?.code === 'PROJECT_HIBERNATED';\n\n const { isProjectDisabled, isProjectReadOnly } = (() => {\n if (serverError?.statusCode === 403) {\n const responseBody = parseErrorBody<{ code?: string }>(serverError.bodyText);\n\n if (responseBody && typeof responseBody.code === 'string') {\n if (responseBody.code === 'PROJECT_PAUSED' || responseBody.code === 'PROJECT_HIBERNATED') {\n return {\n isProjectDisabled: true,\n isProjectReadOnly: false,\n };\n }\n\n if (responseBody.code === 'READ_ONLY_MODE') {\n return {\n isProjectDisabled: false,\n isProjectReadOnly: true,\n };\n }\n }\n\n return {\n isProjectDisabled: true,\n isProjectReadOnly: false,\n };\n }\n\n return {\n isProjectDisabled: false,\n isProjectReadOnly: false,\n };\n })();\n\n useEffect(() => {\n if (!shouldFallbackToAggregate) {\n return;\n }\n\n setUnsupportedTotalCount({ field: totalCountField, schema });\n }, [schema, shouldFallbackToAggregate, totalCountField]);\n\n const fetchMore = useCallback(\n (args: FetchMoreOptions): void => {\n if (isLoadingMoreRef.current || isReloadingRef.current) {\n return;\n }\n\n isLoadingMoreRef.current = true;\n setIsLoadingMore(true);\n\n const { limit } = args.variables;\n const offset = nextOffsetRef.current;\n\n fetchNextPageRef\n .current({\n ...args,\n query: fetchMoreDocumentRef.current,\n variables: {\n // fetchMore uses a count-free document, so Apollo will not inherit\n // the original operation's where/sort unless we pass them again.\n ...variablesRef.current,\n ...args.variables,\n offset,\n limit,\n },\n })\n .then(({ data: res }) => {\n const mappedFetchMoreResults = mapResults({\n data: res,\n entityNamePlural,\n isForm,\n schema,\n scope,\n defaultScope,\n });\n // Advance by the fetched page window (capped at limit), not by how many unique\n // rows survived client-side merge. Cap protects against Apollo returning a\n // merged cache blob larger than the requested page.\n const pageLength = mappedFetchMoreResults.results.length;\n nextOffsetRef.current = offset + (pageLength === 0 ? 0 : Math.min(pageLength, limit));\n\n setResult((prevRows) => {\n const merged = uniqBy(prop('_id'), [\n ...prevRows.results,\n ...mappedFetchMoreResults.results,\n ]) as Results['results'];\n\n // Empty/duplicate pages must end pagination, otherwise load-more loops forever\n // when aggregate count is ahead of rows that the where-clause can actually return.\n if (merged.length === prevRows.results.length) {\n return {\n count: prevRows.results.length,\n results: prevRows.results,\n } as Results;\n }\n\n // Count-free pagination pages report 0; the first page's total stands.\n return {\n count: mappedFetchMoreResults.count || prevRows.count,\n results: merged,\n } as Results;\n });\n })\n .catch((fetchError: unknown) => {\n console.error('Error fetching more data:', fetchError);\n })\n .finally(() => {\n isLoadingMoreRef.current = false;\n setIsLoadingMore(false);\n });\n },\n [defaultScope, entityNamePlural, isForm, schema, scope]\n );\n\n const reload = useCallback(\n (options?: { preserve?: boolean }): Promise<void> => {\n if (isReloadingRef.current) {\n return Promise.resolve();\n }\n\n const preserve = options?.preserve === true;\n\n isReloadingRef.current = true;\n isLoadingMoreRef.current = false;\n setIsLoadingMore(false);\n\n if (!preserve) {\n syncedQueryKeyRef.current = null;\n pendingQueryKeyRef.current = null;\n nextOffsetRef.current = 0;\n setIsReloading(true);\n setResult({ count: 0, results: [] });\n }\n\n return refetchRef\n .current()\n .then(({ data: res }) => {\n const queryKey = JSON.stringify({ entityNamePlural, scope, selection, includeCount, variables });\n const mapped = mapResults({ data: res, entityNamePlural, isForm, schema, scope, defaultScope });\n\n syncedQueryKeyRef.current = queryKey;\n pendingQueryKeyRef.current = null;\n nextOffsetRef.current = getVariablesOffset(variables) + mapped.results.length;\n setResult(mapped);\n })\n .catch((fetchError: unknown) => {\n console.error('Error reloading data:', fetchError);\n })\n .finally(() => {\n isReloadingRef.current = false;\n setIsReloading(false);\n });\n },\n [defaultScope, entityNamePlural, isForm, schema, scope, selection, includeCount, variables]\n );\n\n useEffect(() => {\n if (schemaMismatchMessage) {\n setSchemaErrorMessage(schemaMismatchMessage);\n\n return;\n }\n\n if (data && schemaErrorMessage && !effectiveError) {\n setSchemaErrorMessage(null);\n }\n }, [data, effectiveError, schemaErrorMessage, schemaMismatchMessage, setSchemaErrorMessage]);\n\n useEffect(() => {\n if (effectiveError || schemaMismatchMessage || isTotalCountFallbackLoading) {\n return;\n }\n\n const queryKey = JSON.stringify({ entityNamePlural, scope, selection, includeCount, variables });\n\n // Already synced for this query identity — ignore Apollo `data` updates from fetchMore.\n if (syncedQueryKeyRef.current === queryKey) {\n return;\n }\n\n if (isLoading && pendingQueryKeyRef.current !== queryKey) {\n pendingQueryKeyRef.current = queryKey;\n nextOffsetRef.current = 0;\n setResult({ count: 0, results: [] });\n\n return;\n }\n\n if (isLoading) {\n return;\n }\n\n const mapped = mapResults({ data, entityNamePlural, isForm, schema, scope, defaultScope });\n syncedQueryKeyRef.current = queryKey;\n pendingQueryKeyRef.current = null;\n nextOffsetRef.current = getVariablesOffset(variables) + mapped.results.length;\n setResult(mapped);\n }, [\n defaultScope,\n data,\n effectiveError,\n entityNamePlural,\n isForm,\n isLoading,\n isTotalCountFallbackLoading,\n schema,\n schemaMismatchMessage,\n scope,\n selection,\n includeCount,\n variables,\n ]);\n\n // After an Apollo refetch (delete/upload), replace accumulated pages with the\n // fresh first page. fetchMore uses NetworkStatus.fetchMore and is ignored.\n useEffect(() => {\n const previousStatus = previousNetworkStatusRef.current;\n previousNetworkStatusRef.current = networkStatus;\n\n if (effectiveError || schemaMismatchMessage || isReloadingRef.current || isTotalCountFallbackLoading) {\n return;\n }\n\n if (previousStatus !== NetworkStatus.refetch || networkStatus !== NetworkStatus.ready || !data) {\n return;\n }\n\n const queryKey = JSON.stringify({ entityNamePlural, scope, selection, includeCount, variables });\n const mapped = mapResults({ data, entityNamePlural, isForm, schema, scope, defaultScope });\n syncedQueryKeyRef.current = queryKey;\n pendingQueryKeyRef.current = null;\n nextOffsetRef.current = getVariablesOffset(variables) + mapped.results.length;\n setResult(mapped);\n }, [\n defaultScope,\n data,\n effectiveError,\n entityNamePlural,\n isForm,\n isTotalCountFallbackLoading,\n networkStatus,\n schema,\n schemaMismatchMessage,\n scope,\n selection,\n includeCount,\n variables,\n ]);\n\n // Soft-refresh after mutations (tags, deletes, uploads). Local paginated state\n // ignores Apollo cache writes, so we must refetch and remap explicitly.\n useEffect(() => {\n if (isForm) {\n return;\n }\n\n const listQueryName = `Get${getOperationEntityName(entityNamePlural)}`;\n\n const unsubscribeRefetch = subscribeEntityListRefetch((queryNames) => {\n if (!queryNames.has(listQueryName) || isLoadingMoreRef.current || isReloadingRef.current) {\n return;\n }\n\n return refetchRef\n .current()\n .then(({ data: res }) => {\n const queryKey = JSON.stringify({ entityNamePlural, scope, selection, includeCount, variables });\n const mapped = mapResults({ data: res, entityNamePlural, isForm, schema, scope, defaultScope });\n syncedQueryKeyRef.current = queryKey;\n pendingQueryKeyRef.current = null;\n nextOffsetRef.current = getVariablesOffset(variables) + mapped.results.length;\n setResult(mapped);\n })\n .catch((fetchError: unknown) => {\n console.error('Error soft-refreshing entity list:', fetchError);\n });\n });\n\n const unsubscribeRemoval = subscribeEntityListRemoval((queryName, entityIds) => {\n if (queryName !== listQueryName) {\n return;\n }\n\n setResult((prev) => {\n const nextResults = prev.results.filter((row) => {\n const rowId = typeof row._id === 'string' ? row._id : undefined;\n\n return !rowId || !entityIds.has(rowId);\n });\n const removedCount = prev.results.length - nextResults.length;\n\n if (removedCount === 0) {\n return prev;\n }\n\n return {\n count: Math.max(0, prev.count - removedCount),\n results: nextResults,\n } as Results;\n });\n });\n\n const unsubscribePatch = subscribeEntityListPatch((queryName, patches) => {\n if (queryName !== listQueryName) {\n return;\n }\n\n setResult((prev) => applyEntityListPatches(prev, patches, variables?.sort));\n });\n\n return () => {\n unsubscribeRefetch();\n unsubscribeRemoval();\n unsubscribePatch();\n };\n }, [defaultScope, entityNamePlural, isForm, schema, scope, selection, includeCount, variables]);\n\n return {\n // Refetch keeps existing rows visible; only initial load / explicit reload show as loading.\n isLoading: (isLoading && networkStatus !== NetworkStatus.refetch) || isReloading || isTotalCountFallbackLoading,\n isLoadingMore,\n fetchMore,\n reload,\n count: result.count,\n data: result.results,\n isProjectDisabled,\n isProjectHibernated,\n isProjectReadOnly,\n schemaErrorMessage,\n };\n}\n\nfunction getVariablesOffset(variables: OperationVariables | undefined): number {\n const offset = variables?.offset;\n\n return typeof offset === 'number' && Number.isFinite(offset) ? offset : 0;\n}\n\nfunction mapResults(\n args: {\n data: (EntityQueryResults & EntityQueryAggregate) | undefined;\n defaultScope: string;\n } & UseEntityQueryParams\n): MappedEntityQueryResults | MappedFormEntityQueryResults {\n const entityNamePlural = args.entityNamePlural as keyof FormEntityItem;\n\n if (!args.data?.[entityNamePlural]) {\n return { count: 0, results: [] };\n }\n\n return args.isForm\n ? mapQueryResultForFormFields(args.entityNamePlural, args.scope, args.data, args.schema, args.defaultScope)\n : mapQueryResult(args.entityNamePlural, args.scope, args.data, args.schema);\n}\n\nfunction applyEntityListPatches(prev: Results, patches: EntityListRowPatch[], sort: unknown): Results {\n const patchById = new Map(patches.map((patch) => [patch._id, patch]));\n let didPatch = false;\n const nextResults = prev.results.map((row) => {\n const rowId = typeof row._id === 'string' ? row._id : undefined;\n\n if (!rowId) {\n return row;\n }\n\n const patch = patchById.get(rowId);\n\n if (!patch) {\n return row;\n }\n\n didPatch = true;\n\n return {\n ...row,\n ...patch.attributes,\n };\n });\n\n if (!didPatch) {\n return prev;\n }\n\n return {\n count: prev.count,\n results: sortEntityListResults(nextResults, sort),\n } as Results;\n}\n\nfunction sortEntityListResults<T extends { [key: string]: unknown }>(results: T[], sort: unknown): T[] {\n if (!Array.isArray(sort) || sort.length === 0) {\n return results;\n }\n\n const [primarySort] = sort;\n\n if (!primarySort || typeof primarySort !== 'object') {\n return results;\n }\n\n const [primarySortEntry] = Object.entries(primarySort as { [key: string]: unknown });\n const [sortField, sortDirection] = primarySortEntry ?? [];\n\n if (!sortField || (sortDirection !== 'ASC' && sortDirection !== 'DESC')) {\n return results;\n }\n\n const direction = sortDirection === 'DESC' ? -1 : 1;\n\n return [...results].sort((left, right) => {\n const leftValue = left[sortField];\n const rightValue = right[sortField];\n const leftText = typeof leftValue === 'string' ? leftValue : '';\n const rightText = typeof rightValue === 'string' ? rightValue : '';\n\n return leftText.localeCompare(rightText) * direction;\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/graphql-client/refetch-entity-lists.ts","../src/graphql-client/use-entity-query.ts"],"names":["refetchTimer","pendingQueryNames","pendingResolvers","listeners","removalListeners","patchListeners","getEntityListQueryName","entityNameOrPlural","schema","getOperationEntityName","assetSchema","byPlural","entity","byName","plural","subscribeEntityListRefetch","listener","subscribeEntityListRemoval","subscribeEntityListPatch","scheduleEntityListRemoval","apolloClient","queryName","entityIds","ids","scheduleEntityListRefetch","scheduleEntityListPatch","patches","nextPatches","patch","_apolloClient","resolve","reject","names","resolvers","finish","error","fail","useEntityQuery","entityNamePlural","scope","variables","isForm","selection","includeCount","fetchPolicy","result","setResult","useState","isLoadingMore","setIsLoadingMore","isReloading","setIsReloading","unsupportedTotalCount","setUnsupportedTotalCount","isLoadingMoreRef","useRef","isReloadingRef","nextOffsetRef","syncedQueryKeyRef","pendingQueryKeyRef","defaultScope","useDefaultScope","totalCountField","entitySchema","getEntitySchema","countMode","queryDocument","useMemo","gql","getEntityQuery","fetchMoreDocument","schemaErrorMessage","setSchemaErrorMessage","useGraphQLError","isLoading","data","fetchNextPage","refetch","networkStatus","useQuery","fetchNextPageRef","refetchRef","fetchMoreDocumentRef","previousNetworkStatusRef","variablesRef","isMissingTotalCountField","isMissingGraphQLFieldError","shouldFallbackToAggregate","effectiveError","isTotalCountFallbackLoading","serverError","getServerError","schemaMismatchMessage","getGraphQLSchemaMismatchMessage","isProjectHibernated","parseErrorBody","isProjectDisabled","isProjectReadOnly","responseBody","useEffect","fetchMore","useCallback","args","limit","offset","res","mappedFetchMoreResults","mapResults","pageLength","prevRows","merged","uniqBy","prop","fetchError","reload","options","preserve","queryKey","mapped","getVariablesOffset","previousStatus","NetworkStatus","listQueryName","unsubscribeRefetch","queryNames","unsubscribeRemoval","prev","nextResults","row","rowId","removedCount","unsubscribePatch","applyEntityListPatches","mapQueryResultForFormFields","mapQueryResult","sort","patchById","didPatch","sortEntityListResults","results","primarySort","primarySortEntry","sortField","sortDirection","direction","left","right","leftValue","rightValue","leftText","rightText"],"mappings":"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","file":"chunk-3V7VAQBP.js","sourcesContent":["import type { ApolloClient } from '@apollo/client';\nimport type { Schema } from '../core/types';\nimport { assetSchema } from '../entities/assets-schema';\nimport { getOperationEntityName } from './queries';\n\ntype EntityListRefreshListener = (queryNames: ReadonlySet<string>) => void | Promise<void>;\ntype EntityListRemovalListener = (queryName: string, entityIds: ReadonlySet<string>) => void;\ntype EntityListPatchListener = (queryName: string, patches: EntityListRowPatch[]) => void;\n\nexport type EntityListRowPatch = {\n _id: string;\n attributes: { [key: string]: string };\n};\n\nlet refetchTimer: ReturnType<typeof setTimeout> | null = null;\nconst pendingQueryNames = new Set<string>();\nconst pendingResolvers: Array<{ resolve: () => void; reject: (error: unknown) => void }> = [];\nconst listeners = new Set<EntityListRefreshListener>();\nconst removalListeners = new Set<EntityListRemovalListener>();\nconst patchListeners = new Set<EntityListPatchListener>();\n\nexport function getEntityListQueryName(entityNameOrPlural: string, schema: Schema): string {\n if (entityNameOrPlural === '_asset' || entityNameOrPlural === '_assets') {\n return `Get${getOperationEntityName(assetSchema.plural)}`;\n }\n\n const byPlural = schema.find((entity) => entity.plural === entityNameOrPlural);\n const byName = schema.find((entity) => entity.name === entityNameOrPlural);\n const plural = byPlural?.plural ?? byName?.plural ?? entityNameOrPlural;\n\n return `Get${getOperationEntityName(plural)}`;\n}\n\n/**\n * Subscribe to soft list refreshes. Listeners should refetch their own query and\n * remap local paginated state (useEntityQuery ignores Apollo cache writes after sync).\n */\nexport function subscribeEntityListRefetch(listener: EntityListRefreshListener): () => void {\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n}\n\n/**\n * Subscribe to optimistic row removals (e.g. after delete) before the soft-refetch lands.\n */\nexport function subscribeEntityListRemoval(listener: EntityListRemovalListener): () => void {\n removalListeners.add(listener);\n\n return () => {\n removalListeners.delete(listener);\n };\n}\n\n/**\n * Subscribe to in-place row patches (e.g. tag connect/disconnect) without a full list refetch.\n */\nexport function subscribeEntityListPatch(listener: EntityListPatchListener): () => void {\n patchListeners.add(listener);\n\n return () => {\n patchListeners.delete(listener);\n };\n}\n\n/**\n * Immediately drop rows from mounted lists, then soft-refetch to sync counts/pages.\n */\nexport function scheduleEntityListRemoval(\n apolloClient: ApolloClient,\n queryName: string,\n entityIds: string[]\n): Promise<void> {\n const ids = new Set(entityIds.filter(Boolean));\n\n if (ids.size > 0) {\n for (const listener of removalListeners) {\n listener(queryName, ids);\n }\n }\n\n return scheduleEntityListRefetch(apolloClient, queryName);\n}\n\n/**\n * Patch mounted list rows in place. Use when a mutation cannot change list cardinality\n * (e.g. tag connect/disconnect) so we avoid a full GetAssets soft-refetch.\n */\nexport function scheduleEntityListPatch(queryName: string, patches: EntityListRowPatch[]): void {\n const nextPatches = patches.filter((patch) => Boolean(patch._id));\n\n if (nextPatches.length === 0) {\n return;\n }\n\n for (const listener of patchListeners) {\n listener(queryName, nextPatches);\n }\n}\n\n/**\n * Ask mounted entity lists to soft-refresh. Debounced so batch deletes coalesce.\n */\nexport function scheduleEntityListRefetch(_apolloClient: ApolloClient, queryName: string): Promise<void> {\n pendingQueryNames.add(queryName);\n\n return new Promise<void>((resolve, reject) => {\n pendingResolvers.push({ resolve, reject });\n\n if (refetchTimer) {\n clearTimeout(refetchTimer);\n }\n\n refetchTimer = setTimeout(() => {\n const names = new Set(pendingQueryNames);\n const resolvers = pendingResolvers.splice(0);\n pendingQueryNames.clear();\n refetchTimer = null;\n\n void Promise.all([...listeners].map((listener) => Promise.resolve(listener(names))))\n .then(() => {\n for (const { resolve: finish } of resolvers) {\n finish();\n }\n })\n .catch((error: unknown) => {\n console.error('Error refreshing entity lists:', error);\n\n for (const { reject: fail } of resolvers) {\n fail(error);\n }\n });\n }, 50);\n });\n}\n","import { useDefaultScope } from '../core/default-scope';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { prop, uniqBy } from 'ramda';\nimport { gql, NetworkStatus } from '@apollo/client';\nimport type { OperationVariables } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport {\n getGraphQLSchemaMismatchMessage,\n getServerError,\n isMissingGraphQLFieldError,\n parseErrorBody,\n} from './error-utils';\nimport {\n getEntityQuery,\n getEntitySchema,\n getOperationEntityName,\n mapQueryResult,\n mapQueryResultForFormFields,\n} from './queries';\nimport {\n subscribeEntityListPatch,\n subscribeEntityListRefetch,\n subscribeEntityListRemoval,\n type EntityListRowPatch,\n} from './refetch-entity-lists';\nimport { useGraphQLError } from './graphql-context';\nimport type {\n EntityQueryAggregate,\n EntityQueryResults,\n FormEntityItem,\n MappedEntityQueryResults,\n MappedEntityItem,\n MappedFormEntityQueryResults,\n UseEntityQueryParams,\n ImageValue,\n} from './types';\n\ntype FetchMoreOptions = {\n // `offset` is accepted for call-site compatibility but overridden by nextOffsetRef.\n // `where`/`sort` are inherited from the active query unless overridden here.\n variables: OperationVariables & { offset: number; limit: number };\n};\ntype Results = (MappedEntityQueryResults | MappedFormEntityQueryResults) | { count: 0; results: [] };\n\nexport function useEntityQuery({\n entityNamePlural,\n schema,\n scope,\n variables,\n isForm,\n selection = 'full',\n includeCount = true,\n fetchPolicy,\n}: UseEntityQueryParams): {\n count: number;\n data: MappedEntityItem[] | FormEntityItem[] | ImageValue[] | undefined;\n fetchMore: (args: FetchMoreOptions) => void;\n isLoading: boolean;\n isLoadingMore: boolean;\n isProjectDisabled: boolean;\n /** Disabled because the Free project is hibernated (also sets isProjectDisabled). */\n isProjectHibernated: boolean;\n isProjectReadOnly: boolean;\n reload: (options?: { preserve?: boolean }) => Promise<void>;\n schemaErrorMessage: string | null;\n} {\n const [result, setResult] = useState<Results>({\n count: 0,\n results: [],\n });\n const [isLoadingMore, setIsLoadingMore] = useState(false);\n const [isReloading, setIsReloading] = useState(false);\n const [unsupportedTotalCount, setUnsupportedTotalCount] = useState<{\n field: string;\n schema: UseEntityQueryParams['schema'];\n } | null>(null);\n const isLoadingMoreRef = useRef(false);\n const isReloadingRef = useRef(false);\n // Next offset for fetchMore — advanced by each requested page window, not by the\n // deduplicated row count. Using unique rows.length as offset collapses when pages\n // overlap (unstable sorts / tied timestamps) into irregular steps like 25→35→42.\n const nextOffsetRef = useRef(0);\n // Tracks the query identity we last synced into local result state.\n // fetchMore updates Apollo `data` without changing this identity; syncing those\n // updates would wipe accumulated pages and retrigger infinite load-more.\n // Must include entity/scope — variables alone collide across entity navigations.\n const syncedQueryKeyRef = useRef<string | null>(null);\n const pendingQueryKeyRef = useRef<string | null>(null);\n const defaultScope = useDefaultScope();\n const totalCountField = `${entityNamePlural}Total`;\n const entitySchema = getEntitySchema(schema, entityNamePlural);\n const canUseTotalCount =\n variables?.where === undefined &&\n (entitySchema?.spaces?.length ?? 0) === 0 &&\n (unsupportedTotalCount?.field !== totalCountField || unsupportedTotalCount.schema !== schema);\n const countMode = canUseTotalCount ? 'total' : 'aggregate';\n const queryDocument = useMemo(\n () =>\n gql(getEntityQuery(entityNamePlural, scope, schema, { selection, countMode, includeCount, defaultScope }).query),\n [entityNamePlural, scope, schema, selection, countMode, includeCount, defaultScope]\n );\n // fetchMore pages skip the top-level aggregate count (a filtered label scan\n // on the server); the total from the first page still stands.\n const fetchMoreDocument = useMemo(\n () => gql(getEntityQuery(entityNamePlural, scope, schema, { selection, includeCount: false, defaultScope }).query),\n [entityNamePlural, scope, schema, selection, defaultScope]\n );\n const { schemaErrorMessage, setSchemaErrorMessage } = useGraphQLError();\n const {\n loading: isLoading,\n data,\n fetchMore: fetchNextPage,\n refetch,\n error,\n networkStatus,\n } = useQuery<EntityQueryResults & EntityQueryAggregate>(queryDocument, {\n variables,\n notifyOnNetworkStatusChange: true,\n fetchPolicy,\n });\n const fetchNextPageRef = useRef(fetchNextPage);\n const refetchRef = useRef(refetch);\n const fetchMoreDocumentRef = useRef(fetchMoreDocument);\n const previousNetworkStatusRef = useRef(networkStatus);\n const variablesRef = useRef(variables);\n fetchNextPageRef.current = fetchNextPage;\n refetchRef.current = refetch;\n fetchMoreDocumentRef.current = fetchMoreDocument;\n variablesRef.current = variables;\n\n // Parse 403 error response to determine the specific error code\n const isMissingTotalCountField = includeCount && isMissingGraphQLFieldError(error, totalCountField);\n const shouldFallbackToAggregate = countMode === 'total' && isMissingTotalCountField;\n const effectiveError = isMissingTotalCountField ? undefined : error;\n const isTotalCountFallbackLoading = isMissingTotalCountField && !data?.[entityNamePlural];\n const serverError = getServerError(effectiveError);\n const schemaMismatchMessage = getGraphQLSchemaMismatchMessage(effectiveError);\n\n const isProjectHibernated =\n serverError?.statusCode === 403 &&\n parseErrorBody<{ code?: string }>(serverError.bodyText)?.code === 'PROJECT_HIBERNATED';\n\n const { isProjectDisabled, isProjectReadOnly } = (() => {\n if (serverError?.statusCode === 403) {\n const responseBody = parseErrorBody<{ code?: string }>(serverError.bodyText);\n\n if (responseBody && typeof responseBody.code === 'string') {\n if (responseBody.code === 'PROJECT_PAUSED' || responseBody.code === 'PROJECT_HIBERNATED') {\n return {\n isProjectDisabled: true,\n isProjectReadOnly: false,\n };\n }\n\n if (responseBody.code === 'READ_ONLY_MODE') {\n return {\n isProjectDisabled: false,\n isProjectReadOnly: true,\n };\n }\n }\n\n return {\n isProjectDisabled: true,\n isProjectReadOnly: false,\n };\n }\n\n return {\n isProjectDisabled: false,\n isProjectReadOnly: false,\n };\n })();\n\n useEffect(() => {\n if (!shouldFallbackToAggregate) {\n return;\n }\n\n setUnsupportedTotalCount({ field: totalCountField, schema });\n }, [schema, shouldFallbackToAggregate, totalCountField]);\n\n const fetchMore = useCallback(\n (args: FetchMoreOptions): void => {\n if (isLoadingMoreRef.current || isReloadingRef.current) {\n return;\n }\n\n isLoadingMoreRef.current = true;\n setIsLoadingMore(true);\n\n const { limit } = args.variables;\n const offset = nextOffsetRef.current;\n\n fetchNextPageRef\n .current({\n ...args,\n query: fetchMoreDocumentRef.current,\n variables: {\n // fetchMore uses a count-free document, so Apollo will not inherit\n // the original operation's where/sort unless we pass them again.\n ...variablesRef.current,\n ...args.variables,\n offset,\n limit,\n },\n })\n .then(({ data: res }) => {\n const mappedFetchMoreResults = mapResults({\n data: res,\n entityNamePlural,\n isForm,\n schema,\n scope,\n defaultScope,\n });\n // Advance by the fetched page window (capped at limit), not by how many unique\n // rows survived client-side merge. Cap protects against Apollo returning a\n // merged cache blob larger than the requested page.\n const pageLength = mappedFetchMoreResults.results.length;\n nextOffsetRef.current = offset + (pageLength === 0 ? 0 : Math.min(pageLength, limit));\n\n setResult((prevRows) => {\n const merged = uniqBy(prop('_id'), [\n ...prevRows.results,\n ...mappedFetchMoreResults.results,\n ]) as Results['results'];\n\n // Empty/duplicate pages must end pagination, otherwise load-more loops forever\n // when aggregate count is ahead of rows that the where-clause can actually return.\n if (merged.length === prevRows.results.length) {\n return {\n count: prevRows.results.length,\n results: prevRows.results,\n } as Results;\n }\n\n // Count-free pagination pages report 0; the first page's total stands.\n return {\n count: mappedFetchMoreResults.count || prevRows.count,\n results: merged,\n } as Results;\n });\n })\n .catch((fetchError: unknown) => {\n console.error('Error fetching more data:', fetchError);\n })\n .finally(() => {\n isLoadingMoreRef.current = false;\n setIsLoadingMore(false);\n });\n },\n [defaultScope, entityNamePlural, isForm, schema, scope]\n );\n\n const reload = useCallback(\n (options?: { preserve?: boolean }): Promise<void> => {\n if (isReloadingRef.current) {\n return Promise.resolve();\n }\n\n const preserve = options?.preserve === true;\n\n isReloadingRef.current = true;\n isLoadingMoreRef.current = false;\n setIsLoadingMore(false);\n\n if (!preserve) {\n syncedQueryKeyRef.current = null;\n pendingQueryKeyRef.current = null;\n nextOffsetRef.current = 0;\n setIsReloading(true);\n setResult({ count: 0, results: [] });\n }\n\n return refetchRef\n .current()\n .then(({ data: res }) => {\n const queryKey = JSON.stringify({ entityNamePlural, scope, selection, includeCount, variables });\n const mapped = mapResults({ data: res, entityNamePlural, isForm, schema, scope, defaultScope });\n\n syncedQueryKeyRef.current = queryKey;\n pendingQueryKeyRef.current = null;\n nextOffsetRef.current = getVariablesOffset(variables) + mapped.results.length;\n setResult(mapped);\n })\n .catch((fetchError: unknown) => {\n console.error('Error reloading data:', fetchError);\n })\n .finally(() => {\n isReloadingRef.current = false;\n setIsReloading(false);\n });\n },\n [defaultScope, entityNamePlural, isForm, schema, scope, selection, includeCount, variables]\n );\n\n useEffect(() => {\n if (schemaMismatchMessage) {\n setSchemaErrorMessage(schemaMismatchMessage);\n\n return;\n }\n\n if (data && schemaErrorMessage && !effectiveError) {\n setSchemaErrorMessage(null);\n }\n }, [data, effectiveError, schemaErrorMessage, schemaMismatchMessage, setSchemaErrorMessage]);\n\n useEffect(() => {\n if (effectiveError || schemaMismatchMessage || isTotalCountFallbackLoading) {\n return;\n }\n\n const queryKey = JSON.stringify({ entityNamePlural, scope, selection, includeCount, variables });\n\n // Already synced for this query identity — ignore Apollo `data` updates from fetchMore.\n if (syncedQueryKeyRef.current === queryKey) {\n return;\n }\n\n if (isLoading && pendingQueryKeyRef.current !== queryKey) {\n pendingQueryKeyRef.current = queryKey;\n nextOffsetRef.current = 0;\n setResult({ count: 0, results: [] });\n\n return;\n }\n\n if (isLoading) {\n return;\n }\n\n const mapped = mapResults({ data, entityNamePlural, isForm, schema, scope, defaultScope });\n syncedQueryKeyRef.current = queryKey;\n pendingQueryKeyRef.current = null;\n nextOffsetRef.current = getVariablesOffset(variables) + mapped.results.length;\n setResult(mapped);\n }, [\n defaultScope,\n data,\n effectiveError,\n entityNamePlural,\n isForm,\n isLoading,\n isTotalCountFallbackLoading,\n schema,\n schemaMismatchMessage,\n scope,\n selection,\n includeCount,\n variables,\n ]);\n\n // After an Apollo refetch (delete/upload), replace accumulated pages with the\n // fresh first page. fetchMore uses NetworkStatus.fetchMore and is ignored.\n useEffect(() => {\n const previousStatus = previousNetworkStatusRef.current;\n previousNetworkStatusRef.current = networkStatus;\n\n if (effectiveError || schemaMismatchMessage || isReloadingRef.current || isTotalCountFallbackLoading) {\n return;\n }\n\n if (previousStatus !== NetworkStatus.refetch || networkStatus !== NetworkStatus.ready || !data) {\n return;\n }\n\n const queryKey = JSON.stringify({ entityNamePlural, scope, selection, includeCount, variables });\n const mapped = mapResults({ data, entityNamePlural, isForm, schema, scope, defaultScope });\n syncedQueryKeyRef.current = queryKey;\n pendingQueryKeyRef.current = null;\n nextOffsetRef.current = getVariablesOffset(variables) + mapped.results.length;\n setResult(mapped);\n }, [\n defaultScope,\n data,\n effectiveError,\n entityNamePlural,\n isForm,\n isTotalCountFallbackLoading,\n networkStatus,\n schema,\n schemaMismatchMessage,\n scope,\n selection,\n includeCount,\n variables,\n ]);\n\n // Soft-refresh after mutations (tags, deletes, uploads). Local paginated state\n // ignores Apollo cache writes, so we must refetch and remap explicitly.\n useEffect(() => {\n if (isForm) {\n return;\n }\n\n const listQueryName = `Get${getOperationEntityName(entityNamePlural)}`;\n\n const unsubscribeRefetch = subscribeEntityListRefetch((queryNames) => {\n if (!queryNames.has(listQueryName) || isLoadingMoreRef.current || isReloadingRef.current) {\n return;\n }\n\n return refetchRef\n .current()\n .then(({ data: res }) => {\n const queryKey = JSON.stringify({ entityNamePlural, scope, selection, includeCount, variables });\n const mapped = mapResults({ data: res, entityNamePlural, isForm, schema, scope, defaultScope });\n syncedQueryKeyRef.current = queryKey;\n pendingQueryKeyRef.current = null;\n nextOffsetRef.current = getVariablesOffset(variables) + mapped.results.length;\n setResult(mapped);\n })\n .catch((fetchError: unknown) => {\n console.error('Error soft-refreshing entity list:', fetchError);\n });\n });\n\n const unsubscribeRemoval = subscribeEntityListRemoval((queryName, entityIds) => {\n if (queryName !== listQueryName) {\n return;\n }\n\n setResult((prev) => {\n const nextResults = prev.results.filter((row) => {\n const rowId = typeof row._id === 'string' ? row._id : undefined;\n\n return !rowId || !entityIds.has(rowId);\n });\n const removedCount = prev.results.length - nextResults.length;\n\n if (removedCount === 0) {\n return prev;\n }\n\n return {\n count: Math.max(0, prev.count - removedCount),\n results: nextResults,\n } as Results;\n });\n });\n\n const unsubscribePatch = subscribeEntityListPatch((queryName, patches) => {\n if (queryName !== listQueryName) {\n return;\n }\n\n setResult((prev) => applyEntityListPatches(prev, patches, variables?.sort));\n });\n\n return () => {\n unsubscribeRefetch();\n unsubscribeRemoval();\n unsubscribePatch();\n };\n }, [defaultScope, entityNamePlural, isForm, schema, scope, selection, includeCount, variables]);\n\n return {\n // Refetch keeps existing rows visible; only initial load / explicit reload show as loading.\n isLoading: (isLoading && networkStatus !== NetworkStatus.refetch) || isReloading || isTotalCountFallbackLoading,\n isLoadingMore,\n fetchMore,\n reload,\n count: result.count,\n data: result.results,\n isProjectDisabled,\n isProjectHibernated,\n isProjectReadOnly,\n schemaErrorMessage,\n };\n}\n\nfunction getVariablesOffset(variables: OperationVariables | undefined): number {\n const offset = variables?.offset;\n\n return typeof offset === 'number' && Number.isFinite(offset) ? offset : 0;\n}\n\nfunction mapResults(\n args: {\n data: (EntityQueryResults & EntityQueryAggregate) | undefined;\n defaultScope: string;\n } & UseEntityQueryParams\n): MappedEntityQueryResults | MappedFormEntityQueryResults {\n const entityNamePlural = args.entityNamePlural as keyof FormEntityItem;\n\n if (!args.data?.[entityNamePlural]) {\n return { count: 0, results: [] };\n }\n\n return args.isForm\n ? mapQueryResultForFormFields(args.entityNamePlural, args.scope, args.data, args.schema, args.defaultScope)\n : mapQueryResult(args.entityNamePlural, args.scope, args.data, args.schema);\n}\n\nfunction applyEntityListPatches(prev: Results, patches: EntityListRowPatch[], sort: unknown): Results {\n const patchById = new Map(patches.map((patch) => [patch._id, patch]));\n let didPatch = false;\n const nextResults = prev.results.map((row) => {\n const rowId = typeof row._id === 'string' ? row._id : undefined;\n\n if (!rowId) {\n return row;\n }\n\n const patch = patchById.get(rowId);\n\n if (!patch) {\n return row;\n }\n\n didPatch = true;\n\n return {\n ...row,\n ...patch.attributes,\n };\n });\n\n if (!didPatch) {\n return prev;\n }\n\n return {\n count: prev.count,\n results: sortEntityListResults(nextResults, sort),\n } as Results;\n}\n\nfunction sortEntityListResults<T extends { [key: string]: unknown }>(results: T[], sort: unknown): T[] {\n if (!Array.isArray(sort) || sort.length === 0) {\n return results;\n }\n\n const [primarySort] = sort;\n\n if (!primarySort || typeof primarySort !== 'object') {\n return results;\n }\n\n const [primarySortEntry] = Object.entries(primarySort as { [key: string]: unknown });\n const [sortField, sortDirection] = primarySortEntry ?? [];\n\n if (!sortField || (sortDirection !== 'ASC' && sortDirection !== 'DESC')) {\n return results;\n }\n\n const direction = sortDirection === 'DESC' ? -1 : 1;\n\n return [...results].sort((left, right) => {\n const leftValue = left[sortField];\n const rightValue = right[sortField];\n const leftText = typeof leftValue === 'string' ? leftValue : '';\n const rightText = typeof rightValue === 'string' ? rightValue : '';\n\n return leftText.localeCompare(rightText) * direction;\n });\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import'./index.css';import {c,a,d as d$1}from'./chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import'./index.css';import {c,a,d as d$1}from'./chunk-3V7VAQBP.js';import {f}from'./chunk-YGG43LHF.js';import {d}from'./chunk-MBBE4RND.js';import {useCallback}from'react';import {toast}from'sonner';import {useApolloClient}from'@apollo/client/react';function E(i){let{currentProjectSchema:t}=f();return useCallback(a$1=>{t&&c(a(i,t),a$1);},[i,t])}var g=["image/jpeg","image/png","image/webp","image/vnd.microsoft.icon","image/bmp","image/gif","image/tiff","image/svg+xml","image/avif","image/heic","image/heif","image/heic-sequence","image/heif-sequence","image/apng","audio/aac","audio/mpeg","audio/wav","audio/webm","audio/midi","audio/x-midi","audio/ogg","video/x-msvideo","video/mp4","video/mpeg","video/webm","video/quicktime","video/ogg","video/mp2t","video/3gpp","video/3gpp2","application/x-7z-compressed","application/zip","application/vnd.amazon.ebook","application/octet-stream","application/epub+zip","application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-fontobject","application/gzip","application/x-gzip","application/java-archive","application/json","application/ld+json","text/javascript","application/vnd.oasis.opendocument.presentation","application/vnd.oasis.opendocument.spreadsheet","application/vnd.oasis.opendocument.text","application/ogg","application/vnd.ms-powerpoint","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.rar","application/x-tar","application/vnd.visio","application/xhtml+xml","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/xml"];function F(i,t){if(!i.type)return true;let a=t?t.split(",").map(e=>e.trim()).filter(Boolean):g;return a.length===0?true:a.some(e=>e.endsWith("/*")?i.type.startsWith(e.slice(0,-1)):i.type===e)}async function x(i,t){let a=new URLSearchParams({filename:i.name}),e=await fetch(`${d(t).assets}?${a.toString()}`,{method:"POST",headers:{"Content-Type":i.type||"application/octet-stream"},body:i});if(!e.ok)throw new Error(`Upload failed for ${i.name}`);let n=await e.json(),o={_id:n._id,path:n.path??"",originalFilename:n.originalFilename??i.name,size:n.size??i.size,mimeType:n.mimeType??i.type,lqip:n.lqip??"",width:n.width??0,height:n.height??0};return {pathname:o.path,lqip:o.lqip||void 0,originalFilename:o.originalFilename,size:o.size,mimeType:o.mimeType,width:o.width||void 0,height:o.height||void 0,_id:o._id,asset:o}}async function h(i,t){let{projectId:a,accept:e,maxBytes:n=4*1024*1024,onUploadStart:o}=t,l=[];for(let p of Array.from(i)){if(p.size>n){toast.error(`File size too big (max ${(n/(1024*1024)).toFixed(0)}MB): ${p.name}`);continue}if(!F(p,e)){toast.error(`Unsupported file type: ${p.name}`);continue}l.push(p);}if(l.length===0)return [];o?.();try{let p=await Promise.all(l.map(async f=>x(f,a)));return p.length>0&&toast.success(`Uploaded ${p.length} file${p.length>1?"s":""}`),p}catch(p){return console.error(p),toast.error("Upload failed. Please try again."),[]}}async function b(i){let{accept:t,multiple:a=true}=i,e=document.createElement("input");e.type="file",e.accept=t??g.join(","),e.multiple=a,e.style.display="none",document.body.appendChild(e);try{let n=await new Promise(o=>{e.addEventListener("change",()=>o(e.files),{once:!0}),e.addEventListener("cancel",()=>o(null),{once:!0}),e.click();});return !n||n.length===0?[]:h(n,i)}finally{document.body.removeChild(e);}}function q(){let i=useApolloClient();return useCallback(async t=>{let a=t.files?await h(t.files,t):await b(t);return a.length>0&&await d$1(i,"GetAssets").catch(e=>{console.error("Error refreshing asset lists after upload:",e);}),a},[i])}export{E as a,x as b,q as c};//# sourceMappingURL=chunk-JHYLYOJJ.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-JHYLYOJJ.js.map
|