@burdenoff/microfe-files 2026.527.1 → 2026.527.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/files/components/FileBrowser.js +186 -170
- package/dist/files/components/FileBrowser.js.map +1 -1
- package/dist/files/components/FolderCard.js +147 -161
- package/dist/files/components/FolderCard.js.map +1 -1
- package/dist/files/components/MoveDialog.js +9 -12
- package/dist/files/components/MoveDialog.js.map +1 -1
- package/dist/files/hooks/useCreateFolder.js +15 -7
- package/dist/files/hooks/useCreateFolder.js.map +1 -1
- package/dist/files/hooks/useMoveFile.js +1 -2
- package/dist/files/hooks/useMoveFile.js.map +1 -1
- package/dist/files/hooks/useMoveFolder.js +0 -2
- package/dist/files/hooks/useMoveFolder.js.map +1 -1
- package/dist/files/hooks/useStarredItems.js +4 -3
- package/dist/files/hooks/useStarredItems.js.map +1 -1
- package/dist/files/hooks/useToggleStar.js +10 -10
- package/dist/files/hooks/useToggleStar.js.map +1 -1
- package/dist/files/pages/BrowserPage.js +314 -300
- package/dist/files/pages/BrowserPage.js.map +1 -1
- package/dist/files/utils/quotaUtils.js +14 -0
- package/dist/files/utils/quotaUtils.js.map +1 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FolderCard.js","names":[],"sources":["../../../src/files/components/FolderCard.tsx"],"sourcesContent":["import { type FC, useState, useMemo } from \"react\";\nimport {\n Folder,\n FolderOpen,\n Share2,\n Trash2,\n Edit,\n ChevronRight,\n Copy,\n FolderInput,\n Info,\n Activity,\n Star,\n RotateCcw,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport type { FolderItem } from \"../types\";\nimport { formatFileDate } from \"../utils\";\nimport { useFilesStore } from \"../store/filesStore\";\nimport { ActionMenu } from \"./ActionMenu\";\nimport { getDragOperation, canDropOnFolder } from \"../hooks/useDragDrop\";\nimport { tWithFallback } from \"../utils/i18n\";\nimport type { DragData } from \"../hooks/useDragDrop\";\n\ninterface FolderCardProps {\n folder: FolderItem;\n isSelected?: boolean;\n isDragging?: boolean;\n isDropTarget?: boolean;\n draggedItem?: DragData | null;\n onSelect?: (folderId: string) => void;\n onOpen?: (folder: FolderItem) => void;\n onShare?: (folder: FolderItem) => void;\n onDelete?: (folder: FolderItem) => void;\n onRestore?: (folder: FolderItem) => void;\n onRename?: (folder: FolderItem) => void;\n onFavorite?: (folder: FolderItem) => void;\n onCopy?: (folder: FolderItem) => void;\n onMove?: (folder: FolderItem) => void;\n onInfo?: (folder: FolderItem) => void;\n onActivity?: (folder: FolderItem) => void;\n onDragStart?: (folder: FolderItem, operation: \"move\" | \"copy\") => void;\n onDragEnd?: () => void;\n onDrop?: (folder: FolderItem) => void;\n onContextMenu?: (folder: FolderItem, x: number, y: number) => void;\n}\n\ninterface DraggableFolderCardProps extends Omit<\n FolderCardProps,\n \"onDragStart\" | \"onDragEnd\" | \"onDrop\"\n> {\n onDragStart?: (folder: FolderItem, operation: \"move\" | \"copy\") => void;\n onDragEnd?: () => void;\n onDrop?: (folder: FolderItem) => void;\n onContextMenu?: (folder: FolderItem, x: number, y: number) => void;\n}\n\nexport const FolderCard: FC<DraggableFolderCardProps> = ({\n folder,\n isSelected = false,\n isDragging = false,\n isDropTarget = false,\n draggedItem = null,\n onSelect,\n onOpen,\n onShare,\n onDelete,\n onRestore,\n onRename,\n onFavorite,\n onCopy,\n onMove,\n onInfo,\n onActivity,\n onDragStart,\n onDragEnd,\n onDrop,\n onContextMenu,\n}) => {\n const { t } = useI18n();\n const [showActions, setShowActions] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [menuOpen, setMenuOpen] = useState(false);\n const { toggleFolderSelection } = useFilesStore();\n\n const canDrop = canDropOnFolder(draggedItem, folder);\n const isValidDropTarget = isDropTarget && canDrop;\n\n const handleClick = () => {\n if (onOpen) {\n onOpen(folder);\n }\n };\n\n const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n e.stopPropagation();\n if (onSelect) {\n onSelect(folder.id);\n } else {\n toggleFolderSelection(folder.id);\n }\n };\n\n const handleActionClick = (e: React.MouseEvent, action: () => void) => {\n e.stopPropagation();\n action();\n setShowActions(false);\n };\n\n const handleDragStart = (e: React.DragEvent<HTMLDivElement>) => {\n e.dataTransfer.effectAllowed = \"copyMove\";\n e.dataTransfer.setData(\"application/x-file-id\", folder.id);\n e.dataTransfer.setData(\"application/x-file-type\", \"folder\");\n const operation = getDragOperation(e);\n e.dataTransfer.setData(\"application/x-drag-operation\", operation);\n onDragStart?.(folder, operation);\n };\n\n const handleDragEnd = () => {\n onDragEnd?.();\n };\n\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {\n if (isValidDropTarget) {\n e.preventDefault();\n e.dataTransfer.dropEffect =\n draggedItem?.operation === \"copy\" ? \"copy\" : \"move\";\n }\n };\n\n const handleDragEnter = (e: React.DragEvent<HTMLDivElement>) => {\n if (isValidDropTarget) {\n e.preventDefault();\n }\n };\n\n const handleDragLeave = () => {};\n\n const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n if (isValidDropTarget) {\n onDrop?.(folder);\n }\n };\n\n const handleContextMenu = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onContextMenu?.(folder, e.clientX, e.clientY);\n };\n\n const FolderIcon = isHovered ? FolderOpen : Folder;\n\n // Memoize menu items to prevent re-renders\n const menuItems = useMemo(\n () => [\n ...(onShare\n ? [\n {\n label: tWithFallback(t, \"files.card.share\", \"Share\"),\n icon: <Share2 className=\"size-4\" />,\n onClick: () => onShare(folder),\n },\n ]\n : []),\n ...(onCopy\n ? [\n {\n label: tWithFallback(t, \"files.card.makeCopy\", \"Make a copy\"),\n icon: <Copy className=\"size-4\" />,\n onClick: () => onCopy(folder),\n },\n ]\n : []),\n ...(onMove\n ? [\n {\n label: tWithFallback(t, \"files.card.moveTo\", \"Move to\"),\n icon: <FolderInput className=\"size-4\" />,\n onClick: () => onMove(folder),\n },\n ]\n : []),\n ...(onRename\n ? [\n {\n label: tWithFallback(t, \"files.card.rename\", \"Rename\"),\n icon: <Edit className=\"size-4\" />,\n onClick: () => onRename(folder),\n divider: true,\n },\n ]\n : []),\n ...(onFavorite\n ? [\n {\n label: folder.starred\n ? tWithFallback(\n t,\n \"files.card.removeFromStarred\",\n \"Remove from starred\",\n )\n : tWithFallback(t, \"files.card.addToStarred\", \"Add to starred\"),\n icon: <Star className=\"size-4\" />,\n onClick: () => onFavorite(folder),\n },\n ]\n : []),\n ...(onInfo\n ? [\n {\n label: tWithFallback(t, \"files.card.details\", \"Details\"),\n icon: <Info className=\"size-4\" />,\n onClick: () => onInfo(folder),\n },\n ]\n : []),\n ...(onActivity\n ? [\n {\n label: tWithFallback(t, \"files.card.activity\", \"Activity\"),\n icon: <Activity className=\"size-4\" />,\n onClick: () => onActivity(folder),\n },\n ]\n : []),\n ...(onDelete\n ? [\n {\n label: tWithFallback(t, \"files.card.delete\", \"Delete\"),\n icon: <Trash2 className=\"size-4\" />,\n onClick: () => onDelete(folder),\n variant: \"danger\" as const,\n divider: true,\n },\n ]\n : []),\n ...(onRestore\n ? [\n {\n label: tWithFallback(t, \"files.card.restore\", \"Restore\"),\n icon: <RotateCcw className=\"size-4\" />,\n onClick: () => onRestore(folder),\n },\n ]\n : []),\n ],\n [\n folder,\n onShare,\n onCopy,\n onMove,\n onRename,\n onFavorite,\n onInfo,\n onActivity,\n onDelete,\n onRestore,\n t,\n ],\n );\n\n return (\n <div\n className={`@container group relative cursor-pointer overflow-hidden rounded-card border bg-bg-surface shadow-elevation-1 transition-shadow hover:shadow-elevation-2 focus-within:shadow-elevation-2 ${isDragging ? \"opacity-50\" : \"\"} ${isValidDropTarget ? \"border-action-primary-bg ring-2 ring-action-primary-bg ring-offset-2\" : \"border-border-subtle\"}`}\n onClick={handleClick}\n onContextMenu={handleContextMenu}\n onMouseEnter={() => {\n setShowActions(true);\n setIsHovered(true);\n }}\n onMouseLeave={() => {\n setShowActions(false);\n setIsHovered(false);\n }}\n onFocus={() => {\n setShowActions(true);\n setIsHovered(true);\n }}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget)) {\n setShowActions(false);\n setIsHovered(false);\n }\n }}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n handleClick();\n }\n }}\n draggable={Boolean(onDragStart)}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragOver={handleDragOver}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n role=\"button\"\n tabIndex={0}\n aria-label={`${tWithFallback(t, \"files.browser.openFolder\", \"Open folder\")} ${folder.name}`}\n >\n {/* Selection checkbox */}\n <div\n className={`absolute top-2 left-2 z-10 transition-opacity ${\n isSelected\n ? \"opacity-100\"\n : \"opacity-0 group-hover:opacity-100 group-focus-within:opacity-100\"\n }`}\n >\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={handleCheckboxChange}\n className=\"size-4 rounded border-border-default bg-bg-surface text-action-primary-bg focus:ring-2 focus:ring-action-primary-bg focus:ring-offset-2\"\n aria-label={`Select ${folder.name}`}\n />\n </div>\n\n {/* Favorite indicator */}\n {folder.starred && (\n <div className=\"absolute top-2 right-2 z-10\">\n <Star className=\"size-4 fill-yellow-400 text-yellow-400\" />\n </div>\n )}\n\n {/* Folder icon section */}\n <div className=\"aspect-[4/3] bg-bg-sunken flex items-center justify-center\">\n <FolderIcon className=\"size-10 @md:size-14 text-action-primary-bg\" />\n </div>\n\n {/* Folder info */}\n <div className=\"p-3 @md:p-4\">\n <div className=\"flex items-center justify-between gap-2 mb-1\">\n <h3 className=\"font-text-md font-weight-medium text-text-primary truncate flex-1\">\n {folder.name}\n </h3>\n <ChevronRight className=\"size-4 text-text-muted flex-shrink-0\" />\n </div>\n\n <div className=\"flex items-center gap-2 text-text-secondary font-text-sm\">\n <span>\n {folder.filesCount ?? 0}{\" \"}\n {(folder.filesCount ?? 0) === 1\n ? tWithFallback(t, \"files.folder.item\", \"item\")\n : tWithFallback(t, \"files.browser.items\", \"items\")}\n </span>\n <span className=\"hidden @sm:inline text-border-subtle\">•</span>\n <span className=\"hidden @sm:inline\">\n {formatFileDate(folder.updatedAt)}\n </span>\n </div>\n\n {/* Extended metadata on larger containers */}\n {folder.createdBy && (\n <div className=\"hidden @md:flex items-center gap-2 mt-2 text-text-muted font-text-xs\">\n <div className=\"flex items-center gap-1\">\n {folder.createdBy.avatar && (\n <img\n src={folder.createdBy.avatar}\n alt={folder.createdBy.name}\n className=\"size-4 rounded-full\"\n />\n )}\n <span>{folder.createdBy.name}</span>\n </div>\n </div>\n )}\n </div>\n\n {/* Action buttons (on hover) with dropdown menu */}\n {showActions && (\n <div className=\"absolute bottom-3 right-3 flex items-center gap-1 bg-bg-elevated border border-border-subtle rounded shadow-elevation-2 p-1\">\n {onShare && (\n <button\n type=\"button\"\n onClick={(e) => handleActionClick(e, () => onShare(folder))}\n className=\"p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.share\", \"Share\")}\n title={tWithFallback(t, \"files.card.share\", \"Share\")}\n >\n <Share2 className=\"size-4 text-text-primary\" />\n </button>\n )}\n\n {onRename && (\n <button\n type=\"button\"\n onClick={(e) => handleActionClick(e, () => onRename(folder))}\n className=\"p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.rename\", \"Rename\")}\n title={tWithFallback(t, \"files.card.rename\", \"Rename\")}\n >\n <Edit className=\"size-4 text-text-primary\" />\n </button>\n )}\n\n {onRestore && (\n <button\n type=\"button\"\n onClick={(e) => handleActionClick(e, () => onRestore(folder))}\n className=\"p-1.5 hover:bg-status-success-bg-subtle rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.restore\", \"Restore\")}\n title={tWithFallback(t, \"files.card.restore\", \"Restore\")}\n >\n <RotateCcw className=\"size-4 text-status-success-text\" />\n </button>\n )}\n\n {/* More options dropdown */}\n <div onClick={(e) => e.stopPropagation()}>\n <ActionMenu\n items={menuItems}\n align=\"right\"\n triggerClassName=\"p-1.5\"\n isOpen={menuOpen}\n onToggle={setMenuOpen}\n />\n </div>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AAyDA,IAAa,KAA4C,EACvD,WACA,gBAAa,IACb,gBAAa,IACb,kBAAe,IACf,iBAAc,MACd,aACA,WACA,YACA,aACA,cACA,aACA,eACA,WACA,WACA,WACA,eACA,gBACA,cACA,WACA,uBACI;CACJ,IAAM,EAAE,SAAM,GAAS,EACjB,CAAC,GAAa,KAAkB,EAAS,GAAM,EAC/C,CAAC,GAAW,KAAgB,EAAS,GAAM,EAC3C,CAAC,IAAU,KAAe,EAAS,GAAM,EACzC,EAAE,6BAA0B,GAAe,EAE3C,IAAU,EAAgB,GAAa,EAAO,EAC9C,IAAoB,KAAgB,GAEpC,UAAoB;AACxB,EAAI,KACF,EAAO,EAAO;IAIZ,KAAwB,MAA2C;AAEvE,EADA,EAAE,iBAAiB,EACf,IACF,EAAS,EAAO,GAAG,GAEnB,EAAsB,EAAO,GAAG;IAI9B,KAAqB,GAAqB,MAAuB;AAGrE,EAFA,EAAE,iBAAiB,EACnB,GAAQ,EACR,EAAe,GAAM;IAGjB,KAAmB,MAAuC;AAG9D,EAFA,EAAE,aAAa,gBAAgB,YAC/B,EAAE,aAAa,QAAQ,yBAAyB,EAAO,GAAG,EAC1D,EAAE,aAAa,QAAQ,2BAA2B,SAAS;EAC3D,IAAM,IAAY,EAAiB,EAAE;AAErC,EADA,EAAE,aAAa,QAAQ,gCAAgC,EAAU,EACjE,IAAc,GAAQ,EAAU;IAG5B,WAAsB;AAC1B,OAAa;IAGT,MAAkB,MAAuC;AAC7D,EAAI,MACF,EAAE,gBAAgB,EAClB,EAAE,aAAa,aACb,GAAa,cAAc,SAAS,SAAS;IAI7C,MAAmB,MAAuC;AAC9D,EAAI,KACF,EAAE,gBAAgB;IAIhB,WAAwB,IAExB,MAAc,MAAuC;AAEzD,EADA,EAAE,gBAAgB,EACd,KACF,IAAS,EAAO;IAId,MAAqB,MAAwB;AAGjD,EAFA,EAAE,gBAAgB,EAClB,EAAE,iBAAiB,EACnB,IAAgB,GAAQ,EAAE,SAAS,EAAE,QAAQ;IAGzC,KAAa,IAAY,KAAa,GAGtC,KAAY,QACV;EACJ,GAAI,IACA,CACE;GACE,OAAO,EAAc,GAAG,oBAAoB,QAAQ;GACpD,MAAM,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA;GACnC,eAAe,EAAQ,EAAO;GAC/B,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,OAAO,EAAc,GAAG,uBAAuB,cAAc;GAC7D,MAAM,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA;GACjC,eAAe,EAAO,EAAO;GAC9B,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,OAAO,EAAc,GAAG,qBAAqB,UAAU;GACvD,MAAM,kBAAC,GAAD,EAAa,WAAU,UAAW,CAAA;GACxC,eAAe,EAAO,EAAO;GAC9B,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,OAAO,EAAc,GAAG,qBAAqB,SAAS;GACtD,MAAM,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA;GACjC,eAAe,EAAS,EAAO;GAC/B,SAAS;GACV,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,OAAO,EAAO,UACV,EACE,GACA,gCACA,sBACD,GACD,EAAc,GAAG,2BAA2B,iBAAiB;GACjE,MAAM,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA;GACjC,eAAe,EAAW,EAAO;GAClC,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,OAAO,EAAc,GAAG,sBAAsB,UAAU;GACxD,MAAM,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA;GACjC,eAAe,EAAO,EAAO;GAC9B,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,OAAO,EAAc,GAAG,uBAAuB,WAAW;GAC1D,MAAM,kBAAC,IAAD,EAAU,WAAU,UAAW,CAAA;GACrC,eAAe,EAAW,EAAO;GAClC,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,OAAO,EAAc,GAAG,qBAAqB,SAAS;GACtD,MAAM,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA;GACnC,eAAe,EAAS,EAAO;GAC/B,SAAS;GACT,SAAS;GACV,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,OAAO,EAAc,GAAG,sBAAsB,UAAU;GACxD,MAAM,kBAAC,GAAD,EAAW,WAAU,UAAW,CAAA;GACtC,eAAe,EAAU,EAAO;GACjC,CACF,GACD,EAAE;EACP,EACD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;AAED,QACE,kBAAC,OAAD;EACE,WAAW,4LAA4L,IAAa,eAAe,GAAG,GAAG,IAAoB,yEAAyE;EACtU,SAAS;EACT,eAAe;EACf,oBAAoB;AAElB,GADA,EAAe,GAAK,EACpB,EAAa,GAAK;;EAEpB,oBAAoB;AAElB,GADA,EAAe,GAAM,EACrB,EAAa,GAAM;;EAErB,eAAe;AAEb,GADA,EAAe,GAAK,EACpB,EAAa,GAAK;;EAEpB,SAAS,MAAU;AACjB,GAAK,EAAM,cAAc,SAAS,EAAM,cAAc,KACpD,EAAe,GAAM,EACrB,EAAa,GAAM;;EAGvB,YAAY,MAAU;AACpB,IAAI,EAAM,QAAQ,WAAW,EAAM,QAAQ,SACzC,EAAM,gBAAgB,EACtB,GAAa;;EAGjB,WAAW,EAAQ;EACnB,aAAa;EACb,WAAW;EACX,YAAY;EACZ,aAAa;EACb,aAAa;EACb,QAAQ;EACR,MAAK;EACL,UAAU;EACV,cAAY,GAAG,EAAc,GAAG,4BAA4B,cAAc,CAAC,GAAG,EAAO;YArCvF;GAwCE,kBAAC,OAAD;IACE,WAAW,iDACT,IACI,gBACA;cAGN,kBAAC,SAAD;KACE,MAAK;KACL,SAAS;KACT,UAAU;KACV,WAAU;KACV,cAAY,UAAU,EAAO;KAC7B,CAAA;IACE,CAAA;GAGL,EAAO,WACN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD,EAAM,WAAU,0CAA2C,CAAA;IACvD,CAAA;GAIR,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,IAAD,EAAY,WAAU,8CAA+C,CAAA;IACjE,CAAA;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAO;OACL,CAAA,EACL,kBAAC,GAAD,EAAc,WAAU,wCAAyC,CAAA,CAC7D;;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,QAAD,EAAA,UAAA;QACG,EAAO,cAAc;QAAG;SACvB,EAAO,cAAc,OAAO,IAC1B,EAAc,GAAG,qBAAqB,OAAO,GAC7C,EAAc,GAAG,uBAAuB,QAAQ;QAC/C,EAAA,CAAA;OACP,kBAAC,QAAD;QAAM,WAAU;kBAAuC;QAAQ,CAAA;OAC/D,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAe,EAAO,UAAU;QAC5B,CAAA;OACH;;KAGL,EAAO,aACN,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACG,EAAO,UAAU,UAChB,kBAAC,OAAD;QACE,KAAK,EAAO,UAAU;QACtB,KAAK,EAAO,UAAU;QACtB,WAAU;QACV,CAAA,EAEJ,kBAAC,QAAD,EAAA,UAAO,EAAO,UAAU,MAAY,CAAA,CAChC;;MACF,CAAA;KAEJ;;GAGL,KACC,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,KACC,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,MAAM,EAAkB,SAAS,EAAQ,EAAO,CAAC;MAC3D,WAAU;MACV,cAAY,EAAc,GAAG,oBAAoB,QAAQ;MACzD,OAAO,EAAc,GAAG,oBAAoB,QAAQ;gBAEpD,kBAAC,GAAD,EAAQ,WAAU,4BAA6B,CAAA;MACxC,CAAA;KAGV,KACC,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,MAAM,EAAkB,SAAS,EAAS,EAAO,CAAC;MAC5D,WAAU;MACV,cAAY,EAAc,GAAG,qBAAqB,SAAS;MAC3D,OAAO,EAAc,GAAG,qBAAqB,SAAS;gBAEtD,kBAAC,GAAD,EAAM,WAAU,4BAA6B,CAAA;MACtC,CAAA;KAGV,KACC,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,MAAM,EAAkB,SAAS,EAAU,EAAO,CAAC;MAC7D,WAAU;MACV,cAAY,EAAc,GAAG,sBAAsB,UAAU;MAC7D,OAAO,EAAc,GAAG,sBAAsB,UAAU;gBAExD,kBAAC,GAAD,EAAW,WAAU,mCAAoC,CAAA;MAClD,CAAA;KAIX,kBAAC,OAAD;MAAK,UAAU,MAAM,EAAE,iBAAiB;gBACtC,kBAAC,GAAD;OACE,OAAO;OACP,OAAM;OACN,kBAAiB;OACjB,QAAQ;OACR,UAAU;OACV,CAAA;MACE,CAAA;KACF;;GAEJ"}
|
|
1
|
+
{"version":3,"file":"FolderCard.js","names":[],"sources":["../../../src/files/components/FolderCard.tsx"],"sourcesContent":["import { type FC, useState, useMemo } from \"react\";\nimport {\n Folder,\n FolderOpen,\n Share2,\n Trash2,\n Edit,\n ChevronRight,\n FolderInput,\n Info,\n Activity,\n Star,\n RotateCcw,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport type { FolderItem } from \"../types\";\nimport { formatFileDate } from \"../utils\";\nimport { useFilesStore } from \"../store/filesStore\";\nimport { ActionMenu } from \"./ActionMenu\";\nimport { getDragOperation, canDropOnFolder } from \"../hooks/useDragDrop\";\nimport { tWithFallback } from \"../utils/i18n\";\nimport type { DragData } from \"../hooks/useDragDrop\";\n\ninterface FolderCardProps {\n folder: FolderItem;\n isSelected?: boolean;\n isDragging?: boolean;\n isDropTarget?: boolean;\n draggedItem?: DragData | null;\n onSelect?: (folderId: string) => void;\n onOpen?: (folder: FolderItem) => void;\n onShare?: (folder: FolderItem) => void;\n onDelete?: (folder: FolderItem) => void;\n onRestore?: (folder: FolderItem) => void;\n onRename?: (folder: FolderItem) => void;\n onFavorite?: (folder: FolderItem) => void;\n onCopy?: (folder: FolderItem) => void;\n onMove?: (folder: FolderItem) => void;\n onInfo?: (folder: FolderItem) => void;\n onActivity?: (folder: FolderItem) => void;\n onDragStart?: (folder: FolderItem, operation: \"move\" | \"copy\") => void;\n onDragEnd?: () => void;\n onDrop?: (folder: FolderItem) => void;\n onContextMenu?: (folder: FolderItem, x: number, y: number) => void;\n}\n\ninterface DraggableFolderCardProps extends Omit<\n FolderCardProps,\n \"onDragStart\" | \"onDragEnd\" | \"onDrop\"\n> {\n onDragStart?: (folder: FolderItem, operation: \"move\" | \"copy\") => void;\n onDragEnd?: () => void;\n onDrop?: (folder: FolderItem) => void;\n onContextMenu?: (folder: FolderItem, x: number, y: number) => void;\n}\n\nexport const FolderCard: FC<DraggableFolderCardProps> = ({\n folder,\n isSelected = false,\n isDragging = false,\n isDropTarget = false,\n draggedItem = null,\n onSelect,\n onOpen,\n onShare,\n onDelete,\n onRestore,\n onRename,\n onFavorite,\n onCopy: _onCopy,\n onMove,\n onInfo,\n onActivity,\n onDragStart,\n onDragEnd,\n onDrop,\n onContextMenu,\n}) => {\n const { t } = useI18n();\n const [isHovered, setIsHovered] = useState(false);\n const [menuOpen, setMenuOpen] = useState(false);\n const { toggleFolderSelection } = useFilesStore();\n\n const canDrop = canDropOnFolder(draggedItem, folder);\n const isValidDropTarget = isDropTarget && canDrop;\n\n const filesCount = folder.filesCount ?? 0;\n const subfoldersCount = folder.subfoldersCount ?? 0;\n const totalItems = filesCount + subfoldersCount;\n\n const handleClick = () => {\n if (onOpen) {\n onOpen(folder);\n }\n };\n\n const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n e.stopPropagation();\n if (onSelect) {\n onSelect(folder.id);\n } else {\n toggleFolderSelection(folder.id);\n }\n };\n\n const handleActionClick = (e: React.MouseEvent, action: () => void) => {\n e.stopPropagation();\n action();\n };\n\n const handleDragStart = (e: React.DragEvent<HTMLDivElement>) => {\n e.dataTransfer.effectAllowed = \"copyMove\";\n e.dataTransfer.setData(\"application/x-file-id\", folder.id);\n e.dataTransfer.setData(\"application/x-file-type\", \"folder\");\n const operation = getDragOperation(e);\n e.dataTransfer.setData(\"application/x-drag-operation\", operation);\n onDragStart?.(folder, operation);\n };\n\n const handleDragEnd = () => {\n onDragEnd?.();\n };\n\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {\n if (isValidDropTarget) {\n e.preventDefault();\n e.dataTransfer.dropEffect =\n draggedItem?.operation === \"copy\" ? \"copy\" : \"move\";\n }\n };\n\n const handleDragEnter = (e: React.DragEvent<HTMLDivElement>) => {\n if (isValidDropTarget) {\n e.preventDefault();\n }\n };\n\n const handleDragLeave = () => {};\n\n const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n if (isValidDropTarget) {\n onDrop?.(folder);\n }\n };\n\n const handleContextMenu = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onContextMenu?.(folder, e.clientX, e.clientY);\n };\n\n const FolderIcon = isHovered ? FolderOpen : Folder;\n\n const menuItems = useMemo(\n () => [\n ...(onShare\n ? [\n {\n label: tWithFallback(t, \"files.card.share\", \"Share\"),\n icon: <Share2 className=\"size-4\" />,\n onClick: () => onShare(folder),\n },\n ]\n : []),\n ...(onMove\n ? [\n {\n label: tWithFallback(t, \"files.card.moveTo\", \"Move to\"),\n icon: <FolderInput className=\"size-4\" />,\n onClick: () => onMove(folder),\n },\n ]\n : []),\n ...(onRename\n ? [\n {\n label: tWithFallback(t, \"files.card.rename\", \"Rename\"),\n icon: <Edit className=\"size-4\" />,\n onClick: () => onRename(folder),\n divider: true,\n },\n ]\n : []),\n ...(onFavorite\n ? [\n {\n label: folder.starred\n ? tWithFallback(\n t,\n \"files.card.removeFromStarred\",\n \"Remove from starred\",\n )\n : tWithFallback(t, \"files.card.addToStarred\", \"Add to starred\"),\n icon: <Star className=\"size-4\" />,\n onClick: () => onFavorite(folder),\n },\n ]\n : []),\n ...(onInfo\n ? [\n {\n label: tWithFallback(t, \"files.card.details\", \"Details\"),\n icon: <Info className=\"size-4\" />,\n onClick: () => onInfo(folder),\n },\n ]\n : []),\n ...(onActivity\n ? [\n {\n label: tWithFallback(t, \"files.card.activity\", \"Activity\"),\n icon: <Activity className=\"size-4\" />,\n onClick: () => onActivity(folder),\n },\n ]\n : []),\n ...(onDelete\n ? [\n {\n label: tWithFallback(t, \"files.card.delete\", \"Delete\"),\n icon: <Trash2 className=\"size-4\" />,\n onClick: () => onDelete(folder),\n variant: \"danger\" as const,\n divider: true,\n },\n ]\n : []),\n ...(onRestore\n ? [\n {\n label: tWithFallback(t, \"files.card.restore\", \"Restore\"),\n icon: <RotateCcw className=\"size-4\" />,\n onClick: () => onRestore(folder),\n },\n ]\n : []),\n ],\n [\n folder,\n onShare,\n onMove,\n onRename,\n onFavorite,\n onInfo,\n onActivity,\n onDelete,\n onRestore,\n t,\n ],\n );\n\n return (\n <div\n className={`group relative cursor-pointer rounded-card border bg-bg-surface shadow-elevation-1 transition-all hover:shadow-elevation-2 focus-within:shadow-elevation-2 ${\n isDragging ? \"opacity-50\" : \"\"\n } ${\n isValidDropTarget\n ? \"border-action-primary-bg ring-2 ring-action-primary-bg ring-offset-2\"\n : isSelected\n ? \"border-action-primary-bg bg-bg-accent\"\n : \"border-border-subtle\"\n }`}\n onClick={handleClick}\n onContextMenu={handleContextMenu}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => {\n if (!menuOpen) setIsHovered(false);\n }}\n onFocus={() => setIsHovered(true)}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget) && !menuOpen) {\n setIsHovered(false);\n }\n }}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n handleClick();\n }\n }}\n draggable={Boolean(onDragStart)}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragOver={handleDragOver}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n role=\"button\"\n tabIndex={0}\n aria-label={`${tWithFallback(t, \"files.browser.openFolder\", \"Open folder\")} ${folder.name}`}\n >\n <div className=\"flex items-center gap-3 p-3\">\n {/* Selection checkbox */}\n <div\n className={`flex-shrink-0 transition-opacity ${\n isSelected\n ? \"opacity-100\"\n : \"opacity-0 group-hover:opacity-100 group-focus-within:opacity-100\"\n }`}\n onClick={(e) => e.stopPropagation()}\n >\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={handleCheckboxChange}\n className=\"size-4 rounded border-border-default bg-bg-surface text-action-primary-bg focus:ring-2 focus:ring-action-primary-bg focus:ring-offset-2\"\n aria-label={`Select ${folder.name}`}\n />\n </div>\n\n {/* Folder icon */}\n <div className=\"flex-shrink-0 flex items-center justify-center size-10 rounded-lg bg-action-primary-bg/10\">\n <FolderIcon className=\"size-5 text-action-primary-bg\" />\n </div>\n\n {/* Folder info */}\n <div className=\"flex-1 min-w-0 pr-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-sm font-medium text-text-primary truncate\">\n {folder.name}\n </span>\n {folder.starred && (\n <Star className=\"size-3 flex-shrink-0 fill-yellow-400 text-yellow-400\" />\n )}\n </div>\n <div className=\"flex items-center gap-1 mt-0.5 text-xs text-text-secondary\">\n {subfoldersCount > 0 && (\n <>\n <span>\n {subfoldersCount}{\" \"}\n {subfoldersCount === 1\n ? tWithFallback(t, \"files.folder.subfolder\", \"folder\")\n : tWithFallback(t, \"files.folder.subfolders\", \"folders\")}\n </span>\n {filesCount > 0 && (\n <span className=\"text-border-subtle\">·</span>\n )}\n </>\n )}\n {filesCount > 0 && (\n <span>\n {filesCount}{\" \"}\n {filesCount === 1\n ? tWithFallback(t, \"files.folder.file\", \"file\")\n : tWithFallback(t, \"files.folder.files\", \"files\")}\n </span>\n )}\n {totalItems === 0 && (\n <span>{tWithFallback(t, \"files.folder.empty\", \"Empty\")}</span>\n )}\n <span className=\"text-border-subtle\">·</span>\n <span className=\"truncate\">{formatFileDate(folder.updatedAt)}</span>\n </div>\n </div>\n\n {/* Right-side actions — always reserve space so layout is stable */}\n <div className=\"flex-shrink-0 flex items-center gap-1\">\n {isHovered && onRestore && (\n <button\n type=\"button\"\n onClick={(e) => handleActionClick(e, () => onRestore(folder))}\n className=\"p-1.5 hover:bg-status-success-bg-subtle rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.restore\", \"Restore\")}\n title={tWithFallback(t, \"files.card.restore\", \"Restore\")}\n >\n <RotateCcw className=\"size-4 text-status-success-text\" />\n </button>\n )}\n {isHovered && onShare && (\n <button\n onClick={(e) => handleActionClick(e, () => onShare(folder))}\n className=\"p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.share\", \"Share\")}\n title={tWithFallback(t, \"files.card.share\", \"Share\")}\n >\n <Share2 className=\"size-4 text-text-secondary\" />\n </button>\n )}\n {isHovered && onRename && (\n <button\n onClick={(e) => handleActionClick(e, () => onRename(folder))}\n className=\"p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.rename\", \"Rename\")}\n title={tWithFallback(t, \"files.card.rename\", \"Rename\")}\n >\n <Edit className=\"size-4 text-text-secondary\" />\n </button>\n )}\n <div onClick={(e) => e.stopPropagation()}>\n <ActionMenu\n items={menuItems}\n align=\"right\"\n triggerClassName={\n !isHovered && !menuOpen\n ? \"opacity-0 group-hover:opacity-100\"\n : \"\"\n }\n isOpen={menuOpen}\n onToggle={(open) => {\n setMenuOpen(open);\n if (open) setIsHovered(true);\n }}\n />\n </div>\n </div>\n\n {/* Navigate-into arrow */}\n <ChevronRight className=\"flex-shrink-0 size-4 text-text-muted opacity-0 group-hover:opacity-100 transition-opacity\" />\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -6,19 +6,19 @@ import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
|
6
6
|
import { useI18n as u } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
7
7
|
//#region src/files/components/MoveDialog.tsx
|
|
8
8
|
var d = ({ item: d, type: f, onClose: p, onMove: m, isLoading: h = !1 }) => {
|
|
9
|
-
let { t: g } = u(), [_, v] = n(null), [y, b] = n([]), [x, S] = n(
|
|
9
|
+
let { t: g } = u(), [_, v] = n(null), [y, b] = n([]), [x, S] = n(void 0), { data: C, loading: w } = t(_ || void 0), T = C?.getFolders?.folders || [], E = (e) => {
|
|
10
10
|
v(e.id), b([...y, {
|
|
11
11
|
id: e.id,
|
|
12
12
|
name: e.name
|
|
13
|
-
}]);
|
|
13
|
+
}]), S(e.id);
|
|
14
14
|
}, D = (e) => {
|
|
15
|
-
if (e === -1) v(null), b([]);
|
|
15
|
+
if (e === -1) v(null), b([]), S(null);
|
|
16
16
|
else {
|
|
17
17
|
let t = y[e];
|
|
18
|
-
v(t.id), b(y.slice(0, e + 1));
|
|
18
|
+
v(t.id), b(y.slice(0, e + 1)), S(t.id);
|
|
19
19
|
}
|
|
20
20
|
}, O = async () => {
|
|
21
|
-
x
|
|
21
|
+
x === void 0 || x === d.id || (await m(x), p());
|
|
22
22
|
}, k = T.filter((e) => !(f === "folder" && e.id === d.id));
|
|
23
23
|
return /* @__PURE__ */ c("div", {
|
|
24
24
|
className: "fixed inset-0 backdrop-blur-sm flex items-center justify-center z-[100] animate-in fade-in duration-200",
|
|
@@ -69,12 +69,6 @@ var d = ({ item: d, type: f, onClose: p, onMove: m, isLoading: h = !1 }) => {
|
|
|
69
69
|
children: w ? /* @__PURE__ */ c("div", {
|
|
70
70
|
className: "flex items-center justify-center py-8",
|
|
71
71
|
children: /* @__PURE__ */ c(o, { className: "size-6 text-text-tertiary animate-spin" })
|
|
72
|
-
}) : k.length === 0 ? /* @__PURE__ */ l("div", {
|
|
73
|
-
className: "text-center py-8",
|
|
74
|
-
children: [/* @__PURE__ */ c(i, { className: "size-12 text-text-tertiary mx-auto mb-3" }), /* @__PURE__ */ c("p", {
|
|
75
|
-
className: "text-sm text-text-secondary",
|
|
76
|
-
children: e(g, "files.moveDialog.empty.noFolders", "No folders here")
|
|
77
|
-
})]
|
|
78
72
|
}) : /* @__PURE__ */ l("div", {
|
|
79
73
|
className: "space-y-1",
|
|
80
74
|
children: [/* @__PURE__ */ l("button", {
|
|
@@ -85,7 +79,10 @@ var d = ({ item: d, type: f, onClose: p, onMove: m, isLoading: h = !1 }) => {
|
|
|
85
79
|
className: "font-medium text-text-primary",
|
|
86
80
|
children: e(g, "files.moveDialog.actions.moveHere", "Move here")
|
|
87
81
|
})]
|
|
88
|
-
}), k.
|
|
82
|
+
}), k.length === 0 ? /* @__PURE__ */ c("p", {
|
|
83
|
+
className: "text-sm text-text-secondary text-center py-4",
|
|
84
|
+
children: e(g, "files.moveDialog.empty.noSubfolders", "No subfolders")
|
|
85
|
+
}) : k.map((t) => /* @__PURE__ */ l("div", {
|
|
89
86
|
className: `flex items-center justify-between gap-3 px-3 py-2.5 rounded-lg transition-all duration-200 ${x === t.id ? "bg-bg-accent border-2 border-action-primary-border" : "hover:bg-action-ghost-bg-hover border-2 border-transparent"}`,
|
|
90
87
|
children: [/* @__PURE__ */ l("button", {
|
|
91
88
|
type: "button",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MoveDialog.js","names":[],"sources":["../../../src/files/components/MoveDialog.tsx"],"sourcesContent":["import { type FC, useState } from \"react\";\nimport { Folder, Home, ChevronRight, Loader2, X } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport type { FileItem, FolderItem } from \"../types\";\nimport { useFoldersQuery } from \"../hooks/useFoldersQuery\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ninterface MoveDialogProps {\n item: FileItem | FolderItem;\n type: \"file\" | \"folder\";\n onClose: () => void;\n onMove: (destinationFolderId: string | null) => Promise<void>;\n isLoading?: boolean;\n}\n\nexport const MoveDialog: FC<MoveDialogProps> = ({\n item,\n type,\n onClose,\n onMove,\n isLoading = false,\n}) => {\n const { t } = useI18n();\n const [currentFolderId, setCurrentFolderId] = useState<string | null>(null);\n const [breadcrumbs, setBreadcrumbs] = useState<\n Array<{ id: string; name: string }>\n >([]);\n const [selectedDestination, setSelectedDestination] = useState<string | null>(\n null,\n );\n\n // Fetch folders in current location\n const { data, loading: loadingFolders } = useFoldersQuery(\n currentFolderId || undefined,\n );\n const folders = (data?.getFolders?.folders || []) as FolderItem[];\n\n const handleFolderClick = (folder: FolderItem) => {\n setCurrentFolderId(folder.id);\n setBreadcrumbs([...breadcrumbs, { id: folder.id, name: folder.name }]);\n };\n\n const handleBreadcrumbClick = (index: number) => {\n if (index === -1) {\n // Go to root\n setCurrentFolderId(null);\n setBreadcrumbs([]);\n } else {\n const crumb = breadcrumbs[index];\n setCurrentFolderId(crumb.id);\n setBreadcrumbs(breadcrumbs.slice(0, index + 1));\n }\n };\n\n const handleMove = async () => {\n if (selectedDestination === item.id) {\n // Can't move to itself\n return;\n }\n\n await onMove(selectedDestination);\n onClose();\n };\n\n const filteredFolders = folders.filter((folder) => {\n // Don't show the item itself if it's a folder\n if (type === \"folder\" && folder.id === item.id) {\n return false;\n }\n return true;\n });\n\n return (\n <div\n className=\"fixed inset-0 backdrop-blur-sm flex items-center justify-center z-[100] animate-in fade-in duration-200\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={tWithFallback(\n t,\n \"files.moveDialog.ariaLabel\",\n \"Move {{type}} {{name}}\",\n { type, name: item.name },\n )}\n >\n <div className=\"bg-bg-surface rounded-lg shadow-xl w-full max-w-md mx-4 max-h-[80vh] flex flex-col animate-in zoom-in-95 duration-200\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border-default\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tWithFallback(t, \"files.moveDialog.title\", 'Move \"{{name}}\"', {\n name: item.name,\n })}\n </h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"p-1 text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200\"\n aria-label={tWithFallback(\n t,\n \"files.moveDialog.actions.close\",\n \"Close move dialog\",\n )}\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n {/* Breadcrumb navigation */}\n <div className=\"px-6 py-3 border-b border-border-default bg-bg-muted\">\n <div className=\"flex items-center gap-2 text-sm overflow-x-auto\">\n <button\n type=\"button\"\n onClick={() => handleBreadcrumbClick(-1)}\n className=\"flex items-center gap-1.5 text-text-primary hover:bg-action-ghost-bg-hover px-2 py-1 rounded transition-colors duration-200 whitespace-nowrap\"\n >\n <Home className=\"size-4\" />\n <span>\n {tWithFallback(t, \"files.browser.rootLabel\", \"My Drive\")}\n </span>\n </button>\n {breadcrumbs.map((crumb, index) => (\n <div\n key={crumb.id}\n className=\"flex items-center gap-2 whitespace-nowrap\"\n >\n <ChevronRight className=\"size-4 text-text-tertiary\" />\n <button\n type=\"button\"\n onClick={() => handleBreadcrumbClick(index)}\n className={`hover:bg-action-ghost-bg-hover px-2 py-1 rounded transition-colors duration-200 ${\n index === breadcrumbs.length - 1\n ? \"text-text-primary font-medium\"\n : \"text-text-secondary\"\n }`}\n >\n {crumb.name}\n </button>\n </div>\n ))}\n </div>\n </div>\n\n {/* Folder list */}\n <div className=\"flex-1 overflow-y-auto px-6 py-4\">\n {loadingFolders ? (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"size-6 text-text-tertiary animate-spin\" />\n </div>\n ) : filteredFolders.length === 0 ? (\n <div className=\"text-center py-8\">\n <Folder className=\"size-12 text-text-tertiary mx-auto mb-3\" />\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n \"files.moveDialog.empty.noFolders\",\n \"No folders here\",\n )}\n </p>\n </div>\n ) : (\n <div className=\"space-y-1\">\n {/* Option to move to current folder */}\n <button\n type=\"button\"\n onClick={() => setSelectedDestination(currentFolderId)}\n className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-left transition-all duration-200 ${\n selectedDestination === currentFolderId\n ? \"bg-bg-accent border-2 border-action-primary-border\"\n : \"hover:bg-action-ghost-bg-hover border-2 border-transparent\"\n }`}\n >\n <Folder className=\"size-5 text-text-link\" />\n <span className=\"font-medium text-text-primary\">\n {tWithFallback(\n t,\n \"files.moveDialog.actions.moveHere\",\n \"Move here\",\n )}\n </span>\n </button>\n\n {/* List of subfolders */}\n {filteredFolders.map((folder) => (\n <div\n key={folder.id}\n className={`flex items-center justify-between gap-3 px-3 py-2.5 rounded-lg transition-all duration-200 ${\n selectedDestination === folder.id\n ? \"bg-bg-accent border-2 border-action-primary-border\"\n : \"hover:bg-action-ghost-bg-hover border-2 border-transparent\"\n }`}\n >\n <button\n type=\"button\"\n onClick={() => setSelectedDestination(folder.id)}\n className=\"flex items-center gap-3 flex-1 min-w-0\"\n >\n <Folder className=\"size-5 text-text-link flex-shrink-0\" />\n <span className=\"font-medium text-text-primary truncate\">\n {folder.name}\n </span>\n </button>\n <button\n type=\"button\"\n onClick={() => handleFolderClick(folder)}\n className=\"p-1.5 text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200 flex-shrink-0\"\n title={tWithFallback(\n t,\n \"files.moveDialog.actions.openFolder\",\n \"Open folder\",\n )}\n aria-label={tWithFallback(\n t,\n \"files.moveDialog.actions.openFolderNamed\",\n \"Open {{name}}\",\n { name: folder.name },\n )}\n >\n <ChevronRight className=\"size-4\" />\n </button>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"flex items-center justify-end gap-2 px-6 py-4 border-t border-border-default\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"px-4 py-2 text-sm font-medium text-text-primary hover:bg-action-ghost-bg-hover rounded-lg transition-colors duration-200\"\n >\n {tWithFallback(t, \"files.common.actions.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n onClick={handleMove}\n disabled={isLoading || selectedDestination === undefined}\n className=\"px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover disabled:bg-bg-muted disabled:text-text-tertiary disabled:cursor-not-allowed transition-colors duration-200 flex items-center gap-2\"\n >\n {isLoading && <Loader2 className=\"size-4 animate-spin\" />}\n {isLoading\n ? tWithFallback(t, \"files.moveDialog.actions.moving\", \"Moving...\")\n : tWithFallback(t, \"files.common.actions.move\", \"Move\")}\n </button>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MoveDialog.js","names":[],"sources":["../../../src/files/components/MoveDialog.tsx"],"sourcesContent":["import { type FC, useState } from \"react\";\nimport { Folder, Home, ChevronRight, Loader2, X } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport type { FileItem, FolderItem } from \"../types\";\nimport { useFoldersQuery } from \"../hooks/useFoldersQuery\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ninterface MoveDialogProps {\n item: FileItem | FolderItem;\n type: \"file\" | \"folder\";\n onClose: () => void;\n onMove: (destinationFolderId: string | null) => Promise<void>;\n isLoading?: boolean;\n}\n\nexport const MoveDialog: FC<MoveDialogProps> = ({\n item,\n type,\n onClose,\n onMove,\n isLoading = false,\n}) => {\n const { t } = useI18n();\n const [currentFolderId, setCurrentFolderId] = useState<string | null>(null);\n const [breadcrumbs, setBreadcrumbs] = useState<\n Array<{ id: string; name: string }>\n >([]);\n // undefined = nothing selected yet; null = root selected; string = folder id selected\n const [selectedDestination, setSelectedDestination] = useState<\n string | null | undefined\n >(undefined);\n\n // Fetch folders in current location\n const { data, loading: loadingFolders } = useFoldersQuery(\n currentFolderId || undefined,\n );\n const folders = (data?.getFolders?.folders || []) as FolderItem[];\n\n const handleFolderNavigate = (folder: FolderItem) => {\n setCurrentFolderId(folder.id);\n setBreadcrumbs([...breadcrumbs, { id: folder.id, name: folder.name }]);\n setSelectedDestination(folder.id);\n };\n\n const handleBreadcrumbClick = (index: number) => {\n if (index === -1) {\n setCurrentFolderId(null);\n setBreadcrumbs([]);\n setSelectedDestination(null);\n } else {\n const crumb = breadcrumbs[index];\n setCurrentFolderId(crumb.id);\n setBreadcrumbs(breadcrumbs.slice(0, index + 1));\n setSelectedDestination(crumb.id);\n }\n };\n\n const handleMove = async () => {\n if (selectedDestination === undefined || selectedDestination === item.id) {\n return;\n }\n await onMove(selectedDestination);\n onClose();\n };\n\n const filteredFolders = folders.filter((folder) => {\n // Don't show the item itself if it's a folder\n if (type === \"folder\" && folder.id === item.id) {\n return false;\n }\n return true;\n });\n\n return (\n <div\n className=\"fixed inset-0 backdrop-blur-sm flex items-center justify-center z-[100] animate-in fade-in duration-200\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={tWithFallback(\n t,\n \"files.moveDialog.ariaLabel\",\n \"Move {{type}} {{name}}\",\n { type, name: item.name },\n )}\n >\n <div className=\"bg-bg-surface rounded-lg shadow-xl w-full max-w-md mx-4 max-h-[80vh] flex flex-col animate-in zoom-in-95 duration-200\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border-default\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tWithFallback(t, \"files.moveDialog.title\", 'Move \"{{name}}\"', {\n name: item.name,\n })}\n </h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"p-1 text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200\"\n aria-label={tWithFallback(\n t,\n \"files.moveDialog.actions.close\",\n \"Close move dialog\",\n )}\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n {/* Breadcrumb navigation */}\n <div className=\"px-6 py-3 border-b border-border-default bg-bg-muted\">\n <div className=\"flex items-center gap-2 text-sm overflow-x-auto\">\n <button\n type=\"button\"\n onClick={() => handleBreadcrumbClick(-1)}\n className=\"flex items-center gap-1.5 text-text-primary hover:bg-action-ghost-bg-hover px-2 py-1 rounded transition-colors duration-200 whitespace-nowrap\"\n >\n <Home className=\"size-4\" />\n <span>\n {tWithFallback(t, \"files.browser.rootLabel\", \"My Drive\")}\n </span>\n </button>\n {breadcrumbs.map((crumb, index) => (\n <div\n key={crumb.id}\n className=\"flex items-center gap-2 whitespace-nowrap\"\n >\n <ChevronRight className=\"size-4 text-text-tertiary\" />\n <button\n type=\"button\"\n onClick={() => handleBreadcrumbClick(index)}\n className={`hover:bg-action-ghost-bg-hover px-2 py-1 rounded transition-colors duration-200 ${\n index === breadcrumbs.length - 1\n ? \"text-text-primary font-medium\"\n : \"text-text-secondary\"\n }`}\n >\n {crumb.name}\n </button>\n </div>\n ))}\n </div>\n </div>\n\n {/* Folder list */}\n <div className=\"flex-1 overflow-y-auto px-6 py-4\">\n {loadingFolders ? (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"size-6 text-text-tertiary animate-spin\" />\n </div>\n ) : (\n <div className=\"space-y-1\">\n {/* Option to move to current folder */}\n <button\n type=\"button\"\n onClick={() => setSelectedDestination(currentFolderId)}\n className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-left transition-all duration-200 ${\n selectedDestination === currentFolderId\n ? \"bg-bg-accent border-2 border-action-primary-border\"\n : \"hover:bg-action-ghost-bg-hover border-2 border-transparent\"\n }`}\n >\n <Folder className=\"size-5 text-text-link\" />\n <span className=\"font-medium text-text-primary\">\n {tWithFallback(\n t,\n \"files.moveDialog.actions.moveHere\",\n \"Move here\",\n )}\n </span>\n </button>\n\n {filteredFolders.length === 0 ? (\n <p className=\"text-sm text-text-secondary text-center py-4\">\n {tWithFallback(\n t,\n \"files.moveDialog.empty.noSubfolders\",\n \"No subfolders\",\n )}\n </p>\n ) : (\n /* List of subfolders — clicking name selects, ChevronRight navigates in */\n filteredFolders.map((folder) => (\n <div\n key={folder.id}\n className={`flex items-center justify-between gap-3 px-3 py-2.5 rounded-lg transition-all duration-200 ${\n selectedDestination === folder.id\n ? \"bg-bg-accent border-2 border-action-primary-border\"\n : \"hover:bg-action-ghost-bg-hover border-2 border-transparent\"\n }`}\n >\n <button\n type=\"button\"\n onClick={() => setSelectedDestination(folder.id)}\n className=\"flex items-center gap-3 flex-1 min-w-0\"\n >\n <Folder className=\"size-5 text-text-link flex-shrink-0\" />\n <span className=\"font-medium text-text-primary truncate\">\n {folder.name}\n </span>\n </button>\n <button\n type=\"button\"\n onClick={() => handleFolderNavigate(folder)}\n className=\"p-1.5 text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200 flex-shrink-0\"\n title={tWithFallback(\n t,\n \"files.moveDialog.actions.openFolder\",\n \"Open folder\",\n )}\n aria-label={tWithFallback(\n t,\n \"files.moveDialog.actions.openFolderNamed\",\n \"Open {{name}}\",\n { name: folder.name },\n )}\n >\n <ChevronRight className=\"size-4\" />\n </button>\n </div>\n ))\n )}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"flex items-center justify-end gap-2 px-6 py-4 border-t border-border-default\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"px-4 py-2 text-sm font-medium text-text-primary hover:bg-action-ghost-bg-hover rounded-lg transition-colors duration-200\"\n >\n {tWithFallback(t, \"files.common.actions.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n onClick={handleMove}\n disabled={isLoading || selectedDestination === undefined}\n className=\"px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover disabled:bg-bg-muted disabled:text-text-tertiary disabled:cursor-not-allowed transition-colors duration-200 flex items-center gap-2\"\n >\n {isLoading && <Loader2 className=\"size-4 animate-spin\" />}\n {isLoading\n ? tWithFallback(t, \"files.moveDialog.actions.moving\", \"Moving...\")\n : tWithFallback(t, \"files.common.actions.move\", \"Move\")}\n </button>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;AAeA,IAAa,KAAmC,EAC9C,SACA,SACA,YACA,WACA,eAAY,SACR;CACJ,IAAM,EAAE,SAAM,GAAS,EACjB,CAAC,GAAiB,KAAsB,EAAwB,KAAK,EACrE,CAAC,GAAa,KAAkB,EAEpC,EAAE,CAAC,EAEC,CAAC,GAAqB,KAA0B,EAEpD,KAAA,EAAU,EAGN,EAAE,SAAM,SAAS,MAAmB,EACxC,KAAmB,KAAA,EACpB,EACK,IAAW,GAAM,YAAY,WAAW,EAAE,EAE1C,KAAwB,MAAuB;AAGnD,EAFA,EAAmB,EAAO,GAAG,EAC7B,EAAe,CAAC,GAAG,GAAa;GAAE,IAAI,EAAO;GAAI,MAAM,EAAO;GAAM,CAAC,CAAC,EACtE,EAAuB,EAAO,GAAG;IAG7B,KAAyB,MAAkB;AAC/C,MAAI,MAAU,GAGZ,CAFA,EAAmB,KAAK,EACxB,EAAe,EAAE,CAAC,EAClB,EAAuB,KAAK;OACvB;GACL,IAAM,IAAQ,EAAY;AAG1B,GAFA,EAAmB,EAAM,GAAG,EAC5B,EAAe,EAAY,MAAM,GAAG,IAAQ,EAAE,CAAC,EAC/C,EAAuB,EAAM,GAAG;;IAI9B,IAAa,YAAY;AACzB,QAAwB,KAAA,KAAa,MAAwB,EAAK,OAGtE,MAAM,EAAO,EAAoB,EACjC,GAAS;IAGL,IAAkB,EAAQ,QAAQ,MAEtC,EAAI,MAAS,YAAY,EAAO,OAAO,EAAK,IAI5C;AAEF,QACE,kBAAC,OAAD;EACE,WAAU;EACV,MAAK;EACL,cAAW;EACX,cAAY,EACV,GACA,8BACA,0BACA;GAAE;GAAM,MAAM,EAAK;GAAM,CAC1B;YAED,kBAAC,OAAD;GAAK,WAAU;aAAf;IAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAc,GAAG,0BAA0B,qBAAmB,EAC7D,MAAM,EAAK,MACZ,CAAC;MACC,CAAA,EACL,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;MACV,cAAY,EACV,GACA,kCACA,oBACD;gBAED,kBAAC,GAAD,EAAG,WAAU,UAAW,CAAA;MACjB,CAAA,CACL;;IAGN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAsB,GAAG;OACxC,WAAU;iBAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,EAC3B,kBAAC,QAAD,EAAA,UACG,EAAc,GAAG,2BAA2B,WAAW,EACnD,CAAA,CACA;UACR,EAAY,KAAK,GAAO,MACvB,kBAAC,OAAD;OAEE,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAc,WAAU,6BAA8B,CAAA,EACtD,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAsB,EAAM;QAC3C,WAAW,mFACT,MAAU,EAAY,SAAS,IAC3B,kCACA;kBAGL,EAAM;QACA,CAAA,CACL;SAfC,EAAM,GAeP,CACN,CACE;;KACF,CAAA;IAGN,kBAAC,OAAD;KAAK,WAAU;eACZ,IACC,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAS,WAAU,0CAA2C,CAAA;MAC1D,CAAA,GAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CAEE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAuB,EAAgB;OACtD,WAAW,+FACT,MAAwB,IACpB,uDACA;iBANR,CASE,kBAAC,GAAD,EAAQ,WAAU,yBAA0B,CAAA,EAC5C,kBAAC,QAAD;QAAM,WAAU;kBACb,EACC,GACA,qCACA,YACD;QACI,CAAA,CACA;UAER,EAAgB,WAAW,IAC1B,kBAAC,KAAD;OAAG,WAAU;iBACV,EACC,GACA,uCACA,gBACD;OACC,CAAA,GAGJ,EAAgB,KAAK,MACnB,kBAAC,OAAD;OAEE,WAAW,8FACT,MAAwB,EAAO,KAC3B,uDACA;iBALR,CAQE,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAuB,EAAO,GAAG;QAChD,WAAU;kBAHZ,CAKE,kBAAC,GAAD,EAAQ,WAAU,uCAAwC,CAAA,EAC1D,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAO;SACH,CAAA,CACA;WACT,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAqB,EAAO;QAC3C,WAAU;QACV,OAAO,EACL,GACA,uCACA,cACD;QACD,cAAY,EACV,GACA,4CACA,iBACA,EAAE,MAAM,EAAO,MAAM,CACtB;kBAED,kBAAC,GAAD,EAAc,WAAU,UAAW,CAAA;QAC5B,CAAA,CACL;SAnCC,EAAO,GAmCR,CACN,CAEA;;KAEJ,CAAA;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;gBAET,EAAc,GAAG,+BAA+B,SAAS;MACnD,CAAA,EACT,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,UAAU,KAAa,MAAwB,KAAA;MAC/C,WAAU;gBAJZ,CAMG,KAAa,kBAAC,GAAD,EAAS,WAAU,uBAAwB,CAAA,EACxD,IACG,EAAc,GAAG,mCAAmC,YAAY,GAChE,EAAc,GAAG,6BAA6B,OAAO,CAClD;QACL;;IACF;;EACF,CAAA"}
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import { useCreateFolderMutation as e } from "../../generated/wspace-operations.js";
|
|
2
2
|
//#region src/files/hooks/useCreateFolder.ts
|
|
3
3
|
var t = () => {
|
|
4
|
-
let [t, { loading: n, error: r }] = e({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
let [t, { loading: n, error: r }] = e({
|
|
5
|
+
refetchQueries: [
|
|
6
|
+
"GetFilesRootBrowsePage",
|
|
7
|
+
"GetFilesFolderBrowsePage",
|
|
8
|
+
"GetFilesRecentPage"
|
|
9
|
+
],
|
|
10
|
+
awaitRefetchQueries: !0
|
|
11
|
+
});
|
|
10
12
|
return {
|
|
11
|
-
mutateAsync: async (e) =>
|
|
13
|
+
mutateAsync: async (e) => {
|
|
14
|
+
let n = await t({ variables: { input: e } });
|
|
15
|
+
return {
|
|
16
|
+
data: n.data?.createFolder ?? null,
|
|
17
|
+
error: n.error ?? null
|
|
18
|
+
};
|
|
19
|
+
},
|
|
12
20
|
isPending: n,
|
|
13
21
|
error: r
|
|
14
22
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCreateFolder.js","names":[],"sources":["../../../src/files/hooks/useCreateFolder.ts"],"sourcesContent":["import { useCreateFolderMutation } from \"../../generated/wspace-operations\";\n\nexport interface CreateFolderInput {\n name: string;\n description?: string;\n parentFolderId?: string;\n visibility?: string;\n color?: string;\n icon?: string;\n}\n\nexport const useCreateFolder = () => {\n const [createFolderMutation, { loading, error }] = useCreateFolderMutation({\n refetchQueries: [\n \"GetFilesRootBrowsePage\",\n \"GetFilesFolderBrowsePage\",\n \"GetFilesRecentPage\",\n
|
|
1
|
+
{"version":3,"file":"useCreateFolder.js","names":[],"sources":["../../../src/files/hooks/useCreateFolder.ts"],"sourcesContent":["import { useCreateFolderMutation } from \"../../generated/wspace-operations\";\n\nexport interface CreateFolderInput {\n name: string;\n description?: string;\n parentFolderId?: string;\n visibility?: string;\n color?: string;\n icon?: string;\n}\n\nexport const useCreateFolder = () => {\n const [createFolderMutation, { loading, error }] = useCreateFolderMutation({\n refetchQueries: [\n \"GetFilesRootBrowsePage\",\n \"GetFilesFolderBrowsePage\",\n \"GetFilesRecentPage\",\n ],\n awaitRefetchQueries: true,\n });\n\n return {\n mutateAsync: async (input: CreateFolderInput) => {\n const result = await createFolderMutation({\n variables: { input },\n });\n return {\n data: result.data?.createFolder ?? null,\n error: result.error ?? null,\n };\n },\n isPending: loading,\n error,\n };\n};\n"],"mappings":";;AAWA,IAAa,UAAwB;CACnC,IAAM,CAAC,GAAsB,EAAE,YAAS,cAAW,EAAwB;EACzE,gBAAgB;GACd;GACA;GACA;GACD;EACD,qBAAqB;EACtB,CAAC;AAEF,QAAO;EACL,aAAa,OAAO,MAA6B;GAC/C,IAAM,IAAS,MAAM,EAAqB,EACxC,WAAW,EAAE,UAAO,EACrB,CAAC;AACF,UAAO;IACL,MAAM,EAAO,MAAM,gBAAgB;IACnC,OAAO,EAAO,SAAS;IACxB;;EAEH,WAAW;EACX;EACD"}
|
|
@@ -4,8 +4,7 @@ var t = () => {
|
|
|
4
4
|
let [t, { loading: n, error: r }] = e({ refetchQueries: [
|
|
5
5
|
"GetFilesRootBrowsePage",
|
|
6
6
|
"GetFilesFolderBrowsePage",
|
|
7
|
-
"GetFilesRecentPage"
|
|
8
|
-
"GetFiles"
|
|
7
|
+
"GetFilesRecentPage"
|
|
9
8
|
] });
|
|
10
9
|
return {
|
|
11
10
|
mutateAsync: async ({ fileId: e, targetFolderId: n }) => (await t({ variables: { input: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMoveFile.js","names":[],"sources":["../../../src/files/hooks/useMoveFile.ts"],"sourcesContent":["import { useMoveFileMutation } from \"../../generated/wspace-operations\";\n\nexport interface MoveFileInput {\n fileId: string;\n targetFolderId: string | null;\n}\n\nexport const useMoveFile = () => {\n const [moveFileMutation, { loading, error }] = useMoveFileMutation({\n refetchQueries: [\n \"GetFilesRootBrowsePage\",\n \"GetFilesFolderBrowsePage\",\n \"GetFilesRecentPage\",\n
|
|
1
|
+
{"version":3,"file":"useMoveFile.js","names":[],"sources":["../../../src/files/hooks/useMoveFile.ts"],"sourcesContent":["import { useMoveFileMutation } from \"../../generated/wspace-operations\";\n\nexport interface MoveFileInput {\n fileId: string;\n targetFolderId: string | null;\n}\n\nexport const useMoveFile = () => {\n const [moveFileMutation, { loading, error }] = useMoveFileMutation({\n refetchQueries: [\n \"GetFilesRootBrowsePage\",\n \"GetFilesFolderBrowsePage\",\n \"GetFilesRecentPage\",\n ],\n });\n\n return {\n mutateAsync: async ({ fileId, targetFolderId }: MoveFileInput) => {\n const result = await moveFileMutation({\n variables: {\n input: {\n fileId,\n targetFolderId,\n },\n },\n });\n return result.data?.moveFile;\n },\n isPending: loading,\n error,\n };\n};\n"],"mappings":";;AAOA,IAAa,UAAoB;CAC/B,IAAM,CAAC,GAAkB,EAAE,YAAS,cAAW,EAAoB,EACjE,gBAAgB;EACd;EACA;EACA;EACD,EACF,CAAC;AAEF,QAAO;EACL,aAAa,OAAO,EAAE,WAAQ,yBACb,MAAM,EAAiB,EACpC,WAAW,EACT,OAAO;GACL;GACA;GACD,EACF,EACF,CAAC,EACY,MAAM;EAEtB,WAAW;EACX;EACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMoveFolder.js","names":[],"sources":["../../../src/files/hooks/useMoveFolder.ts"],"sourcesContent":["import { useMoveFolderMutation } from \"../../generated/wspace-operations\";\n\nexport interface MoveFolderInput {\n folderId: string;\n targetParentFolderId: string | null;\n}\n\nexport const useMoveFolder = () => {\n const [moveFolderMutation, { loading, error }] = useMoveFolderMutation({\n refetchQueries: [\n \"GetFilesRootBrowsePage\",\n \"GetFilesFolderBrowsePage\",\n \"
|
|
1
|
+
{"version":3,"file":"useMoveFolder.js","names":[],"sources":["../../../src/files/hooks/useMoveFolder.ts"],"sourcesContent":["import { useMoveFolderMutation } from \"../../generated/wspace-operations\";\n\nexport interface MoveFolderInput {\n folderId: string;\n targetParentFolderId: string | null;\n}\n\nexport const useMoveFolder = () => {\n const [moveFolderMutation, { loading, error }] = useMoveFolderMutation({\n refetchQueries: [\n \"GetFilesRootBrowsePage\",\n \"GetFilesFolderBrowsePage\",\n \"GetFilesRecentPage\",\n \"GetFolders\",\n ],\n });\n\n return {\n mutateAsync: async ({\n folderId,\n targetParentFolderId,\n }: MoveFolderInput) => {\n const result = await moveFolderMutation({\n variables: {\n input: {\n folderId,\n targetParentFolderId,\n },\n },\n });\n\n return result.data?.moveFolder;\n },\n isPending: loading,\n error,\n };\n};\n"],"mappings":";;AAOA,IAAa,UAAsB;CACjC,IAAM,CAAC,GAAoB,EAAE,YAAS,cAAW,EAAsB,EACrE,gBAAgB;EACd;EACA;EACA;EACA;EACD,EACF,CAAC;AAEF,QAAO;EACL,aAAa,OAAO,EAClB,aACA,+BAEe,MAAM,EAAmB,EACtC,WAAW,EACT,OAAO;GACL;GACA;GACD,EACF,EACF,CAAC,EAEY,MAAM;EAEtB,WAAW;EACX;EACD"}
|
|
@@ -3,13 +3,14 @@ import { useGetFilesStarredPageQuery as e } from "../../generated/wspace-operati
|
|
|
3
3
|
var t = (t) => {
|
|
4
4
|
let n = e({
|
|
5
5
|
variables: { pagination: { limit: 100 } },
|
|
6
|
-
skip: t?.skip
|
|
7
|
-
|
|
6
|
+
skip: t?.skip,
|
|
7
|
+
errorPolicy: "all"
|
|
8
|
+
}), r = (n.error?.message ?? "").includes("FEATURE_DISABLED");
|
|
8
9
|
return {
|
|
9
10
|
files: n.data?.getStarredFiles?.files || [],
|
|
10
11
|
folders: n.data?.getStarredFolders?.folders || [],
|
|
11
12
|
isLoading: n.loading,
|
|
12
|
-
error: n.error ?? null
|
|
13
|
+
error: r ? null : n.error ?? null
|
|
13
14
|
};
|
|
14
15
|
};
|
|
15
16
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStarredItems.js","names":[],"sources":["../../../src/files/hooks/useStarredItems.ts"],"sourcesContent":["/**\n * Starred Items Hook\n *\n * Fetches starred files and folders for the starred view.\n * Uses one page-owned query for both starred files and folders.\n */\n\nimport { useGetFilesStarredPageQuery } from \"../../generated/wspace-operations\";\nimport type { FileItem, FolderItem } from \"../types\";\n\nexport const useStarredItems = (options?: { skip?: boolean }) => {\n const query = useGetFilesStarredPageQuery({\n variables: {\n pagination: { limit: 100 },\n },\n skip: options?.skip,\n });\n\n return {\n files: (query.data?.getStarredFiles?.files || []) as FileItem[],\n folders: (query.data?.getStarredFolders?.folders || []) as FolderItem[],\n isLoading: query.loading,\n error: query.error ?? null,\n };\n};\n"],"mappings":";;AAUA,IAAa,KAAmB,MAAiC;CAC/D,IAAM,IAAQ,EAA4B;EACxC,WAAW,EACT,YAAY,EAAE,OAAO,KAAK,EAC3B;EACD,MAAM,GAAS;
|
|
1
|
+
{"version":3,"file":"useStarredItems.js","names":[],"sources":["../../../src/files/hooks/useStarredItems.ts"],"sourcesContent":["/**\n * Starred Items Hook\n *\n * Fetches starred files and folders for the starred view.\n * Uses one page-owned query for both starred files and folders.\n */\n\nimport { useGetFilesStarredPageQuery } from \"../../generated/wspace-operations\";\nimport type { FileItem, FolderItem } from \"../types\";\n\nexport const useStarredItems = (options?: { skip?: boolean }) => {\n const query = useGetFilesStarredPageQuery({\n variables: {\n pagination: { limit: 100 },\n },\n skip: options?.skip,\n errorPolicy: \"all\",\n });\n\n // ApolloError serialises all graphQL error messages into its top-level\n // message, so checking for the code string is a reliable way to detect\n // FEATURE_DISABLED without depending on Apollo 4's restricted ErrorLike type.\n const isFeatureDisabled = (query.error?.message ?? \"\").includes(\n \"FEATURE_DISABLED\",\n );\n\n return {\n files: (query.data?.getStarredFiles?.files || []) as FileItem[],\n folders: (query.data?.getStarredFolders?.folders || []) as FolderItem[],\n isLoading: query.loading,\n error: isFeatureDisabled ? null : (query.error ?? null),\n };\n};\n"],"mappings":";;AAUA,IAAa,KAAmB,MAAiC;CAC/D,IAAM,IAAQ,EAA4B;EACxC,WAAW,EACT,YAAY,EAAE,OAAO,KAAK,EAC3B;EACD,MAAM,GAAS;EACf,aAAa;EACd,CAAC,EAKI,KAAqB,EAAM,OAAO,WAAW,IAAI,SACrD,mBACD;AAED,QAAO;EACL,OAAQ,EAAM,MAAM,iBAAiB,SAAS,EAAE;EAChD,SAAU,EAAM,MAAM,mBAAmB,WAAW,EAAE;EACtD,WAAW,EAAM;EACjB,OAAO,IAAoB,OAAQ,EAAM,SAAS;EACnD"}
|
|
@@ -2,17 +2,17 @@ import { useToggleFileStarredMutation as e, useToggleFolderStarredMutation as t
|
|
|
2
2
|
//#region src/files/hooks/useToggleStar.ts
|
|
3
3
|
var n = () => {
|
|
4
4
|
let [n, { loading: r, error: i }] = e({ refetchQueries: [
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
5
|
+
"GetFilesRootBrowsePage",
|
|
6
|
+
"GetFilesFolderBrowsePage",
|
|
7
|
+
"GetFilesStarredPage",
|
|
8
|
+
"GetFilesRecentPage",
|
|
9
|
+
"GetFolders"
|
|
10
10
|
] }), [a, { loading: o, error: s }] = t({ refetchQueries: [
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
11
|
+
"GetFilesRootBrowsePage",
|
|
12
|
+
"GetFilesFolderBrowsePage",
|
|
13
|
+
"GetFilesStarredPage",
|
|
14
|
+
"GetFilesRecentPage",
|
|
15
|
+
"GetFolders"
|
|
16
16
|
] });
|
|
17
17
|
return {
|
|
18
18
|
mutateAsync: async ({ id: e, type: t }) => t === "file" ? (await n({ variables: { id: e } })).data?.toggleFileStarred : (await a({ variables: { id: e } })).data?.toggleFolderStarred,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useToggleStar.js","names":[],"sources":["../../../src/files/hooks/useToggleStar.ts"],"sourcesContent":["import {\n useToggleFileStarredMutation,\n useToggleFolderStarredMutation,\n} from \"../../generated/wspace-operations\";\n\nexport interface ToggleStarInput {\n id: string;\n type: \"file\" | \"folder\";\n}\n\nexport const useToggleStar = () => {\n const [\n toggleFileStarredMutation,\n { loading: fileLoading, error: fileError },\n ] = useToggleFileStarredMutation({\n refetchQueries: [\n \"
|
|
1
|
+
{"version":3,"file":"useToggleStar.js","names":[],"sources":["../../../src/files/hooks/useToggleStar.ts"],"sourcesContent":["import {\n useToggleFileStarredMutation,\n useToggleFolderStarredMutation,\n} from \"../../generated/wspace-operations\";\n\nexport interface ToggleStarInput {\n id: string;\n type: \"file\" | \"folder\";\n}\n\nexport const useToggleStar = () => {\n const [\n toggleFileStarredMutation,\n { loading: fileLoading, error: fileError },\n ] = useToggleFileStarredMutation({\n refetchQueries: [\n \"GetFilesRootBrowsePage\",\n \"GetFilesFolderBrowsePage\",\n \"GetFilesStarredPage\",\n \"GetFilesRecentPage\",\n \"GetFolders\",\n ],\n });\n\n const [\n toggleFolderStarredMutation,\n { loading: folderLoading, error: folderError },\n ] = useToggleFolderStarredMutation({\n refetchQueries: [\n \"GetFilesRootBrowsePage\",\n \"GetFilesFolderBrowsePage\",\n \"GetFilesStarredPage\",\n \"GetFilesRecentPage\",\n \"GetFolders\",\n ],\n });\n\n return {\n mutateAsync: async ({ id, type }: ToggleStarInput) => {\n if (type === \"file\") {\n const result = await toggleFileStarredMutation({\n variables: { id },\n });\n return result.data?.toggleFileStarred;\n } else {\n const result = await toggleFolderStarredMutation({\n variables: { id },\n });\n return result.data?.toggleFolderStarred;\n }\n },\n isPending: fileLoading || folderLoading,\n error: fileError || folderError,\n };\n};\n"],"mappings":";;AAUA,IAAa,UAAsB;CACjC,IAAM,CACJ,GACA,EAAE,SAAS,GAAa,OAAO,OAC7B,EAA6B,EAC/B,gBAAgB;EACd;EACA;EACA;EACA;EACA;EACD,EACF,CAAC,EAEI,CACJ,GACA,EAAE,SAAS,GAAe,OAAO,OAC/B,EAA+B,EACjC,gBAAgB;EACd;EACA;EACA;EACA;EACA;EACD,EACF,CAAC;AAEF,QAAO;EACL,aAAa,OAAO,EAAE,OAAI,cACpB,MAAS,UACI,MAAM,EAA0B,EAC7C,WAAW,EAAE,OAAI,EAClB,CAAC,EACY,MAAM,qBAEL,MAAM,EAA4B,EAC/C,WAAW,EAAE,OAAI,EAClB,CAAC,EACY,MAAM;EAGxB,WAAW,KAAe;EAC1B,OAAO,KAAa;EACrB"}
|