@flexkit/asset-manager 0.0.6 → 0.0.7

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/README.md ADDED
@@ -0,0 +1,68 @@
1
+ <div align="center">
2
+ <a href="https://flexkit.io">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://flexkit.io/public/logos/icon-dark-background.png">
5
+ <img alt="Flexkit logo" src="https://flexkit.io/public/logos/icon-light-background.png" height="128">
6
+ </picture>
7
+ </a>
8
+ <h1>Flexkit Asset Manager</h1>
9
+
10
+ <a href="https://www.npmjs.com/package/@flexkit/asset-manager"><img alt="NPM version" src="https://img.shields.io/npm/v/%40flexkit%2Fasset-manager?style=for-the-badge&labelColor=%23000000&color=%232563eb"></a>
11
+ <a href="https://github.com/flexkit-io/flexkit/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/npm/l/%40flexkit%2Fasset-manager?style=for-the-badge&labelColor=%23000000&color=%230ccf6a"></a>
12
+ <a href="https://github.com/orgs/flexkit-io/discussions"><img alt="Join the community on GitHub" src="https://img.shields.io/badge/Join%20the%20comunity-blue.svg?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgNDggNDgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTcgOEg0MVY0MEg3VjhaIiBmaWxsPSIjMDIwODE3Ij48L3BhdGg+PHBhdGggZD0iTTI0IDBDNDIgMCA0OCA2IDQ4IDI0QzQ4IDQyIDQyIDQ4IDI0IDQ4QzYgNDggMCA0MiAwIDI0QzAgNiA2IDAgMjQgMFpNMTcuNzQ5NCA5LjUyMzgxSDguNzYxOUwxOS4yODMzIDIzLjgzMTNMOC43NjE5IDM4LjcwNzhIMTcuNzQ5NEwyMS4wNDk5IDMzLjY2MzlWMTQuMjU0OUwxNy43NDk0IDkuNTIzODFaTTM4Ljk1NzcgOS41MjM4MUgyOS45NTQyTDI2LjI4NTcgMTQuODIyOVYzMy4wNDA2TDI5Ljk1NDIgMzguNzA3OEgzOC45NTc3TDI4LjM5MDggMjMuODMxM0wzOC45NTc3IDkuNTIzODFaIiBmaWxsPSJ3aGl0ZSI+PC9wYXRoPjwvc3ZnPg==&labelColor=%23000000"></a>
13
+
14
+ </div>
15
+
16
+ **Flexkit Asset Manager is a Studio plugin that provides a first-class interface for managing digital assets such as images, documents, PDFs, and other files within your Flexkit projects.**
17
+
18
+ It allows users to upload, browse, organize, and relate assets to entities defined in their schema, making assets a natural part of the same graph-based data model used for business data.
19
+
20
+ The Asset Manager integrates seamlessly with the Flexkit Studio and GraphQL API, enabling assets to be queried, related, and managed just like any other entity. It is designed to be extensible and customizable, so teams can adapt asset workflows, metadata, and UI components to the needs of their product.
21
+
22
+ ![Screenshot](assets/screenshot.png)
23
+
24
+ ## Installation
25
+
26
+ ```shell
27
+ npm install @flexkit/asset-manager
28
+ ```
29
+
30
+ ### Configuring
31
+
32
+ ```ts
33
+ // `flexkit.config.ts`:
34
+ import { defineConfig } from '@flexkit/studio';
35
+ import { AssetManager } from '@flexkit/asset-manager';
36
+
37
+ export default defineConfig({
38
+ plugins: [AssetManager()],
39
+ });
40
+ ```
41
+
42
+ ## Contributing
43
+
44
+ Contributions to Flexkit are welcome and highly appreciated. However, before you jump right into it, we would like you to review our [Contribution Guidelines](/contributing.md) to make sure you have a smooth experience contributing to Flexkit.
45
+
46
+ ## Reporting Issues
47
+
48
+ Found a bug? Have a feature request?
49
+
50
+ Open an issue with:
51
+ • Repro steps
52
+ • Expected vs actual behavior
53
+ • Screenshots when helpful
54
+ • Schema snippet (if relevant)
55
+
56
+ ## License
57
+
58
+ This project is licensed under the **MIT license**.
59
+
60
+ See [LICENSE](https://github.com/flexkit-io/flexkit/blob/main/LICENSE) for more information.
61
+
62
+ ---
63
+
64
+ ## Security
65
+
66
+ If you believe you have found a security vulnerability in Flexkit, we encourage you to **_responsibly disclose this and NOT open a public issue_**.
67
+
68
+ Please email us at security@flexkit.io to report any security vulnerabilities.
package/dist/index.js CHANGED
@@ -1,18 +1,18 @@
1
- import {FileStack,TagIcon,PlusIcon,Loader2,Ellipsis,LoaderCircle,Search,X,ImagePlayIcon,ImageIcon,FilePlayIcon,LayersIcon,SplinePointerIcon,ListChecks,MinusIcon,Trash2Icon}from'lucide-react';import {IMAGES_BASE_URL,useLocation,useAppContext,useConfig,assetSchema,useEntityQuery,ProjectDisabled,SchemaError,Outlet,useEntityMutation,getEntityCreateMutation,getEntityQuery,gql,getEntityDeleteMutation,getEntityUpdateMutation,useParams,useUploadAssets,useDispatch,useSearch,DataTableFacetedFilter}from'@flexkit/studio';import {TooltipProvider,Tooltip,TooltipTrigger,TooltipPortal,TooltipContent,ResizablePanelGroup,ResizablePanel,ResizableHandle,Dialog,DialogTrigger,Button,DialogContent,DialogHeader,DialogTitle,DialogDescription,Input,DialogFooter,ScrollArea,DropdownMenu,DropdownMenuTrigger,DropdownMenuContent,DropdownMenuItem,DropdownMenuSeparator,Skeleton,CommandDialog,CommandInput,CommandList,CommandEmpty,CommandGroup,CommandItem,CommandSeparator}from'@flexkit/studio/ui';import {defaultStyles,FileIcon}from'react-file-icon';import {jsx,jsxs}from'react/jsx-runtime';import {useState,useMemo,useCallback,useRef,useEffect}from'react';import {find,propEq}from'ramda';import {useGridColumnsDefinition,DataTable}from'@flexkit/studio/data-grid';function Ie({value:c}){if(!c)return null;let t=c,s=/\.(png|jpe?g|gif|webp|avif|svg)$/i.test(t),f=x=>{let I=x.split("?")[0].split(".");return I.length>1?I.pop().toLowerCase():"file"},h=t.endsWith(".svg")?`${IMAGES_BASE_URL}${t}`:`${IMAGES_BASE_URL}${t}?w=84&h=84&f=webp`,E=t.endsWith(".svg")?`${IMAGES_BASE_URL}${t}`:`${IMAGES_BASE_URL}${t}?w=624&h=624&f=webp`;return jsx("div",{className:"fk-z-10",children:jsx(TooltipProvider,{children:s?jsxs(Tooltip,{children:[jsx(TooltipTrigger,{asChild:true,children:jsx("img",{src:h,alt:"asset",className:"fk-w-12 fk-h-12 fk-cursor-zoom-in"})}),jsx(TooltipPortal,{children:jsx(TooltipContent,{children:jsx("img",{src:E,alt:"asset",className:"fk-w-52 fk-h-52"})})})]}):jsxs(Tooltip,{children:[jsx(TooltipTrigger,{asChild:true,children:jsx("div",{className:"fk-w-7 fk-h-7 fk-rounded fk-bg-transparent fk-flex fk-items-center fk-justify-center [&>svg]:fk-h-full [&>svg]:fk-w-auto",children:(()=>{let x=f(t),u=defaultStyles[x];return jsx(FileIcon,{extension:x,...u||{}})})()})}),jsx(TooltipPortal,{children:jsx(TooltipContent,{children:jsx("div",{className:"fk-text-sm fk-text-muted-foreground",children:"Preview not available"})})})]})})})}function Ae(){let{scope:c}=useAppContext(),{currentProjectSchema:t}=useConfig(),[s,f,h]=useEntityMutation(),[E,x]=useState(""),[u,I]=useState(false),[R,U]=useState(false),[D,P]=useState(null),[H,g]=useState(false),[A,C]=useState(null),[k,_]=useState(""),[T,N]=useState(false),[$,w]=useState(false),b="_tag",y="_tags",F=useMemo(()=>({where:{},options:{limit:200,offset:0,sort:[{name:"ASC"}]}}),[]),{data:J,isLoading:X}=useEntityQuery({entityNamePlural:y,schema:t,scope:c,variables:F}),K=(Array.isArray(J)?J:[]).map(i=>{let r=i;return {_id:r._id,name:r.name}}),te=useCallback(async()=>{let i=E.trim();if(!i)return;N(true);let r=typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now()}`,M=getEntityCreateMutation(y,t,{name:{value:i,disabled:false,scope:"default"}},r),O=getEntityQuery(y,c,t),Y=gql`
2
- ${O.query}
3
- `;await new Promise(Z=>{f(gql`
4
- ${M}
5
- `),h({refetchQueries:[Y],onCompleted:()=>{x(""),I(false),Z();}}),s(true);}),N(false);},[y,s,t,c,f,h,E]),oe=useCallback(async i=>{w(true);let r=getEntityDeleteMutation(b,t,i),q=getEntityQuery(y,c,t),M=gql`
6
- ${q.query}
7
- `;await new Promise(O=>{f(gql`
8
- ${r}
9
- `),h({variables:{where:{_id:i}},refetchQueries:[M],onCompleted:()=>{O();}}),s(true);}),w(false);},[b,y,s,t,c,f,h]),ne=useCallback(async()=>{let i=k.trim();if(!i||!A)return;N(true);let r={name:{value:i,disabled:false,scope:"default"}},q={},M=getEntityUpdateMutation(y,A._id,c,t,q,r),O=getEntityQuery(y,c,t),Y=gql`
10
- ${O.query}
11
- `;await new Promise(Z=>{f(gql`
12
- ${M}
13
- `),h({variables:{where:{_id:A._id}},refetchQueries:[Y],onCompleted:()=>{g(false),C(null),_(""),Z();}}),s(true);}),N(false);},[k,y,s,t,c,f,h,A]);return jsxs("div",{className:"fk-flex fk-h-full fk-max-h-screen fk-flex-col fk-gap-2",children:[jsxs("div",{className:"fk-flex fk-h-12 fk-items-center fk-border-b fk-border-b-border fk-px-4 fk-lg:fk-h-[60px] fk-lg:fk-px-6",children:[jsx(TagIcon,{className:"fk-h-4 fk-w-4"}),jsx("span",{className:"fk-px-4 fk-text-sm fk-font-semibold fk-tracking-tight",children:"Tags"}),jsx(TooltipProvider,{children:jsxs(Tooltip,{children:[jsx(TooltipTrigger,{asChild:true,children:jsxs(Dialog,{open:u,onOpenChange:I,children:[jsx(DialogTrigger,{asChild:true,children:jsxs(Button,{variant:"secondary",size:"icon",className:"fk-ml-auto fk-h-8 fk-w-8",children:[jsx(PlusIcon,{className:"fk-h-4 fk-w-4"}),jsx("span",{className:"fk-sr-only",children:"Add tag"})]})}),jsxs(DialogContent,{children:[jsxs(DialogHeader,{children:[jsx(DialogTitle,{children:"New tag"}),jsx(DialogDescription,{className:"fk-sr-only",children:"Create a new tag"})]}),jsx("div",{className:"fk-flex fk-gap-2",children:jsx(Input,{autoFocus:true,value:E,placeholder:"New tag name",onChange:i=>x(i.target.value),onKeyDown:i=>{i.key==="Enter"&&te();}})}),jsx(DialogFooter,{children:jsxs(Button,{disabled:T,onClick:te,variant:"default",children:[T?jsx(Loader2,{className:"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin"}):null,"Add"]})})]})]})}),jsx(TooltipContent,{children:jsx("p",{children:"Add tag"})})]})})]}),jsx(ScrollArea,{className:"fk-h-full",children:jsx("div",{className:"fk-flex fk-flex-col fk-gap-2 fk-px-4 fk-py-2",children:X?jsx("div",{className:"fk-text-sm fk-text-muted-foreground",children:"Loading..."}):K.length===0?jsx("div",{className:"fk-text-sm fk-text-muted-foreground",children:"No tags yet"}):K.map(i=>jsxs("div",{className:"fk-group fk-flex fk-items-center fk-justify-between fk-rounded fk-border fk-border-border fk-bg-card fk-px-3 fk-py-1",children:[jsx("span",{className:"fk-text-sm",children:i.name}),jsxs(DropdownMenu,{children:[jsx(DropdownMenuTrigger,{asChild:true,children:jsx(Button,{"aria-label":`Actions for ${i.name}`,title:`Actions for ${i.name}`,variant:"ghost",size:"icon",className:"fk-h-7 fk-w-7 fk-text-muted-foreground hover:fk-text-foreground",children:jsx(Ellipsis,{className:"fk-h-4 fk-w-4"})})}),jsxs(DropdownMenuContent,{align:"end",className:"w-[160px]",children:[jsx(DropdownMenuItem,{onClick:()=>{C(i),_(i.name),g(true);},children:"Edit"}),jsx(DropdownMenuSeparator,{}),jsx(DropdownMenuItem,{className:"fk-text-destructive",onClick:()=>{P(i),U(true);},children:"Remove"})]})]})]},i._id))})}),jsx(Dialog,{open:H,onOpenChange:g,children:jsxs(DialogContent,{children:[jsxs(DialogHeader,{children:[jsx(DialogTitle,{children:"Edit tag"}),jsx(DialogDescription,{className:"fk-sr-only",children:"Rename an existing tag"})]}),jsx("div",{className:"fk-flex fk-gap-2",children:jsx(Input,{autoFocus:true,value:k,placeholder:"Tag name",onChange:i=>_(i.target.value),onKeyDown:i=>{i.key==="Enter"&&ne();}})}),jsxs(DialogFooter,{children:[jsx(Button,{disabled:T,variant:"secondary",onClick:()=>{g(false),C(null);},children:"Cancel"}),jsxs(Button,{disabled:T,onClick:ne,variant:"default",children:[T?jsx(Loader2,{className:"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin"}):null,"Save"]})]})]})}),jsx(Dialog,{open:R,onOpenChange:U,children:jsxs(DialogContent,{children:[jsxs(DialogHeader,{children:[jsx(DialogTitle,{children:"Delete tag"}),jsx(DialogDescription,{className:"fk-sr-only",children:"Confirm deletion of a tag"})]}),jsxs("div",{className:"fk-text-sm fk-text-muted-foreground",children:["Are you sure you want to delete the tag"," ",jsx("span",{className:"fk-font-semibold fk-text-foreground",children:D?.name}),"?"]}),jsxs(DialogFooter,{children:[jsx(Button,{disabled:$,variant:"secondary",onClick:()=>{U(false),P(null);},children:"Cancel"}),jsxs(Button,{disabled:$,variant:"destructive",onClick:()=>{D&&(async()=>(await oe(D._id),U(false),P(null)))();},children:[$?jsx(Loader2,{className:"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin"}):null,"Delete"]})]})]})})]})}var Vt=[{value:"image/gif",label:"GIF",icon:ImagePlayIcon},{value:"image/jpeg",label:"JPEG",icon:ImageIcon},{value:"video/mp4",label:"MP4",icon:FilePlayIcon},{value:"image/png",label:"PNG",icon:LayersIcon},{value:"image/svg+xml",label:"SVG",icon:SplinePointerIcon},{value:"image/webp",label:"WebP",icon:ImageIcon}];function Ve({entityName:c,table:t,onSearchWhereChange:s}){let f=t.getState().columnFilters.length>0,{projectId:h}=useParams(),E=useUploadAssets(),x=useDispatch(),{scope:u}=useAppContext(),[I,R]=useState(false),[U,D]=useState(false),[P,H]=useState([]),[g,A]=useState([]),[C,k,_]=useEntityMutation(),{currentProjectSchema:T}=useConfig(),[N,$]=useState(""),w=useRef({}),b=useRef({});function y(){return {searchRequests:{searches:[{collection:"_assets"},{collection:"_tags"}]},commonParams:{q:""}}}let F=useMemo(()=>y(),[]),[J,X$1]=useState(F),{results:K,isLoading:te}=useSearch(h??"",J),oe=useRef(""),ne=useCallback(Wt(e=>{X$1({...F,commonParams:{q:e}});},300),[F]);async function i(){await E({projectId:h,accept:"image/*",multiple:true,maxBytes:4*1024*1024});}let r=t.getSelectedRowModel().rows.map(e=>e.original._id),{data:q}=useEntityQuery({entityNamePlural:"_tags",schema:T,scope:u,variables:{where:{},options:{limit:500,offset:0,sort:[{name:"ASC"}]}}}),M=Array.isArray(q)?q.map(e=>({_id:e._id,name:e.name})):[],{data:O}=useEntityQuery({entityNamePlural:"_assets",schema:T,scope:u,variables:{where:{},options:{limit:500,offset:0,sort:[{_updatedAt:"DESC"}]}}});function Y(e){if(e==="image/gif")return "GIF";if(e==="image/jpeg")return "JPEG";if(e==="video/mp4")return "MP4";if(e==="image/png")return "PNG";if(e==="image/svg+xml")return "SVG";if(e==="image/webp")return "WebP";let a=e.split("/");return a.length===2&&a[1]?a[1].toUpperCase():e}function Z(e){return e==="image/svg+xml"?SplinePointerIcon:e.startsWith("image/")?ImageIcon:e.startsWith("video/")?FilePlayIcon:LayersIcon}let ve=useMemo(()=>{let e=Array.isArray(O)?O:[],a=new Set;for(let p of e){let S=p.mimeType??"";S&&a.add(S);}return Array.from(a.values()).sort().map(p=>({value:p,label:Y(p),icon:Z(p)}))},[O]),Ze=ve.length>0?ve:Vt,et=useMemo(()=>M.map(e=>({value:e._id,label:e.name})),[M]);function xe(){if(!s)return;let e=[];Object.keys(w.current).length>0&&e.push(w.current),Object.keys(b.current).length>0&&e.push(b.current);let a=e.length===0?{}:e.length===1?e[0]:{AND:e},l=JSON.stringify(a);oe.current!==l&&(oe.current=l,s(a));}async function tt(){x({type:"AlertDialog",payload:{options:{dialogTitle:`Delete ${r.length} asset${r.length>1?"s":""}`,dialogMessage:r.length>1?"Are you sure you want to delete the selected assets? They will be deleted permanently.":"Are you sure you want to delete the selected asset? The item will be deleted permanently.",dialogCancelTitle:"Cancel",dialogActionLabel:"Delete",isDestructive:true,dialogActionCancel:()=>{},dialogActionSubmit:()=>{for(let e of r)x({type:"DeleteEntity",payload:{entityId:e,entityName:c,silent:true}});t.resetRowSelection();}}}});}let ot=useCallback(async()=>{if(r.length===0||P.length===0)return;let e={tags:{relationships:{connect:P.map(l=>({_id:l}))},disabled:false,scope:u}},a=getEntityUpdateMutation("_assets",r[0]??"",u,T,{},e);await new Promise(l=>{k(gql`
14
- ${a}
15
- `),_({variables:{where:{_id_IN:r}},onCompleted:()=>l()}),C(true);}),R(false),H([]),t.resetRowSelection();},[C,u,r,P,k,_,t]),nt=useCallback(async()=>{if(r.length===0||g.length===0)return;let e={tags:{relationships:{disconnect:g},disabled:false,scope:u}},a=getEntityUpdateMutation("_assets",r[0]??"",u,T,{},e);await new Promise(l=>{k(gql`
16
- ${a}
17
- `),_({variables:{where:{_id_IN:r}},onCompleted:()=>l()}),C(true);}),D(false),A([]),t.resetRowSelection();},[C,u,r,g,k,_,t]);useEffect(()=>{if(!s)return;let e=K??[],a=N.trim(),l={};if(a.length===0)l={};else if(e.length===0)l={_id_IN:[]};else {let p=e.filter(L=>L._entityNamePlural==="_assets").map(L=>({_id:L._id})),S=e.filter(L=>L._entityNamePlural==="_tags").map(L=>({tagsConnection_SOME:{node:{_id:L._id}}})),z=[...p,...S];l=z.length>0?{OR:z}:{_id_IN:[]};}w.current=l,xe();},[s,K,N]);let at=JSON.stringify(t.getState().columnFilters);return useEffect(()=>{if(!s)return;let e=t.getState().columnFilters.find(z=>z.id==="mimeType"),a=Array.isArray(e?.value)?e?.value:[],l=t.getState().columnFilters.find(z=>z.id==="tags"),p=Array.isArray(l?.value)?l?.value:[],S=[];if(a.length>0&&S.push({mimeType_IN:a}),p.length>0){let z=p.map(L=>({tagsConnection_SOME:{node:{_id:L}}}));S.push(z.length===1?z[0]:{OR:z});}S.length===0?b.current={}:S.length===1?b.current=S[0]:b.current={AND:S},xe();},[at,s,t]),jsxs("div",{className:"fk-flex fk-items-center fk-justify-between",children:[jsxs("div",{className:"fk-flex fk-flex-1 fk-items-center fk-space-x-2",children:[jsxs("div",{className:"fk-relative",children:[te?jsx(LoaderCircle,{className:"fk-absolute fk-left-2 fk-top-2 fk-h-4 fk-w-4 fk-shrink-0 fk-opacity-50 fk-animate-spin"}):jsx(Search,{className:"fk-absolute fk-left-2 fk-top-2 fk-h-4 fk-w-4 fk-shrink-0 fk-opacity-50"}),jsx(Input,{placeholder:"Search assets...",name:"search-assets",value:N,onChange:e=>{let a=e.target.value;if($(a),a.trim().length===0){X$1({...F,commonParams:{q:""}}),s&&s({});return}ne(a);},className:"fk-h-8 fk-w-[150px] lg:fk-w-[250px] fk-pl-8"}),N?jsx("button",{"aria-label":"Clear search",className:"fk-absolute fk-right-2 fk-top-2 fk-text-muted-foreground hover:fk-text-foreground",onClick:()=>{$(""),X$1({...F,commonParams:{q:""}}),s&&s({});},type:"button",children:jsx(X,{className:"fk-h-4 fk-w-4"})}):null]}),t.getColumn("mimeType")&&jsx(DataTableFacetedFilter,{column:t.getColumn("mimeType"),title:"File type",options:Ze}),t.getColumn("tags")&&jsx(DataTableFacetedFilter,{column:t.getColumn("tags"),title:"Tags",options:et}),f&&jsxs(Button,{variant:"ghost",onClick:()=>{t.resetColumnFilters(),s&&s({});},className:"fk-h-8 fk-px-2 lg:fk-px-3",children:["Reset",jsx(X,{className:"fk-ml-2 fk-h-4 fk-w-4"})]})]}),r.length>0?jsx("div",{className:"fk-flex fk-items-center fk-gap-2",children:jsxs(DropdownMenu,{children:[jsx(DropdownMenuTrigger,{asChild:true,children:jsxs(Button,{className:"fk-h-8 fk-mr-2 lg:fk-flex",size:"sm",variant:"secondary",children:["Actions ",jsx(ListChecks,{className:"fk-ml-2 fk-h-4 fk-w-4"})]})}),jsxs(DropdownMenuContent,{align:"end",className:"fk-w-[240px]",children:[jsxs(DropdownMenuItem,{onClick:()=>R(true),children:[jsx(TagIcon,{className:"fk-mr-2 fk-h-4 fk-w-4"})," Add tag"]}),jsxs(DropdownMenuItem,{onClick:()=>D(true),children:[jsx(MinusIcon,{className:"fk-mr-2 fk-h-4 fk-w-4"})," Remove tag"]}),jsx(DropdownMenuSeparator,{}),jsxs(DropdownMenuItem,{onClick:tt,className:"fk-text-destructive",children:[jsx(Trash2Icon,{className:"fk-mr-2 fk-h-4 fk-w-4"})," Delete asset",r.length>1?"s":""," (",r.length,")"]})]})]})}):null,jsx(Button,{className:"fk-ml-auto fk-h-8 lg:fk-flex",onClick:i,size:"sm",variant:"default",children:"Upload assets"}),jsxs(CommandDialog,{open:I,onOpenChange:R,children:[jsx(CommandInput,{placeholder:"Search tags..."}),jsxs(CommandList,{className:"fk-h-[300px]",children:[jsx(CommandEmpty,{children:"No tags found."}),jsx(CommandGroup,{heading:"Tags",children:M.map(e=>{let a=P.includes(e._id);return jsxs(CommandItem,{onSelect:()=>{H(l=>a?l.filter(p=>p!==e._id):[...l,e._id]);},children:[jsx("input",{className:"fk-mr-2",checked:a,onChange:()=>{},type:"checkbox"}),e.name]},e._id)})})]}),jsx(CommandSeparator,{}),jsx("div",{className:"fk-p-2",children:jsx(Button,{className:"fk-w-full",onClick:ot,disabled:P.length===0,children:"Add tag(s) to selected assets"})})]}),jsxs(CommandDialog,{open:U,onOpenChange:D,children:[jsx(CommandInput,{placeholder:"Search tags..."}),jsxs(CommandList,{className:"fk-h-[300px]",children:[jsx(CommandEmpty,{children:"No tags found."}),jsx(CommandGroup,{heading:"Tags",children:M.map(e=>{let a=g.includes(e._id);return jsxs(CommandItem,{onSelect:()=>{A(l=>a?l.filter(p=>p!==e._id):[...l,e._id]);},children:[jsx("input",{className:"fk-mr-2",checked:a,onChange:()=>{},type:"checkbox"}),e.name]},e._id)})})]}),jsx(CommandSeparator,{}),jsx("div",{className:"fk-p-2",children:jsx(Button,{className:"fk-w-full",onClick:nt,disabled:g.length===0,children:"Remove tag(s) from selected assets"})})]})]})}function Wt(c,t=300){let s;return function(...f){clearTimeout(s),s=setTimeout(()=>c.apply(this,f),t);}}var ie=25;function We(){let c="_assets",{search:t}=useLocation(),f=new URLSearchParams(t).get("id"),{scope:h}=useAppContext(),{projects:E,currentProjectId:x}=useConfig(),{schema:u}=find(propEq(x??"","projectId"))(E),I=useGridColumnsDefinition({attributesSchema:assetSchema.attributes,checkboxSelect:"multiple"}),[R,U]=useState({}),D=f?{_id:f}:{NOT:{path:null}},H={where:useMemo(()=>!R||Object.keys(R).length===0||f?D:{AND:[D,R]},[f,R]),options:{offset:0,limit:ie,sort:[{_updatedAt:"DESC"}]}},{isLoading:g,fetchMore:A,count:C,data:k,isProjectDisabled:_}=useEntityQuery({entityNamePlural:c,schema:u,scope:h,variables:H}),T=useCallback(w=>{let b=k?.length??0;if(w&&C>0&&b>0){let{scrollHeight:y,scrollTop:F,clientHeight:J}=w;y-F-J<500&&!g&&b<C&&A({variables:{options:{offset:k?.length??0,limit:ie}}});}},[C,k?.length,A,g]),N=Array(ie).fill({}),$=mo(I);return _?jsx("div",{className:"fk-flex fk-flex-col fk-h-full fk-pl-3",children:jsx(ProjectDisabled,{})}):jsxs("div",{className:"fk-flex fk-flex-col fk-h-full fk-pl-3",children:[jsx(SchemaError,{}),jsx("h2",{className:"fk-mb-4 fk-text-lg fk-font-semibold fk-leading-none fk-tracking-tight",children:"Asset Manager"}),jsx(DataTable,{classNames:{row:"fk-h-20"},columns:g?$:I,data:g?N:k??[],entityName:assetSchema.name,pageSize:ie,onScroll:w=>{T(w.target);},toolbarComponent:w=>jsx(Ve,{entityName:assetSchema.name,table:w,onSearchWhereChange:b=>U(b)})}),jsx(Outlet,{})]})}function mo(c){return c.map(t=>({...t,cell:()=>jsx(Skeleton,{className:"fk-h-4 fk-w-full",style:{marginTop:"7px",marginBottom:"6px"}})}))}function Ke(){return jsxs(ResizablePanelGroup,{direction:"horizontal",className:"fk-h-full",children:[jsx(ResizablePanel,{className:"fk-p-3",defaultSize:82,children:jsx("div",{className:"fk-flex fk-flex-col fk-h-full",children:jsx(We,{})})}),jsx(ResizableHandle,{className:"hover:fk-bg-blue-500 fk-transition-colors",withHandle:true}),jsx(ResizablePanel,{defaultSize:18,minSize:10,children:jsx("div",{className:"sm:fk-hidden md:fk-block",children:jsx(Ae,{})})})]})}function on(){return {name:"flexkit.asset-manager",contributes:{apps:[{name:"asset-manager",icon:jsx(FileStack,{strokeWidth:1.5}),title:"Asset Manager",component:jsx(Ke,{}),routes:[]}],previewFields:{assetPreviewField:{component:Ie,description:"Asset preview field for the asset manager"}}}}}export{on as AssetManager};//# sourceMappingURL=index.js.map
1
+ import'./index.css';import {FileStack,TagIcon,PlusIcon,Loader2,Ellipsis,LoaderCircle,Search,X,ImagePlayIcon,ImageIcon,FilePlayIcon,LayersIcon,SplinePointerIcon,ListChecks,MinusIcon,Trash2Icon}from'lucide-react';import {IMAGES_BASE_URL,useLocation,useAppContext,useConfig,useGridColumnsDefinition,assetSchema,useEntityQuery,ProjectDisabled,SchemaError,DataTable,Outlet,useEntityMutation,getEntityCreateMutation,getEntityQuery,gql,getEntityDeleteMutation,getEntityUpdateMutation,useParams,useUploadAssets,useDispatch,useSearch,DataTableFacetedFilter}from'@flexkit/studio';import {TooltipProvider,Tooltip,TooltipTrigger,TooltipPortal,TooltipContent,ResizablePanelGroup,ResizablePanel,ResizableHandle,Dialog,DialogTrigger,Button,DialogContent,DialogHeader,DialogTitle,DialogDescription,Input,DialogFooter,ScrollArea,DropdownMenu,DropdownMenuTrigger,DropdownMenuContent,DropdownMenuItem,DropdownMenuSeparator,Skeleton,CommandDialog,CommandInput,CommandList,CommandEmpty,CommandGroup,CommandItem,CommandSeparator}from'@flexkit/studio/ui';import {defaultStyles,FileIcon}from'react-file-icon';import {jsx,jsxs}from'react/jsx-runtime';import {useState,useMemo,useRef,useCallback,useEffect}from'react';import {find,propEq}from'ramda';var rt=FileIcon;function Ie({value:m}){if(!m)return null;let t=m,i=/\.(png|jpe?g|gif|webp|avif|svg)$/i.test(t),f=T=>{let[d]=T.split("?"),S=d.split(".");return S.length>1?S.pop().toLowerCase():"file"},v=t.endsWith(".svg")?`${IMAGES_BASE_URL}${t}`:`${IMAGES_BASE_URL}${t}?w=84&h=84&f=webp`,O=t.endsWith(".svg")?`${IMAGES_BASE_URL}${t}`:`${IMAGES_BASE_URL}${t}?w=624&h=624&f=webp`;return jsx("div",{className:"fk-z-10",children:jsx(TooltipProvider,{children:i?jsxs(Tooltip,{children:[jsx(TooltipTrigger,{asChild:true,children:jsx("img",{src:v,alt:"asset",className:"fk-w-12 fk-h-12 fk-cursor-zoom-in"})}),jsx(TooltipPortal,{children:jsx(TooltipContent,{children:jsx("img",{src:O,alt:"asset",className:"fk-w-52 fk-h-52"})})})]}):jsxs(Tooltip,{children:[jsx(TooltipTrigger,{asChild:true,children:jsx("div",{className:"fk-w-7 fk-h-7 fk-rounded fk-bg-transparent fk-flex fk-items-center fk-justify-center [&>svg]:fk-h-full [&>svg]:fk-w-auto",children:(()=>{let T=f(t),d=defaultStyles[T];return jsx(rt,{extension:T,...d||{}})})()})}),jsx(TooltipPortal,{children:jsx(TooltipContent,{children:jsx("div",{className:"fk-text-sm fk-text-muted-foreground",children:"Preview not available"})})})]})})})}function Ae(){let{scope:m}=useAppContext(),{currentProjectSchema:t}=useConfig(),[i,f,v]=useEntityMutation(),[O,T]=useState(""),[d,S]=useState(false),[I,B]=useState(false),[N,P]=useState(null),[J,k]=useState(false),[_,D]=useState(null),[p,A]=useState(""),[w,b]=useState(false),[W,q]=useState(false),M="_tag",u="_tags",h=useMemo(()=>({where:{},options:{limit:200,offset:0,sort:[{name:"ASC"}]}}),[]),{data:V,isLoading:G}=useEntityQuery({entityNamePlural:u,schema:t,scope:m,variables:h}),z=(Array.isArray(V)?V:[]).map(o=>{let l=o;return {_id:l._id,name:l.name}}),X=useCallback(async()=>{let o=O.trim();if(!o)return;b(true);let l=typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now()}`,E=getEntityCreateMutation(u,t,{name:{value:o,disabled:false,scope:"default"}},l),F=getEntityQuery(u,m,t),ee=gql`
2
+ ${F.query}
3
+ `;await new Promise(te=>{f(gql`
4
+ ${E}
5
+ `),v({refetchQueries:[ee],onCompleted:()=>{T(""),S(false),te();}}),i(true);}),b(false);},[u,i,t,m,f,v,O]),K=useCallback(async o=>{q(true);let l=getEntityDeleteMutation(M,t,o),j=getEntityQuery(u,m,t),E=gql`
6
+ ${j.query}
7
+ `;await new Promise(F=>{f(gql`
8
+ ${l}
9
+ `),v({variables:{where:{_id:o}},refetchQueries:[E],onCompleted:()=>{F();}}),i(true);}),q(false);},[M,u,i,t,m,f,v]),ae=useCallback(async()=>{let o=p.trim();if(!o||!_)return;b(true);let l={name:{value:o,disabled:false,scope:"default"}},j={},E=getEntityUpdateMutation(u,_._id,m,t,j,l),F=getEntityQuery(u,m,t),ee=gql`
10
+ ${F.query}
11
+ `;await new Promise(te=>{f(gql`
12
+ ${E}
13
+ `),v({variables:{where:{_id:_._id}},refetchQueries:[ee],onCompleted:()=>{k(false),D(null),A(""),te();}}),i(true);}),b(false);},[p,u,i,t,m,f,v,_]);return jsxs("div",{className:"fk-flex fk-h-full fk-max-h-screen fk-flex-col fk-gap-2",children:[jsxs("div",{className:"fk-flex fk-h-12 fk-items-center fk-border-b fk-border-b-border fk-px-4 fk-lg:fk-h-[60px] fk-lg:fk-px-6",children:[jsx(TagIcon,{className:"fk-h-4 fk-w-4"}),jsx("span",{className:"fk-px-4 fk-text-sm fk-font-semibold fk-tracking-tight",children:"Tags"}),jsx(TooltipProvider,{children:jsxs(Tooltip,{children:[jsx(TooltipTrigger,{asChild:true,children:jsxs(Dialog,{open:d,onOpenChange:S,children:[jsx(DialogTrigger,{asChild:true,children:jsxs(Button,{variant:"secondary",size:"icon",className:"fk-ml-auto fk-h-8 fk-w-8",children:[jsx(PlusIcon,{className:"fk-h-4 fk-w-4"}),jsx("span",{className:"fk-sr-only",children:"Add tag"})]})}),jsxs(DialogContent,{children:[jsxs(DialogHeader,{children:[jsx(DialogTitle,{children:"New tag"}),jsx(DialogDescription,{className:"fk-sr-only",children:"Create a new tag"})]}),jsx("div",{className:"fk-flex fk-gap-2",children:jsx(Input,{autoFocus:true,value:O,placeholder:"New tag name",onChange:o=>T(o.target.value),onKeyDown:o=>{o.key==="Enter"&&X();}})}),jsx(DialogFooter,{children:jsxs(Button,{disabled:w,onClick:X,variant:"default",children:[w?jsx(Loader2,{className:"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin"}):null,"Add"]})})]})]})}),jsx(TooltipContent,{children:jsx("p",{children:"Add tag"})})]})})]}),jsx(ScrollArea,{className:"fk-h-full",children:jsx("div",{className:"fk-flex fk-flex-col fk-gap-2 fk-px-4 fk-py-2",children:G?jsx("div",{className:"fk-text-sm fk-text-muted-foreground",children:"Loading..."}):z.length===0?jsx("div",{className:"fk-text-sm fk-text-muted-foreground",children:"No tags yet"}):z.map(o=>jsxs("div",{className:"fk-group fk-flex fk-items-center fk-justify-between fk-rounded fk-border fk-border-border fk-bg-card fk-px-3 fk-py-1",children:[jsx("span",{className:"fk-text-sm",children:o.name}),jsxs(DropdownMenu,{children:[jsx(DropdownMenuTrigger,{asChild:true,children:jsx(Button,{"aria-label":`Actions for ${o.name}`,title:`Actions for ${o.name}`,variant:"ghost",size:"icon",className:"fk-h-7 fk-w-7 fk-text-muted-foreground hover:fk-text-foreground",children:jsx(Ellipsis,{className:"fk-h-4 fk-w-4"})})}),jsxs(DropdownMenuContent,{align:"end",className:"w-[160px]",children:[jsx(DropdownMenuItem,{onClick:()=>{D(o),A(o.name),k(true);},children:"Edit"}),jsx(DropdownMenuSeparator,{}),jsx(DropdownMenuItem,{className:"fk-text-destructive",onClick:()=>{P(o),B(true);},children:"Remove"})]})]})]},o._id))})}),jsx(Dialog,{open:J,onOpenChange:k,children:jsxs(DialogContent,{children:[jsxs(DialogHeader,{children:[jsx(DialogTitle,{children:"Edit tag"}),jsx(DialogDescription,{className:"fk-sr-only",children:"Rename an existing tag"})]}),jsx("div",{className:"fk-flex fk-gap-2",children:jsx(Input,{autoFocus:true,value:p,placeholder:"Tag name",onChange:o=>A(o.target.value),onKeyDown:o=>{o.key==="Enter"&&ae();}})}),jsxs(DialogFooter,{children:[jsx(Button,{disabled:w,variant:"secondary",onClick:()=>{k(false),D(null);},children:"Cancel"}),jsxs(Button,{disabled:w,onClick:ae,variant:"default",children:[w?jsx(Loader2,{className:"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin"}):null,"Save"]})]})]})}),jsx(Dialog,{open:I,onOpenChange:B,children:jsxs(DialogContent,{children:[jsxs(DialogHeader,{children:[jsx(DialogTitle,{children:"Delete tag"}),jsx(DialogDescription,{className:"fk-sr-only",children:"Confirm deletion of a tag"})]}),jsxs("div",{className:"fk-text-sm fk-text-muted-foreground",children:["Are you sure you want to delete the tag"," ",jsx("span",{className:"fk-font-semibold fk-text-foreground",children:N?.name}),"?"]}),jsxs(DialogFooter,{children:[jsx(Button,{disabled:W,variant:"secondary",onClick:()=>{B(false),P(null);},children:"Cancel"}),jsxs(Button,{disabled:W,variant:"destructive",onClick:()=>{N&&(async()=>(await K(N._id),B(false),P(null)))();},children:[W?jsx(Loader2,{className:"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin"}):null,"Delete"]})]})]})})]})}var Vt=[{value:"image/gif",label:"GIF",icon:ImagePlayIcon},{value:"image/jpeg",label:"JPEG",icon:ImageIcon},{value:"video/mp4",label:"MP4",icon:FilePlayIcon},{value:"image/png",label:"PNG",icon:LayersIcon},{value:"image/svg+xml",label:"SVG",icon:SplinePointerIcon},{value:"image/webp",label:"WebP",icon:ImageIcon}];function Je({entityName:m,table:t,onSearchWhereChange:i}){let f=t.getState().columnFilters.length>0,{projectId:v}=useParams(),O=useUploadAssets(),T=useDispatch(),{scope:d}=useAppContext(),[S,I]=useState(false),[B,N]=useState(false),[P,J]=useState([]),[k,_]=useState([]),[D,p,A]=useEntityMutation(),{currentProjectSchema:w}=useConfig(),[b,W]=useState(""),q=useRef({}),M=useRef({});function u(){return {searchRequests:{searches:[{collection:"_assets"},{collection:"_tags"}]},commonParams:{q:""}}}let h=useMemo(()=>u(),[]),[V,G]=useState(h),{results:z,isLoading:X$1}=useSearch(v??"",V),K=useRef(""),ae=useCallback(Xt(e=>{G({...h,commonParams:{q:e}});},300),[h]);async function o(){await O({projectId:v,accept:"image/*",multiple:true,maxBytes:4*1024*1024});}let l=t.getSelectedRowModel().rows.map(e=>e.original._id),{data:j}=useEntityQuery({entityNamePlural:"_tags",schema:w,scope:d,variables:{where:{},options:{limit:500,offset:0,sort:[{name:"ASC"}]}}}),E=Array.isArray(j)?j.map(e=>({_id:e._id,name:e.name})):[],{data:F}=useEntityQuery({entityNamePlural:"_assets",schema:w,scope:d,variables:{where:{},options:{limit:500,offset:0,sort:[{_updatedAt:"DESC"}]}}});function ee(e){if(e==="image/gif")return "GIF";if(e==="image/jpeg")return "JPEG";if(e==="video/mp4")return "MP4";if(e==="image/png")return "PNG";if(e==="image/svg+xml")return "SVG";if(e==="image/webp")return "WebP";let s=e.split("/");return s.length===2&&s[1]?s[1].toUpperCase():e}function te(e){return e==="image/svg+xml"?SplinePointerIcon:e.startsWith("image/")?ImageIcon:e.startsWith("video/")?FilePlayIcon:LayersIcon}let Ce=useMemo(()=>{let e=Array.isArray(F)?F:[],s=new Set;for(let y of e){let x=y.mimeType??"";x&&s.add(x);}return Array.from(s.values()).sort().map(y=>({value:y,label:ee(y),icon:te(y)}))},[F]),Ze=Ce.length>0?Ce:Vt,et=useMemo(()=>E.map(e=>({value:e._id,label:e.name})),[E]);function Te(){if(!i)return;let e=[];Object.keys(q.current).length>0&&e.push(q.current),Object.keys(M.current).length>0&&e.push(M.current);let s=e.length===0?{}:e.length===1?e[0]:{AND:e},r=JSON.stringify(s);K.current!==r&&(K.current=r,i(s));}async function tt(){T({type:"AlertDialog",payload:{options:{dialogTitle:`Delete ${l.length} asset${l.length>1?"s":""}`,dialogMessage:l.length>1?"Are you sure you want to delete the selected assets? They will be deleted permanently.":"Are you sure you want to delete the selected asset? The item will be deleted permanently.",dialogCancelTitle:"Cancel",dialogActionLabel:"Delete",isDestructive:true,dialogActionCancel:()=>{},dialogActionSubmit:()=>{for(let e of l)T({type:"DeleteEntity",payload:{entityId:e,entityName:m,silent:true}});t.resetRowSelection();}}}});}let nt=useCallback(async()=>{if(l.length===0||P.length===0)return;let e={tags:{relationships:{connect:P.map(r=>({_id:r}))},disabled:false,scope:d}},s=getEntityUpdateMutation("_assets",l[0]??"",d,w,{},e);await new Promise(r=>{p(gql`
14
+ ${s}
15
+ `),A({variables:{where:{_id_IN:l}},onCompleted:()=>r()}),D(true);}),I(false),J([]),t.resetRowSelection();},[D,d,l,P,p,A,t]),at=useCallback(async()=>{if(l.length===0||k.length===0)return;let e={tags:{relationships:{disconnect:k},disabled:false,scope:d}},s=getEntityUpdateMutation("_assets",l[0]??"",d,w,{},e);await new Promise(r=>{p(gql`
16
+ ${s}
17
+ `),A({variables:{where:{_id_IN:l}},onCompleted:()=>r()}),D(true);}),N(false),_([]),t.resetRowSelection();},[D,d,l,k,p,A,t]);useEffect(()=>{if(!i)return;let e=z??[],s=b.trim(),r={};if(s.length===0)r={};else if(e.length===0)r={_id_IN:[]};else {let y=e.filter(L=>L._entityNamePlural==="_assets").map(L=>({_id:L._id})),x=e.filter(L=>L._entityNamePlural==="_tags").map(L=>({tagsConnection_SOME:{node:{_id:L._id}}})),R=[...y,...x];r=R.length>0?{OR:R}:{_id_IN:[]};}q.current=r,Te();},[i,z,b]);let st=JSON.stringify(t.getState().columnFilters);return useEffect(()=>{if(!i)return;let e=t.getState().columnFilters.find(R=>R.id==="mimeType"),s=Array.isArray(e?.value)?e?.value:[],r=t.getState().columnFilters.find(R=>R.id==="tags"),y=Array.isArray(r?.value)?r?.value:[],x=[];if(s.length>0&&x.push({mimeType_IN:s}),y.length>0){let R=y.map(L=>({tagsConnection_SOME:{node:{_id:L}}}));x.push(R.length===1?R[0]:{OR:R});}x.length===0?M.current={}:x.length===1?M.current=x[0]:M.current={AND:x},Te();},[st,i,t]),jsxs("div",{className:"fk-flex fk-items-center fk-justify-between",children:[jsxs("div",{className:"fk-flex fk-flex-1 fk-items-center fk-space-x-2",children:[jsxs("div",{className:"fk-relative",children:[X$1?jsx(LoaderCircle,{className:"fk-absolute fk-left-2 fk-top-2 fk-h-4 fk-w-4 fk-shrink-0 fk-opacity-50 fk-animate-spin"}):jsx(Search,{className:"fk-absolute fk-left-2 fk-top-2 fk-h-4 fk-w-4 fk-shrink-0 fk-opacity-50"}),jsx(Input,{placeholder:"Search assets...",name:"search-assets",value:b,onChange:e=>{let{value:s}=e.target;if(W(s),s.trim().length===0){G({...h,commonParams:{q:""}}),i&&i({});return}ae(s);},className:"fk-h-8 fk-w-[150px] lg:fk-w-[250px] fk-pl-8"}),b?jsx("button",{"aria-label":"Clear search",className:"fk-absolute fk-right-2 fk-top-2 fk-text-muted-foreground hover:fk-text-foreground",onClick:()=>{W(""),G({...h,commonParams:{q:""}}),i&&i({});},type:"button",children:jsx(X,{className:"fk-h-4 fk-w-4"})}):null]}),t.getColumn("mimeType")&&jsx(DataTableFacetedFilter,{column:t.getColumn("mimeType"),title:"File type",options:Ze}),t.getColumn("tags")&&jsx(DataTableFacetedFilter,{column:t.getColumn("tags"),title:"Tags",options:et}),f&&jsxs(Button,{variant:"ghost",onClick:()=>{t.resetColumnFilters(),i&&i({});},className:"fk-h-8 fk-px-2 lg:fk-px-3",children:["Reset",jsx(X,{className:"fk-ml-2 fk-h-4 fk-w-4"})]})]}),l.length>0?jsx("div",{className:"fk-flex fk-items-center fk-gap-2",children:jsxs(DropdownMenu,{children:[jsx(DropdownMenuTrigger,{asChild:true,children:jsxs(Button,{className:"fk-h-8 fk-mr-2 lg:fk-flex",size:"sm",variant:"secondary",children:["Actions ",jsx(ListChecks,{className:"fk-ml-2 fk-h-4 fk-w-4"})]})}),jsxs(DropdownMenuContent,{align:"end",className:"fk-w-[240px]",children:[jsxs(DropdownMenuItem,{onClick:()=>I(true),children:[jsx(TagIcon,{className:"fk-mr-2 fk-h-4 fk-w-4"})," Add tag"]}),jsxs(DropdownMenuItem,{onClick:()=>N(true),children:[jsx(MinusIcon,{className:"fk-mr-2 fk-h-4 fk-w-4"})," Remove tag"]}),jsx(DropdownMenuSeparator,{}),jsxs(DropdownMenuItem,{onClick:tt,className:"fk-text-destructive",children:[jsx(Trash2Icon,{className:"fk-mr-2 fk-h-4 fk-w-4"})," Delete asset",l.length>1?"s":""," (",l.length,")"]})]})]})}):null,jsx(Button,{className:"fk-ml-auto fk-h-8 lg:fk-flex",onClick:o,size:"sm",variant:"default",children:"Upload assets"}),jsxs(CommandDialog,{open:S,onOpenChange:I,children:[jsx(CommandInput,{placeholder:"Search tags..."}),jsxs(CommandList,{className:"fk-h-[300px]",children:[jsx(CommandEmpty,{children:"No tags found."}),jsx(CommandGroup,{heading:"Tags",children:E.map(e=>{let s=P.includes(e._id);return jsxs(CommandItem,{onSelect:()=>{J(r=>s?r.filter(y=>y!==e._id):[...r,e._id]);},children:[jsx("input",{className:"fk-mr-2",checked:s,onChange:()=>{},type:"checkbox"}),e.name]},e._id)})})]}),jsx(CommandSeparator,{}),jsx("div",{className:"fk-p-2",children:jsx(Button,{className:"fk-w-full",onClick:nt,disabled:P.length===0,children:"Add tag(s) to selected assets"})})]}),jsxs(CommandDialog,{open:B,onOpenChange:N,children:[jsx(CommandInput,{placeholder:"Search tags..."}),jsxs(CommandList,{className:"fk-h-[300px]",children:[jsx(CommandEmpty,{children:"No tags found."}),jsx(CommandGroup,{heading:"Tags",children:E.map(e=>{let s=k.includes(e._id);return jsxs(CommandItem,{onSelect:()=>{_(r=>s?r.filter(y=>y!==e._id):[...r,e._id]);},children:[jsx("input",{className:"fk-mr-2",checked:s,onChange:()=>{},type:"checkbox"}),e.name]},e._id)})})]}),jsx(CommandSeparator,{}),jsx("div",{className:"fk-p-2",children:jsx(Button,{className:"fk-w-full",onClick:at,disabled:k.length===0,children:"Remove tag(s) from selected assets"})})]})]})}function Xt(m,t=300){let i;return function(...f){clearTimeout(i),i=setTimeout(()=>m.apply(this,f),t);}}var oe=25;function Ve(){let m="_assets",{search:t}=useLocation(),f=new URLSearchParams(t).get("id"),{scope:v}=useAppContext(),{projects:O,currentProjectId:T}=useConfig(),{schema:d}=find(propEq(T??"","projectId"))(O),S=useGridColumnsDefinition({attributesSchema:assetSchema.attributes,checkboxSelect:"multiple"}),[I,B]=useState({}),N=f?{_id:f}:{NOT:{path:null}},J={where:useMemo(()=>!I||Object.keys(I).length===0||f?N:{AND:[N,I]},[f,I]),options:{offset:0,limit:oe,sort:[{_updatedAt:"DESC"}]}},{isLoading:k,fetchMore:_,count:D,data:p,isProjectDisabled:A}=useEntityQuery({entityNamePlural:m,schema:d,scope:v,variables:J}),w=useRef(null),b=k&&(p==null||p.length===0),W=useCallback(u=>{let h=p?.length??0;if(!k&&u&&D>0&&h>0){let{scrollHeight:V,scrollTop:G,clientHeight:z}=u,X=V-G-z,K=Math.min(500,Math.floor(z*.75));if(X<K&&h<D){if(w.current===h)return;w.current=h,_({variables:{options:{offset:p?.length??0,limit:oe}}});}}},[D,p?.length,_,k]),q=Array(oe).fill({}),M=gn(S);return A?jsx("div",{className:"fk-flex fk-flex-col fk-h-full fk-pl-3",children:jsx(ProjectDisabled,{})}):jsxs("div",{className:"fk-flex fk-flex-col fk-h-full fk-pl-3",children:[jsx(SchemaError,{}),jsx("h2",{className:"fk-mb-4 fk-text-lg fk-font-semibold fk-leading-none fk-tracking-tight",children:"Asset Manager"}),jsx(DataTable,{classNames:{row:"fk-h-20"},columns:b?M:S,data:b?q:p??[],entityName:assetSchema.name,pageSize:oe,onScroll:u=>{W(u.currentTarget);},toolbarComponent:u=>jsx(Je,{entityName:assetSchema.name,table:u,onSearchWhereChange:h=>B(h)})}),jsx(Outlet,{})]})}function gn(m){return m.map(t=>({...t,cell:()=>jsx(Skeleton,{className:"fk-h-4 fk-w-full",style:{marginTop:"7px",marginBottom:"6px"}})}))}function Ke(){return jsxs(ResizablePanelGroup,{direction:"horizontal",className:"fk-h-full",children:[jsx(ResizablePanel,{className:"fk-p-3",defaultSize:82,children:jsx("div",{className:"fk-flex fk-flex-col fk-h-full",children:jsx(Ve,{})})}),jsx(ResizableHandle,{className:"hover:fk-bg-blue-500 fk-transition-colors",withHandle:true}),jsx(ResizablePanel,{defaultSize:18,minSize:10,children:jsx("div",{className:"sm:fk-hidden md:fk-block",children:jsx(Ae,{})})})]})}function Zn(){return {name:"flexkit.asset-manager",contributes:{apps:[{name:"asset-manager",icon:jsx(FileStack,{strokeWidth:1.5}),title:"Asset Manager",component:jsx(Ke,{}),routes:[]}],previewFields:{assetPreviewField:{component:Ie,description:"Asset preview field for the asset manager"}}}}}export{Zn as AssetManager};//# sourceMappingURL=index.js.map
18
18
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/data-grid/preview-components/asset.tsx","../src/sidebar.tsx","../src/data-grid/data-table-toolbar.tsx","../src/list.tsx","../src/root.tsx","../src/index.tsx"],"names":["Asset","value","path","isImage","getExtensionFromPath","p","parts","thumbnaillUrl","IMAGES_BASE_URL","fullUrl","jsx","TooltipProvider","jsxs","Tooltip","TooltipTrigger","TooltipPortal","TooltipContent","ext","style","defaultStyles","FileTypeIcon","Sidebar","scope","useAppContext","schema","useConfig","runMutation","setMutation","setOptions","useEntityMutation","newTagName","setNewTagName","useState","isDialogOpen","setIsDialogOpen","isDeleteOpen","setIsDeleteOpen","tagToDelete","setTagToDelete","isEditOpen","setIsEditOpen","tagToEdit","setTagToEdit","editTagName","setEditTagName","isSubmitting","setIsSubmitting","isDeleting","setIsDeleting","entityName","entityNamePlural","variables","useMemo","data","isLoading","useEntityQuery","tags","item","it","handleCreate","useCallback","name","_id","mutation","getEntityCreateMutation","entityQuery","getEntityQuery","refreshQuery","gql","resolve","handleDelete","getEntityDeleteMutation","handleRename","dataToMutate","originalData","getEntityUpdateMutation","TagIcon","Dialog","DialogTrigger","Button","PlusIcon","DialogContent","DialogHeader","DialogTitle","DialogDescription","Input","e","DialogFooter","Loader2","ScrollArea","tag","DropdownMenu","DropdownMenuTrigger","Ellipsis","DropdownMenuContent","DropdownMenuItem","DropdownMenuSeparator","mimeTypes","ImagePlayIcon","ImageIcon","FilePlayIcon","LayersIcon","SplinePointerIcon","DataTableToolbar","table","onSearchWhereChange","isFiltered","projectId","useParams","uploadAssets","useUploadAssets","dispatch","useDispatch","isTagDialogOpen","setIsTagDialogOpen","isRemoveTagDialogOpen","setIsRemoveTagDialogOpen","selectedTagIds","setSelectedTagIds","selectedRemoveTagIds","setSelectedRemoveTagIds","search","setSearch","textWhereRef","useRef","filterWhereRef","getBaseSearchRequest","baseSearchRequest","searchQuery","setSearchQuery","results","useSearch","lastWhereRef","debouncedSetSearchQuery","debounce","query","handleUpload","selectedIds","row","tagsData","allTags","t","mimeSampleData","getMimeLabel","mime","getMimeIcon","dynamicMimeOptions","items","unique","mimeTypeOptions","tagOptions","emitCombinedWhere","clauses","combinedWhere","whereKey","handleBatchDelete","id","handleAddTagsToSelected","handleRemoveTagsFromSelected","useEffect","safeResults","trimmed","nextWhere","assetIdClauses","r","tagClauses","orClauses","columnFiltersKey","mimeFilter","f","mimeValues","tagsFilter","tagValues","orTags","LoaderCircle","SearchIcon","ResetIcon","DataTableFacetedFilter","ListChecks","MinusIcon","Trash2Icon","CommandDialog","CommandInput","CommandList","CommandEmpty","CommandGroup","isSelected","CommandItem","prev","CommandSeparator","fn","ms","timeoutId","args","pageSize","List","useLocation","entityId","projects","currentProjectId","find","propEq","columnsDefinition","useGridColumnsDefinition","assetSchema","searchWhere","setSearchWhere","whereBase","fetchMore","count","isProjectDisabled","fetchMoreOnBottomReached","containerRefElement","rowsCount","scrollHeight","scrollTop","clientHeight","loadingData","loadingColumns","getLoadingColumns","ProjectDisabled","SchemaError","DataTable","w","Outlet","columns","column","Skeleton","Root","ResizablePanelGroup","ResizablePanel","ResizableHandle","AssetManager","FileStackIcon"],"mappings":"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","file":"index.js","sourcesContent":["import { IMAGES_BASE_URL } from '@flexkit/studio';\nimport { Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger } from '@flexkit/studio/ui';\nimport { FileIcon as FileTypeIcon, defaultStyles } from 'react-file-icon';\n\nexport function Asset({ value }: { value: string }): JSX.Element | null {\n if (!value) {\n return null;\n }\n\n const path = value;\n\n const isImage = /\\.(png|jpe?g|gif|webp|avif|svg)$/i.test(path);\n\n const getExtensionFromPath = (p: string): string => {\n const clean = p.split('?')[0];\n const parts = clean.split('.');\n\n if (parts.length > 1) {\n return parts.pop()!.toLowerCase();\n }\n\n return 'file';\n };\n\n const thumbnaillUrl = path.endsWith('.svg')\n ? `${IMAGES_BASE_URL}${path}`\n : `${IMAGES_BASE_URL}${path}?w=84&h=84&f=webp`;\n\n const fullUrl = path.endsWith('.svg') ? `${IMAGES_BASE_URL}${path}` : `${IMAGES_BASE_URL}${path}?w=624&h=624&f=webp`;\n\n return (\n <div className=\"fk-z-10\">\n <TooltipProvider>\n {isImage ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <img src={thumbnaillUrl} alt=\"asset\" className=\"fk-w-12 fk-h-12 fk-cursor-zoom-in\" />\n </TooltipTrigger>\n <TooltipPortal>\n <TooltipContent>\n <img src={fullUrl} alt=\"asset\" className=\"fk-w-52 fk-h-52\" />\n </TooltipContent>\n </TooltipPortal>\n </Tooltip>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <div className=\"fk-w-7 fk-h-7 fk-rounded fk-bg-transparent fk-flex fk-items-center fk-justify-center [&>svg]:fk-h-full [&>svg]:fk-w-auto\">\n {(() => {\n const ext = getExtensionFromPath(path);\n const style = (\n defaultStyles as Record<string, Record<string, string | number | boolean | undefined>>\n )[ext];\n\n return <FileTypeIcon extension={ext} {...(style || {})} />;\n })()}\n </div>\n </TooltipTrigger>\n <TooltipPortal>\n <TooltipContent>\n <div className=\"fk-text-sm fk-text-muted-foreground\">Preview not available</div>\n </TooltipContent>\n </TooltipPortal>\n </Tooltip>\n )}\n </TooltipProvider>\n </div>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { Loader2, PlusIcon, TagIcon, Ellipsis } from 'lucide-react';\nimport {\n Button,\n Input,\n ScrollArea,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n DialogDescription,\n DialogTrigger,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@flexkit/studio/ui';\nimport {\n gql,\n useAppContext,\n useEntityMutation,\n useEntityQuery,\n getEntityDeleteMutation,\n useConfig,\n} from '@flexkit/studio';\nimport { getEntityCreateMutation, getEntityQuery, getEntityUpdateMutation } from '@flexkit/studio';\nimport type { EntityData, FormEntityItem } from '@flexkit/studio';\n\ntype TagItem = { _id: string; name: string };\n\nexport function Sidebar(): JSX.Element {\n const { scope } = useAppContext();\n const { currentProjectSchema: schema } = useConfig();\n const [runMutation, setMutation, setOptions] = useEntityMutation();\n const [newTagName, setNewTagName] = useState<string>('');\n const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);\n const [isDeleteOpen, setIsDeleteOpen] = useState<boolean>(false);\n const [tagToDelete, setTagToDelete] = useState<TagItem | null>(null);\n const [isEditOpen, setIsEditOpen] = useState<boolean>(false);\n const [tagToEdit, setTagToEdit] = useState<TagItem | null>(null);\n const [editTagName, setEditTagName] = useState<string>('');\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n const [isDeleting, setIsDeleting] = useState<boolean>(false);\n\n const entityName = '_tag';\n const entityNamePlural = '_tags';\n const variables = useMemo(() => ({ where: {}, options: { limit: 200, offset: 0, sort: [{ name: 'ASC' }] } }), []);\n const { data, isLoading } = useEntityQuery({\n entityNamePlural,\n schema,\n scope,\n variables,\n });\n\n const tags: TagItem[] = (Array.isArray(data) ? (data as unknown[]) : []).map((item) => {\n const it = item as { _id: string; name: string };\n return { _id: it._id, name: it.name };\n });\n\n const handleCreate = useCallback(async (): Promise<void> => {\n const name = newTagName.trim();\n\n if (!name) {\n return;\n }\n\n setIsSubmitting(true);\n const _id = typeof crypto !== 'undefined' && 'randomUUID' in crypto ? crypto.randomUUID() : `${Date.now()}`;\n const entityData = { name: { value: name, disabled: false, scope: 'default' } } as unknown as EntityData;\n const mutation = getEntityCreateMutation(entityNamePlural, schema, entityData, _id);\n const entityQuery = getEntityQuery(entityNamePlural, scope, schema);\n const refreshQuery = gql`\n ${entityQuery.query}\n `;\n\n await new Promise<void>((resolve) => {\n setMutation(gql`\n ${mutation}\n `);\n setOptions({\n refetchQueries: [refreshQuery],\n onCompleted: () => {\n setNewTagName('');\n setIsDialogOpen(false);\n resolve();\n },\n });\n runMutation(true);\n });\n setIsSubmitting(false);\n }, [entityNamePlural, runMutation, schema, scope, setMutation, setOptions, newTagName]);\n\n const handleDelete = useCallback(\n async (_id: string): Promise<void> => {\n setIsDeleting(true);\n const mutation = getEntityDeleteMutation(entityName, schema, _id);\n const entityQuery = getEntityQuery(entityNamePlural, scope, schema);\n const refreshQuery = gql`\n ${entityQuery.query}\n `;\n\n await new Promise<void>((resolve) => {\n setMutation(gql`\n ${mutation}\n `);\n setOptions({\n variables: { where: { _id } },\n refetchQueries: [refreshQuery],\n onCompleted: () => {\n resolve();\n },\n });\n runMutation(true);\n });\n setIsDeleting(false);\n },\n [entityName, entityNamePlural, runMutation, schema, scope, setMutation, setOptions]\n );\n\n const handleRename = useCallback(async (): Promise<void> => {\n const name = editTagName.trim();\n\n if (!name || !tagToEdit) {\n return;\n }\n\n setIsSubmitting(true);\n\n const dataToMutate = { name: { value: name, disabled: false, scope: 'default' } } as unknown as EntityData;\n const originalData = {} as unknown as FormEntityItem;\n const mutation = getEntityUpdateMutation(\n entityNamePlural,\n tagToEdit._id,\n scope,\n schema,\n originalData,\n dataToMutate\n );\n const entityQuery = getEntityQuery(entityNamePlural, scope, schema);\n const refreshQuery = gql`\n ${entityQuery.query}\n `;\n\n await new Promise<void>((resolve) => {\n setMutation(gql`\n ${mutation}\n `);\n setOptions({\n variables: { where: { _id: tagToEdit._id } },\n refetchQueries: [refreshQuery],\n onCompleted: () => {\n setIsEditOpen(false);\n setTagToEdit(null);\n setEditTagName('');\n resolve();\n },\n });\n runMutation(true);\n });\n\n setIsSubmitting(false);\n }, [editTagName, entityNamePlural, runMutation, schema, scope, setMutation, setOptions, tagToEdit]);\n\n return (\n <div className=\"fk-flex fk-h-full fk-max-h-screen fk-flex-col fk-gap-2\">\n <div className=\"fk-flex fk-h-12 fk-items-center fk-border-b fk-border-b-border fk-px-4 fk-lg:fk-h-[60px] fk-lg:fk-px-6\">\n <TagIcon className=\"fk-h-4 fk-w-4\" />\n <span className=\"fk-px-4 fk-text-sm fk-font-semibold fk-tracking-tight\">Tags</span>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>\n <DialogTrigger asChild>\n <Button variant=\"secondary\" size=\"icon\" className=\"fk-ml-auto fk-h-8 fk-w-8\">\n <PlusIcon className=\"fk-h-4 fk-w-4\" />\n <span className=\"fk-sr-only\">Add tag</span>\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>New tag</DialogTitle>\n <DialogDescription className=\"fk-sr-only\">Create a new tag</DialogDescription>\n </DialogHeader>\n <div className=\"fk-flex fk-gap-2\">\n <Input\n autoFocus\n value={newTagName}\n placeholder=\"New tag name\"\n onChange={(e) => setNewTagName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n void handleCreate();\n }\n }}\n />\n </div>\n <DialogFooter>\n <Button disabled={isSubmitting} onClick={handleCreate} variant=\"default\">\n {isSubmitting ? <Loader2 className=\"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin\" /> : null}\n Add\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </TooltipTrigger>\n <TooltipContent>\n <p>Add tag</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </div>\n\n <ScrollArea className=\"fk-h-full\">\n <div className=\"fk-flex fk-flex-col fk-gap-2 fk-px-4 fk-py-2\">\n {isLoading ? (\n <div className=\"fk-text-sm fk-text-muted-foreground\">Loading...</div>\n ) : tags.length === 0 ? (\n <div className=\"fk-text-sm fk-text-muted-foreground\">No tags yet</div>\n ) : (\n tags.map((tag) => (\n <div\n key={tag._id}\n className=\"fk-group fk-flex fk-items-center fk-justify-between fk-rounded fk-border fk-border-border fk-bg-card fk-px-3 fk-py-1\"\n >\n <span className=\"fk-text-sm\">{tag.name}</span>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n aria-label={`Actions for ${tag.name}`}\n title={`Actions for ${tag.name}`}\n variant=\"ghost\"\n size=\"icon\"\n className=\"fk-h-7 fk-w-7 fk-text-muted-foreground hover:fk-text-foreground\"\n >\n <Ellipsis className=\"fk-h-4 fk-w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-[160px]\">\n <DropdownMenuItem\n onClick={() => {\n setTagToEdit(tag);\n setEditTagName(tag.name);\n setIsEditOpen(true);\n }}\n >\n Edit\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"fk-text-destructive\"\n onClick={() => {\n setTagToDelete(tag);\n setIsDeleteOpen(true);\n }}\n >\n Remove\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n ))\n )}\n </div>\n </ScrollArea>\n <Dialog open={isEditOpen} onOpenChange={setIsEditOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Edit tag</DialogTitle>\n <DialogDescription className=\"fk-sr-only\">Rename an existing tag</DialogDescription>\n </DialogHeader>\n <div className=\"fk-flex fk-gap-2\">\n <Input\n autoFocus\n value={editTagName}\n placeholder=\"Tag name\"\n onChange={(e) => setEditTagName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n void handleRename();\n }\n }}\n />\n </div>\n <DialogFooter>\n <Button\n disabled={isSubmitting}\n variant=\"secondary\"\n onClick={() => {\n setIsEditOpen(false);\n setTagToEdit(null);\n }}\n >\n Cancel\n </Button>\n <Button disabled={isSubmitting} onClick={handleRename} variant=\"default\">\n {isSubmitting ? <Loader2 className=\"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin\" /> : null}\n Save\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n <Dialog open={isDeleteOpen} onOpenChange={setIsDeleteOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Delete tag</DialogTitle>\n <DialogDescription className=\"fk-sr-only\">Confirm deletion of a tag</DialogDescription>\n </DialogHeader>\n <div className=\"fk-text-sm fk-text-muted-foreground\">\n Are you sure you want to delete the tag{' '}\n <span className=\"fk-font-semibold fk-text-foreground\">{tagToDelete?.name}</span>?\n </div>\n <DialogFooter>\n <Button\n disabled={isDeleting}\n variant=\"secondary\"\n onClick={() => {\n setIsDeleteOpen(false);\n setTagToDelete(null);\n }}\n >\n Cancel\n </Button>\n <Button\n disabled={isDeleting}\n variant=\"destructive\"\n onClick={() => {\n if (!tagToDelete) {\n return;\n }\n\n void (async () => {\n await handleDelete(tagToDelete._id);\n setIsDeleteOpen(false);\n setTagToDelete(null);\n })();\n }}\n >\n {isDeleting ? <Loader2 className=\"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin\" /> : null}\n Delete\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </div>\n );\n}\n","'use client';\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n FilePlayIcon,\n ImageIcon,\n ImagePlayIcon,\n LayersIcon,\n ListChecks,\n MinusIcon,\n SplinePointerIcon,\n TagIcon,\n Trash2Icon,\n LoaderCircle,\n Search as SearchIcon,\n X as ResetIcon,\n} from 'lucide-react';\nimport type { ReactTable, SearchRequestProps } from '@flexkit/studio';\nimport {\n Button,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandItem,\n CommandGroup,\n CommandEmpty,\n CommandSeparator,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Input,\n} from '@flexkit/studio/ui';\nimport {\n DataTableFacetedFilter,\n useParams,\n useUploadAssets,\n useDispatch,\n useEntityQuery,\n useEntityMutation,\n useAppContext,\n gql,\n useConfig,\n getEntityUpdateMutation,\n useSearch,\n} from '@flexkit/studio';\n\ninterface DataTableToolbarProps<TData> {\n entityName: string;\n table: ReactTable<TData>;\n onSearchWhereChange?: (where: Record<string, unknown>) => void;\n}\n\nconst mimeTypes = [\n {\n value: 'image/gif',\n label: 'GIF',\n icon: ImagePlayIcon,\n },\n {\n value: 'image/jpeg',\n label: 'JPEG',\n icon: ImageIcon,\n },\n {\n value: 'video/mp4',\n label: 'MP4',\n icon: FilePlayIcon,\n },\n {\n value: 'image/png',\n label: 'PNG',\n icon: LayersIcon,\n },\n {\n value: 'image/svg+xml',\n label: 'SVG',\n icon: SplinePointerIcon,\n },\n {\n value: 'image/webp',\n label: 'WebP',\n icon: ImageIcon,\n },\n];\n\nexport function DataTableToolbar<TData>({\n entityName,\n table,\n onSearchWhereChange,\n}: DataTableToolbarProps<TData>): JSX.Element {\n const isFiltered = table.getState().columnFilters.length > 0;\n const { projectId } = useParams();\n const uploadAssets = useUploadAssets();\n const dispatch = useDispatch();\n const { scope } = useAppContext();\n const [isTagDialogOpen, setIsTagDialogOpen] = useState(false);\n const [isRemoveTagDialogOpen, setIsRemoveTagDialogOpen] = useState(false);\n const [selectedTagIds, setSelectedTagIds] = useState<string[]>([]);\n const [selectedRemoveTagIds, setSelectedRemoveTagIds] = useState<string[]>([]);\n const [runMutation, setMutation, setOptions] = useEntityMutation();\n const { currentProjectSchema: schema } = useConfig();\n const [search, setSearch] = useState('');\n const textWhereRef = useRef<Record<string, unknown>>({});\n const filterWhereRef = useRef<Record<string, unknown>>({});\n\n function getBaseSearchRequest(): SearchRequestProps {\n return {\n searchRequests: {\n searches: [{ collection: '_assets' }, { collection: '_tags' }],\n },\n commonParams: { q: '' },\n };\n }\n\n const baseSearchRequest = useMemo(() => getBaseSearchRequest(), []);\n const [searchQuery, setSearchQuery] = useState<SearchRequestProps>(baseSearchRequest);\n const { results, isLoading } = useSearch(projectId ?? '', searchQuery);\n const lastWhereRef = useRef<string>('');\n\n const debouncedSetSearchQuery = useCallback(\n debounce((query: string) => {\n setSearchQuery({ ...baseSearchRequest, commonParams: { q: query } });\n }, 300),\n [baseSearchRequest]\n );\n\n async function handleUpload(): Promise<void> {\n await uploadAssets({ projectId, accept: 'image/*', multiple: true, maxBytes: 4 * 1024 * 1024 });\n }\n\n // Collect selected entity ids from the table\n const selectedIds: string[] = table\n .getSelectedRowModel()\n .rows.map((row) => (row.original as unknown as { _id: string })._id);\n\n // Load tags for the selector\n const { data: tagsData } = useEntityQuery({\n entityNamePlural: '_tags',\n schema,\n scope,\n variables: { where: {}, options: { limit: 500, offset: 0, sort: [{ name: 'ASC' }] } },\n });\n const allTags = Array.isArray(tagsData)\n ? (tagsData as unknown[]).map((t) => ({ _id: (t as { _id: string })._id, name: (t as { name: string }).name }))\n : [];\n\n // Load a sample of assets to derive dynamic mime type options\n const { data: mimeSampleData } = useEntityQuery({\n entityNamePlural: '_assets',\n schema,\n scope,\n variables: { where: {}, options: { limit: 500, offset: 0, sort: [{ _updatedAt: 'DESC' }] } },\n });\n\n type AssetItem = { _id: string; mimeType?: string | null };\n\n function getMimeLabel(mime: string): string {\n if (mime === 'image/gif') {\n return 'GIF';\n }\n\n if (mime === 'image/jpeg') {\n return 'JPEG';\n }\n\n if (mime === 'video/mp4') {\n return 'MP4';\n }\n\n if (mime === 'image/png') {\n return 'PNG';\n }\n\n if (mime === 'image/svg+xml') {\n return 'SVG';\n }\n\n if (mime === 'image/webp') {\n return 'WebP';\n }\n\n const parts = mime.split('/');\n\n if (parts.length === 2 && parts[1]) {\n return parts[1].toUpperCase();\n }\n\n return mime;\n }\n\n function getMimeIcon(mime: string) {\n if (mime === 'image/svg+xml') {\n return SplinePointerIcon;\n }\n\n if (mime.startsWith('image/')) {\n return ImageIcon;\n }\n\n if (mime.startsWith('video/')) {\n return FilePlayIcon;\n }\n\n return LayersIcon;\n }\n\n const dynamicMimeOptions = useMemo(() => {\n const items = Array.isArray(mimeSampleData) ? (mimeSampleData as unknown as AssetItem[]) : [];\n const unique = new Set<string>();\n\n for (const item of items) {\n const value = item.mimeType ?? '';\n\n if (value) {\n unique.add(value);\n }\n }\n\n const values = Array.from(unique.values()).sort();\n\n return values.map((value) => ({ value, label: getMimeLabel(value), icon: getMimeIcon(value) }));\n }, [mimeSampleData]);\n\n const mimeTypeOptions = dynamicMimeOptions.length > 0 ? dynamicMimeOptions : mimeTypes;\n\n const tagOptions = useMemo(() => {\n return allTags.map((t) => ({ value: t._id, label: t.name }));\n }, [allTags]);\n\n function emitCombinedWhere(): void {\n if (!onSearchWhereChange) {\n return;\n }\n\n const clauses: Record<string, unknown>[] = [];\n\n if (Object.keys(textWhereRef.current).length > 0) {\n clauses.push(textWhereRef.current);\n }\n\n if (Object.keys(filterWhereRef.current).length > 0) {\n clauses.push(filterWhereRef.current);\n }\n\n const combinedWhere = clauses.length === 0 ? {} : clauses.length === 1 ? clauses[0] : { AND: clauses };\n const whereKey = JSON.stringify(combinedWhere);\n\n if (lastWhereRef.current !== whereKey) {\n lastWhereRef.current = whereKey;\n onSearchWhereChange(combinedWhere);\n }\n }\n\n async function handleBatchDelete(): Promise<void> {\n dispatch({\n type: 'AlertDialog',\n payload: {\n options: {\n dialogTitle: `Delete ${selectedIds.length} asset${selectedIds.length > 1 ? 's' : ''}`,\n dialogMessage:\n selectedIds.length > 1\n ? `Are you sure you want to delete the selected assets? They will be deleted permanently.`\n : `Are you sure you want to delete the selected asset? The item will be deleted permanently.`,\n dialogCancelTitle: 'Cancel',\n dialogActionLabel: 'Delete',\n isDestructive: true,\n dialogActionCancel: () => {},\n dialogActionSubmit: () => {\n for (const id of selectedIds) {\n const payload = { entityId: id, entityName, silent: true } as unknown as {\n entityId: string;\n entityName: string;\n };\n dispatch({ type: 'DeleteEntity', payload });\n }\n\n table.resetRowSelection();\n },\n },\n },\n });\n }\n\n const handleAddTagsToSelected = useCallback(async (): Promise<void> => {\n if (selectedIds.length === 0 || selectedTagIds.length === 0) {\n return;\n }\n\n // Build relationship connect for multiple tags\n const dataToMutate = {\n tags: {\n relationships: {\n connect: selectedTagIds.map((id) => ({ _id: id })),\n },\n disabled: false,\n scope,\n },\n } as unknown as Record<string, unknown>;\n\n const mutation = getEntityUpdateMutation('_assets', selectedIds[0] ?? '', scope, schema, {}, dataToMutate as never);\n\n await new Promise<void>((resolve) => {\n setMutation(gql`\n ${mutation}\n `);\n setOptions({\n variables: { where: { _id_IN: selectedIds } },\n onCompleted: () => resolve(),\n });\n runMutation(true);\n });\n\n setIsTagDialogOpen(false);\n setSelectedTagIds([]);\n table.resetRowSelection();\n }, [runMutation, scope, selectedIds, selectedTagIds, setMutation, setOptions, table]);\n\n const handleRemoveTagsFromSelected = useCallback(async (): Promise<void> => {\n if (selectedIds.length === 0 || selectedRemoveTagIds.length === 0) {\n return;\n }\n\n const dataToMutate = {\n tags: {\n relationships: {\n disconnect: selectedRemoveTagIds,\n },\n disabled: false,\n scope,\n },\n } as unknown as Record<string, unknown>;\n\n const mutation = getEntityUpdateMutation('_assets', selectedIds[0] ?? '', scope, schema, {}, dataToMutate as never);\n\n await new Promise<void>((resolve) => {\n setMutation(gql`\n ${mutation}\n `);\n setOptions({\n variables: { where: { _id_IN: selectedIds } },\n onCompleted: () => resolve(),\n });\n runMutation(true);\n });\n\n setIsRemoveTagDialogOpen(false);\n setSelectedRemoveTagIds([]);\n table.resetRowSelection();\n }, [runMutation, scope, selectedIds, selectedRemoveTagIds, setMutation, setOptions, table]);\n\n useEffect(() => {\n if (!onSearchWhereChange) {\n return;\n }\n\n const safeResults = results ?? [];\n const trimmed = search.trim();\n\n let nextWhere: Record<string, unknown> = {};\n\n if (trimmed.length === 0) {\n nextWhere = {};\n } else if (safeResults.length === 0) {\n nextWhere = { _id_IN: [] };\n } else {\n const assetIdClauses = safeResults.filter((r) => r._entityNamePlural === '_assets').map((r) => ({ _id: r._id }));\n\n const tagClauses = safeResults\n .filter((r) => r._entityNamePlural === '_tags')\n .map((r) => ({ tagsConnection_SOME: { node: { _id: r._id } } }));\n\n const orClauses = [...assetIdClauses, ...tagClauses];\n nextWhere = orClauses.length > 0 ? { OR: orClauses } : { _id_IN: [] };\n }\n\n textWhereRef.current = nextWhere;\n emitCombinedWhere();\n }, [onSearchWhereChange, results, search]);\n\n // Watch column filter changes (e.g., mime type) and push server-side where\n const columnFiltersKey = JSON.stringify(table.getState().columnFilters);\n\n useEffect(() => {\n if (!onSearchWhereChange) {\n return;\n }\n\n const mimeFilter = table.getState().columnFilters.find((f) => f.id === 'mimeType');\n const mimeValues = (Array.isArray(mimeFilter?.value) ? (mimeFilter?.value as unknown[]) : []) as string[];\n\n const tagsFilter = table.getState().columnFilters.find((f) => f.id === 'tags');\n const tagValues = (Array.isArray(tagsFilter?.value) ? (tagsFilter?.value as unknown[]) : []) as string[];\n\n const clauses: Record<string, unknown>[] = [];\n\n if (mimeValues.length > 0) {\n clauses.push({ mimeType_IN: mimeValues } as Record<string, unknown>);\n }\n\n if (tagValues.length > 0) {\n const orTags = tagValues.map((id) => ({ tagsConnection_SOME: { node: { _id: id } } }));\n clauses.push(orTags.length === 1 ? orTags[0] : { OR: orTags });\n }\n\n if (clauses.length === 0) {\n filterWhereRef.current = {};\n } else if (clauses.length === 1) {\n filterWhereRef.current = clauses[0] as Record<string, unknown>;\n } else {\n filterWhereRef.current = { AND: clauses } as Record<string, unknown>;\n }\n\n emitCombinedWhere();\n }, [columnFiltersKey, onSearchWhereChange, table]);\n\n return (\n <div className=\"fk-flex fk-items-center fk-justify-between\">\n <div className=\"fk-flex fk-flex-1 fk-items-center fk-space-x-2\">\n <div className=\"fk-relative\">\n {isLoading ? (\n <LoaderCircle className=\"fk-absolute fk-left-2 fk-top-2 fk-h-4 fk-w-4 fk-shrink-0 fk-opacity-50 fk-animate-spin\" />\n ) : (\n <SearchIcon className=\"fk-absolute fk-left-2 fk-top-2 fk-h-4 fk-w-4 fk-shrink-0 fk-opacity-50\" />\n )}\n <Input\n placeholder=\"Search assets...\"\n name=\"search-assets\"\n value={search}\n onChange={(e) => {\n const value = e.target.value;\n setSearch(value);\n\n if (value.trim().length === 0) {\n setSearchQuery({ ...baseSearchRequest, commonParams: { q: '' } });\n\n if (onSearchWhereChange) {\n onSearchWhereChange({});\n }\n\n return;\n }\n\n debouncedSetSearchQuery(value);\n }}\n className=\"fk-h-8 fk-w-[150px] lg:fk-w-[250px] fk-pl-8\"\n />\n {search ? (\n <button\n aria-label=\"Clear search\"\n className=\"fk-absolute fk-right-2 fk-top-2 fk-text-muted-foreground hover:fk-text-foreground\"\n onClick={() => {\n setSearch('');\n setSearchQuery({ ...baseSearchRequest, commonParams: { q: '' } });\n if (onSearchWhereChange) {\n onSearchWhereChange({});\n }\n }}\n type=\"button\"\n >\n <ResetIcon className=\"fk-h-4 fk-w-4\" />\n </button>\n ) : null}\n </div>\n {table.getColumn('mimeType') && (\n <DataTableFacetedFilter column={table.getColumn('mimeType')} title=\"File type\" options={mimeTypeOptions} />\n )}\n {table.getColumn('tags') && (\n <DataTableFacetedFilter column={table.getColumn('tags')} title=\"Tags\" options={tagOptions} />\n )}\n {isFiltered && (\n <Button\n variant=\"ghost\"\n onClick={() => {\n table.resetColumnFilters();\n\n if (onSearchWhereChange) {\n onSearchWhereChange({});\n }\n }}\n className=\"fk-h-8 fk-px-2 lg:fk-px-3\"\n >\n Reset\n <ResetIcon className=\"fk-ml-2 fk-h-4 fk-w-4\" />\n </Button>\n )}\n </div>\n {selectedIds.length > 0 ? (\n <div className=\"fk-flex fk-items-center fk-gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button className=\"fk-h-8 fk-mr-2 lg:fk-flex\" size=\"sm\" variant=\"secondary\">\n Actions <ListChecks className=\"fk-ml-2 fk-h-4 fk-w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"fk-w-[240px]\">\n <DropdownMenuItem onClick={() => setIsTagDialogOpen(true)}>\n <TagIcon className=\"fk-mr-2 fk-h-4 fk-w-4\" /> Add tag\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => setIsRemoveTagDialogOpen(true)}>\n <MinusIcon className=\"fk-mr-2 fk-h-4 fk-w-4\" /> Remove tag\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={handleBatchDelete} className=\"fk-text-destructive\">\n <Trash2Icon className=\"fk-mr-2 fk-h-4 fk-w-4\" /> Delete asset{selectedIds.length > 1 ? 's' : ''} (\n {selectedIds.length})\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n ) : null}\n <Button className=\"fk-ml-auto fk-h-8 lg:fk-flex\" onClick={handleUpload} size=\"sm\" variant=\"default\">\n Upload assets\n </Button>\n\n <CommandDialog open={isTagDialogOpen} onOpenChange={setIsTagDialogOpen}>\n <CommandInput placeholder=\"Search tags...\" />\n <CommandList className=\"fk-h-[300px]\">\n <CommandEmpty>No tags found.</CommandEmpty>\n <CommandGroup heading=\"Tags\">\n {allTags.map((tag) => {\n const isSelected = selectedTagIds.includes(tag._id);\n return (\n <CommandItem\n key={tag._id}\n onSelect={() => {\n setSelectedTagIds((prev) =>\n isSelected ? prev.filter((id) => id !== tag._id) : [...prev, tag._id]\n );\n }}\n >\n <input className=\"fk-mr-2\" checked={isSelected} onChange={() => {}} type=\"checkbox\" />\n {tag.name}\n </CommandItem>\n );\n })}\n </CommandGroup>\n </CommandList>\n <CommandSeparator />\n <div className=\"fk-p-2\">\n <Button className=\"fk-w-full\" onClick={handleAddTagsToSelected} disabled={selectedTagIds.length === 0}>\n Add tag(s) to selected assets\n </Button>\n </div>\n </CommandDialog>\n\n <CommandDialog open={isRemoveTagDialogOpen} onOpenChange={setIsRemoveTagDialogOpen}>\n <CommandInput placeholder=\"Search tags...\" />\n <CommandList className=\"fk-h-[300px]\">\n <CommandEmpty>No tags found.</CommandEmpty>\n <CommandGroup heading=\"Tags\">\n {allTags.map((tag) => {\n const isSelected = selectedRemoveTagIds.includes(tag._id);\n return (\n <CommandItem\n key={tag._id}\n onSelect={() => {\n setSelectedRemoveTagIds((prev) =>\n isSelected ? prev.filter((id) => id !== tag._id) : [...prev, tag._id]\n );\n }}\n >\n <input className=\"fk-mr-2\" checked={isSelected} onChange={() => {}} type=\"checkbox\" />\n {tag.name}\n </CommandItem>\n );\n })}\n </CommandGroup>\n </CommandList>\n <CommandSeparator />\n <div className=\"fk-p-2\">\n <Button\n className=\"fk-w-full\"\n onClick={handleRemoveTagsFromSelected}\n disabled={selectedRemoveTagIds.length === 0}\n >\n Remove tag(s) from selected assets\n </Button>\n </div>\n </CommandDialog>\n </div>\n );\n}\n\nfunction debounce<TArgs extends unknown[]>(fn: (...args: TArgs) => void, ms = 300) {\n let timeoutId: ReturnType<typeof setTimeout>;\n\n return function (this: unknown, ...args: TArgs) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn.apply(this, args), ms);\n };\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { find, propEq } from 'ramda';\nimport {\n assetSchema,\n useAppContext,\n useConfig,\n useLocation,\n Outlet,\n useEntityQuery,\n ProjectDisabled,\n SchemaError,\n} from '@flexkit/studio';\nimport { Skeleton } from '@flexkit/studio/ui';\nimport { DataTable } from '@flexkit/studio/data-grid';\nimport type { ColumnDef, SingleProject, Row } from '@flexkit/studio';\nimport { useGridColumnsDefinition } from '@flexkit/studio/data-grid';\nimport { DataTableToolbar } from './data-grid/data-table-toolbar';\n\nconst pageSize = 25;\n\nexport function List(): JSX.Element {\n const entityName = '_assets';\n const { search } = useLocation();\n const query = new URLSearchParams(search);\n const entityId = query.get('id');\n const { scope } = useAppContext();\n const { projects, currentProjectId } = useConfig();\n const { schema } = find(propEq(currentProjectId ?? '', 'projectId'))(projects) as SingleProject;\n const columnsDefinition = useGridColumnsDefinition({\n attributesSchema: assetSchema.attributes,\n checkboxSelect: 'multiple',\n });\n\n const [searchWhere, setSearchWhere] = useState<Record<string, unknown>>({});\n\n const whereBase = entityId ? { _id: entityId } : { NOT: { path: null } };\n const where = useMemo(() => {\n if (!searchWhere || Object.keys(searchWhere).length === 0) {\n return whereBase;\n }\n\n if (entityId) {\n return whereBase; // ignore search when a single asset is selected via id\n }\n\n return { AND: [whereBase, searchWhere] } as Record<string, unknown>;\n }, [entityId, searchWhere]);\n\n const variables = { where, options: { offset: 0, limit: pageSize, sort: [{ _updatedAt: 'DESC' }] } };\n\n const { isLoading, fetchMore, count, data, isProjectDisabled } = useEntityQuery({\n entityNamePlural: entityName ?? '',\n schema,\n scope,\n variables,\n });\n\n // called on scroll and possibly on mount to fetch more data as the user scrolls and reaches bottom of table\n const fetchMoreOnBottomReached = useCallback(\n (containerRefElement?: HTMLDivElement | null) => {\n const rowsCount = data?.length ?? 0;\n\n if (containerRefElement && count > 0 && rowsCount > 0) {\n const { scrollHeight, scrollTop, clientHeight } = containerRefElement;\n //once the user has scrolled within 500px of the bottom of the table, fetch more data if we can\n if (scrollHeight - scrollTop - clientHeight < 500 && !isLoading && rowsCount < count) {\n fetchMore({\n variables: {\n options: {\n offset: data?.length ?? 0,\n limit: pageSize,\n },\n },\n });\n }\n }\n },\n [count, data?.length, fetchMore, isLoading]\n );\n\n const loadingData = Array(pageSize).fill({});\n const loadingColumns = getLoadingColumns(columnsDefinition);\n\n if (isProjectDisabled) {\n return (\n <div className=\"fk-flex fk-flex-col fk-h-full fk-pl-3\">\n <ProjectDisabled />\n </div>\n );\n }\n\n return (\n <div className=\"fk-flex fk-flex-col fk-h-full fk-pl-3\">\n <SchemaError />\n <h2 className=\"fk-mb-4 fk-text-lg fk-font-semibold fk-leading-none fk-tracking-tight\">Asset Manager</h2>\n <DataTable\n classNames={{ row: 'fk-h-20' }}\n columns={isLoading ? loadingColumns : columnsDefinition}\n data={isLoading ? loadingData : (data ?? [])}\n entityName={assetSchema.name}\n pageSize={pageSize}\n onScroll={(e) => {\n fetchMoreOnBottomReached(e.target as HTMLDivElement);\n }}\n toolbarComponent={(table) => (\n <DataTableToolbar\n entityName={assetSchema.name}\n table={table}\n onSearchWhereChange={(w) => setSearchWhere(w)}\n />\n )}\n />\n <Outlet />\n </div>\n );\n}\n\ntype AttributeValue = {\n _id: string;\n [key: string]: string | AttributeValue | null;\n __typename: string;\n};\n\nfunction getLoadingColumns(columns: object[]): ColumnDef<AttributeValue>[] {\n return columns.map((column) => ({\n ...column,\n cell: () => <Skeleton className=\"fk-h-4 fk-w-full\" style={{ marginTop: '7px', marginBottom: '6px' }} />,\n })) as unknown as ColumnDef<AttributeValue>[];\n}\n","'use client';\n\nimport { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@flexkit/studio/ui';\nimport { Sidebar } from './sidebar';\nimport { List } from './list';\n\nexport function Root(): JSX.Element {\n return (\n <ResizablePanelGroup direction=\"horizontal\" className=\"fk-h-full\">\n <ResizablePanel className=\"fk-p-3\" defaultSize={82}>\n <div className=\"fk-flex fk-flex-col fk-h-full\">\n <List />\n </div>\n </ResizablePanel>\n <ResizableHandle className=\"hover:fk-bg-blue-500 fk-transition-colors\" withHandle />\n <ResizablePanel defaultSize={18} minSize={10}>\n <div className=\"sm:fk-hidden md:fk-block\">\n <Sidebar />\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n );\n}\n","import './styles.css';\n\nimport { FileStack as FileStackIcon } from 'lucide-react';\nimport type { PluginOptions } from '@flexkit/studio';\nimport { Asset } from './data-grid/preview-components/asset';\nimport { Root } from './root';\n\nexport function AssetManager(): PluginOptions {\n return {\n name: 'flexkit.asset-manager',\n contributes: {\n apps: [\n {\n name: 'asset-manager',\n icon: <FileStackIcon strokeWidth={1.5} />,\n title: 'Asset Manager',\n component: <Root />,\n routes: [],\n },\n ],\n previewFields: {\n assetPreviewField: {\n component: Asset,\n description: 'Asset preview field for the asset manager',\n },\n },\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/data-grid/preview-components/asset.tsx","../src/sidebar.tsx","../src/data-grid/data-table-toolbar.tsx","../src/list.tsx","../src/root.tsx","../src/index.tsx"],"names":["FileTypeIconCompat","FileTypeIcon","Asset","value","path","isImage","getExtensionFromPath","p","clean","parts","thumbnaillUrl","IMAGES_BASE_URL","fullUrl","jsx","TooltipProvider","jsxs","Tooltip","TooltipTrigger","TooltipPortal","TooltipContent","ext","style","defaultStyles","Sidebar","scope","useAppContext","schema","useConfig","runMutation","setMutation","setOptions","useEntityMutation","newTagName","setNewTagName","useState","isDialogOpen","setIsDialogOpen","isDeleteOpen","setIsDeleteOpen","tagToDelete","setTagToDelete","isEditOpen","setIsEditOpen","tagToEdit","setTagToEdit","editTagName","setEditTagName","isSubmitting","setIsSubmitting","isDeleting","setIsDeleting","entityName","entityNamePlural","variables","useMemo","data","isLoading","useEntityQuery","tags","item","it","handleCreate","useCallback","name","_id","mutation","getEntityCreateMutation","entityQuery","getEntityQuery","refreshQuery","gql","resolve","handleDelete","getEntityDeleteMutation","handleRename","dataToMutate","originalData","getEntityUpdateMutation","TagIcon","Dialog","DialogTrigger","Button","PlusIcon","DialogContent","DialogHeader","DialogTitle","DialogDescription","Input","e","DialogFooter","Loader2","ScrollArea","tag","DropdownMenu","DropdownMenuTrigger","Ellipsis","DropdownMenuContent","DropdownMenuItem","DropdownMenuSeparator","mimeTypes","ImagePlayIcon","ImageIcon","FilePlayIcon","LayersIcon","SplinePointerIcon","DataTableToolbar","table","onSearchWhereChange","isFiltered","projectId","useParams","uploadAssets","useUploadAssets","dispatch","useDispatch","isTagDialogOpen","setIsTagDialogOpen","isRemoveTagDialogOpen","setIsRemoveTagDialogOpen","selectedTagIds","setSelectedTagIds","selectedRemoveTagIds","setSelectedRemoveTagIds","search","setSearch","textWhereRef","useRef","filterWhereRef","getBaseSearchRequest","baseSearchRequest","searchQuery","setSearchQuery","results","useSearch","lastWhereRef","debouncedSetSearchQuery","debounce","query","handleUpload","selectedIds","row","tagsData","allTags","t","mimeSampleData","getMimeLabel","mime","getMimeIcon","dynamicMimeOptions","items","unique","mimeTypeOptions","tagOptions","emitCombinedWhere","clauses","combinedWhere","whereKey","handleBatchDelete","id","handleAddTagsToSelected","handleRemoveTagsFromSelected","useEffect","safeResults","trimmed","nextWhere","assetIdClauses","r","tagClauses","orClauses","columnFiltersKey","mimeFilter","f","mimeValues","tagsFilter","tagValues","orTags","LoaderCircle","SearchIcon","ResetIcon","DataTableFacetedFilter","ListChecks","MinusIcon","Trash2Icon","CommandDialog","CommandInput","CommandList","CommandEmpty","CommandGroup","isSelected","CommandItem","prev","CommandSeparator","fn","ms","timeoutId","args","pageSize","List","useLocation","entityId","projects","currentProjectId","find","propEq","columnsDefinition","useGridColumnsDefinition","assetSchema","searchWhere","setSearchWhere","whereBase","fetchMore","count","isProjectDisabled","lastRequestedOffsetRef","isInitialLoading","fetchMoreOnBottomReached","containerRefElement","rowsCount","scrollHeight","scrollTop","clientHeight","remaining","threshold","loadingData","loadingColumns","getLoadingColumns","ProjectDisabled","SchemaError","DataTable","w","Outlet","columns","column","Skeleton","Root","ResizablePanelGroup","ResizablePanel","ResizableHandle","AssetManager","FileStackIcon"],"mappings":"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","file":"index.js","sourcesContent":["import { IMAGES_BASE_URL } from '@flexkit/studio';\nimport { Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger } from '@flexkit/studio/ui';\nimport type { ComponentType } from 'react';\nimport { FileIcon as FileTypeIcon, defaultStyles } from 'react-file-icon';\n\n// Temporary fix due to runtime mismatch between React 18 and React 19 types\ntype FileTypeIconCompatProps = {\n extension: string;\n [key: string]: string | number | boolean | undefined;\n};\n\nconst FileTypeIconCompat = FileTypeIcon as unknown as ComponentType<FileTypeIconCompatProps>;\n\nexport function Asset({ value }: { value: string }): JSX.Element | null {\n if (!value) {\n return null;\n }\n\n const path = value;\n\n const isImage = /\\.(png|jpe?g|gif|webp|avif|svg)$/i.test(path);\n\n const getExtensionFromPath = (p: string): string => {\n const [clean] = p.split('?');\n const parts = clean.split('.');\n\n if (parts.length > 1) {\n return parts.pop()!.toLowerCase();\n }\n\n return 'file';\n };\n\n const thumbnaillUrl = path.endsWith('.svg')\n ? `${IMAGES_BASE_URL}${path}`\n : `${IMAGES_BASE_URL}${path}?w=84&h=84&f=webp`;\n\n const fullUrl = path.endsWith('.svg') ? `${IMAGES_BASE_URL}${path}` : `${IMAGES_BASE_URL}${path}?w=624&h=624&f=webp`;\n\n return (\n <div className=\"fk-z-10\">\n <TooltipProvider>\n {isImage ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <img src={thumbnaillUrl} alt=\"asset\" className=\"fk-w-12 fk-h-12 fk-cursor-zoom-in\" />\n </TooltipTrigger>\n <TooltipPortal>\n <TooltipContent>\n <img src={fullUrl} alt=\"asset\" className=\"fk-w-52 fk-h-52\" />\n </TooltipContent>\n </TooltipPortal>\n </Tooltip>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <div className=\"fk-w-7 fk-h-7 fk-rounded fk-bg-transparent fk-flex fk-items-center fk-justify-center [&>svg]:fk-h-full [&>svg]:fk-w-auto\">\n {(() => {\n const ext = getExtensionFromPath(path);\n const style = (\n defaultStyles as unknown as {\n [key: string]: { [key: string]: string | number | boolean | undefined } | undefined;\n }\n )[ext];\n\n return <FileTypeIconCompat extension={ext} {...(style || {})} />;\n })()}\n </div>\n </TooltipTrigger>\n <TooltipPortal>\n <TooltipContent>\n <div className=\"fk-text-sm fk-text-muted-foreground\">Preview not available</div>\n </TooltipContent>\n </TooltipPortal>\n </Tooltip>\n )}\n </TooltipProvider>\n </div>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { Loader2, PlusIcon, TagIcon, Ellipsis } from 'lucide-react';\nimport {\n Button,\n Input,\n ScrollArea,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n DialogDescription,\n DialogTrigger,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@flexkit/studio/ui';\nimport {\n gql,\n useAppContext,\n useEntityMutation,\n useEntityQuery,\n getEntityDeleteMutation,\n useConfig,\n} from '@flexkit/studio';\nimport { getEntityCreateMutation, getEntityQuery, getEntityUpdateMutation } from '@flexkit/studio';\nimport type { EntityData, FormEntityItem } from '@flexkit/studio';\n\ntype TagItem = { _id: string; name: string };\n\nexport function Sidebar(): JSX.Element {\n const { scope } = useAppContext();\n const { currentProjectSchema: schema } = useConfig();\n const [runMutation, setMutation, setOptions] = useEntityMutation();\n const [newTagName, setNewTagName] = useState<string>('');\n const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);\n const [isDeleteOpen, setIsDeleteOpen] = useState<boolean>(false);\n const [tagToDelete, setTagToDelete] = useState<TagItem | null>(null);\n const [isEditOpen, setIsEditOpen] = useState<boolean>(false);\n const [tagToEdit, setTagToEdit] = useState<TagItem | null>(null);\n const [editTagName, setEditTagName] = useState<string>('');\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n const [isDeleting, setIsDeleting] = useState<boolean>(false);\n\n const entityName = '_tag';\n const entityNamePlural = '_tags';\n const variables = useMemo(() => ({ where: {}, options: { limit: 200, offset: 0, sort: [{ name: 'ASC' }] } }), []);\n const { data, isLoading } = useEntityQuery({\n entityNamePlural,\n schema,\n scope,\n variables,\n });\n\n const tags: TagItem[] = (Array.isArray(data) ? (data as unknown[]) : []).map((item) => {\n const it = item as { _id: string; name: string };\n return { _id: it._id, name: it.name };\n });\n\n const handleCreate = useCallback(async (): Promise<void> => {\n const name = newTagName.trim();\n\n if (!name) {\n return;\n }\n\n setIsSubmitting(true);\n const _id = typeof crypto !== 'undefined' && 'randomUUID' in crypto ? crypto.randomUUID() : `${Date.now()}`;\n const entityData = { name: { value: name, disabled: false, scope: 'default' } } as unknown as EntityData;\n const mutation = getEntityCreateMutation(entityNamePlural, schema, entityData, _id);\n const entityQuery = getEntityQuery(entityNamePlural, scope, schema);\n const refreshQuery = gql`\n ${entityQuery.query}\n `;\n\n await new Promise<void>((resolve) => {\n setMutation(gql`\n ${mutation}\n `);\n setOptions({\n refetchQueries: [refreshQuery],\n onCompleted: () => {\n setNewTagName('');\n setIsDialogOpen(false);\n resolve();\n },\n });\n runMutation(true);\n });\n setIsSubmitting(false);\n }, [entityNamePlural, runMutation, schema, scope, setMutation, setOptions, newTagName]);\n\n const handleDelete = useCallback(\n async (_id: string): Promise<void> => {\n setIsDeleting(true);\n const mutation = getEntityDeleteMutation(entityName, schema, _id);\n const entityQuery = getEntityQuery(entityNamePlural, scope, schema);\n const refreshQuery = gql`\n ${entityQuery.query}\n `;\n\n await new Promise<void>((resolve) => {\n setMutation(gql`\n ${mutation}\n `);\n setOptions({\n variables: { where: { _id } },\n refetchQueries: [refreshQuery],\n onCompleted: () => {\n resolve();\n },\n });\n runMutation(true);\n });\n setIsDeleting(false);\n },\n [entityName, entityNamePlural, runMutation, schema, scope, setMutation, setOptions]\n );\n\n const handleRename = useCallback(async (): Promise<void> => {\n const name = editTagName.trim();\n\n if (!name || !tagToEdit) {\n return;\n }\n\n setIsSubmitting(true);\n\n const dataToMutate = { name: { value: name, disabled: false, scope: 'default' } } as unknown as EntityData;\n const originalData = {} as unknown as FormEntityItem;\n const mutation = getEntityUpdateMutation(\n entityNamePlural,\n tagToEdit._id,\n scope,\n schema,\n originalData,\n dataToMutate\n );\n const entityQuery = getEntityQuery(entityNamePlural, scope, schema);\n const refreshQuery = gql`\n ${entityQuery.query}\n `;\n\n await new Promise<void>((resolve) => {\n setMutation(gql`\n ${mutation}\n `);\n setOptions({\n variables: { where: { _id: tagToEdit._id } },\n refetchQueries: [refreshQuery],\n onCompleted: () => {\n setIsEditOpen(false);\n setTagToEdit(null);\n setEditTagName('');\n resolve();\n },\n });\n runMutation(true);\n });\n\n setIsSubmitting(false);\n }, [editTagName, entityNamePlural, runMutation, schema, scope, setMutation, setOptions, tagToEdit]);\n\n return (\n <div className=\"fk-flex fk-h-full fk-max-h-screen fk-flex-col fk-gap-2\">\n <div className=\"fk-flex fk-h-12 fk-items-center fk-border-b fk-border-b-border fk-px-4 fk-lg:fk-h-[60px] fk-lg:fk-px-6\">\n <TagIcon className=\"fk-h-4 fk-w-4\" />\n <span className=\"fk-px-4 fk-text-sm fk-font-semibold fk-tracking-tight\">Tags</span>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>\n <DialogTrigger asChild>\n <Button variant=\"secondary\" size=\"icon\" className=\"fk-ml-auto fk-h-8 fk-w-8\">\n <PlusIcon className=\"fk-h-4 fk-w-4\" />\n <span className=\"fk-sr-only\">Add tag</span>\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>New tag</DialogTitle>\n <DialogDescription className=\"fk-sr-only\">Create a new tag</DialogDescription>\n </DialogHeader>\n <div className=\"fk-flex fk-gap-2\">\n <Input\n autoFocus\n value={newTagName}\n placeholder=\"New tag name\"\n onChange={(e) => setNewTagName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n void handleCreate();\n }\n }}\n />\n </div>\n <DialogFooter>\n <Button disabled={isSubmitting} onClick={handleCreate} variant=\"default\">\n {isSubmitting ? <Loader2 className=\"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin\" /> : null}\n Add\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </TooltipTrigger>\n <TooltipContent>\n <p>Add tag</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </div>\n\n <ScrollArea className=\"fk-h-full\">\n <div className=\"fk-flex fk-flex-col fk-gap-2 fk-px-4 fk-py-2\">\n {isLoading ? (\n <div className=\"fk-text-sm fk-text-muted-foreground\">Loading...</div>\n ) : tags.length === 0 ? (\n <div className=\"fk-text-sm fk-text-muted-foreground\">No tags yet</div>\n ) : (\n tags.map((tag) => (\n <div\n key={tag._id}\n className=\"fk-group fk-flex fk-items-center fk-justify-between fk-rounded fk-border fk-border-border fk-bg-card fk-px-3 fk-py-1\"\n >\n <span className=\"fk-text-sm\">{tag.name}</span>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n aria-label={`Actions for ${tag.name}`}\n title={`Actions for ${tag.name}`}\n variant=\"ghost\"\n size=\"icon\"\n className=\"fk-h-7 fk-w-7 fk-text-muted-foreground hover:fk-text-foreground\"\n >\n <Ellipsis className=\"fk-h-4 fk-w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-[160px]\">\n <DropdownMenuItem\n onClick={() => {\n setTagToEdit(tag);\n setEditTagName(tag.name);\n setIsEditOpen(true);\n }}\n >\n Edit\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"fk-text-destructive\"\n onClick={() => {\n setTagToDelete(tag);\n setIsDeleteOpen(true);\n }}\n >\n Remove\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n ))\n )}\n </div>\n </ScrollArea>\n <Dialog open={isEditOpen} onOpenChange={setIsEditOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Edit tag</DialogTitle>\n <DialogDescription className=\"fk-sr-only\">Rename an existing tag</DialogDescription>\n </DialogHeader>\n <div className=\"fk-flex fk-gap-2\">\n <Input\n autoFocus\n value={editTagName}\n placeholder=\"Tag name\"\n onChange={(e) => setEditTagName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n void handleRename();\n }\n }}\n />\n </div>\n <DialogFooter>\n <Button\n disabled={isSubmitting}\n variant=\"secondary\"\n onClick={() => {\n setIsEditOpen(false);\n setTagToEdit(null);\n }}\n >\n Cancel\n </Button>\n <Button disabled={isSubmitting} onClick={handleRename} variant=\"default\">\n {isSubmitting ? <Loader2 className=\"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin\" /> : null}\n Save\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n <Dialog open={isDeleteOpen} onOpenChange={setIsDeleteOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Delete tag</DialogTitle>\n <DialogDescription className=\"fk-sr-only\">Confirm deletion of a tag</DialogDescription>\n </DialogHeader>\n <div className=\"fk-text-sm fk-text-muted-foreground\">\n Are you sure you want to delete the tag{' '}\n <span className=\"fk-font-semibold fk-text-foreground\">{tagToDelete?.name}</span>?\n </div>\n <DialogFooter>\n <Button\n disabled={isDeleting}\n variant=\"secondary\"\n onClick={() => {\n setIsDeleteOpen(false);\n setTagToDelete(null);\n }}\n >\n Cancel\n </Button>\n <Button\n disabled={isDeleting}\n variant=\"destructive\"\n onClick={() => {\n if (!tagToDelete) {\n return;\n }\n\n void (async () => {\n await handleDelete(tagToDelete._id);\n setIsDeleteOpen(false);\n setTagToDelete(null);\n })();\n }}\n >\n {isDeleting ? <Loader2 className=\"fk-h-4 fk-w-4 fk-mr-2 fk-animate-spin\" /> : null}\n Delete\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </div>\n );\n}\n","'use client';\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n FilePlayIcon,\n ImageIcon,\n ImagePlayIcon,\n LayersIcon,\n ListChecks,\n MinusIcon,\n SplinePointerIcon,\n TagIcon,\n Trash2Icon,\n LoaderCircle,\n Search as SearchIcon,\n X as ResetIcon,\n} from 'lucide-react';\nimport type { ReactTable, SearchRequestProps } from '@flexkit/studio';\nimport {\n Button,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandItem,\n CommandGroup,\n CommandEmpty,\n CommandSeparator,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Input,\n} from '@flexkit/studio/ui';\nimport {\n DataTableFacetedFilter,\n useParams,\n useUploadAssets,\n useDispatch,\n useEntityQuery,\n useEntityMutation,\n useAppContext,\n gql,\n useConfig,\n getEntityUpdateMutation,\n useSearch,\n} from '@flexkit/studio';\n\ninterface DataTableToolbarProps<TData> {\n entityName: string;\n table: ReactTable<TData>;\n onSearchWhereChange?: (where: WhereClause) => void;\n}\n\ntype WhereClause = { [key: string]: unknown };\n\nconst mimeTypes = [\n {\n value: 'image/gif',\n label: 'GIF',\n icon: ImagePlayIcon,\n },\n {\n value: 'image/jpeg',\n label: 'JPEG',\n icon: ImageIcon,\n },\n {\n value: 'video/mp4',\n label: 'MP4',\n icon: FilePlayIcon,\n },\n {\n value: 'image/png',\n label: 'PNG',\n icon: LayersIcon,\n },\n {\n value: 'image/svg+xml',\n label: 'SVG',\n icon: SplinePointerIcon,\n },\n {\n value: 'image/webp',\n label: 'WebP',\n icon: ImageIcon,\n },\n];\n\nexport function DataTableToolbar<TData>({\n entityName,\n table,\n onSearchWhereChange,\n}: DataTableToolbarProps<TData>): JSX.Element {\n const isFiltered = table.getState().columnFilters.length > 0;\n const { projectId } = useParams();\n const uploadAssets = useUploadAssets();\n const dispatch = useDispatch();\n const { scope } = useAppContext();\n const [isTagDialogOpen, setIsTagDialogOpen] = useState(false);\n const [isRemoveTagDialogOpen, setIsRemoveTagDialogOpen] = useState(false);\n const [selectedTagIds, setSelectedTagIds] = useState<string[]>([]);\n const [selectedRemoveTagIds, setSelectedRemoveTagIds] = useState<string[]>([]);\n const [runMutation, setMutation, setOptions] = useEntityMutation();\n const { currentProjectSchema: schema } = useConfig();\n const [search, setSearch] = useState('');\n const textWhereRef = useRef<WhereClause>({});\n const filterWhereRef = useRef<WhereClause>({});\n\n function getBaseSearchRequest(): SearchRequestProps {\n return {\n searchRequests: {\n searches: [{ collection: '_assets' }, { collection: '_tags' }],\n },\n commonParams: { q: '' },\n };\n }\n\n const baseSearchRequest = useMemo(() => getBaseSearchRequest(), []);\n const [searchQuery, setSearchQuery] = useState<SearchRequestProps>(baseSearchRequest);\n const { results, isLoading } = useSearch(projectId ?? '', searchQuery);\n const lastWhereRef = useRef<string>('');\n\n const debouncedSetSearchQuery = useCallback(\n debounce((query: string) => {\n setSearchQuery({ ...baseSearchRequest, commonParams: { q: query } });\n }, 300),\n [baseSearchRequest]\n );\n\n async function handleUpload(): Promise<void> {\n await uploadAssets({ projectId, accept: 'image/*', multiple: true, maxBytes: 4 * 1024 * 1024 });\n }\n\n // Collect selected entity ids from the table\n const selectedIds: string[] = table\n .getSelectedRowModel()\n .rows.map((row) => (row.original as unknown as { _id: string })._id);\n\n // Load tags for the selector\n const { data: tagsData } = useEntityQuery({\n entityNamePlural: '_tags',\n schema,\n scope,\n variables: { where: {}, options: { limit: 500, offset: 0, sort: [{ name: 'ASC' }] } },\n });\n const allTags = Array.isArray(tagsData)\n ? (tagsData as unknown[]).map((t) => ({ _id: (t as { _id: string })._id, name: (t as { name: string }).name }))\n : [];\n\n // Load a sample of assets to derive dynamic mime type options\n const { data: mimeSampleData } = useEntityQuery({\n entityNamePlural: '_assets',\n schema,\n scope,\n variables: { where: {}, options: { limit: 500, offset: 0, sort: [{ _updatedAt: 'DESC' }] } },\n });\n\n type AssetItem = { _id: string; mimeType?: string | null };\n\n function getMimeLabel(mime: string): string {\n if (mime === 'image/gif') {\n return 'GIF';\n }\n\n if (mime === 'image/jpeg') {\n return 'JPEG';\n }\n\n if (mime === 'video/mp4') {\n return 'MP4';\n }\n\n if (mime === 'image/png') {\n return 'PNG';\n }\n\n if (mime === 'image/svg+xml') {\n return 'SVG';\n }\n\n if (mime === 'image/webp') {\n return 'WebP';\n }\n\n const parts = mime.split('/');\n\n if (parts.length === 2 && parts[1]) {\n return parts[1].toUpperCase();\n }\n\n return mime;\n }\n\n function getMimeIcon(mime: string) {\n if (mime === 'image/svg+xml') {\n return SplinePointerIcon;\n }\n\n if (mime.startsWith('image/')) {\n return ImageIcon;\n }\n\n if (mime.startsWith('video/')) {\n return FilePlayIcon;\n }\n\n return LayersIcon;\n }\n\n const dynamicMimeOptions = useMemo(() => {\n const items = Array.isArray(mimeSampleData) ? (mimeSampleData as unknown as AssetItem[]) : [];\n const unique = new Set<string>();\n\n for (const item of items) {\n const value = item.mimeType ?? '';\n\n if (value) {\n unique.add(value);\n }\n }\n\n const values = Array.from(unique.values()).sort();\n\n return values.map((value) => ({ value, label: getMimeLabel(value), icon: getMimeIcon(value) }));\n }, [mimeSampleData]);\n\n const mimeTypeOptions = dynamicMimeOptions.length > 0 ? dynamicMimeOptions : mimeTypes;\n\n const tagOptions = useMemo(() => {\n return allTags.map((t) => ({ value: t._id, label: t.name }));\n }, [allTags]);\n\n function emitCombinedWhere(): void {\n if (!onSearchWhereChange) {\n return;\n }\n\n const clauses: WhereClause[] = [];\n\n if (Object.keys(textWhereRef.current).length > 0) {\n clauses.push(textWhereRef.current);\n }\n\n if (Object.keys(filterWhereRef.current).length > 0) {\n clauses.push(filterWhereRef.current);\n }\n\n const combinedWhere = clauses.length === 0 ? {} : clauses.length === 1 ? clauses[0] : { AND: clauses };\n const whereKey = JSON.stringify(combinedWhere);\n\n if (lastWhereRef.current !== whereKey) {\n lastWhereRef.current = whereKey;\n onSearchWhereChange(combinedWhere);\n }\n }\n\n async function handleBatchDelete(): Promise<void> {\n dispatch({\n type: 'AlertDialog',\n payload: {\n options: {\n dialogTitle: `Delete ${selectedIds.length} asset${selectedIds.length > 1 ? 's' : ''}`,\n dialogMessage:\n selectedIds.length > 1\n ? `Are you sure you want to delete the selected assets? They will be deleted permanently.`\n : `Are you sure you want to delete the selected asset? The item will be deleted permanently.`,\n dialogCancelTitle: 'Cancel',\n dialogActionLabel: 'Delete',\n isDestructive: true,\n dialogActionCancel: () => {},\n dialogActionSubmit: () => {\n for (const id of selectedIds) {\n const payload = { entityId: id, entityName, silent: true } as unknown as {\n entityId: string;\n entityName: string;\n };\n dispatch({ type: 'DeleteEntity', payload });\n }\n\n table.resetRowSelection();\n },\n },\n },\n });\n }\n\n const handleAddTagsToSelected = useCallback(async (): Promise<void> => {\n if (selectedIds.length === 0 || selectedTagIds.length === 0) {\n return;\n }\n\n // Build relationship connect for multiple tags\n const dataToMutate = {\n tags: {\n relationships: {\n connect: selectedTagIds.map((id) => ({ _id: id })),\n },\n disabled: false,\n scope,\n },\n } as unknown as WhereClause;\n\n const mutation = getEntityUpdateMutation('_assets', selectedIds[0] ?? '', scope, schema, {}, dataToMutate as never);\n\n await new Promise<void>((resolve) => {\n setMutation(gql`\n ${mutation}\n `);\n setOptions({\n variables: { where: { _id_IN: selectedIds } },\n onCompleted: () => resolve(),\n });\n runMutation(true);\n });\n\n setIsTagDialogOpen(false);\n setSelectedTagIds([]);\n table.resetRowSelection();\n }, [runMutation, scope, selectedIds, selectedTagIds, setMutation, setOptions, table]);\n\n const handleRemoveTagsFromSelected = useCallback(async (): Promise<void> => {\n if (selectedIds.length === 0 || selectedRemoveTagIds.length === 0) {\n return;\n }\n\n const dataToMutate = {\n tags: {\n relationships: {\n disconnect: selectedRemoveTagIds,\n },\n disabled: false,\n scope,\n },\n } as unknown as WhereClause;\n\n const mutation = getEntityUpdateMutation('_assets', selectedIds[0] ?? '', scope, schema, {}, dataToMutate as never);\n\n await new Promise<void>((resolve) => {\n setMutation(gql`\n ${mutation}\n `);\n setOptions({\n variables: { where: { _id_IN: selectedIds } },\n onCompleted: () => resolve(),\n });\n runMutation(true);\n });\n\n setIsRemoveTagDialogOpen(false);\n setSelectedRemoveTagIds([]);\n table.resetRowSelection();\n }, [runMutation, scope, selectedIds, selectedRemoveTagIds, setMutation, setOptions, table]);\n\n useEffect(() => {\n if (!onSearchWhereChange) {\n return;\n }\n\n const safeResults = results ?? [];\n const trimmed = search.trim();\n\n let nextWhere: WhereClause = {};\n\n if (trimmed.length === 0) {\n nextWhere = {};\n } else if (safeResults.length === 0) {\n nextWhere = { _id_IN: [] };\n } else {\n const assetIdClauses = safeResults.filter((r) => r._entityNamePlural === '_assets').map((r) => ({ _id: r._id }));\n\n const tagClauses = safeResults\n .filter((r) => r._entityNamePlural === '_tags')\n .map((r) => ({ tagsConnection_SOME: { node: { _id: r._id } } }));\n\n const orClauses = [...assetIdClauses, ...tagClauses];\n nextWhere = orClauses.length > 0 ? { OR: orClauses } : { _id_IN: [] };\n }\n\n textWhereRef.current = nextWhere;\n emitCombinedWhere();\n }, [onSearchWhereChange, results, search]);\n\n // Watch column filter changes (e.g., mime type) and push server-side where\n const columnFiltersKey = JSON.stringify(table.getState().columnFilters);\n\n useEffect(() => {\n if (!onSearchWhereChange) {\n return;\n }\n\n const mimeFilter = table.getState().columnFilters.find((f) => f.id === 'mimeType');\n const mimeValues = (Array.isArray(mimeFilter?.value) ? (mimeFilter?.value as unknown[]) : []) as string[];\n\n const tagsFilter = table.getState().columnFilters.find((f) => f.id === 'tags');\n const tagValues = (Array.isArray(tagsFilter?.value) ? (tagsFilter?.value as unknown[]) : []) as string[];\n\n const clauses: WhereClause[] = [];\n\n if (mimeValues.length > 0) {\n clauses.push({ mimeType_IN: mimeValues } as WhereClause);\n }\n\n if (tagValues.length > 0) {\n const orTags = tagValues.map((id) => ({ tagsConnection_SOME: { node: { _id: id } } }));\n clauses.push(orTags.length === 1 ? orTags[0] : { OR: orTags });\n }\n\n if (clauses.length === 0) {\n filterWhereRef.current = {};\n } else if (clauses.length === 1) {\n filterWhereRef.current = clauses[0] as WhereClause;\n } else {\n filterWhereRef.current = { AND: clauses } as WhereClause;\n }\n\n emitCombinedWhere();\n }, [columnFiltersKey, onSearchWhereChange, table]);\n\n return (\n <div className=\"fk-flex fk-items-center fk-justify-between\">\n <div className=\"fk-flex fk-flex-1 fk-items-center fk-space-x-2\">\n <div className=\"fk-relative\">\n {isLoading ? (\n <LoaderCircle className=\"fk-absolute fk-left-2 fk-top-2 fk-h-4 fk-w-4 fk-shrink-0 fk-opacity-50 fk-animate-spin\" />\n ) : (\n <SearchIcon className=\"fk-absolute fk-left-2 fk-top-2 fk-h-4 fk-w-4 fk-shrink-0 fk-opacity-50\" />\n )}\n <Input\n placeholder=\"Search assets...\"\n name=\"search-assets\"\n value={search}\n onChange={(e) => {\n const { value } = e.target;\n setSearch(value);\n\n if (value.trim().length === 0) {\n setSearchQuery({ ...baseSearchRequest, commonParams: { q: '' } });\n\n if (onSearchWhereChange) {\n onSearchWhereChange({});\n }\n\n return;\n }\n\n debouncedSetSearchQuery(value);\n }}\n className=\"fk-h-8 fk-w-[150px] lg:fk-w-[250px] fk-pl-8\"\n />\n {search ? (\n <button\n aria-label=\"Clear search\"\n className=\"fk-absolute fk-right-2 fk-top-2 fk-text-muted-foreground hover:fk-text-foreground\"\n onClick={() => {\n setSearch('');\n setSearchQuery({ ...baseSearchRequest, commonParams: { q: '' } });\n if (onSearchWhereChange) {\n onSearchWhereChange({});\n }\n }}\n type=\"button\"\n >\n <ResetIcon className=\"fk-h-4 fk-w-4\" />\n </button>\n ) : null}\n </div>\n {table.getColumn('mimeType') && (\n <DataTableFacetedFilter column={table.getColumn('mimeType')} title=\"File type\" options={mimeTypeOptions} />\n )}\n {table.getColumn('tags') && (\n <DataTableFacetedFilter column={table.getColumn('tags')} title=\"Tags\" options={tagOptions} />\n )}\n {isFiltered && (\n <Button\n variant=\"ghost\"\n onClick={() => {\n table.resetColumnFilters();\n\n if (onSearchWhereChange) {\n onSearchWhereChange({});\n }\n }}\n className=\"fk-h-8 fk-px-2 lg:fk-px-3\"\n >\n Reset\n <ResetIcon className=\"fk-ml-2 fk-h-4 fk-w-4\" />\n </Button>\n )}\n </div>\n {selectedIds.length > 0 ? (\n <div className=\"fk-flex fk-items-center fk-gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button className=\"fk-h-8 fk-mr-2 lg:fk-flex\" size=\"sm\" variant=\"secondary\">\n Actions <ListChecks className=\"fk-ml-2 fk-h-4 fk-w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"fk-w-[240px]\">\n <DropdownMenuItem onClick={() => setIsTagDialogOpen(true)}>\n <TagIcon className=\"fk-mr-2 fk-h-4 fk-w-4\" /> Add tag\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => setIsRemoveTagDialogOpen(true)}>\n <MinusIcon className=\"fk-mr-2 fk-h-4 fk-w-4\" /> Remove tag\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={handleBatchDelete} className=\"fk-text-destructive\">\n <Trash2Icon className=\"fk-mr-2 fk-h-4 fk-w-4\" /> Delete asset{selectedIds.length > 1 ? 's' : ''} (\n {selectedIds.length})\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n ) : null}\n <Button className=\"fk-ml-auto fk-h-8 lg:fk-flex\" onClick={handleUpload} size=\"sm\" variant=\"default\">\n Upload assets\n </Button>\n\n <CommandDialog open={isTagDialogOpen} onOpenChange={setIsTagDialogOpen}>\n <CommandInput placeholder=\"Search tags...\" />\n <CommandList className=\"fk-h-[300px]\">\n <CommandEmpty>No tags found.</CommandEmpty>\n <CommandGroup heading=\"Tags\">\n {allTags.map((tag) => {\n const isSelected = selectedTagIds.includes(tag._id);\n return (\n <CommandItem\n key={tag._id}\n onSelect={() => {\n setSelectedTagIds((prev) =>\n isSelected ? prev.filter((id) => id !== tag._id) : [...prev, tag._id]\n );\n }}\n >\n <input className=\"fk-mr-2\" checked={isSelected} onChange={() => {}} type=\"checkbox\" />\n {tag.name}\n </CommandItem>\n );\n })}\n </CommandGroup>\n </CommandList>\n <CommandSeparator />\n <div className=\"fk-p-2\">\n <Button className=\"fk-w-full\" onClick={handleAddTagsToSelected} disabled={selectedTagIds.length === 0}>\n Add tag(s) to selected assets\n </Button>\n </div>\n </CommandDialog>\n\n <CommandDialog open={isRemoveTagDialogOpen} onOpenChange={setIsRemoveTagDialogOpen}>\n <CommandInput placeholder=\"Search tags...\" />\n <CommandList className=\"fk-h-[300px]\">\n <CommandEmpty>No tags found.</CommandEmpty>\n <CommandGroup heading=\"Tags\">\n {allTags.map((tag) => {\n const isSelected = selectedRemoveTagIds.includes(tag._id);\n return (\n <CommandItem\n key={tag._id}\n onSelect={() => {\n setSelectedRemoveTagIds((prev) =>\n isSelected ? prev.filter((id) => id !== tag._id) : [...prev, tag._id]\n );\n }}\n >\n <input className=\"fk-mr-2\" checked={isSelected} onChange={() => {}} type=\"checkbox\" />\n {tag.name}\n </CommandItem>\n );\n })}\n </CommandGroup>\n </CommandList>\n <CommandSeparator />\n <div className=\"fk-p-2\">\n <Button\n className=\"fk-w-full\"\n onClick={handleRemoveTagsFromSelected}\n disabled={selectedRemoveTagIds.length === 0}\n >\n Remove tag(s) from selected assets\n </Button>\n </div>\n </CommandDialog>\n </div>\n );\n}\n\nfunction debounce<TArgs extends unknown[]>(fn: (...args: TArgs) => void, ms = 300) {\n let timeoutId: ReturnType<typeof setTimeout>;\n\n return function (this: unknown, ...args: TArgs) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn.apply(this, args), ms);\n };\n}\n","import { useCallback, useMemo, useRef, useState } from 'react';\nimport { find, propEq } from 'ramda';\nimport {\n assetSchema,\n DataTable,\n useAppContext,\n useConfig,\n useLocation,\n Outlet,\n useEntityQuery,\n ProjectDisabled,\n SchemaError,\n useGridColumnsDefinition,\n} from '@flexkit/studio';\nimport { Skeleton } from '@flexkit/studio/ui';\nimport type { ColumnDef, SingleProject } from '@flexkit/studio';\nimport { DataTableToolbar } from './data-grid/data-table-toolbar';\n\ntype WhereClause = { [key: string]: unknown };\n\nconst pageSize = 25;\n\nexport function List(): JSX.Element {\n const entityName = '_assets';\n const { search } = useLocation();\n const query = new URLSearchParams(search);\n const entityId = query.get('id');\n const { scope } = useAppContext();\n const { projects, currentProjectId } = useConfig();\n const { schema } = find(propEq(currentProjectId ?? '', 'projectId'))(projects) as SingleProject;\n const columnsDefinition = useGridColumnsDefinition({\n attributesSchema: assetSchema.attributes,\n checkboxSelect: 'multiple',\n });\n\n const [searchWhere, setSearchWhere] = useState<WhereClause>({});\n\n const whereBase = entityId ? { _id: entityId } : { NOT: { path: null } };\n const where = useMemo(() => {\n if (!searchWhere || Object.keys(searchWhere).length === 0) {\n return whereBase;\n }\n\n if (entityId) {\n return whereBase; // ignore search when a single asset is selected via id\n }\n\n return { AND: [whereBase, searchWhere] } as WhereClause;\n }, [entityId, searchWhere]);\n\n const variables = { where, options: { offset: 0, limit: pageSize, sort: [{ _updatedAt: 'DESC' }] } };\n\n const { isLoading, fetchMore, count, data, isProjectDisabled } = useEntityQuery({\n entityNamePlural: entityName ?? '',\n schema,\n scope,\n variables,\n });\n\n const lastRequestedOffsetRef = useRef<number | null>(null);\n const isInitialLoading = isLoading && (data == null || data.length === 0);\n\n // called on scroll and possibly on mount to fetch more data as the user scrolls and reaches bottom of table\n const fetchMoreOnBottomReached = useCallback(\n (containerRefElement?: HTMLDivElement | null) => {\n const rowsCount = data?.length ?? 0;\n\n if (isLoading) {\n return;\n }\n\n if (containerRefElement && count > 0 && rowsCount > 0) {\n const { scrollHeight, scrollTop, clientHeight } = containerRefElement;\n const remaining = scrollHeight - scrollTop - clientHeight;\n const threshold = Math.min(500, Math.floor(clientHeight * 0.75));\n\n //once the user has scrolled within 500px of the bottom of the table, fetch more data if we can\n if (remaining < threshold && rowsCount < count) {\n if (lastRequestedOffsetRef.current === rowsCount) {\n return;\n }\n\n lastRequestedOffsetRef.current = rowsCount;\n\n fetchMore({\n variables: {\n options: {\n offset: data?.length ?? 0,\n limit: pageSize,\n },\n },\n });\n }\n }\n },\n [count, data?.length, fetchMore, isLoading]\n );\n\n const loadingData = Array(pageSize).fill({});\n const loadingColumns = getLoadingColumns(columnsDefinition);\n\n if (isProjectDisabled) {\n return (\n <div className=\"fk-flex fk-flex-col fk-h-full fk-pl-3\">\n <ProjectDisabled />\n </div>\n );\n }\n\n return (\n <div className=\"fk-flex fk-flex-col fk-h-full fk-pl-3\">\n <SchemaError />\n <h2 className=\"fk-mb-4 fk-text-lg fk-font-semibold fk-leading-none fk-tracking-tight\">Asset Manager</h2>\n <DataTable\n classNames={{ row: 'fk-h-20' }}\n columns={isInitialLoading ? loadingColumns : columnsDefinition}\n data={isInitialLoading ? loadingData : (data ?? [])}\n entityName={assetSchema.name}\n pageSize={pageSize}\n onScroll={(e) => {\n fetchMoreOnBottomReached(e.currentTarget as HTMLDivElement);\n }}\n toolbarComponent={(table) => (\n <DataTableToolbar\n entityName={assetSchema.name}\n table={table}\n onSearchWhereChange={(w) => setSearchWhere(w)}\n />\n )}\n />\n <Outlet />\n </div>\n );\n}\n\ntype AttributeValue = {\n _id: string;\n [key: string]: string | AttributeValue | null;\n __typename: string;\n};\n\nfunction getLoadingColumns(columns: object[]): ColumnDef<AttributeValue>[] {\n return columns.map((column) => ({\n ...column,\n cell: () => <Skeleton className=\"fk-h-4 fk-w-full\" style={{ marginTop: '7px', marginBottom: '6px' }} />,\n })) as unknown as ColumnDef<AttributeValue>[];\n}\n","'use client';\n\nimport { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@flexkit/studio/ui';\nimport { Sidebar } from './sidebar';\nimport { List } from './list';\n\nexport function Root(): JSX.Element {\n return (\n <ResizablePanelGroup direction=\"horizontal\" className=\"fk-h-full\">\n <ResizablePanel className=\"fk-p-3\" defaultSize={82}>\n <div className=\"fk-flex fk-flex-col fk-h-full\">\n <List />\n </div>\n </ResizablePanel>\n <ResizableHandle className=\"hover:fk-bg-blue-500 fk-transition-colors\" withHandle />\n <ResizablePanel defaultSize={18} minSize={10}>\n <div className=\"sm:fk-hidden md:fk-block\">\n <Sidebar />\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n );\n}\n","import { FileStack as FileStackIcon } from 'lucide-react';\nimport type { PluginOptions } from '@flexkit/studio';\nimport { Asset } from './data-grid/preview-components/asset';\nimport { Root } from './root';\n\nexport function AssetManager(): PluginOptions {\n return {\n name: 'flexkit.asset-manager',\n contributes: {\n apps: [\n {\n name: 'asset-manager',\n icon: <FileStackIcon strokeWidth={1.5} />,\n title: 'Asset Manager',\n component: <Root />,\n routes: [],\n },\n ],\n previewFields: {\n assetPreviewField: {\n component: Asset,\n description: 'Asset preview field for the asset manager',\n },\n },\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,10 +1,19 @@
1
1
  {
2
2
  "name": "@flexkit/asset-manager",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
+ "description": "Flexkit plugin for browsing and managing assets in a project.",
5
+ "keywords": [
6
+ "flexkit",
7
+ "studio",
8
+ "react",
9
+ "node",
10
+ "assets",
11
+ "flexkit-plugin"
12
+ ],
4
13
  "type": "module",
5
14
  "main": "./dist/index.js",
6
15
  "style": "dist/index.css",
7
- "module": "./dist/index.mjs",
16
+ "module": "./dist/index.js",
8
17
  "types": "./dist/index.d.ts",
9
18
  "license": "MIT",
10
19
  "repository": {
@@ -45,28 +54,28 @@
45
54
  "tailwindcss": "3.4.10",
46
55
  "tsup": "8.5.0",
47
56
  "typescript": "^5.3.3",
57
+ "@flexkit/studio": "0.0.7",
48
58
  "eslint-config-custom": "0.0.0",
49
- "@flexkit/studio": "0.0.6",
50
- "tsconfig": "0.0.0",
51
- "tailwind-config": "0.0.1"
59
+ "tailwind-config": "0.0.1",
60
+ "tsconfig": "0.0.0"
52
61
  },
53
62
  "dependencies": {
54
63
  "react-file-icon": "1.6.0",
55
- "lucide-react": "0.544.0",
64
+ "lucide-react": "0.555.0",
56
65
  "ramda": "^0.29.1",
57
66
  "swr": "^2.2.4"
58
67
  },
59
68
  "peerDependencies": {
60
69
  "react": "^18.0.0 || ^19.0.0",
61
70
  "react-dom": "^18.0.0 || ^19.0.0",
62
- "@flexkit/studio": "0.0.6"
71
+ "@flexkit/studio": "0.0.7"
63
72
  },
64
73
  "publishConfig": {
65
74
  "access": "public"
66
75
  },
67
76
  "scripts": {
68
- "build": "tsup src/index.tsx --format esm --dts --external react && tailwindcss -i ./src/styles.css -o dist/index.css",
69
- "dev": "tsup src/index.tsx --format esm --watch --dts --external react && tailwindcss -i ./src/styles.css -o ./dist/index.css --watch",
77
+ "build": "tailwindcss -i ./src/styles.css -o dist/index.css && tsup src/index.tsx --format esm --dts --external react",
78
+ "dev": "tailwindcss -i ./src/styles.css -o ./dist/index.css --watch & tsup src/index.tsx --format esm --watch --dts --external react",
70
79
  "lint": "eslint \"src/**/*.ts*\"",
71
80
  "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
72
81
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/styles.css"],"sourcesContent":["/*\n! tailwindcss v3.4.10 | MIT License | https://tailwindcss.com\n*//*\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\n*/\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n::before,\n::after {\n --tw-content: '';\n}\n\n/*\n1. Use a consistent sensible line-height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n3. Use a more readable tab size.\n4. Use the user's configured `sans` font-family by default.\n5. Use the user's configured `sans` font-feature-settings by default.\n6. Use the user's configured `sans` font-variation-settings by default.\n7. Disable tap highlights on iOS\n*/\n\nhtml,\n:host {\n line-height: 1.5; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n -moz-tab-size: 4; /* 3 */\n -o-tab-size: 4;\n tab-size: 4; /* 3 */\n font-family: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; /* 4 */\n font-feature-settings: normal; /* 5 */\n font-variation-settings: normal; /* 6 */\n -webkit-tap-highlight-color: transparent; /* 7 */\n}\n\n/*\n1. Remove the margin in all browsers.\n2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.\n*/\n\nbody {\n margin: 0; /* 1 */\n line-height: inherit; /* 2 */\n}\n\n/*\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n3. Ensure horizontal rules are visible by default.\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n border-top-width: 1px; /* 3 */\n}\n\n/*\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/*\nRemove the default font size and weight for headings.\n*/\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/*\nReset links to optimize for opt-in styling instead of opt-out.\n*/\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/*\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/*\n1. Use the user's configured `mono` font-family by default.\n2. Use the user's configured `mono` font-feature-settings by default.\n3. Use the user's configured `mono` font-variation-settings by default.\n4. Correct the odd `em` font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family: var(--font-geist-mono), ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; /* 1 */\n font-feature-settings: normal; /* 2 */\n font-variation-settings: normal; /* 3 */\n font-size: 1em; /* 4 */\n}\n\n/*\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/*\nPrevent `sub` and `sup` elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n3. Remove gaps between table borders by default.\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n border-collapse: collapse; /* 3 */\n}\n\n/*\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n3. Remove default padding in all browsers.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-feature-settings: inherit; /* 1 */\n font-variation-settings: inherit; /* 1 */\n font-size: 100%; /* 1 */\n font-weight: inherit; /* 1 */\n line-height: inherit; /* 1 */\n letter-spacing: inherit; /* 1 */\n color: inherit; /* 1 */\n margin: 0; /* 2 */\n padding: 0; /* 3 */\n}\n\n/*\nRemove the inheritance of text transform in Edge and Firefox.\n*/\n\nbutton,\nselect {\n text-transform: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Remove default button styles.\n*/\n\nbutton,\ninput:where([type='button']),\ninput:where([type='reset']),\ninput:where([type='submit']) {\n -webkit-appearance: button; /* 1 */\n background-color: transparent; /* 2 */\n background-image: none; /* 2 */\n}\n\n/*\nUse the modern Firefox focus style for all focusable elements.\n*/\n\n:-moz-focusring {\n outline: auto;\n}\n\n/*\nRemove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\n*/\n\n:-moz-ui-invalid {\n box-shadow: none;\n}\n\n/*\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/*\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n\n/*\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/*\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to `inherit` in Safari.\n*/\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/*\nRemoves the default spacing and border for appropriate elements.\n*/\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nlegend {\n padding: 0;\n}\n\nol,\nul,\nmenu {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/*\nReset default styling for dialogs.\n*/\ndialog {\n padding: 0;\n}\n\n/*\nPrevent resizing textareas horizontally by default.\n*/\n\ntextarea {\n resize: vertical;\n}\n\n/*\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\n2. Set the default placeholder color to the user's configured gray 400 color.\n*/\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\ninput::placeholder,\ntextarea::placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\n/*\nSet the default cursor for buttons.\n*/\n\nbutton,\n[role=\"button\"] {\n cursor: pointer;\n}\n\n/*\nMake sure disabled buttons don't get the pointer cursor.\n*/\n:disabled {\n cursor: default;\n}\n\n/*\n1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)\n2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\n This can trigger a poorly considered lint error in some tools but is included by design.\n*/\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block; /* 1 */\n vertical-align: middle; /* 2 */\n}\n\n/*\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\n*/\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n/* Make elements with the HTML hidden attribute stay hidden by default */\n[hidden] {\n display: none;\n}\n\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n.fk-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n.fk-absolute {\n position: absolute;\n}\n.fk-relative {\n position: relative;\n}\n.fk-left-2 {\n left: 0.5rem;\n}\n.fk-right-2 {\n right: 0.5rem;\n}\n.fk-top-2 {\n top: 0.5rem;\n}\n.fk-z-10 {\n z-index: 10;\n}\n.fk-mb-4 {\n margin-bottom: 1rem;\n}\n.fk-ml-2 {\n margin-left: 0.5rem;\n}\n.fk-ml-auto {\n margin-left: auto;\n}\n.fk-mr-2 {\n margin-right: 0.5rem;\n}\n.fk-flex {\n display: flex;\n}\n.fk-h-12 {\n height: 3rem;\n}\n.fk-h-20 {\n height: 5rem;\n}\n.fk-h-4 {\n height: 1rem;\n}\n.fk-h-52 {\n height: 13rem;\n}\n.fk-h-7 {\n height: 1.75rem;\n}\n.fk-h-8 {\n height: 2rem;\n}\n.fk-h-\\[300px\\] {\n height: 300px;\n}\n.fk-h-full {\n height: 100%;\n}\n.fk-max-h-screen {\n max-height: 100vh;\n}\n.fk-w-12 {\n width: 3rem;\n}\n.fk-w-4 {\n width: 1rem;\n}\n.fk-w-52 {\n width: 13rem;\n}\n.fk-w-7 {\n width: 1.75rem;\n}\n.fk-w-8 {\n width: 2rem;\n}\n.fk-w-\\[150px\\] {\n width: 150px;\n}\n.fk-w-\\[240px\\] {\n width: 240px;\n}\n.fk-w-full {\n width: 100%;\n}\n.fk-flex-1 {\n flex: 1 1 0%;\n}\n.fk-shrink-0 {\n flex-shrink: 0;\n}\n@keyframes fk-spin {\n\n to {\n transform: rotate(360deg);\n }\n}\n.fk-animate-spin {\n animation: fk-spin 1s linear infinite;\n}\n.fk-cursor-zoom-in {\n cursor: zoom-in;\n}\n.fk-flex-col {\n flex-direction: column;\n}\n.fk-items-center {\n align-items: center;\n}\n.fk-justify-center {\n justify-content: center;\n}\n.fk-justify-between {\n justify-content: space-between;\n}\n.fk-gap-2 {\n gap: 0.5rem;\n}\n.fk-space-x-2 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(0.5rem * var(--tw-space-x-reverse));\n margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));\n}\n.fk-rounded {\n border-radius: 0.25rem;\n}\n.fk-border {\n border-width: 1px;\n}\n.fk-border-b {\n border-bottom-width: 1px;\n}\n.fk-border-border {\n border-color: hsl(var(--border));\n}\n.fk-border-b-border {\n border-bottom-color: hsl(var(--border));\n}\n.fk-bg-card {\n background-color: hsl(var(--card));\n}\n.fk-bg-transparent {\n background-color: transparent;\n}\n.fk-p-2 {\n padding: 0.5rem;\n}\n.fk-p-3 {\n padding: 0.75rem;\n}\n.fk-px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.fk-px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n.fk-px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n.fk-py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n}\n.fk-py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n.fk-pl-3 {\n padding-left: 0.75rem;\n}\n.fk-pl-8 {\n padding-left: 2rem;\n}\n.fk-text-lg {\n font-size: 1.125rem;\n line-height: 1.75rem;\n}\n.fk-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.fk-font-semibold {\n font-weight: 600;\n}\n.fk-leading-none {\n line-height: 1;\n}\n.fk-tracking-tight {\n letter-spacing: -0.025em;\n}\n.fk-text-destructive {\n color: hsl(var(--destructive));\n}\n.fk-text-foreground {\n color: hsl(var(--foreground));\n}\n.fk-text-muted-foreground {\n color: hsl(var(--muted-foreground));\n}\n.fk-opacity-50 {\n opacity: 0.5;\n}\n.fk-transition-colors {\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n@keyframes enter {\n\n from {\n opacity: var(--tw-enter-opacity, 1);\n transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0));\n }\n}\n@keyframes exit {\n\n to {\n opacity: var(--tw-exit-opacity, 1);\n transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));\n }\n}\n\nhtml,\nbody {\n height: 100%;\n}\n\n.hover\\:fk-bg-blue-500:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(59 130 246 / var(--tw-bg-opacity));\n}\n\n.hover\\:fk-text-foreground:hover {\n color: hsl(var(--foreground));\n}\n\n@media (min-width: 640px) {\n\n .sm\\:fk-hidden {\n display: none;\n }\n}\n\n@media (min-width: 768px) {\n\n .md\\:fk-block {\n display: block;\n }\n}\n\n@media (min-width: 1024px) {\n\n .lg\\:fk-flex {\n display: flex;\n }\n\n .lg\\:fk-w-\\[250px\\] {\n width: 250px;\n }\n\n .lg\\:fk-px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n }\n}\n\n.\\[\\&\\>svg\\]\\:fk-h-full>svg {\n height: 100%;\n}\n\n.\\[\\&\\>svg\\]\\:fk-w-auto>svg {\n width: auto;\n}\n"],"mappings":"AAOA,EACA,QACA,OACE,WAAY,WACZ,aAAc,EACd,aAAc,MACd,aAAc,OAChB,CAEA,QACA,OACE,cAAc,EAChB,CAYA,KACA,MACE,YAAa,IACb,yBAA0B,KAC1B,cAAe,EACf,YAAa,EACV,SAAU,EACb,YAAa,IAAI,kBAAkB,CAAE,aAAa,CAAE,SAAS,CAAE,UAAU,CAAE,mBAAmB,CAAE,gBAAgB,CAAE,iBAAiB,CAAE,mBACrI,sBAAuB,OACvB,wBAAyB,OACzB,4BAA6B,WAC/B,CAOA,KAjDA,OAkDU,EACR,YAAa,OACf,CAQA,GACE,OAAQ,EACR,MAAO,QACP,iBAAkB,GACpB,CAMA,IAAI,OAAO,CAAC,QACV,wBAAyB,UAAU,OAC3B,gBAAiB,UAAU,MACrC,CAMA,GACA,GACA,GACA,GACA,GACA,GACE,UAAW,QACX,YAAa,OACf,CAMA,EACE,MAAO,QACP,gBAAiB,OACnB,CAMA,EACA,OACE,YAAa,MACf,CASA,KACA,IACA,KACA,IACE,YAAa,IAAI,kBAAkB,CAAE,YAAY,CAAE,cAAc,CAAE,KAAK,CAAE,MAAM,CAAE,QAAQ,CAAE,iBAAiB,CAAE,aAAa,CAAE,UAC9H,sBAAuB,OACvB,wBAAyB,OACzB,UAAW,GACb,CAMA,MACE,UAAW,GACb,CAMA,IACA,IACE,UAAW,IACX,YAAa,EACb,SAAU,SACV,eAAgB,QAClB,CAEA,IACE,OAAQ,MACV,CAEA,IACE,IAAK,KACP,CAQA,MACE,YAAa,EACb,aAAc,QACd,gBAAiB,QACnB,CAQA,OACA,MACA,SACA,OACA,SACE,YAAa,QACb,sBAAuB,QACvB,wBAAyB,QACzB,UAAW,KACX,YAAa,QACb,YAAa,QACb,eAAgB,QAChB,MAAO,QAtLT,OAuLU,EAvLV,QAwLW,CACX,CAMA,OACA,OACE,eAAgB,IAClB,CAOA,OACA,KAAK,OAAO,CAAC,cACb,KAAK,OAAO,CAAC,aACb,KAAK,OAAO,CAAC,cACX,mBAAoB,OACpB,iBAAkB,YAClB,iBAAkB,IACpB,CAMA,gBACE,QAAS,IACX,CAMA,iBACE,WAAY,IACd,CAMA,SACE,eAAgB,QAClB,CAMA,4BACA,4BACE,OAAQ,IACV,CAOA,CAAC,aACC,mBAAoB,UACpB,eAAgB,IAClB,CAMA,4BACE,mBAAoB,IACtB,CAOA,6BACE,mBAAoB,OACpB,KAAM,OACR,CAMA,QACE,QAAS,SACX,CAMA,WACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,OACA,EACA,IAvSA,OAwSU,CACV,CAEA,SA3SA,OA4SU,EA5SV,QA6SW,CACX,CAEA,OAhTA,QAiTW,CACX,CAEA,GACA,GACA,KACE,WAAY,KAvTd,OAwTU,EAxTV,QAyTW,CACX,CAKA,OA/TA,QAgUW,CACX,CAMA,SACE,OAAQ,QACV,CAOA,KAAK,mBAAoB,QAAQ,mBAC/B,QAAS,EACT,MAAO,OACT,CAEA,KAAK,cACL,QAAQ,cACN,QAAS,EACT,MAAO,OACT,CAMA,OACA,CAAC,aACC,OAAQ,OACV,CAKA,UACE,OAAQ,OACV,CAQA,IACA,IACA,MACA,OACA,MACA,OACA,MACA,OACE,QAAS,MACT,eAAgB,MAClB,CAMA,IACA,MACE,UAAW,KACX,OAAQ,IACV,CAGA,CAAC,QACC,QAAS,IACX,CAEA,EAAG,QAAU,OACX,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,aACA,aACA,kBACA,6BAA6B,UAC7B,8BACA,6BACA,4BACA,eACA,oBACA,sBACA,uBACA,wBACA,kBACA,wBAAwB,IACxB,wBAAwB,KACxB,iBAAiB,IAAI,GAAG,IAAI,IAAI,EAAE,IAClC,yBAAyB,EAAE,EAAE,MAC7B,kBAAkB,EAAE,EAAE,MACtB,aAAa,EAAE,EAAE,MACjB,qBAAqB,EAAE,EAAE,MACzB,YACA,kBACA,gBACA,iBACA,kBACA,cACA,gBACA,aACA,mBACA,qBACA,2BACA,yBACA,0BACA,2BACA,uBACA,wBACA,yBACA,sBACA,oBACA,sBACA,qBACA,oBACF,CAEA,WACE,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,aACA,aACA,kBACA,6BAA6B,UAC7B,8BACA,6BACA,4BACA,eACA,oBACA,sBACA,uBACA,wBACA,kBACA,wBAAwB,IACxB,wBAAwB,KACxB,iBAAiB,IAAI,GAAG,IAAI,IAAI,EAAE,IAClC,yBAAyB,EAAE,EAAE,MAC7B,kBAAkB,EAAE,EAAE,MACtB,aAAa,EAAE,EAAE,MACjB,qBAAqB,EAAE,EAAE,MACzB,YACA,kBACA,gBACA,iBACA,kBACA,cACA,gBACA,aACA,mBACA,qBACA,2BACA,yBACA,0BACA,2BACA,uBACA,wBACA,yBACA,sBACA,oBACA,sBACA,qBACA,oBACF,CACA,CAAC,WACC,SAAU,SACV,MAAO,IACP,OAAQ,IA1fV,QA2fW,EA3fX,OA4fU,KACR,SAAU,OACV,KAAM,KAAK,CAAC,CAAE,CAAC,CAAE,CAAC,CAAE,GACpB,YAAa,OACb,aAAc,CAChB,CACA,CAAC,YACC,SAAU,QACZ,CACA,CAAC,YACC,SAAU,QACZ,CACA,CAAC,UACC,KAAM,KACR,CACA,CAAC,WACC,MAAO,KACT,CACA,CAAC,SACC,IAAK,KACP,CACA,CAAC,QACC,QAAS,EACX,CACA,CAAC,QACC,cAAe,IACjB,CACA,CAAC,QACC,YAAa,KACf,CACA,CAAC,WACC,YAAa,IACf,CACA,CAAC,QACC,aAAc,KAChB,CACA,CAAC,QACC,QAAS,IACX,CACA,CAAC,QACC,OAAQ,IACV,CACA,CAAC,QACC,OAAQ,IACV,CACA,CAAC,OACC,OAAQ,IACV,CACA,CAAC,QACC,OAAQ,KACV,CACA,CAAC,OACC,OAAQ,OACV,CACA,CAAC,OACC,OAAQ,IACV,CACA,CAAC,eACC,OAAQ,KACV,CACA,CAAC,UACC,OAAQ,IACV,CACA,CAAC,gBACC,WAAY,KACd,CACA,CAAC,QACC,MAAO,IACT,CACA,CAAC,OACC,MAAO,IACT,CACA,CAAC,QACC,MAAO,KACT,CACA,CAAC,OACC,MAAO,OACT,CACA,CAAC,OACC,MAAO,IACT,CACA,CAAC,e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","names":[]}