@burdenoff/microfe-files 2026.1014.12 → 2026.1016.10
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 +37 -0
- package/dist/config/index.js.map +1 -1
- package/dist/files/FilesRoot.js +17 -10
- package/dist/files/FilesRoot.js.map +1 -1
- package/dist/files/FilesRoutes.d.ts +1 -1
- package/dist/files/FilesRoutes.js.map +1 -1
- package/dist/files/components/ActionMenu.js.map +1 -1
- package/dist/files/components/ConfirmDialog.d.ts +1 -1
- package/dist/files/components/ConfirmDialog.js.map +1 -1
- package/dist/files/components/ContextMenu.d.ts +1 -1
- package/dist/files/components/ContextMenu.js.map +1 -1
- package/dist/files/components/CopyDialog.js.map +1 -1
- package/dist/files/components/EmptyState.d.ts +1 -1
- package/dist/files/components/EmptyState.js.map +1 -1
- package/dist/files/components/FileBrowser.js +2 -1
- package/dist/files/components/FileBrowser.js.map +1 -1
- package/dist/files/components/FileCard.d.ts.map +1 -1
- package/dist/files/components/FileCard.js +150 -142
- package/dist/files/components/FileCard.js.map +1 -1
- package/dist/files/components/FileInfoPanel.d.ts +1 -1
- package/dist/files/components/FileInfoPanel.d.ts.map +1 -1
- package/dist/files/components/FileInfoPanel.js +3 -7
- package/dist/files/components/FileInfoPanel.js.map +1 -1
- package/dist/files/components/FileListItem.d.ts.map +1 -1
- package/dist/files/components/FileListItem.js +1 -1
- package/dist/files/components/FileListItem.js.map +1 -1
- package/dist/files/components/FilePreviewModal.d.ts +1 -1
- package/dist/files/components/FilePreviewModal.d.ts.map +1 -1
- package/dist/files/components/FilePreviewModal.js +5 -0
- package/dist/files/components/FilePreviewModal.js.map +1 -1
- package/dist/files/components/FileVersionPanel.d.ts.map +1 -1
- package/dist/files/components/FileVersionPanel.js +122 -121
- package/dist/files/components/FileVersionPanel.js.map +1 -1
- package/dist/files/components/FolderCard.d.ts.map +1 -1
- package/dist/files/components/FolderCard.js +1 -1
- package/dist/files/components/FolderCard.js.map +1 -1
- package/dist/files/components/MoveDialog.js +2 -2
- package/dist/files/components/MoveDialog.js.map +1 -1
- package/dist/files/components/SearchBar.d.ts +1 -1
- package/dist/files/components/SearchBar.d.ts.map +1 -1
- package/dist/files/components/SearchBar.js +132 -128
- package/dist/files/components/SearchBar.js.map +1 -1
- package/dist/files/components/ShareDialog.d.ts +1 -1
- package/dist/files/components/ShareDialog.js.map +1 -1
- package/dist/files/components/StorageBanner.js.map +1 -1
- package/dist/files/components/TabBar.d.ts +1 -1
- package/dist/files/components/TabBar.js.map +1 -1
- package/dist/files/components/Toast.d.ts +1 -1
- package/dist/files/components/Toast.js.map +1 -1
- package/dist/files/components/UploadQueue.d.ts +1 -1
- package/dist/files/components/UploadQueue.js +1 -1
- package/dist/files/components/UploadQueue.js.map +1 -1
- package/dist/files/components/contextMenuItems.d.ts +4 -4
- package/dist/files/components/contextMenuItems.js.map +1 -1
- package/dist/files/components/viewers/AudioPlayer.d.ts +1 -1
- package/dist/files/components/viewers/AudioPlayer.js.map +1 -1
- package/dist/files/components/viewers/CodeViewer.d.ts +1 -1
- package/dist/files/components/viewers/CodeViewer.js.map +1 -1
- package/dist/files/components/viewers/ImageViewer.d.ts +1 -1
- package/dist/files/components/viewers/ImageViewer.js.map +1 -1
- package/dist/files/components/viewers/PDFViewer.d.ts +1 -1
- package/dist/files/components/viewers/PDFViewer.js.map +1 -1
- package/dist/files/components/viewers/TextViewer.d.ts +1 -1
- package/dist/files/components/viewers/TextViewer.js.map +1 -1
- package/dist/files/components/viewers/VideoPlayer.d.ts +1 -1
- package/dist/files/components/viewers/VideoPlayer.js.map +1 -1
- package/dist/files/graphql-types.d.ts +2 -17
- package/dist/files/graphql-types.d.ts.map +1 -1
- package/dist/files/hooks/useBatchOperations.d.ts +6 -1
- package/dist/files/hooks/useBatchOperations.d.ts.map +1 -1
- package/dist/files/hooks/useBatchOperations.js +8 -7
- package/dist/files/hooks/useBatchOperations.js.map +1 -1
- package/dist/files/hooks/useBinItems.d.ts.map +1 -1
- package/dist/files/hooks/useBinItems.js +14 -12
- package/dist/files/hooks/useBinItems.js.map +1 -1
- package/dist/files/hooks/useBrowsePage.d.ts +131 -8
- package/dist/files/hooks/useBrowsePage.d.ts.map +1 -1
- package/dist/files/hooks/useBrowsePage.js +23 -22
- package/dist/files/hooks/useBrowsePage.js.map +1 -1
- package/dist/files/hooks/useCopyFile.d.ts +22 -1
- package/dist/files/hooks/useCopyFile.d.ts.map +1 -1
- package/dist/files/hooks/useCopyFile.js +9 -8
- package/dist/files/hooks/useCopyFile.js.map +1 -1
- package/dist/files/hooks/useCreateFolder.d.ts +23 -1
- package/dist/files/hooks/useCreateFolder.d.ts.map +1 -1
- package/dist/files/hooks/useCreateFolder.js +16 -9
- package/dist/files/hooks/useCreateFolder.js.map +1 -1
- package/dist/files/hooks/useCreateFolderShare.d.ts +20 -1
- package/dist/files/hooks/useCreateFolderShare.d.ts.map +1 -1
- package/dist/files/hooks/useCreateFolderShare.js +22 -7
- package/dist/files/hooks/useCreateFolderShare.js.map +1 -1
- package/dist/files/hooks/useCreateShare.d.ts +19 -1
- package/dist/files/hooks/useCreateShare.d.ts.map +1 -1
- package/dist/files/hooks/useCreateShare.js +22 -7
- package/dist/files/hooks/useCreateShare.js.map +1 -1
- package/dist/files/hooks/useDeleteFile.d.ts +1 -1
- package/dist/files/hooks/useDeleteFile.d.ts.map +1 -1
- package/dist/files/hooks/useDeleteFile.js +8 -7
- package/dist/files/hooks/useDeleteFile.js.map +1 -1
- package/dist/files/hooks/useDeleteFolder.d.ts +1 -1
- package/dist/files/hooks/useDeleteFolder.d.ts.map +1 -1
- package/dist/files/hooks/useDeleteFolder.js +9 -8
- package/dist/files/hooks/useDeleteFolder.js.map +1 -1
- package/dist/files/hooks/useDragDrop.js.map +1 -1
- package/dist/files/hooks/useFileVersions.d.ts +36 -9
- package/dist/files/hooks/useFileVersions.d.ts.map +1 -1
- package/dist/files/hooks/useFileVersions.js +14 -13
- package/dist/files/hooks/useFileVersions.js.map +1 -1
- package/dist/files/hooks/useFoldersQuery.d.ts +8 -4
- package/dist/files/hooks/useFoldersQuery.d.ts.map +1 -1
- package/dist/files/hooks/useFoldersQuery.js +7 -6
- package/dist/files/hooks/useFoldersQuery.js.map +1 -1
- package/dist/files/hooks/useKeyboardNavigation.js +7 -8
- package/dist/files/hooks/useKeyboardNavigation.js.map +1 -1
- package/dist/files/hooks/useMoveFile.d.ts +22 -1
- package/dist/files/hooks/useMoveFile.d.ts.map +1 -1
- package/dist/files/hooks/useMoveFile.js +9 -8
- package/dist/files/hooks/useMoveFile.js.map +1 -1
- package/dist/files/hooks/useMoveFolder.d.ts +22 -1
- package/dist/files/hooks/useMoveFolder.d.ts.map +1 -1
- package/dist/files/hooks/useMoveFolder.js +9 -8
- package/dist/files/hooks/useMoveFolder.js.map +1 -1
- package/dist/files/hooks/usePermanentlyDeleteFile.d.ts +1 -1
- package/dist/files/hooks/usePermanentlyDeleteFile.d.ts.map +1 -1
- package/dist/files/hooks/usePermanentlyDeleteFile.js +8 -7
- package/dist/files/hooks/usePermanentlyDeleteFile.js.map +1 -1
- package/dist/files/hooks/usePermanentlyDeleteFolder.d.ts +1 -1
- package/dist/files/hooks/usePermanentlyDeleteFolder.d.ts.map +1 -1
- package/dist/files/hooks/usePermanentlyDeleteFolder.js +8 -7
- package/dist/files/hooks/usePermanentlyDeleteFolder.js.map +1 -1
- package/dist/files/hooks/useRecentFiles.d.ts.map +1 -1
- package/dist/files/hooks/useRecentFiles.js +13 -11
- package/dist/files/hooks/useRecentFiles.js.map +1 -1
- package/dist/files/hooks/useRenameFile.d.ts +22 -1
- package/dist/files/hooks/useRenameFile.d.ts.map +1 -1
- package/dist/files/hooks/useRenameFile.js +9 -8
- package/dist/files/hooks/useRenameFile.js.map +1 -1
- package/dist/files/hooks/useRenameFolder.d.ts +22 -1
- package/dist/files/hooks/useRenameFolder.d.ts.map +1 -1
- package/dist/files/hooks/useRenameFolder.js +9 -8
- package/dist/files/hooks/useRenameFolder.js.map +1 -1
- package/dist/files/hooks/useRestoreFile.d.ts +22 -1
- package/dist/files/hooks/useRestoreFile.d.ts.map +1 -1
- package/dist/files/hooks/useRestoreFile.js +8 -7
- package/dist/files/hooks/useRestoreFile.js.map +1 -1
- package/dist/files/hooks/useRestoreFolder.d.ts +22 -1
- package/dist/files/hooks/useRestoreFolder.d.ts.map +1 -1
- package/dist/files/hooks/useRestoreFolder.js +8 -7
- package/dist/files/hooks/useRestoreFolder.js.map +1 -1
- package/dist/files/hooks/useSearch.d.ts +2 -3
- package/dist/files/hooks/useSearch.d.ts.map +1 -1
- package/dist/files/hooks/useSearch.js +14 -12
- package/dist/files/hooks/useSearch.js.map +1 -1
- package/dist/files/hooks/useStarredItems.d.ts +2 -3
- package/dist/files/hooks/useStarredItems.d.ts.map +1 -1
- package/dist/files/hooks/useStarredItems.js +12 -10
- package/dist/files/hooks/useStarredItems.js.map +1 -1
- package/dist/files/hooks/useStorageQuota.d.ts.map +1 -1
- package/dist/files/hooks/useStorageQuota.js +17 -16
- package/dist/files/hooks/useStorageQuota.js.map +1 -1
- package/dist/files/hooks/useToast.js.map +1 -1
- package/dist/files/hooks/useToggleStar.d.ts +43 -1
- package/dist/files/hooks/useToggleStar.d.ts.map +1 -1
- package/dist/files/hooks/useToggleStar.js +9 -8
- package/dist/files/hooks/useToggleStar.js.map +1 -1
- package/dist/files/hooks/useUploadFile.d.ts +23 -1
- package/dist/files/hooks/useUploadFile.d.ts.map +1 -1
- package/dist/files/hooks/useUploadFile.js +28 -27
- package/dist/files/hooks/useUploadFile.js.map +1 -1
- package/dist/files/hooks/useUploadQueueState.d.ts +32 -0
- package/dist/files/hooks/useUploadQueueState.d.ts.map +1 -0
- package/dist/files/hooks/useUploadQueueState.js +61 -0
- package/dist/files/hooks/useUploadQueueState.js.map +1 -0
- package/dist/files/index.js +4 -3
- package/dist/files/pages/BrowserPage.d.ts +1 -1
- package/dist/files/pages/BrowserPage.d.ts.map +1 -1
- package/dist/files/pages/BrowserPage.js +383 -387
- package/dist/files/pages/BrowserPage.js.map +1 -1
- package/dist/files/pages/ShareAccessPage.d.ts +1 -1
- package/dist/files/pages/ShareAccessPage.js.map +1 -1
- package/dist/files/providers/FilesProvider.js.map +1 -1
- package/dist/files/store/filesStore.js.map +1 -1
- package/dist/files/types.d.ts.map +1 -1
- package/dist/files/utils/events.js.map +1 -1
- package/dist/files/utils/fileViewModel.d.ts +7 -0
- package/dist/files/utils/fileViewModel.d.ts.map +1 -0
- package/dist/files/utils/fileViewModel.js +34 -0
- package/dist/files/utils/fileViewModel.js.map +1 -0
- package/dist/files/utils/i18n.js.map +1 -1
- package/dist/files/utils/index.js +19 -19
- package/dist/files/utils/index.js.map +1 -1
- package/dist/files/utils/quotaUtils.js +1 -2
- package/dist/files/utils/thumbnail.js +19 -23
- package/dist/files/utils/thumbnail.js.map +1 -1
- package/dist/files/utils/uploadDigest.js +1 -1
- package/dist/files/utils/uploadDigest.js.map +1 -1
- package/dist/generated/global-operations.d.ts +4 -1
- package/dist/generated/global-operations.d.ts.map +1 -1
- package/dist/generated/global-types.d.ts +16 -21
- package/dist/generated/global-types.d.ts.map +1 -1
- package/dist/generated/wspace-operations.d.ts +503 -1784
- package/dist/generated/wspace-operations.d.ts.map +1 -1
- package/dist/generated/wspace-operations.js +15278 -1110
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/generated/wspace-types.d.ts +90013 -24889
- package/dist/generated/wspace-types.d.ts.map +1 -1
- package/dist/generated/wspace-types.js +16 -0
- package/dist/generated/wspace-types.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/shared/hooks/useTr.js.map +1 -1
- package/dist/translations/en.js.map +1 -1
- package/dist/utils/nativeBridge.js +1 -2
- package/package.json +24 -22
- package/dist/files.d.ts +0 -2
|
@@ -19,8 +19,8 @@ var g = ({ item: g, type: _, onClose: v, onMove: y, isLoading: b = !1 }) => {
|
|
|
19
19
|
C(t.id), T(w.slice(0, e + 1)), D(t.id);
|
|
20
20
|
}
|
|
21
21
|
}, N = async () => {
|
|
22
|
-
E
|
|
23
|
-
}, P = A.filter((e) =>
|
|
22
|
+
E !== void 0 && E !== g.id && (await y(E), v());
|
|
23
|
+
}, P = A.filter((e) => _ !== "folder" || e.id !== g.id);
|
|
24
24
|
return /* @__PURE__ */ s(d, {
|
|
25
25
|
open: !0,
|
|
26
26
|
onOpenChange: (e) => {
|
|
@@ -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 } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogFooter,\n Button,\n} from \"@burdenoff/fe-libs/ui\";\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 <ResponsiveDialog\n open\n onOpenChange={(next: boolean) => {\n if (!next && !isLoading) {\n onClose();\n }\n }}\n >\n <ResponsiveDialogContent\n className=\"flex max-h-[80vh] w-full max-w-md flex-col gap-0 p-0\"\n aria-label={tWithFallback(\n t,\n \"files.moveDialog.ariaLabel\",\n \"Move {{type}} {{name}}\",\n { type, name: item.name },\n )}\n >\n {/* Header */}\n <ResponsiveDialogHeader className=\"px-6 py-4 border-b border-border-default text-left\">\n <ResponsiveDialogTitle className=\"text-lg font-semibold text-text-primary\">\n {tWithFallback(t, \"files.moveDialog.title\", 'Move \"{{name}}\"', {\n name: item.name,\n })}\n </ResponsiveDialogTitle>\n </ResponsiveDialogHeader>\n\n {/* Breadcrumb navigation */}\n <div className=\"px-6 py-3 border-b border-border-default bg-bg-sunken\">\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 <ResponsiveDialogFooter className=\"px-6 py-4 border-t border-border-default\">\n <Button type=\"button\" variant=\"outline\" onClick={onClose}>\n {tWithFallback(t, \"files.common.actions.cancel\", \"Cancel\")}\n </Button>\n <Button\n type=\"button\"\n onClick={handleMove}\n disabled={isLoading || selectedDestination === undefined}\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 </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MoveDialog.js","names":["MoveDialog","useI18n","currentFolderId","setCurrentFolderId","useState","breadcrumbs","setBreadcrumbs","selectedDestination","setSelectedDestination","loadingFolders","useFoldersQuery","folders","data","handleFolderNavigate","folder","handleBreadcrumbClick","index","crumb","handleMove","item","onMove","onClose","filteredFolders","type","ResponsiveDialog","next","isLoading","ResponsiveDialogContent","tWithFallback","t","ResponsiveDialogHeader","ResponsiveDialogTitle","Home","ChevronRight","Loader2","Folder","ResponsiveDialogFooter","Button"],"sources":["../../../src/files/components/MoveDialog.tsx"],"sourcesContent":["import { type FC, useState } from \"react\";\nimport { Folder, Home, ChevronRight, Loader2 } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogFooter,\n Button,\n} from \"@burdenoff/fe-libs/ui\";\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 <ResponsiveDialog\n open\n onOpenChange={(next: boolean) => {\n if (!next && !isLoading) {\n onClose();\n }\n }}\n >\n <ResponsiveDialogContent\n className=\"flex max-h-[80vh] w-full max-w-md flex-col gap-0 p-0\"\n aria-label={tWithFallback(\n t,\n \"files.moveDialog.ariaLabel\",\n \"Move {{type}} {{name}}\",\n { type, name: item.name },\n )}\n >\n {/* Header */}\n <ResponsiveDialogHeader className=\"px-6 py-4 border-b border-border-default text-left\">\n <ResponsiveDialogTitle className=\"text-lg font-semibold text-text-primary\">\n {tWithFallback(t, \"files.moveDialog.title\", 'Move \"{{name}}\"', {\n name: item.name,\n })}\n </ResponsiveDialogTitle>\n </ResponsiveDialogHeader>\n\n {/* Breadcrumb navigation */}\n <div className=\"px-6 py-3 border-b border-border-default bg-bg-sunken\">\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 <ResponsiveDialogFooter className=\"px-6 py-4 border-t border-border-default\">\n <Button type=\"button\" variant=\"outline\" onClick={onClose}>\n {tWithFallback(t, \"files.common.actions.cancel\", \"Cancel\")}\n </Button>\n <Button\n type=\"button\"\n onClick={handleMove}\n disabled={isLoading || selectedDestination === undefined}\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 </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n};\n"],"mappings":"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"}
|
|
@@ -8,6 +8,6 @@ interface SearchBarProps {
|
|
|
8
8
|
initialQuery?: string;
|
|
9
9
|
showFilters?: boolean;
|
|
10
10
|
}
|
|
11
|
-
export declare function SearchBar({ onSearch, placeholder, initialQuery, showFilters, }: SearchBarProps): import(
|
|
11
|
+
export declare function SearchBar({ onSearch, placeholder, initialQuery, showFilters, }: SearchBarProps): import('react').JSX.Element;
|
|
12
12
|
export {};
|
|
13
13
|
//# sourceMappingURL=SearchBar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchBar.d.ts","sourceRoot":"","sources":["../../../src/files/components/SearchBar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SearchBar.d.ts","sourceRoot":"","sources":["../../../src/files/components/SearchBar.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG3E,UAAU,cAAc;IACtB,QAAQ,EAAE,CACR,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QACR,UAAU,CAAC,EAAE,eAAe,CAAC;QAC7B,YAAY,CAAC,EAAE,iBAAiB,CAAC;KAClC,KACE,IAAI,CAAC;IACV,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAgCD,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,WAA2C,EAC3C,YAAiB,EACjB,WAAkB,GACnB,EAAE,cAAc,+BAsYhB"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { FileStatus as e, FileVisibility as t, FolderStatus as n } from "../../generated/wspace-types.js";
|
|
2
|
+
import { tWithFallback as r } from "../utils/i18n.js";
|
|
3
|
+
import { useCallback as i, useEffect as a, useEffectEvent as o, useState as s } from "react";
|
|
4
|
+
import { Filter as c, Search as l, X as u } from "lucide-react";
|
|
5
|
+
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
6
|
+
import { useI18n as p } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
6
7
|
//#region src/files/components/SearchBar.tsx
|
|
7
|
-
var
|
|
8
|
+
var m = {
|
|
8
9
|
image: [
|
|
9
10
|
"image/jpeg",
|
|
10
11
|
"image/png",
|
|
@@ -37,225 +38,228 @@ var d = {
|
|
|
37
38
|
"application/x-rar-compressed"
|
|
38
39
|
]
|
|
39
40
|
};
|
|
40
|
-
function
|
|
41
|
-
let { t:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}, [
|
|
45
|
-
let
|
|
46
|
-
(
|
|
47
|
-
|
|
48
|
-
...
|
|
49
|
-
...
|
|
50
|
-
...
|
|
51
|
-
...
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
...w && {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
41
|
+
function h({ onSearch: h, placeholder: g = "Search files and folders...", initialQuery: _ = "", showFilters: v = !0 }) {
|
|
42
|
+
let { t: y } = p(), [b, x] = s(_), [S, C] = s(!1), [w, T] = s({}), E = w.status, D = Object.values(n).find((e) => String(e) === w.status), O = w.visibility, k = w.fileType ? m[w.fileType] : void 0;
|
|
43
|
+
a(() => {
|
|
44
|
+
x(_);
|
|
45
|
+
}, [_]);
|
|
46
|
+
let A = o(() => {
|
|
47
|
+
if (b.length >= 2 || b.length === 0) {
|
|
48
|
+
let e = {
|
|
49
|
+
...k && { mimeTypes: k },
|
|
50
|
+
...E && { status: E },
|
|
51
|
+
...O && { visibility: O },
|
|
52
|
+
...w.starred !== void 0 && { starred: w.starred }
|
|
53
|
+
}, t = {
|
|
54
|
+
...D && { status: D },
|
|
55
|
+
...w.starred !== void 0 && { starred: w.starred }
|
|
56
|
+
};
|
|
57
|
+
h(b, {
|
|
58
|
+
fileFilter: e,
|
|
59
|
+
folderFilter: t
|
|
60
|
+
});
|
|
61
|
+
}
|
|
58
62
|
});
|
|
59
|
-
|
|
63
|
+
a(() => {
|
|
60
64
|
let e = setTimeout(() => {
|
|
61
|
-
|
|
65
|
+
A();
|
|
62
66
|
}, 300);
|
|
63
67
|
return () => clearTimeout(e);
|
|
64
68
|
}, [
|
|
65
|
-
C,
|
|
66
69
|
E,
|
|
67
|
-
|
|
70
|
+
k,
|
|
71
|
+
O,
|
|
72
|
+
D,
|
|
68
73
|
w,
|
|
69
|
-
|
|
70
|
-
_
|
|
74
|
+
b
|
|
71
75
|
]);
|
|
72
|
-
let
|
|
73
|
-
|
|
74
|
-
}, [
|
|
75
|
-
return /* @__PURE__ */
|
|
76
|
+
let j = i(() => {
|
|
77
|
+
x(""), T({}), h("");
|
|
78
|
+
}, [h]), M = Object.values(w).filter((e) => e !== void 0).length;
|
|
79
|
+
return /* @__PURE__ */ f("div", {
|
|
76
80
|
className: "relative",
|
|
77
|
-
children: [/* @__PURE__ */
|
|
81
|
+
children: [/* @__PURE__ */ f("div", {
|
|
78
82
|
className: "relative flex items-center",
|
|
79
83
|
children: [
|
|
80
|
-
/* @__PURE__ */
|
|
81
|
-
/* @__PURE__ */
|
|
84
|
+
/* @__PURE__ */ d(l, { className: "absolute left-3 size-4 text-text-tertiary" }),
|
|
85
|
+
/* @__PURE__ */ d("label", {
|
|
82
86
|
htmlFor: "files-search-input",
|
|
83
87
|
className: "sr-only",
|
|
84
|
-
children:
|
|
88
|
+
children: r(y, "files.search.input.label", "Search files and folders")
|
|
85
89
|
}),
|
|
86
|
-
/* @__PURE__ */
|
|
90
|
+
/* @__PURE__ */ d("input", {
|
|
87
91
|
id: "files-search-input",
|
|
88
92
|
type: "text",
|
|
89
|
-
value:
|
|
90
|
-
onChange: (e) =>
|
|
91
|
-
placeholder:
|
|
92
|
-
"aria-label":
|
|
93
|
+
value: b,
|
|
94
|
+
onChange: (e) => x(e.target.value),
|
|
95
|
+
placeholder: g,
|
|
96
|
+
"aria-label": r(y, "files.search.input.label", "Search files and folders"),
|
|
93
97
|
className: "w-full pl-[3.25rem] pr-20 py-2 border border-border-default rounded-lg focus:outline-none focus:ring-2 focus:ring-action-primary-border focus:border-action-primary-border transition-colors duration-200"
|
|
94
98
|
}),
|
|
95
|
-
/* @__PURE__ */
|
|
99
|
+
/* @__PURE__ */ f("div", {
|
|
96
100
|
className: "absolute right-2 flex items-center gap-1",
|
|
97
|
-
children: [
|
|
101
|
+
children: [b && /* @__PURE__ */ d("button", {
|
|
98
102
|
type: "button",
|
|
99
|
-
onClick:
|
|
103
|
+
onClick: j,
|
|
100
104
|
className: "p-1.5 text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200",
|
|
101
|
-
title:
|
|
102
|
-
"aria-label":
|
|
103
|
-
children: /* @__PURE__ */
|
|
104
|
-
}),
|
|
105
|
+
title: r(y, "files.search.actions.clearSearch", "Clear search"),
|
|
106
|
+
"aria-label": r(y, "files.search.actions.clearSearch", "Clear search"),
|
|
107
|
+
children: /* @__PURE__ */ d(u, { className: "size-4" })
|
|
108
|
+
}), v && /* @__PURE__ */ f("button", {
|
|
105
109
|
type: "button",
|
|
106
|
-
onClick: () =>
|
|
107
|
-
"aria-expanded":
|
|
110
|
+
onClick: () => C(!S),
|
|
111
|
+
"aria-expanded": S,
|
|
108
112
|
"aria-controls": "files-search-filter-panel",
|
|
109
|
-
"aria-label":
|
|
110
|
-
className: `p-1.5 rounded transition-colors duration-200 relative ${
|
|
111
|
-
title:
|
|
112
|
-
children: [/* @__PURE__ */ c
|
|
113
|
+
"aria-label": r(y, "files.search.filters.toggleAria", "Toggle filters"),
|
|
114
|
+
className: `p-1.5 rounded transition-colors duration-200 relative ${S || M > 0 ? "text-text-link bg-bg-accent hover:bg-action-primary-bg/20" : "text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover"}`,
|
|
115
|
+
title: r(y, "files.search.filters.title", "Filters"),
|
|
116
|
+
children: [/* @__PURE__ */ d(c, { className: "size-4" }), M > 0 && /* @__PURE__ */ d("span", {
|
|
113
117
|
className: "absolute -top-1 -right-1 size-4 bg-action-primary-bg text-text-inverse text-[10px] font-bold rounded-full flex items-center justify-center",
|
|
114
|
-
children:
|
|
118
|
+
children: M
|
|
115
119
|
})]
|
|
116
120
|
})]
|
|
117
121
|
})
|
|
118
122
|
]
|
|
119
|
-
}),
|
|
123
|
+
}), S && /* @__PURE__ */ d("div", {
|
|
120
124
|
id: "files-search-filter-panel",
|
|
121
125
|
className: "absolute top-full left-0 right-0 mt-2 p-4 bg-bg-surface border border-border-default rounded-lg shadow-lg z-10 animate-in fade-in duration-200",
|
|
122
|
-
children: /* @__PURE__ */
|
|
126
|
+
children: /* @__PURE__ */ f("div", {
|
|
123
127
|
className: "space-y-4",
|
|
124
128
|
children: [
|
|
125
|
-
/* @__PURE__ */
|
|
129
|
+
/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
126
130
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
127
|
-
children:
|
|
128
|
-
}), /* @__PURE__ */
|
|
129
|
-
value:
|
|
130
|
-
onChange: (e) =>
|
|
131
|
-
...
|
|
131
|
+
children: r(y, "files.search.filters.fileType.label", "File Type")
|
|
132
|
+
}), /* @__PURE__ */ f("select", {
|
|
133
|
+
value: w.fileType || "",
|
|
134
|
+
onChange: (e) => T({
|
|
135
|
+
...w,
|
|
132
136
|
fileType: e.target.value || void 0
|
|
133
137
|
}),
|
|
134
|
-
"aria-label":
|
|
138
|
+
"aria-label": r(y, "files.search.filters.fileType.label", "File Type"),
|
|
135
139
|
className: "w-full px-3 py-2 border border-border-default rounded-lg bg-bg-surface text-text-primary scheme-normal dark:scheme-dark focus:outline-none focus:ring-2 focus:ring-action-primary-border transition-colors duration-200 [&_option]:bg-bg-surface [&_option]:text-text-primary",
|
|
136
140
|
children: [
|
|
137
|
-
/* @__PURE__ */
|
|
141
|
+
/* @__PURE__ */ d("option", {
|
|
138
142
|
value: "",
|
|
139
|
-
children:
|
|
143
|
+
children: r(y, "files.search.filters.fileType.options.all", "All types")
|
|
140
144
|
}),
|
|
141
|
-
/* @__PURE__ */
|
|
145
|
+
/* @__PURE__ */ d("option", {
|
|
142
146
|
value: "image",
|
|
143
|
-
children:
|
|
147
|
+
children: r(y, "files.search.filters.fileType.options.image", "Images")
|
|
144
148
|
}),
|
|
145
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ d("option", {
|
|
146
150
|
value: "video",
|
|
147
|
-
children:
|
|
151
|
+
children: r(y, "files.search.filters.fileType.options.video", "Videos")
|
|
148
152
|
}),
|
|
149
|
-
/* @__PURE__ */
|
|
153
|
+
/* @__PURE__ */ d("option", {
|
|
150
154
|
value: "document",
|
|
151
|
-
children:
|
|
155
|
+
children: r(y, "files.search.filters.fileType.options.document", "Documents")
|
|
152
156
|
}),
|
|
153
|
-
/* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ d("option", {
|
|
154
158
|
value: "pdf",
|
|
155
|
-
children:
|
|
159
|
+
children: r(y, "files.search.filters.fileType.options.pdf", "PDFs")
|
|
156
160
|
}),
|
|
157
|
-
/* @__PURE__ */
|
|
161
|
+
/* @__PURE__ */ d("option", {
|
|
158
162
|
value: "archive",
|
|
159
|
-
children:
|
|
163
|
+
children: r(y, "files.search.filters.fileType.options.archive", "Archives")
|
|
160
164
|
})
|
|
161
165
|
]
|
|
162
166
|
})] }),
|
|
163
|
-
/* @__PURE__ */
|
|
167
|
+
/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
164
168
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
165
|
-
children:
|
|
166
|
-
}), /* @__PURE__ */
|
|
167
|
-
value:
|
|
168
|
-
onChange: (
|
|
169
|
-
...
|
|
170
|
-
status: e.target.value
|
|
169
|
+
children: r(y, "files.search.filters.status.label", "Status")
|
|
170
|
+
}), /* @__PURE__ */ f("select", {
|
|
171
|
+
value: w.status || "",
|
|
172
|
+
onChange: (t) => T({
|
|
173
|
+
...w,
|
|
174
|
+
status: Object.values(e).find((e) => e === t.target.value)
|
|
171
175
|
}),
|
|
172
|
-
"aria-label":
|
|
176
|
+
"aria-label": r(y, "files.search.filters.status.label", "Status"),
|
|
173
177
|
className: "w-full px-3 py-2 border border-border-default rounded-lg bg-bg-surface text-text-primary scheme-normal dark:scheme-dark focus:outline-none focus:ring-2 focus:ring-action-primary-border transition-colors duration-200 [&_option]:bg-bg-surface [&_option]:text-text-primary",
|
|
174
178
|
children: [
|
|
175
|
-
/* @__PURE__ */
|
|
179
|
+
/* @__PURE__ */ d("option", {
|
|
176
180
|
value: "",
|
|
177
|
-
children:
|
|
181
|
+
children: r(y, "files.search.filters.status.options.all", "All statuses")
|
|
178
182
|
}),
|
|
179
|
-
/* @__PURE__ */
|
|
183
|
+
/* @__PURE__ */ d("option", {
|
|
180
184
|
value: "ACTIVE",
|
|
181
|
-
children:
|
|
185
|
+
children: r(y, "files.search.filters.status.options.active", "Active")
|
|
182
186
|
}),
|
|
183
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ d("option", {
|
|
184
188
|
value: "ARCHIVED",
|
|
185
|
-
children:
|
|
189
|
+
children: r(y, "files.search.filters.status.options.archived", "Archived")
|
|
186
190
|
}),
|
|
187
|
-
/* @__PURE__ */
|
|
191
|
+
/* @__PURE__ */ d("option", {
|
|
188
192
|
value: "DELETED",
|
|
189
|
-
children:
|
|
193
|
+
children: r(y, "files.search.filters.status.options.deleted", "Deleted")
|
|
190
194
|
})
|
|
191
195
|
]
|
|
192
196
|
})] }),
|
|
193
|
-
/* @__PURE__ */
|
|
197
|
+
/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
194
198
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
195
|
-
children:
|
|
196
|
-
}), /* @__PURE__ */
|
|
197
|
-
value:
|
|
198
|
-
onChange: (e) =>
|
|
199
|
-
...
|
|
200
|
-
visibility: e.target.value
|
|
199
|
+
children: r(y, "files.search.filters.visibility.label", "Visibility")
|
|
200
|
+
}), /* @__PURE__ */ f("select", {
|
|
201
|
+
value: w.visibility || "",
|
|
202
|
+
onChange: (e) => T({
|
|
203
|
+
...w,
|
|
204
|
+
visibility: Object.values(t).find((t) => t === e.target.value)
|
|
201
205
|
}),
|
|
202
|
-
"aria-label":
|
|
206
|
+
"aria-label": r(y, "files.search.filters.visibility.label", "Visibility"),
|
|
203
207
|
className: "w-full px-3 py-2 border border-border-default rounded-lg bg-bg-surface text-text-primary scheme-normal dark:scheme-dark focus:outline-none focus:ring-2 focus:ring-action-primary-border transition-colors duration-200 [&_option]:bg-bg-surface [&_option]:text-text-primary",
|
|
204
208
|
children: [
|
|
205
|
-
/* @__PURE__ */
|
|
209
|
+
/* @__PURE__ */ d("option", {
|
|
206
210
|
value: "",
|
|
207
|
-
children:
|
|
211
|
+
children: r(y, "files.search.filters.visibility.options.all", "All visibility")
|
|
208
212
|
}),
|
|
209
|
-
/* @__PURE__ */
|
|
213
|
+
/* @__PURE__ */ d("option", {
|
|
210
214
|
value: "PRIVATE",
|
|
211
|
-
children:
|
|
215
|
+
children: r(y, "files.search.filters.visibility.options.private", "Private")
|
|
212
216
|
}),
|
|
213
|
-
/* @__PURE__ */
|
|
217
|
+
/* @__PURE__ */ d("option", {
|
|
214
218
|
value: "TEAM",
|
|
215
|
-
children:
|
|
219
|
+
children: r(y, "files.search.filters.visibility.options.team", "Team")
|
|
216
220
|
}),
|
|
217
|
-
/* @__PURE__ */
|
|
221
|
+
/* @__PURE__ */ d("option", {
|
|
218
222
|
value: "WORKSPACE",
|
|
219
|
-
children:
|
|
223
|
+
children: r(y, "files.search.filters.visibility.options.workspace", "Workspace")
|
|
220
224
|
}),
|
|
221
|
-
/* @__PURE__ */
|
|
225
|
+
/* @__PURE__ */ d("option", {
|
|
222
226
|
value: "PUBLIC",
|
|
223
|
-
children:
|
|
227
|
+
children: r(y, "files.search.filters.visibility.options.public", "Public")
|
|
224
228
|
})
|
|
225
229
|
]
|
|
226
230
|
})] }),
|
|
227
|
-
/* @__PURE__ */
|
|
231
|
+
/* @__PURE__ */ f("div", {
|
|
228
232
|
className: "flex items-center",
|
|
229
|
-
children: [/* @__PURE__ */
|
|
233
|
+
children: [/* @__PURE__ */ d("input", {
|
|
230
234
|
type: "checkbox",
|
|
231
235
|
id: "starred-filter",
|
|
232
|
-
checked:
|
|
233
|
-
onChange: (e) =>
|
|
234
|
-
...
|
|
236
|
+
checked: w.starred || !1,
|
|
237
|
+
onChange: (e) => T({
|
|
238
|
+
...w,
|
|
235
239
|
starred: e.target.checked || void 0
|
|
236
240
|
}),
|
|
237
|
-
"aria-label":
|
|
241
|
+
"aria-label": r(y, "files.search.filters.starred.label", "Starred only"),
|
|
238
242
|
className: "size-4 text-action-primary-bg border-border-default rounded focus:ring-action-primary-border transition-colors duration-200"
|
|
239
|
-
}), /* @__PURE__ */
|
|
243
|
+
}), /* @__PURE__ */ d("label", {
|
|
240
244
|
htmlFor: "starred-filter",
|
|
241
245
|
className: "ml-2 text-sm text-text-primary",
|
|
242
|
-
children:
|
|
246
|
+
children: r(y, "files.search.filters.starredOnly", "Starred only")
|
|
243
247
|
})]
|
|
244
248
|
}),
|
|
245
|
-
/* @__PURE__ */
|
|
249
|
+
/* @__PURE__ */ f("div", {
|
|
246
250
|
className: "flex justify-end gap-2 pt-2 border-t border-border-default",
|
|
247
|
-
children: [/* @__PURE__ */
|
|
251
|
+
children: [/* @__PURE__ */ d("button", {
|
|
248
252
|
type: "button",
|
|
249
253
|
onClick: () => {
|
|
250
|
-
|
|
254
|
+
T({}), C(!1);
|
|
251
255
|
},
|
|
252
256
|
className: "px-3 py-1.5 text-sm text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200",
|
|
253
|
-
children:
|
|
254
|
-
}), /* @__PURE__ */
|
|
257
|
+
children: r(y, "files.search.filters.actions.clear", "Clear filters")
|
|
258
|
+
}), /* @__PURE__ */ d("button", {
|
|
255
259
|
type: "button",
|
|
256
|
-
onClick: () =>
|
|
260
|
+
onClick: () => C(!1),
|
|
257
261
|
className: "px-3 py-1.5 text-sm bg-action-primary-bg text-text-inverse rounded hover:bg-action-primary-bg-hover transition-colors duration-200",
|
|
258
|
-
children:
|
|
262
|
+
children: r(y, "files.search.filters.actions.apply", "Apply")
|
|
259
263
|
})]
|
|
260
264
|
})
|
|
261
265
|
]
|
|
@@ -264,6 +268,6 @@ function f({ onSearch: f, placeholder: p = "Search files and folders...", initia
|
|
|
264
268
|
});
|
|
265
269
|
}
|
|
266
270
|
//#endregion
|
|
267
|
-
export {
|
|
271
|
+
export { h as SearchBar };
|
|
268
272
|
|
|
269
273
|
//# sourceMappingURL=SearchBar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchBar.js","names":[],"sources":["../../../src/files/components/SearchBar.tsx"],"sourcesContent":["import { useState, useEffect, useEffectEvent, useCallback } from \"react\";\nimport { Search, X, Filter } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport type { FileFilterInput, FolderFilterInput } from \"../graphql-types\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ninterface SearchBarProps {\n onSearch: (\n query: string,\n filters?: {\n fileFilter?: FileFilterInput;\n folderFilter?: FolderFilterInput;\n },\n ) => void;\n placeholder?: string;\n initialQuery?: string;\n showFilters?: boolean;\n}\n\nconst FILE_TYPE_MIME_MAP: Record<string, string[]> = {\n image: [\n \"image/jpeg\",\n \"image/png\",\n \"image/gif\",\n \"image/webp\",\n \"image/svg+xml\",\n ],\n video: [\"video/mp4\", \"video/webm\", \"video/quicktime\"],\n document: [\n \"application/msword\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.ms-excel\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \"application/vnd.ms-powerpoint\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \"text/plain\",\n \"text/csv\",\n \"application/json\",\n ],\n pdf: [\"application/pdf\"],\n archive: [\n \"application/zip\",\n \"application/x-tar\",\n \"application/x-7z-compressed\",\n \"application/gzip\",\n \"application/x-rar-compressed\",\n ],\n};\n\nexport function SearchBar({\n onSearch,\n placeholder = \"Search files and folders...\",\n initialQuery = \"\",\n showFilters = true,\n}: SearchBarProps) {\n const { t } = useI18n();\n const [query, setQuery] = useState(initialQuery);\n const [showFilterPanel, setShowFilterPanel] = useState(false);\n const [filters, setFilters] = useState<{\n fileType?: string;\n status?: string;\n visibility?: string;\n starred?: boolean;\n }>({});\n const fileStatus = filters.status as FileFilterInput[\"status\"] | undefined;\n const folderStatus = filters.status as\n | FolderFilterInput[\"status\"]\n | undefined;\n const fileVisibility = filters.visibility as\n | FileFilterInput[\"visibility\"]\n | undefined;\n const fileMimeTypes = filters.fileType\n ? FILE_TYPE_MIME_MAP[filters.fileType]\n : undefined;\n\n useEffect(() => {\n setQuery(initialQuery);\n }, [initialQuery]);\n\n const runSearch = useEffectEvent(() => {\n if (query.length >= 2 || query.length === 0) {\n const fileFilter: FileFilterInput = {\n ...(fileMimeTypes && { mimeTypes: fileMimeTypes }),\n ...(fileStatus && { status: fileStatus }),\n ...(fileVisibility && { visibility: fileVisibility }),\n ...(filters.starred !== undefined && { starred: filters.starred }),\n };\n\n const folderFilter: FolderFilterInput = {\n ...(folderStatus && { status: folderStatus }),\n ...(filters.starred !== undefined && { starred: filters.starred }),\n };\n\n onSearch(query, { fileFilter, folderFilter });\n }\n });\n\n // Debounced search\n useEffect(() => {\n const timer = setTimeout(() => {\n runSearch();\n }, 300);\n\n return () => clearTimeout(timer);\n }, [fileStatus, fileMimeTypes, fileVisibility, folderStatus, filters, query]);\n\n const handleClear = useCallback(() => {\n setQuery(\"\");\n setFilters({});\n onSearch(\"\");\n }, [onSearch]);\n\n const activeFilterCount = Object.values(filters).filter(\n (v) => v !== undefined,\n ).length;\n\n return (\n <div className=\"relative\">\n {/* Search Input */}\n <div className=\"relative flex items-center\">\n <Search className=\"absolute left-3 size-4 text-text-tertiary\" />\n <label htmlFor=\"files-search-input\" className=\"sr-only\">\n {tWithFallback(\n t,\n \"files.search.input.label\",\n \"Search files and folders\",\n )}\n </label>\n <input\n id=\"files-search-input\"\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={placeholder}\n aria-label={tWithFallback(\n t,\n \"files.search.input.label\",\n \"Search files and folders\",\n )}\n className=\"w-full pl-[3.25rem] pr-20 py-2 border border-border-default rounded-lg focus:outline-none focus:ring-2 focus:ring-action-primary-border focus:border-action-primary-border transition-colors duration-200\"\n />\n <div className=\"absolute right-2 flex items-center gap-1\">\n {query && (\n <button\n type=\"button\"\n onClick={handleClear}\n className=\"p-1.5 text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200\"\n title={tWithFallback(\n t,\n \"files.search.actions.clearSearch\",\n \"Clear search\",\n )}\n aria-label={tWithFallback(\n t,\n \"files.search.actions.clearSearch\",\n \"Clear search\",\n )}\n >\n <X className=\"size-4\" />\n </button>\n )}\n {showFilters && (\n <button\n type=\"button\"\n onClick={() => setShowFilterPanel(!showFilterPanel)}\n aria-expanded={showFilterPanel}\n aria-controls=\"files-search-filter-panel\"\n aria-label={tWithFallback(\n t,\n \"files.search.filters.toggleAria\",\n \"Toggle filters\",\n )}\n className={`p-1.5 rounded transition-colors duration-200 relative ${\n showFilterPanel || activeFilterCount > 0\n ? \"text-text-link bg-bg-accent hover:bg-action-primary-bg/20\"\n : \"text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover\"\n }`}\n title={tWithFallback(t, \"files.search.filters.title\", \"Filters\")}\n >\n <Filter className=\"size-4\" />\n {activeFilterCount > 0 && (\n <span className=\"absolute -top-1 -right-1 size-4 bg-action-primary-bg text-text-inverse text-[10px] font-bold rounded-full flex items-center justify-center\">\n {activeFilterCount}\n </span>\n )}\n </button>\n )}\n </div>\n </div>\n\n {/* Filter Panel */}\n {showFilterPanel && (\n <div\n id=\"files-search-filter-panel\"\n className=\"absolute top-full left-0 right-0 mt-2 p-4 bg-bg-surface border border-border-default rounded-lg shadow-lg z-10 animate-in fade-in duration-200\"\n >\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.label\",\n \"File Type\",\n )}\n </label>\n <select\n value={filters.fileType || \"\"}\n onChange={(e) =>\n setFilters({\n ...filters,\n fileType: e.target.value || undefined,\n })\n }\n aria-label={tWithFallback(\n t,\n \"files.search.filters.fileType.label\",\n \"File Type\",\n )}\n className=\"w-full px-3 py-2 border border-border-default rounded-lg bg-bg-surface text-text-primary scheme-normal dark:scheme-dark focus:outline-none focus:ring-2 focus:ring-action-primary-border transition-colors duration-200 [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n <option value=\"\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.all\",\n \"All types\",\n )}\n </option>\n <option value=\"image\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.image\",\n \"Images\",\n )}\n </option>\n <option value=\"video\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.video\",\n \"Videos\",\n )}\n </option>\n <option value=\"document\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.document\",\n \"Documents\",\n )}\n </option>\n <option value=\"pdf\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.pdf\",\n \"PDFs\",\n )}\n </option>\n <option value=\"archive\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.archive\",\n \"Archives\",\n )}\n </option>\n </select>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tWithFallback(\n t,\n \"files.search.filters.status.label\",\n \"Status\",\n )}\n </label>\n <select\n value={filters.status || \"\"}\n onChange={(e) =>\n setFilters({\n ...filters,\n status: e.target.value || undefined,\n })\n }\n aria-label={tWithFallback(\n t,\n \"files.search.filters.status.label\",\n \"Status\",\n )}\n className=\"w-full px-3 py-2 border border-border-default rounded-lg bg-bg-surface text-text-primary scheme-normal dark:scheme-dark focus:outline-none focus:ring-2 focus:ring-action-primary-border transition-colors duration-200 [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n <option value=\"\">\n {tWithFallback(\n t,\n \"files.search.filters.status.options.all\",\n \"All statuses\",\n )}\n </option>\n <option value=\"ACTIVE\">\n {tWithFallback(\n t,\n \"files.search.filters.status.options.active\",\n \"Active\",\n )}\n </option>\n <option value=\"ARCHIVED\">\n {tWithFallback(\n t,\n \"files.search.filters.status.options.archived\",\n \"Archived\",\n )}\n </option>\n <option value=\"DELETED\">\n {tWithFallback(\n t,\n \"files.search.filters.status.options.deleted\",\n \"Deleted\",\n )}\n </option>\n </select>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.label\",\n \"Visibility\",\n )}\n </label>\n <select\n value={filters.visibility || \"\"}\n onChange={(e) =>\n setFilters({\n ...filters,\n visibility: e.target.value || undefined,\n })\n }\n aria-label={tWithFallback(\n t,\n \"files.search.filters.visibility.label\",\n \"Visibility\",\n )}\n className=\"w-full px-3 py-2 border border-border-default rounded-lg bg-bg-surface text-text-primary scheme-normal dark:scheme-dark focus:outline-none focus:ring-2 focus:ring-action-primary-border transition-colors duration-200 [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n <option value=\"\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.options.all\",\n \"All visibility\",\n )}\n </option>\n <option value=\"PRIVATE\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.options.private\",\n \"Private\",\n )}\n </option>\n <option value=\"TEAM\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.options.team\",\n \"Team\",\n )}\n </option>\n <option value=\"WORKSPACE\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.options.workspace\",\n \"Workspace\",\n )}\n </option>\n <option value=\"PUBLIC\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.options.public\",\n \"Public\",\n )}\n </option>\n </select>\n </div>\n\n <div className=\"flex items-center\">\n <input\n type=\"checkbox\"\n id=\"starred-filter\"\n checked={filters.starred || false}\n onChange={(e) =>\n setFilters({\n ...filters,\n starred: e.target.checked || undefined,\n })\n }\n aria-label={tWithFallback(\n t,\n \"files.search.filters.starred.label\",\n \"Starred only\",\n )}\n className=\"size-4 text-action-primary-bg border-border-default rounded focus:ring-action-primary-border transition-colors duration-200\"\n />\n <label\n htmlFor=\"starred-filter\"\n className=\"ml-2 text-sm text-text-primary\"\n >\n {tWithFallback(\n t,\n \"files.search.filters.starredOnly\",\n \"Starred only\",\n )}\n </label>\n </div>\n\n <div className=\"flex justify-end gap-2 pt-2 border-t border-border-default\">\n <button\n type=\"button\"\n onClick={() => {\n setFilters({});\n setShowFilterPanel(false);\n }}\n className=\"px-3 py-1.5 text-sm text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200\"\n >\n {tWithFallback(\n t,\n \"files.search.filters.actions.clear\",\n \"Clear filters\",\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setShowFilterPanel(false)}\n className=\"px-3 py-1.5 text-sm bg-action-primary-bg text-text-inverse rounded hover:bg-action-primary-bg-hover transition-colors duration-200\"\n >\n {tWithFallback(\n t,\n \"files.search.filters.actions.apply\",\n \"Apply\",\n )}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SearchBar.js","names":["FILE_TYPE_MIME_MAP","SearchBar","useI18n","query","setQuery","useState","initialQuery","showFilterPanel","setShowFilterPanel","filters","setFilters","fileStatus","folderStatus","FolderStatus","value","fileVisibility","fileMimeTypes","runSearch","useEffectEvent","fileFilter","folderFilter","timer","handleClear","useCallback","onSearch","activeFilterCount","v","Search","tWithFallback","t","X","showFilters","Filter","FileStatus","e","FileVisibility"],"sources":["../../../src/files/components/SearchBar.tsx"],"sourcesContent":["import {\n FileStatus,\n FolderStatus,\n FileVisibility,\n} from \"../../generated/wspace-types\";\nimport { useState, useEffect, useEffectEvent, useCallback } from \"react\";\nimport { Search, X, Filter } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport type { FileFilterInput, FolderFilterInput } from \"../graphql-types\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ninterface SearchBarProps {\n onSearch: (\n query: string,\n filters?: {\n fileFilter?: FileFilterInput;\n folderFilter?: FolderFilterInput;\n },\n ) => void;\n placeholder?: string;\n initialQuery?: string;\n showFilters?: boolean;\n}\n\nconst FILE_TYPE_MIME_MAP: Record<string, string[]> = {\n image: [\n \"image/jpeg\",\n \"image/png\",\n \"image/gif\",\n \"image/webp\",\n \"image/svg+xml\",\n ],\n video: [\"video/mp4\", \"video/webm\", \"video/quicktime\"],\n document: [\n \"application/msword\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.ms-excel\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \"application/vnd.ms-powerpoint\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \"text/plain\",\n \"text/csv\",\n \"application/json\",\n ],\n pdf: [\"application/pdf\"],\n archive: [\n \"application/zip\",\n \"application/x-tar\",\n \"application/x-7z-compressed\",\n \"application/gzip\",\n \"application/x-rar-compressed\",\n ],\n};\n\nexport function SearchBar({\n onSearch,\n placeholder = \"Search files and folders...\",\n initialQuery = \"\",\n showFilters = true,\n}: SearchBarProps) {\n const { t } = useI18n();\n const [query, setQuery] = useState(initialQuery);\n const [showFilterPanel, setShowFilterPanel] = useState(false);\n const [filters, setFilters] = useState<{\n fileType?: string;\n status?: FileStatus;\n visibility?: FileVisibility;\n starred?: boolean;\n }>({});\n const fileStatus = filters.status;\n const folderStatus = Object.values(FolderStatus).find(\n (value) => String(value) === filters.status,\n );\n const fileVisibility = filters.visibility;\n const fileMimeTypes = filters.fileType\n ? FILE_TYPE_MIME_MAP[filters.fileType]\n : undefined;\n\n useEffect(() => {\n setQuery(initialQuery);\n }, [initialQuery]);\n\n const runSearch = useEffectEvent(() => {\n if (query.length >= 2 || query.length === 0) {\n const fileFilter: FileFilterInput = {\n ...(fileMimeTypes && { mimeTypes: fileMimeTypes }),\n ...(fileStatus && { status: fileStatus }),\n ...(fileVisibility && { visibility: fileVisibility }),\n ...(filters.starred !== undefined && { starred: filters.starred }),\n };\n\n const folderFilter: FolderFilterInput = {\n ...(folderStatus && { status: folderStatus }),\n ...(filters.starred !== undefined && { starred: filters.starred }),\n };\n\n onSearch(query, { fileFilter, folderFilter });\n }\n });\n\n // Debounced search\n useEffect(() => {\n const timer = setTimeout(() => {\n runSearch();\n }, 300);\n\n return () => clearTimeout(timer);\n }, [fileStatus, fileMimeTypes, fileVisibility, folderStatus, filters, query]);\n\n const handleClear = useCallback(() => {\n setQuery(\"\");\n setFilters({});\n onSearch(\"\");\n }, [onSearch]);\n\n const activeFilterCount = Object.values(filters).filter(\n (v) => v !== undefined,\n ).length;\n\n return (\n <div className=\"relative\">\n {/* Search Input */}\n <div className=\"relative flex items-center\">\n <Search className=\"absolute left-3 size-4 text-text-tertiary\" />\n <label htmlFor=\"files-search-input\" className=\"sr-only\">\n {tWithFallback(\n t,\n \"files.search.input.label\",\n \"Search files and folders\",\n )}\n </label>\n <input\n id=\"files-search-input\"\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={placeholder}\n aria-label={tWithFallback(\n t,\n \"files.search.input.label\",\n \"Search files and folders\",\n )}\n className=\"w-full pl-[3.25rem] pr-20 py-2 border border-border-default rounded-lg focus:outline-none focus:ring-2 focus:ring-action-primary-border focus:border-action-primary-border transition-colors duration-200\"\n />\n <div className=\"absolute right-2 flex items-center gap-1\">\n {query && (\n <button\n type=\"button\"\n onClick={handleClear}\n className=\"p-1.5 text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200\"\n title={tWithFallback(\n t,\n \"files.search.actions.clearSearch\",\n \"Clear search\",\n )}\n aria-label={tWithFallback(\n t,\n \"files.search.actions.clearSearch\",\n \"Clear search\",\n )}\n >\n <X className=\"size-4\" />\n </button>\n )}\n {showFilters && (\n <button\n type=\"button\"\n onClick={() => setShowFilterPanel(!showFilterPanel)}\n aria-expanded={showFilterPanel}\n aria-controls=\"files-search-filter-panel\"\n aria-label={tWithFallback(\n t,\n \"files.search.filters.toggleAria\",\n \"Toggle filters\",\n )}\n className={`p-1.5 rounded transition-colors duration-200 relative ${\n showFilterPanel || activeFilterCount > 0\n ? \"text-text-link bg-bg-accent hover:bg-action-primary-bg/20\"\n : \"text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover\"\n }`}\n title={tWithFallback(t, \"files.search.filters.title\", \"Filters\")}\n >\n <Filter className=\"size-4\" />\n {activeFilterCount > 0 && (\n <span className=\"absolute -top-1 -right-1 size-4 bg-action-primary-bg text-text-inverse text-[10px] font-bold rounded-full flex items-center justify-center\">\n {activeFilterCount}\n </span>\n )}\n </button>\n )}\n </div>\n </div>\n\n {/* Filter Panel */}\n {showFilterPanel && (\n <div\n id=\"files-search-filter-panel\"\n className=\"absolute top-full left-0 right-0 mt-2 p-4 bg-bg-surface border border-border-default rounded-lg shadow-lg z-10 animate-in fade-in duration-200\"\n >\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.label\",\n \"File Type\",\n )}\n </label>\n <select\n value={filters.fileType || \"\"}\n onChange={(e) =>\n setFilters({\n ...filters,\n fileType: e.target.value || undefined,\n })\n }\n aria-label={tWithFallback(\n t,\n \"files.search.filters.fileType.label\",\n \"File Type\",\n )}\n className=\"w-full px-3 py-2 border border-border-default rounded-lg bg-bg-surface text-text-primary scheme-normal dark:scheme-dark focus:outline-none focus:ring-2 focus:ring-action-primary-border transition-colors duration-200 [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n <option value=\"\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.all\",\n \"All types\",\n )}\n </option>\n <option value=\"image\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.image\",\n \"Images\",\n )}\n </option>\n <option value=\"video\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.video\",\n \"Videos\",\n )}\n </option>\n <option value=\"document\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.document\",\n \"Documents\",\n )}\n </option>\n <option value=\"pdf\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.pdf\",\n \"PDFs\",\n )}\n </option>\n <option value=\"archive\">\n {tWithFallback(\n t,\n \"files.search.filters.fileType.options.archive\",\n \"Archives\",\n )}\n </option>\n </select>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tWithFallback(\n t,\n \"files.search.filters.status.label\",\n \"Status\",\n )}\n </label>\n <select\n value={filters.status || \"\"}\n onChange={(e) =>\n setFilters({\n ...filters,\n status: Object.values(FileStatus).find(\n (value) => value === e.target.value,\n ),\n })\n }\n aria-label={tWithFallback(\n t,\n \"files.search.filters.status.label\",\n \"Status\",\n )}\n className=\"w-full px-3 py-2 border border-border-default rounded-lg bg-bg-surface text-text-primary scheme-normal dark:scheme-dark focus:outline-none focus:ring-2 focus:ring-action-primary-border transition-colors duration-200 [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n <option value=\"\">\n {tWithFallback(\n t,\n \"files.search.filters.status.options.all\",\n \"All statuses\",\n )}\n </option>\n <option value=\"ACTIVE\">\n {tWithFallback(\n t,\n \"files.search.filters.status.options.active\",\n \"Active\",\n )}\n </option>\n <option value=\"ARCHIVED\">\n {tWithFallback(\n t,\n \"files.search.filters.status.options.archived\",\n \"Archived\",\n )}\n </option>\n <option value=\"DELETED\">\n {tWithFallback(\n t,\n \"files.search.filters.status.options.deleted\",\n \"Deleted\",\n )}\n </option>\n </select>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.label\",\n \"Visibility\",\n )}\n </label>\n <select\n value={filters.visibility || \"\"}\n onChange={(e) =>\n setFilters({\n ...filters,\n visibility: Object.values(FileVisibility).find(\n (value) => value === e.target.value,\n ),\n })\n }\n aria-label={tWithFallback(\n t,\n \"files.search.filters.visibility.label\",\n \"Visibility\",\n )}\n className=\"w-full px-3 py-2 border border-border-default rounded-lg bg-bg-surface text-text-primary scheme-normal dark:scheme-dark focus:outline-none focus:ring-2 focus:ring-action-primary-border transition-colors duration-200 [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n <option value=\"\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.options.all\",\n \"All visibility\",\n )}\n </option>\n <option value=\"PRIVATE\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.options.private\",\n \"Private\",\n )}\n </option>\n <option value=\"TEAM\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.options.team\",\n \"Team\",\n )}\n </option>\n <option value=\"WORKSPACE\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.options.workspace\",\n \"Workspace\",\n )}\n </option>\n <option value=\"PUBLIC\">\n {tWithFallback(\n t,\n \"files.search.filters.visibility.options.public\",\n \"Public\",\n )}\n </option>\n </select>\n </div>\n\n <div className=\"flex items-center\">\n <input\n type=\"checkbox\"\n id=\"starred-filter\"\n checked={filters.starred || false}\n onChange={(e) =>\n setFilters({\n ...filters,\n starred: e.target.checked || undefined,\n })\n }\n aria-label={tWithFallback(\n t,\n \"files.search.filters.starred.label\",\n \"Starred only\",\n )}\n className=\"size-4 text-action-primary-bg border-border-default rounded focus:ring-action-primary-border transition-colors duration-200\"\n />\n <label\n htmlFor=\"starred-filter\"\n className=\"ml-2 text-sm text-text-primary\"\n >\n {tWithFallback(\n t,\n \"files.search.filters.starredOnly\",\n \"Starred only\",\n )}\n </label>\n </div>\n\n <div className=\"flex justify-end gap-2 pt-2 border-t border-border-default\">\n <button\n type=\"button\"\n onClick={() => {\n setFilters({});\n setShowFilterPanel(false);\n }}\n className=\"px-3 py-1.5 text-sm text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200\"\n >\n {tWithFallback(\n t,\n \"files.search.filters.actions.clear\",\n \"Clear filters\",\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setShowFilterPanel(false)}\n className=\"px-3 py-1.5 text-sm bg-action-primary-bg text-text-inverse rounded hover:bg-action-primary-bg-hover transition-colors duration-200\"\n >\n {tWithFallback(\n t,\n \"files.search.filters.actions.apply\",\n \"Apply\",\n )}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;AAwBA,IAAMA,IAA+C;CACnD,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;CACA,OAAO;EAAC;EAAa;EAAc;CAAiB;CACpD,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,KAAK,CAAC,iBAAiB;CACvB,SAAS;EACP;EACA;EACA;EACA;EACA;CACF;AACF;AAEA,SAAgBC,EAAU,EACxB,aACA,iBAAc,+BACd,kBAAe,IACf,iBAAc,MACG;CACjB,IAAM,EAAE,SAAMC,EAAQ,GAChB,CAACC,GAAOC,KAAYC,EAASC,CAAY,GACzC,CAACC,GAAiBC,KAAsBH,EAAS,EAAK,GACtD,CAACI,GAASC,KAAcL,EAK3B,CAAC,CAAC,GACCM,IAAaF,EAAQ,QACrBG,IAAe,OAAO,OAAOC,CAAY,CAAC,CAAC,MAC9C,MAAU,OAAOC,CAAK,MAAML,EAAQ,MACvC,GACMM,IAAiBN,EAAQ,YACzBO,IAAgBP,EAAQ,WAC1BT,EAAmBS,EAAQ,YAC3B,KAAA;CAEJ,QAAgB;EACd,EAASH,CAAY;CACvB,GAAG,CAACA,CAAY,CAAC;CAEjB,IAAMW,IAAYC,QAAqB;EACrC,IAAIf,EAAM,UAAU,KAAKA,EAAM,WAAW,GAAG;GAC3C,IAAMgB,IAA8B;IAClC,GAAIH,KAAiB,EAAE,WAAWA,EAAc;IAChD,GAAIL,KAAc,EAAE,QAAQA,EAAW;IACvC,GAAII,KAAkB,EAAE,YAAYA,EAAe;IACnD,GAAIN,EAAQ,YAAY,KAAA,KAAa,EAAE,SAASA,EAAQ,QAAQ;GAClE,GAEMW,IAAkC;IACtC,GAAIR,KAAgB,EAAE,QAAQA,EAAa;IAC3C,GAAIH,EAAQ,YAAY,KAAA,KAAa,EAAE,SAASA,EAAQ,QAAQ;GAClE;GAEA,EAASN,GAAO;IAAE;IAAY;GAAa,CAAC;EAC9C;CACF,CAAC;CAGD,QAAgB;EACd,IAAMkB,IAAQ,iBAAiB;GAC7B,EAAU;EACZ,GAAG,GAAG;EAEN,aAAa,aAAaA,CAAK;CACjC,GAAG;EAACV;EAAYK;EAAeD;EAAgBH;EAAcH;EAASN;CAAK,CAAC;CAE5E,IAAMmB,IAAcC,QAAkB;EAGpC,AAFAnB,EAAS,EAAE,GACXM,EAAW,CAAC,CAAC,GACbc,EAAS,EAAE;CACb,GAAG,CAACA,CAAQ,CAAC,GAEPC,IAAoB,OAAO,OAAOhB,CAAO,CAAC,CAAC,QAC9C,MAAMiB,MAAM,KAAA,CACf,CAAC,CAAC;CAEF,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CAEE,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,kBAACC,GAAD,EAAQ,WAAU,4CAA6C,CAAA;IAC/D,kBAAC,SAAD;KAAO,SAAQ;KAAqB,WAAU;KAC3C,UAAAC,EACCC,GACA,4BACA,0BACF;IACK,CAAA;IACP,kBAAC,SAAD;KACE,IAAG;KACH,MAAK;KACL,OAAO1B;KACP,WAAW,MAAMC,EAAS,EAAE,OAAO,KAAK;KAC3B;KACb,cAAYwB,EACVC,GACA,4BACA,0BACF;KACA,WAAU;IACX,CAAA;IACD,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACG1B,KACC,kBAAC,UAAD;MACE,MAAK;MACL,SAASmB;MACT,WAAU;MACV,OAAOM,EACLC,GACA,oCACA,cACF;MACA,cAAYD,EACVC,GACA,oCACA,cACF;MAEA,UAAA,kBAACC,GAAD,EAAG,WAAU,SAAU,CAAA;KACjB,CAAA,GAETC,KACC,kBAAC,UAAD;MACE,MAAK;MACL,eAAevB,EAAmB,CAACD,CAAe;MAClD,iBAAeA;MACf,iBAAc;MACd,cAAYqB,EACVC,GACA,mCACA,gBACF;MACA,WAAW,yDACTtB,KAAmBkB,IAAoB,IACnC,8DACA;MAEN,OAAOG,EAAcC,GAAG,8BAA8B,SAAS;MAfjE,UAAA,CAiBE,kBAACG,GAAD,EAAQ,WAAU,SAAU,CAAA,GAC3BP,IAAoB,KACnB,kBAAC,QAAD;OAAM,WAAU;OACb,UAAAA;MACG,CAAA,CAEF;KAEP,CAAA,CAAA;;GACF;EAGJ,CAAA,GAAAlB,KACC,kBAAC,OAAD;GACE,IAAG;GACH,WAAU;GAEV,UAAA,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;MACd,UAAAqB,EACCC,GACA,uCACA,WACF;KACK,CAAA,GACP,kBAAC,UAAD;MACE,OAAOpB,EAAQ,YAAY;MAC3B,WAAW,MACTC,EAAW;OACT,GAAGD;OACH,UAAU,EAAE,OAAO,SAAS,KAAA;MAC9B,CAAC;MAEH,cAAYmB,EACVC,GACA,uCACA,WACF;MACA,WAAU;MAbZ,UAAA;OAeE,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,6CACA,WACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,+CACA,QACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,+CACA,QACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,kDACA,WACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,6CACA,MACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,iDACA,UACF;OACM,CAAA;MACF;KACL,CAAA,CAAA,EAAA,CAAA;KAEL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;MACd,UAAAD,EACCC,GACA,qCACA,QACF;KACK,CAAA,GACP,kBAAC,UAAD;MACE,OAAOpB,EAAQ,UAAU;MACzB,WAAW,MACTC,EAAW;OACT,GAAGD;OACH,QAAQ,OAAO,OAAOwB,CAAU,CAAC,CAAC,MAC/B,MAAUnB,MAAUoB,EAAE,OAAO,KAChC;MACF,CAAC;MAEH,cAAYN,EACVC,GACA,qCACA,QACF;MACA,WAAU;MAfZ,UAAA;OAiBE,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,2CACA,cACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,8CACA,QACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,gDACA,UACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,+CACA,SACF;OACM,CAAA;MACF;KACL,CAAA,CAAA,EAAA,CAAA;KAEL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;MACd,UAAAD,EACCC,GACA,yCACA,YACF;KACK,CAAA,GACP,kBAAC,UAAD;MACE,OAAOpB,EAAQ,cAAc;MAC7B,WAAW,MACTC,EAAW;OACT,GAAGD;OACH,YAAY,OAAO,OAAO0B,CAAc,CAAC,CAAC,MACvC,MAAUrB,MAAU,EAAE,OAAO,KAChC;MACF,CAAC;MAEH,cAAYc,EACVC,GACA,yCACA,YACF;MACA,WAAU;MAfZ,UAAA;OAiBE,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,+CACA,gBACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,mDACA,SACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,gDACA,MACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,qDACA,WACF;OACM,CAAA;OACR,kBAAC,UAAD;QAAQ,OAAM;QACX,UAAAD,EACCC,GACA,kDACA,QACF;OACM,CAAA;MACF;KACL,CAAA,CAAA,EAAA,CAAA;KAEL,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,SAAD;OACE,MAAK;OACL,IAAG;OACH,SAASpB,EAAQ,WAAW;OAC5B,WAAW,MACTC,EAAW;QACT,GAAGD;QACH,SAAS,EAAE,OAAO,WAAW,KAAA;OAC/B,CAAC;OAEH,cAAYmB,EACVC,GACA,sCACA,cACF;OACA,WAAU;MACX,CAAA,GACD,kBAAC,SAAD;OACE,SAAQ;OACR,WAAU;OAET,UAAAD,EACCC,GACA,oCACA,cACF;MACK,CAAA,CACJ;;KAEL,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe;QAEb,AADAnB,EAAW,CAAC,CAAC,GACbF,EAAmB,EAAK;OAC1B;OACA,WAAU;OAET,UAAAoB,EACCC,GACA,sCACA,eACF;MACM,CAAA,GACR,kBAAC,UAAD;OACE,MAAK;OACL,eAAerB,EAAmB,EAAK;OACvC,WAAU;OAET,UAAAoB,EACCC,GACA,sCACA,OACF;MACM,CAAA,CACL;;IACF;;EACF,CAAA,CAEJ;;AAET"}
|
|
@@ -19,6 +19,6 @@ interface ShareDialogProps {
|
|
|
19
19
|
}>;
|
|
20
20
|
isLoading?: boolean;
|
|
21
21
|
}
|
|
22
|
-
export declare function ShareDialog({ item, itemType, onClose, onCreateShare, isLoading, }: ShareDialogProps): import(
|
|
22
|
+
export declare function ShareDialog({ item, itemType, onClose, onCreateShare, isLoading, }: ShareDialogProps): import('react').JSX.Element;
|
|
23
23
|
export {};
|
|
24
24
|
//# sourceMappingURL=ShareDialog.d.ts.map
|