@burdenoff/microfe-files 2026.510.101
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 +12 -0
- package/dist/config/index.d.ts +33 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +28 -0
- package/dist/config/index.js.map +1 -0
- package/dist/dev/main.d.ts +1 -0
- package/dist/dev/main.d.ts.map +1 -0
- package/dist/files/FilesRoot.d.ts +31 -0
- package/dist/files/FilesRoot.d.ts.map +1 -0
- package/dist/files/FilesRoot.js +63 -0
- package/dist/files/FilesRoot.js.map +1 -0
- package/dist/files/FilesRoutes.d.ts +12 -0
- package/dist/files/FilesRoutes.d.ts.map +1 -0
- package/dist/files/FilesRoutes.js +45 -0
- package/dist/files/FilesRoutes.js.map +1 -0
- package/dist/files/components/ActionMenu.d.ts +19 -0
- package/dist/files/components/ActionMenu.d.ts.map +1 -0
- package/dist/files/components/ActionMenu.js +73 -0
- package/dist/files/components/ActionMenu.js.map +1 -0
- package/dist/files/components/ConfirmDialog.d.ts +14 -0
- package/dist/files/components/ConfirmDialog.d.ts.map +1 -0
- package/dist/files/components/ConfirmDialog.js +85 -0
- package/dist/files/components/ConfirmDialog.js.map +1 -0
- package/dist/files/components/ContextMenu.d.ts +59 -0
- package/dist/files/components/ContextMenu.d.ts.map +1 -0
- package/dist/files/components/ContextMenu.js +136 -0
- package/dist/files/components/ContextMenu.js.map +1 -0
- package/dist/files/components/CopyDialog.d.ts +12 -0
- package/dist/files/components/CopyDialog.d.ts.map +1 -0
- package/dist/files/components/CopyDialog.js +139 -0
- package/dist/files/components/CopyDialog.js.map +1 -0
- package/dist/files/components/EmptyState.d.ts +8 -0
- package/dist/files/components/EmptyState.d.ts.map +1 -0
- package/dist/files/components/EmptyState.js +66 -0
- package/dist/files/components/EmptyState.js.map +1 -0
- package/dist/files/components/FileBrowser.d.ts +37 -0
- package/dist/files/components/FileBrowser.d.ts.map +1 -0
- package/dist/files/components/FileBrowser.js +421 -0
- package/dist/files/components/FileBrowser.js.map +1 -0
- package/dist/files/components/FileCard.d.ts +30 -0
- package/dist/files/components/FileCard.d.ts.map +1 -0
- package/dist/files/components/FileCard.js +233 -0
- package/dist/files/components/FileCard.js.map +1 -0
- package/dist/files/components/FileInfoPanel.d.ts +9 -0
- package/dist/files/components/FileInfoPanel.d.ts.map +1 -0
- package/dist/files/components/FileInfoPanel.js +224 -0
- package/dist/files/components/FileInfoPanel.js.map +1 -0
- package/dist/files/components/FileListItem.d.ts +46 -0
- package/dist/files/components/FileListItem.d.ts.map +1 -0
- package/dist/files/components/FileListItem.js +235 -0
- package/dist/files/components/FileListItem.js.map +1 -0
- package/dist/files/components/FilePreviewModal.d.ts +17 -0
- package/dist/files/components/FilePreviewModal.d.ts.map +1 -0
- package/dist/files/components/FilePreviewModal.js +175 -0
- package/dist/files/components/FilePreviewModal.js.map +1 -0
- package/dist/files/components/FileVersionPanel.d.ts +9 -0
- package/dist/files/components/FileVersionPanel.d.ts.map +1 -0
- package/dist/files/components/FileVersionPanel.js +227 -0
- package/dist/files/components/FileVersionPanel.js.map +1 -0
- package/dist/files/components/FolderCard.d.ts +34 -0
- package/dist/files/components/FolderCard.d.ts.map +1 -0
- package/dist/files/components/FolderCard.js +225 -0
- package/dist/files/components/FolderCard.js.map +1 -0
- package/dist/files/components/MoveDialog.d.ts +12 -0
- package/dist/files/components/MoveDialog.d.ts.map +1 -0
- package/dist/files/components/MoveDialog.js +123 -0
- package/dist/files/components/MoveDialog.js.map +1 -0
- package/dist/files/components/SearchBar.d.ts +13 -0
- package/dist/files/components/SearchBar.d.ts.map +1 -0
- package/dist/files/components/SearchBar.js +257 -0
- package/dist/files/components/SearchBar.js.map +1 -0
- package/dist/files/components/ShareDialog.d.ts +24 -0
- package/dist/files/components/ShareDialog.d.ts.map +1 -0
- package/dist/files/components/ShareDialog.js +201 -0
- package/dist/files/components/ShareDialog.js.map +1 -0
- package/dist/files/components/TabBar.d.ts +14 -0
- package/dist/files/components/TabBar.d.ts.map +1 -0
- package/dist/files/components/TabBar.js +65 -0
- package/dist/files/components/TabBar.js.map +1 -0
- package/dist/files/components/Toast.d.ts +14 -0
- package/dist/files/components/Toast.d.ts.map +1 -0
- package/dist/files/components/Toast.js +51 -0
- package/dist/files/components/Toast.js.map +1 -0
- package/dist/files/components/UploadQueue.d.ts +21 -0
- package/dist/files/components/UploadQueue.d.ts.map +1 -0
- package/dist/files/components/UploadQueue.js +171 -0
- package/dist/files/components/UploadQueue.js.map +1 -0
- package/dist/files/components/index.d.ts +43 -0
- package/dist/files/components/index.d.ts.map +1 -0
- package/dist/files/components/viewers/AudioPlayer.d.ts +8 -0
- package/dist/files/components/viewers/AudioPlayer.d.ts.map +1 -0
- package/dist/files/components/viewers/AudioPlayer.js +102 -0
- package/dist/files/components/viewers/AudioPlayer.js.map +1 -0
- package/dist/files/components/viewers/CodeViewer.d.ts +16 -0
- package/dist/files/components/viewers/CodeViewer.d.ts.map +1 -0
- package/dist/files/components/viewers/CodeViewer.js +113 -0
- package/dist/files/components/viewers/CodeViewer.js.map +1 -0
- package/dist/files/components/viewers/ImageViewer.d.ts +8 -0
- package/dist/files/components/viewers/ImageViewer.d.ts.map +1 -0
- package/dist/files/components/viewers/ImageViewer.js +138 -0
- package/dist/files/components/viewers/ImageViewer.js.map +1 -0
- package/dist/files/components/viewers/PDFViewer.d.ts +15 -0
- package/dist/files/components/viewers/PDFViewer.d.ts.map +1 -0
- package/dist/files/components/viewers/PDFViewer.js +80 -0
- package/dist/files/components/viewers/PDFViewer.js.map +1 -0
- package/dist/files/components/viewers/TextViewer.d.ts +8 -0
- package/dist/files/components/viewers/TextViewer.d.ts.map +1 -0
- package/dist/files/components/viewers/TextViewer.js +121 -0
- package/dist/files/components/viewers/TextViewer.js.map +1 -0
- package/dist/files/components/viewers/VideoPlayer.d.ts +8 -0
- package/dist/files/components/viewers/VideoPlayer.d.ts.map +1 -0
- package/dist/files/components/viewers/VideoPlayer.js +138 -0
- package/dist/files/components/viewers/VideoPlayer.js.map +1 -0
- package/dist/files/components/viewers/index.d.ts +7 -0
- package/dist/files/components/viewers/index.d.ts.map +1 -0
- package/dist/files/components/viewers/index.js +6 -0
- package/dist/files/graphql-types.d.ts +317 -0
- package/dist/files/graphql-types.d.ts.map +1 -0
- package/dist/files/hooks/useBatchOperations.d.ts +32 -0
- package/dist/files/hooks/useBatchOperations.d.ts.map +1 -0
- package/dist/files/hooks/useBatchOperations.js +18 -0
- package/dist/files/hooks/useBatchOperations.js.map +1 -0
- package/dist/files/hooks/useBinItems.d.ts +11 -0
- package/dist/files/hooks/useBinItems.d.ts.map +1 -0
- package/dist/files/hooks/useBinItems.js +27 -0
- package/dist/files/hooks/useBinItems.js.map +1 -0
- package/dist/files/hooks/useBrowsePage.d.ts +18 -0
- package/dist/files/hooks/useBrowsePage.d.ts.map +1 -0
- package/dist/files/hooks/useBrowsePage.js +34 -0
- package/dist/files/hooks/useBrowsePage.js.map +1 -0
- package/dist/files/hooks/useCopyFile.d.ts +14 -0
- package/dist/files/hooks/useCopyFile.d.ts.map +1 -0
- package/dist/files/hooks/useCopyFile.js +22 -0
- package/dist/files/hooks/useCopyFile.js.map +1 -0
- package/dist/files/hooks/useCreateFolder.d.ts +14 -0
- package/dist/files/hooks/useCreateFolder.d.ts.map +1 -0
- package/dist/files/hooks/useCreateFolder.js +14 -0
- package/dist/files/hooks/useCreateFolder.js.map +1 -0
- package/dist/files/hooks/useCreateFolderShare.d.ts +16 -0
- package/dist/files/hooks/useCreateFolderShare.d.ts.map +1 -0
- package/dist/files/hooks/useCreateFolderShare.js +14 -0
- package/dist/files/hooks/useCreateFolderShare.js.map +1 -0
- package/dist/files/hooks/useCreateShare.d.ts +16 -0
- package/dist/files/hooks/useCreateShare.d.ts.map +1 -0
- package/dist/files/hooks/useCreateShare.js +14 -0
- package/dist/files/hooks/useCreateShare.js.map +1 -0
- package/dist/files/hooks/useDeleteFile.d.ts +9 -0
- package/dist/files/hooks/useDeleteFile.d.ts.map +1 -0
- package/dist/files/hooks/useDeleteFile.js +20 -0
- package/dist/files/hooks/useDeleteFile.js.map +1 -0
- package/dist/files/hooks/useDeleteFolder.d.ts +10 -0
- package/dist/files/hooks/useDeleteFolder.d.ts.map +1 -0
- package/dist/files/hooks/useDeleteFolder.js +24 -0
- package/dist/files/hooks/useDeleteFolder.js.map +1 -0
- package/dist/files/hooks/useDragDrop.d.ts +31 -0
- package/dist/files/hooks/useDragDrop.d.ts.map +1 -0
- package/dist/files/hooks/useDragDrop.js +45 -0
- package/dist/files/hooks/useDragDrop.js.map +1 -0
- package/dist/files/hooks/useFileVersions.d.ts +52 -0
- package/dist/files/hooks/useFileVersions.d.ts.map +1 -0
- package/dist/files/hooks/useFileVersions.js +52 -0
- package/dist/files/hooks/useFileVersions.js.map +1 -0
- package/dist/files/hooks/useFiles.d.ts +18 -0
- package/dist/files/hooks/useFiles.d.ts.map +1 -0
- package/dist/files/hooks/useFolder.d.ts +7 -0
- package/dist/files/hooks/useFolder.d.ts.map +1 -0
- package/dist/files/hooks/useFolderPath.d.ts +2 -0
- package/dist/files/hooks/useFolderPath.d.ts.map +1 -0
- package/dist/files/hooks/useFoldersQuery.d.ts +7 -0
- package/dist/files/hooks/useFoldersQuery.d.ts.map +1 -0
- package/dist/files/hooks/useFoldersQuery.js +13 -0
- package/dist/files/hooks/useFoldersQuery.js.map +1 -0
- package/dist/files/hooks/useKeyboardNavigation.d.ts +17 -0
- package/dist/files/hooks/useKeyboardNavigation.d.ts.map +1 -0
- package/dist/files/hooks/useKeyboardNavigation.js +105 -0
- package/dist/files/hooks/useKeyboardNavigation.js.map +1 -0
- package/dist/files/hooks/useMoveFile.d.ts +10 -0
- package/dist/files/hooks/useMoveFile.d.ts.map +1 -0
- package/dist/files/hooks/useMoveFile.js +21 -0
- package/dist/files/hooks/useMoveFile.js.map +1 -0
- package/dist/files/hooks/useMoveFolder.d.ts +10 -0
- package/dist/files/hooks/useMoveFolder.d.ts.map +1 -0
- package/dist/files/hooks/useMoveFolder.js +21 -0
- package/dist/files/hooks/useMoveFolder.js.map +1 -0
- package/dist/files/hooks/usePermanentlyDeleteFile.d.ts +9 -0
- package/dist/files/hooks/usePermanentlyDeleteFile.d.ts.map +1 -0
- package/dist/files/hooks/usePermanentlyDeleteFile.js +18 -0
- package/dist/files/hooks/usePermanentlyDeleteFile.js.map +1 -0
- package/dist/files/hooks/usePermanentlyDeleteFolder.d.ts +9 -0
- package/dist/files/hooks/usePermanentlyDeleteFolder.d.ts.map +1 -0
- package/dist/files/hooks/usePermanentlyDeleteFolder.js +18 -0
- package/dist/files/hooks/usePermanentlyDeleteFolder.js.map +1 -0
- package/dist/files/hooks/useRecentFiles.d.ts +10 -0
- package/dist/files/hooks/useRecentFiles.d.ts.map +1 -0
- package/dist/files/hooks/useRecentFiles.js +24 -0
- package/dist/files/hooks/useRecentFiles.js.map +1 -0
- package/dist/files/hooks/useRenameFile.d.ts +10 -0
- package/dist/files/hooks/useRenameFile.d.ts.map +1 -0
- package/dist/files/hooks/useRenameFile.js +21 -0
- package/dist/files/hooks/useRenameFile.js.map +1 -0
- package/dist/files/hooks/useRenameFolder.d.ts +10 -0
- package/dist/files/hooks/useRenameFolder.d.ts.map +1 -0
- package/dist/files/hooks/useRenameFolder.js +21 -0
- package/dist/files/hooks/useRenameFolder.js.map +1 -0
- package/dist/files/hooks/useRestoreFile.d.ts +9 -0
- package/dist/files/hooks/useRestoreFile.d.ts.map +1 -0
- package/dist/files/hooks/useRestoreFile.js +21 -0
- package/dist/files/hooks/useRestoreFile.js.map +1 -0
- package/dist/files/hooks/useRestoreFolder.d.ts +9 -0
- package/dist/files/hooks/useRestoreFolder.d.ts.map +1 -0
- package/dist/files/hooks/useRestoreFolder.js +21 -0
- package/dist/files/hooks/useRestoreFolder.js.map +1 -0
- package/dist/files/hooks/useSearch.d.ts +15 -0
- package/dist/files/hooks/useSearch.d.ts.map +1 -0
- package/dist/files/hooks/useSearch.js +27 -0
- package/dist/files/hooks/useSearch.js.map +1 -0
- package/dist/files/hooks/useStarredItems.d.ts +10 -0
- package/dist/files/hooks/useStarredItems.d.ts.map +1 -0
- package/dist/files/hooks/useStarredItems.js +18 -0
- package/dist/files/hooks/useStarredItems.js.map +1 -0
- package/dist/files/hooks/useToast.d.ts +11 -0
- package/dist/files/hooks/useToast.d.ts.map +1 -0
- package/dist/files/hooks/useToast.js +28 -0
- package/dist/files/hooks/useToast.js.map +1 -0
- package/dist/files/hooks/useToggleStar.d.ts +10 -0
- package/dist/files/hooks/useToggleStar.d.ts.map +1 -0
- package/dist/files/hooks/useToggleStar.js +26 -0
- package/dist/files/hooks/useToggleStar.js.map +1 -0
- package/dist/files/hooks/useUploadFile.d.ts +25 -0
- package/dist/files/hooks/useUploadFile.d.ts.map +1 -0
- package/dist/files/hooks/useUploadFile.js +74 -0
- package/dist/files/hooks/useUploadFile.js.map +1 -0
- package/dist/files/index.d.ts +29 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +3 -0
- package/dist/files/pages/BrowserPage.d.ts +5 -0
- package/dist/files/pages/BrowserPage.d.ts.map +1 -0
- package/dist/files/pages/BrowserPage.js +1014 -0
- package/dist/files/pages/BrowserPage.js.map +1 -0
- package/dist/files/pages/ShareAccessPage.d.ts +2 -0
- package/dist/files/pages/ShareAccessPage.d.ts.map +1 -0
- package/dist/files/pages/ShareAccessPage.js +162 -0
- package/dist/files/pages/ShareAccessPage.js.map +1 -0
- package/dist/files/providers/FilesProvider.d.ts +25 -0
- package/dist/files/providers/FilesProvider.d.ts.map +1 -0
- package/dist/files/providers/FilesProvider.js +18 -0
- package/dist/files/providers/FilesProvider.js.map +1 -0
- package/dist/files/store/filesStore.d.ts +99 -0
- package/dist/files/store/filesStore.d.ts.map +1 -0
- package/dist/files/store/filesStore.js +129 -0
- package/dist/files/store/filesStore.js.map +1 -0
- package/dist/files/types.d.ts +266 -0
- package/dist/files/types.d.ts.map +1 -0
- package/dist/files/utils/events.d.ts +6 -0
- package/dist/files/utils/events.d.ts.map +1 -0
- package/dist/files/utils/events.js +16 -0
- package/dist/files/utils/events.js.map +1 -0
- package/dist/files/utils/i18n.d.ts +5 -0
- package/dist/files/utils/i18n.d.ts.map +1 -0
- package/dist/files/utils/i18n.js +15 -0
- package/dist/files/utils/i18n.js.map +1 -0
- package/dist/files/utils/index.d.ts +74 -0
- package/dist/files/utils/index.d.ts.map +1 -0
- package/dist/files/utils/index.js +50 -0
- package/dist/files/utils/index.js.map +1 -0
- package/dist/files/utils/thumbnail.d.ts +5 -0
- package/dist/files/utils/thumbnail.d.ts.map +1 -0
- package/dist/files/utils/thumbnail.js +39 -0
- package/dist/files/utils/thumbnail.js.map +1 -0
- package/dist/files.d.ts +2 -0
- package/dist/files.js +6 -0
- package/dist/generated/global-operations.d.ts +2 -0
- package/dist/generated/global-operations.d.ts.map +1 -0
- package/dist/generated/global-types.d.ts +21253 -0
- package/dist/generated/global-types.d.ts.map +1 -0
- package/dist/generated/wspace-operations.d.ts +2706 -0
- package/dist/generated/wspace-operations.d.ts.map +1 -0
- package/dist/generated/wspace-operations.js +1085 -0
- package/dist/generated/wspace-operations.js.map +1 -0
- package/dist/generated/wspace-types.d.ts +55214 -0
- package/dist/generated/wspace-types.d.ts.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/shared/types/index.d.ts +101 -0
- package/dist/shared/types/index.d.ts.map +1 -0
- package/dist/utils/nativeBridge.d.ts +3 -0
- package/dist/utils/nativeBridge.d.ts.map +1 -0
- package/dist/utils/nativeBridge.js +2 -0
- package/package.json +126 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { tWithFallback as e } from "../utils/i18n.js";
|
|
2
|
+
import { useEffect as t, useMemo as n, useState as r } from "react";
|
|
3
|
+
import { Calendar as i, Check as a, Copy as o, Download as s, Link as c, Loader2 as l, Lock as u, Mail as d, X as f } from "lucide-react";
|
|
4
|
+
import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
5
|
+
import { useI18n as g } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
6
|
+
//#region src/files/components/ShareDialog.tsx
|
|
7
|
+
function _({ item: _, itemType: v, onClose: y, onCreateShare: b, isLoading: x }) {
|
|
8
|
+
let { t: S } = g(), [C, w] = r(null), [T, E] = r(null), [D, O] = r(!1), [k, A] = r(7), [j, M] = r(0), [N, P] = r(!1), [F, I] = r(""), [L, R] = r(""), [z, B] = r(null), V = n(() => `share-dialog-title-${_.id}`, [_.id]);
|
|
9
|
+
return t(() => {
|
|
10
|
+
let e = (e) => {
|
|
11
|
+
e.key === "Escape" && y();
|
|
12
|
+
};
|
|
13
|
+
return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
|
|
14
|
+
}, [y]), /* @__PURE__ */ m("div", {
|
|
15
|
+
className: "fixed inset-0 bg-bg-overlay flex items-center justify-center z-[100] animate-in fade-in duration-200",
|
|
16
|
+
role: "dialog",
|
|
17
|
+
"aria-modal": "true",
|
|
18
|
+
"aria-labelledby": V,
|
|
19
|
+
children: /* @__PURE__ */ h("div", {
|
|
20
|
+
className: "bg-bg-surface rounded-lg shadow-xl p-6 w-full max-w-md mx-4 animate-in zoom-in-95 duration-200",
|
|
21
|
+
children: [/* @__PURE__ */ h("div", {
|
|
22
|
+
className: "flex items-center justify-between mb-4",
|
|
23
|
+
children: [/* @__PURE__ */ m("h2", {
|
|
24
|
+
id: V,
|
|
25
|
+
className: "text-lg font-semibold text-text-primary",
|
|
26
|
+
children: e(S, "files.shareDialog.title", "Share {{itemType}} \"{{name}}\"", {
|
|
27
|
+
itemType: e(S, v === "folder" ? "files.shareDialog.itemType.folder" : "files.shareDialog.itemType.file", v === "folder" ? "folder" : "file"),
|
|
28
|
+
name: _.name
|
|
29
|
+
})
|
|
30
|
+
}), /* @__PURE__ */ m("button", {
|
|
31
|
+
onClick: y,
|
|
32
|
+
className: "text-text-tertiary hover:text-text-secondary transition-colors duration-200",
|
|
33
|
+
"aria-label": e(S, "files.shareDialog.actions.close", "Close share dialog"),
|
|
34
|
+
children: /* @__PURE__ */ m(f, { className: "size-5" })
|
|
35
|
+
})]
|
|
36
|
+
}), T === null ? /* @__PURE__ */ h(p, { children: [
|
|
37
|
+
z && /* @__PURE__ */ m("div", {
|
|
38
|
+
className: "mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
|
|
39
|
+
children: z
|
|
40
|
+
}),
|
|
41
|
+
/* @__PURE__ */ h("div", {
|
|
42
|
+
className: "space-y-4",
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ h("label", {
|
|
45
|
+
className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
|
|
46
|
+
children: [/* @__PURE__ */ m(i, { className: "size-4" }), e(S, "files.shareDialog.expiry.label", "Link expires in")]
|
|
47
|
+
}), /* @__PURE__ */ h("select", {
|
|
48
|
+
value: k,
|
|
49
|
+
onChange: (e) => A(Number(e.target.value)),
|
|
50
|
+
className: "w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200",
|
|
51
|
+
children: [
|
|
52
|
+
/* @__PURE__ */ m("option", {
|
|
53
|
+
value: 0,
|
|
54
|
+
children: e(S, "files.shareDialog.expiry.options.never", "Never")
|
|
55
|
+
}),
|
|
56
|
+
/* @__PURE__ */ m("option", {
|
|
57
|
+
value: 1,
|
|
58
|
+
children: e(S, "files.shareDialog.expiry.options.oneDay", "1 day")
|
|
59
|
+
}),
|
|
60
|
+
/* @__PURE__ */ m("option", {
|
|
61
|
+
value: 7,
|
|
62
|
+
children: e(S, "files.shareDialog.expiry.options.sevenDays", "7 days")
|
|
63
|
+
}),
|
|
64
|
+
/* @__PURE__ */ m("option", {
|
|
65
|
+
value: 30,
|
|
66
|
+
children: e(S, "files.shareDialog.expiry.options.thirtyDays", "30 days")
|
|
67
|
+
}),
|
|
68
|
+
/* @__PURE__ */ m("option", {
|
|
69
|
+
value: 90,
|
|
70
|
+
children: e(S, "files.shareDialog.expiry.options.ninetyDays", "90 days")
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
})] }),
|
|
74
|
+
/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ h("label", {
|
|
75
|
+
className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
|
|
76
|
+
children: [/* @__PURE__ */ m(s, { className: "size-4" }), e(S, "files.shareDialog.downloads.label", "Maximum downloads")]
|
|
77
|
+
}), /* @__PURE__ */ m("input", {
|
|
78
|
+
type: "number",
|
|
79
|
+
min: "0",
|
|
80
|
+
value: j,
|
|
81
|
+
onChange: (e) => M(Number(e.target.value)),
|
|
82
|
+
placeholder: e(S, "files.shareDialog.downloads.placeholder", "Unlimited"),
|
|
83
|
+
className: "w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200"
|
|
84
|
+
})] }),
|
|
85
|
+
/* @__PURE__ */ h("div", { children: [
|
|
86
|
+
/* @__PURE__ */ h("label", {
|
|
87
|
+
className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
|
|
88
|
+
children: [/* @__PURE__ */ m(u, { className: "size-4" }), e(S, "files.shareDialog.password.label", "Password protection")]
|
|
89
|
+
}),
|
|
90
|
+
/* @__PURE__ */ h("div", {
|
|
91
|
+
className: "flex items-center gap-2",
|
|
92
|
+
children: [/* @__PURE__ */ m("input", {
|
|
93
|
+
type: "checkbox",
|
|
94
|
+
checked: N,
|
|
95
|
+
onChange: (e) => P(e.target.checked),
|
|
96
|
+
className: "rounded transition-colors duration-200"
|
|
97
|
+
}), /* @__PURE__ */ m("span", {
|
|
98
|
+
className: "text-sm text-text-secondary",
|
|
99
|
+
children: e(S, "files.shareDialog.password.require", "Require password")
|
|
100
|
+
})]
|
|
101
|
+
}),
|
|
102
|
+
N && /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("input", {
|
|
103
|
+
type: "password",
|
|
104
|
+
value: F,
|
|
105
|
+
onChange: (e) => I(e.target.value),
|
|
106
|
+
placeholder: e(S, "files.shareDialog.password.placeholder", "Enter password"),
|
|
107
|
+
className: "w-full mt-2 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200"
|
|
108
|
+
}), /* @__PURE__ */ m("p", {
|
|
109
|
+
className: "mt-1 text-xs text-text-tertiary",
|
|
110
|
+
children: e(S, "files.shareDialog.password.help", "Password must be at least 8 characters and contain uppercase, lowercase, and number")
|
|
111
|
+
})] })
|
|
112
|
+
] }),
|
|
113
|
+
/* @__PURE__ */ h("div", { children: [
|
|
114
|
+
/* @__PURE__ */ h("label", {
|
|
115
|
+
className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
|
|
116
|
+
children: [/* @__PURE__ */ m(d, { className: "size-4" }), e(S, "files.shareDialog.invite.label", "Invite specific person (optional)")]
|
|
117
|
+
}),
|
|
118
|
+
/* @__PURE__ */ m("input", {
|
|
119
|
+
type: "email",
|
|
120
|
+
value: L,
|
|
121
|
+
onChange: (e) => R(e.target.value),
|
|
122
|
+
placeholder: "user@example.com",
|
|
123
|
+
className: "w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200"
|
|
124
|
+
}),
|
|
125
|
+
/* @__PURE__ */ m("p", {
|
|
126
|
+
className: "mt-1 text-xs text-text-secondary",
|
|
127
|
+
children: e(S, "files.shareDialog.invite.help", "Leave empty for public link")
|
|
128
|
+
})
|
|
129
|
+
] })
|
|
130
|
+
]
|
|
131
|
+
}),
|
|
132
|
+
/* @__PURE__ */ h("div", {
|
|
133
|
+
className: "flex justify-end gap-2 mt-6",
|
|
134
|
+
children: [/* @__PURE__ */ m("button", {
|
|
135
|
+
onClick: y,
|
|
136
|
+
className: "px-4 py-2 text-sm font-medium text-text-primary hover:bg-action-ghost-bg-hover rounded-lg transition-colors duration-200",
|
|
137
|
+
children: e(S, "files.common.actions.cancel", "Cancel")
|
|
138
|
+
}), /* @__PURE__ */ m("button", {
|
|
139
|
+
onClick: async () => {
|
|
140
|
+
try {
|
|
141
|
+
B(null);
|
|
142
|
+
let e = k > 0 ? new Date(Date.now() + k * 24 * 60 * 60 * 1e3).toISOString() : void 0, t = L ? "EMAIL_INVITE" : "PUBLIC_LINK", n = await b({
|
|
143
|
+
...v === "file" ? { fileId: _.id } : { folderId: _.id },
|
|
144
|
+
shareType: t,
|
|
145
|
+
accessLevel: "DOWNLOAD",
|
|
146
|
+
expiresAt: e,
|
|
147
|
+
maxDownloads: j > 0 ? j : void 0,
|
|
148
|
+
password: N && F ? F : void 0,
|
|
149
|
+
invitedEmail: L || void 0
|
|
150
|
+
});
|
|
151
|
+
E(t), w(n.publicUrl || "");
|
|
152
|
+
} catch (e) {
|
|
153
|
+
B(e instanceof Error ? e.message : "Failed to create share");
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
disabled: x || N && !F,
|
|
157
|
+
className: "flex items-center gap-2 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",
|
|
158
|
+
children: x ? /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(l, { className: "size-4 animate-spin" }), e(S, "files.shareDialog.actions.creating", "Creating...")] }) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(c, { className: "size-4" }), e(S, "files.shareDialog.actions.createLink", "Create share link")] })
|
|
159
|
+
})]
|
|
160
|
+
})
|
|
161
|
+
] }) : /* @__PURE__ */ m(p, { children: /* @__PURE__ */ h("div", {
|
|
162
|
+
className: "space-y-4",
|
|
163
|
+
children: [/* @__PURE__ */ m("div", {
|
|
164
|
+
className: "bg-status-success-bg-subtle border border-status-success-border rounded-lg p-4",
|
|
165
|
+
children: T === "EMAIL_INVITE" ? /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("p", {
|
|
166
|
+
className: "text-sm font-medium text-status-success-text mb-2",
|
|
167
|
+
children: e(S, "files.shareDialog.success.invitationSent", "Invitation sent successfully!")
|
|
168
|
+
}), /* @__PURE__ */ m("p", {
|
|
169
|
+
className: "text-sm text-text-secondary",
|
|
170
|
+
children: e(S, "files.shareDialog.success.invitationSentTo", "An invitation has been sent to {{email}}", { email: L })
|
|
171
|
+
})] }) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("p", {
|
|
172
|
+
className: "text-sm font-medium text-status-success-text mb-2",
|
|
173
|
+
children: e(S, "files.shareDialog.success.linkCreated", "Share link created successfully!")
|
|
174
|
+
}), /* @__PURE__ */ h("div", {
|
|
175
|
+
className: "flex items-center gap-2",
|
|
176
|
+
children: [/* @__PURE__ */ m("input", {
|
|
177
|
+
type: "text",
|
|
178
|
+
value: C || "",
|
|
179
|
+
readOnly: !0,
|
|
180
|
+
className: "flex-1 px-3 py-2 bg-bg-surface border border-status-success-border rounded-lg text-sm"
|
|
181
|
+
}), /* @__PURE__ */ m("button", {
|
|
182
|
+
onClick: async () => {
|
|
183
|
+
C && (await navigator.clipboard.writeText(C), O(!0), setTimeout(() => O(!1), 2e3));
|
|
184
|
+
},
|
|
185
|
+
className: "flex items-center gap-2 px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover transition-colors duration-200",
|
|
186
|
+
children: D ? /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(a, { className: "size-4" }), e(S, "files.shareDialog.actions.copied", "Copied!")] }) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(o, { className: "size-4" }), e(S, "files.common.actions.copy", "Copy")] })
|
|
187
|
+
})]
|
|
188
|
+
})] })
|
|
189
|
+
}), /* @__PURE__ */ m("button", {
|
|
190
|
+
onClick: y,
|
|
191
|
+
className: "w-full px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover transition-colors duration-200",
|
|
192
|
+
children: e(S, "files.common.actions.done", "Done")
|
|
193
|
+
})]
|
|
194
|
+
}) })]
|
|
195
|
+
})
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
//#endregion
|
|
199
|
+
export { _ as ShareDialog };
|
|
200
|
+
|
|
201
|
+
//# sourceMappingURL=ShareDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShareDialog.js","names":[],"sources":["../../../src/files/components/ShareDialog.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\nimport {\n X,\n Link,\n Mail,\n Calendar,\n Download,\n Lock,\n Copy,\n Check,\n Loader2,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport type { FileItem, FolderItem } from \"../types\";\nimport { tWithFallback } from \"../utils/i18n\";\n\nexport interface ShareDialogInput {\n fileId?: string;\n folderId?: string;\n shareType: \"PUBLIC_LINK\" | \"EMAIL_INVITE\";\n accessLevel: \"VIEW\" | \"DOWNLOAD\" | \"EDIT\";\n expiresAt?: string;\n maxDownloads?: number;\n password?: string;\n invitedEmail?: string;\n}\n\ninterface ShareDialogProps {\n item: FileItem | FolderItem;\n itemType: \"file\" | \"folder\";\n onClose: () => void;\n onCreateShare: (\n input: ShareDialogInput,\n ) => Promise<{ publicUrl: string; token: string }>;\n isLoading?: boolean;\n}\n\nexport function ShareDialog({\n item,\n itemType,\n onClose,\n onCreateShare,\n isLoading,\n}: ShareDialogProps) {\n const { t } = useI18n();\n const [shareUrl, setShareUrl] = useState<string | null>(null);\n const [shareType, setShareType] = useState<\n \"PUBLIC_LINK\" | \"EMAIL_INVITE\" | null\n >(null);\n const [copied, setCopied] = useState(false);\n const [expiryDays, setExpiryDays] = useState<number>(7);\n const [maxDownloads, setMaxDownloads] = useState<number>(0);\n const [hasPassword, setHasPassword] = useState(false);\n const [password, setPassword] = useState(\"\");\n const [invitedEmail, setInvitedEmail] = useState(\"\");\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const titleId = useMemo(() => `share-dialog-title-${item.id}`, [item.id]);\n\n useEffect(() => {\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n }\n };\n\n document.addEventListener(\"keydown\", handleEscape);\n return () => document.removeEventListener(\"keydown\", handleEscape);\n }, [onClose]);\n\n const handleCreateShare = async () => {\n try {\n setErrorMessage(null);\n const expiresAt =\n expiryDays > 0\n ? new Date(\n Date.now() + expiryDays * 24 * 60 * 60 * 1000,\n ).toISOString()\n : undefined;\n\n const type: ShareDialogInput[\"shareType\"] = invitedEmail\n ? \"EMAIL_INVITE\"\n : \"PUBLIC_LINK\";\n\n const shareInput: ShareDialogInput = {\n ...(itemType === \"file\" ? { fileId: item.id } : { folderId: item.id }),\n shareType: type,\n accessLevel: \"DOWNLOAD\",\n expiresAt,\n maxDownloads: maxDownloads > 0 ? maxDownloads : undefined,\n password: hasPassword && password ? password : undefined,\n invitedEmail: invitedEmail || undefined,\n };\n\n const result = await onCreateShare(shareInput);\n\n setShareType(type);\n setShareUrl(result.publicUrl || \"\");\n } catch (error) {\n setErrorMessage(\n error instanceof Error ? error.message : \"Failed to create share\",\n );\n }\n };\n\n const handleCopyLink = async () => {\n if (shareUrl) {\n await navigator.clipboard.writeText(shareUrl);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n return (\n <div\n className=\"fixed inset-0 bg-bg-overlay flex items-center justify-center z-[100] animate-in fade-in duration-200\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n >\n <div className=\"bg-bg-surface rounded-lg shadow-xl p-6 w-full max-w-md mx-4 animate-in zoom-in-95 duration-200\">\n <div className=\"flex items-center justify-between mb-4\">\n <h2 id={titleId} className=\"text-lg font-semibold text-text-primary\">\n {tWithFallback(\n t,\n \"files.shareDialog.title\",\n 'Share {{itemType}} \"{{name}}\"',\n {\n itemType: tWithFallback(\n t,\n itemType === \"folder\"\n ? \"files.shareDialog.itemType.folder\"\n : \"files.shareDialog.itemType.file\",\n itemType === \"folder\" ? \"folder\" : \"file\",\n ),\n name: item.name,\n },\n )}\n </h2>\n <button\n onClick={onClose}\n className=\"text-text-tertiary hover:text-text-secondary transition-colors duration-200\"\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.actions.close\",\n \"Close share dialog\",\n )}\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n {shareType === null ? (\n <>\n {errorMessage && (\n <div className=\"mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\">\n {errorMessage}\n </div>\n )}\n\n {/* Share Settings */}\n <div className=\"space-y-4\">\n {/* Expiry */}\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Calendar className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.label\",\n \"Link expires in\",\n )}\n </label>\n <select\n value={expiryDays}\n onChange={(e) => setExpiryDays(Number(e.target.value))}\n className=\"w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n >\n <option value={0}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.never\",\n \"Never\",\n )}\n </option>\n <option value={1}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.oneDay\",\n \"1 day\",\n )}\n </option>\n <option value={7}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.sevenDays\",\n \"7 days\",\n )}\n </option>\n <option value={30}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.thirtyDays\",\n \"30 days\",\n )}\n </option>\n <option value={90}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.ninetyDays\",\n \"90 days\",\n )}\n </option>\n </select>\n </div>\n\n {/* Max Downloads */}\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Download className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.downloads.label\",\n \"Maximum downloads\",\n )}\n </label>\n <input\n type=\"number\"\n min=\"0\"\n value={maxDownloads}\n onChange={(e) => setMaxDownloads(Number(e.target.value))}\n placeholder={tWithFallback(\n t,\n \"files.shareDialog.downloads.placeholder\",\n \"Unlimited\",\n )}\n className=\"w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n />\n </div>\n\n {/* Password Protection */}\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Lock className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.password.label\",\n \"Password protection\",\n )}\n </label>\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n checked={hasPassword}\n onChange={(e) => setHasPassword(e.target.checked)}\n className=\"rounded transition-colors duration-200\"\n />\n <span className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n \"files.shareDialog.password.require\",\n \"Require password\",\n )}\n </span>\n </div>\n {hasPassword && (\n <>\n <input\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n placeholder={tWithFallback(\n t,\n \"files.shareDialog.password.placeholder\",\n \"Enter password\",\n )}\n className=\"w-full mt-2 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n />\n <p className=\"mt-1 text-xs text-text-tertiary\">\n {tWithFallback(\n t,\n \"files.shareDialog.password.help\",\n \"Password must be at least 8 characters and contain uppercase, lowercase, and number\",\n )}\n </p>\n </>\n )}\n </div>\n\n {/* Invited Email */}\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Mail className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.invite.label\",\n \"Invite specific person (optional)\",\n )}\n </label>\n <input\n type=\"email\"\n value={invitedEmail}\n onChange={(e) => setInvitedEmail(e.target.value)}\n placeholder=\"user@example.com\"\n className=\"w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n />\n <p className=\"mt-1 text-xs text-text-secondary\">\n {tWithFallback(\n t,\n \"files.shareDialog.invite.help\",\n \"Leave empty for public link\",\n )}\n </p>\n </div>\n </div>\n\n {/* Create Button */}\n <div className=\"flex justify-end gap-2 mt-6\">\n <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 onClick={handleCreateShare}\n disabled={isLoading || (hasPassword && !password)}\n className=\"flex items-center gap-2 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\"\n >\n {isLoading ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n {tWithFallback(\n t,\n \"files.shareDialog.actions.creating\",\n \"Creating...\",\n )}\n </>\n ) : (\n <>\n <Link className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.actions.createLink\",\n \"Create share link\",\n )}\n </>\n )}\n </button>\n </div>\n </>\n ) : (\n <>\n {/* Share Created Success */}\n <div className=\"space-y-4\">\n <div className=\"bg-status-success-bg-subtle border border-status-success-border rounded-lg p-4\">\n {shareType === \"EMAIL_INVITE\" ? (\n <>\n <p className=\"text-sm font-medium text-status-success-text mb-2\">\n {tWithFallback(\n t,\n \"files.shareDialog.success.invitationSent\",\n \"Invitation sent successfully!\",\n )}\n </p>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n \"files.shareDialog.success.invitationSentTo\",\n \"An invitation has been sent to {{email}}\",\n { email: invitedEmail },\n )}\n </p>\n </>\n ) : (\n <>\n <p className=\"text-sm font-medium text-status-success-text mb-2\">\n {tWithFallback(\n t,\n \"files.shareDialog.success.linkCreated\",\n \"Share link created successfully!\",\n )}\n </p>\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n value={shareUrl || \"\"}\n readOnly\n className=\"flex-1 px-3 py-2 bg-bg-surface border border-status-success-border rounded-lg text-sm\"\n />\n <button\n onClick={handleCopyLink}\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover transition-colors duration-200\"\n >\n {copied ? (\n <>\n <Check className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.actions.copied\",\n \"Copied!\",\n )}\n </>\n ) : (\n <>\n <Copy className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.common.actions.copy\",\n \"Copy\",\n )}\n </>\n )}\n </button>\n </div>\n </>\n )}\n </div>\n\n <button\n onClick={onClose}\n className=\"w-full px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover transition-colors duration-200\"\n >\n {tWithFallback(t, \"files.common.actions.done\", \"Done\")}\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type TabView = "all" | "recent" | "starred" | "bin";
|
|
2
|
+
interface TabBarProps {
|
|
3
|
+
activeTab: TabView;
|
|
4
|
+
onTabChange: (tab: TabView) => void;
|
|
5
|
+
/**
|
|
6
|
+
* Which tabs to render. Order is preserved. Parent filters out
|
|
7
|
+
* feature-flag-gated tabs (e.g. bin/starred) before passing.
|
|
8
|
+
* @default ["all", "recent", "starred", "bin"]
|
|
9
|
+
*/
|
|
10
|
+
tabs?: TabView[];
|
|
11
|
+
}
|
|
12
|
+
export declare function TabBar({ activeTab, onTabChange, tabs, }: TabBarProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=TabBar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabBar.d.ts","sourceRoot":"","sources":["../../../src/files/components/TabBar.tsx"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;AAE3D,UAAU,WAAW;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;CAClB;AASD,wBAAgB,MAAM,CAAC,EACrB,SAAS,EACT,WAAW,EACX,IAA0C,GAC3C,EAAE,WAAW,2CA6Cb"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { tWithFallback as e } from "../utils/i18n.js";
|
|
2
|
+
import { Clock as t, Folder as n, Star as r, Trash2 as i } from "lucide-react";
|
|
3
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
4
|
+
import { useI18n as s } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
5
|
+
//#region src/files/components/TabBar.tsx
|
|
6
|
+
var c = [
|
|
7
|
+
{
|
|
8
|
+
id: "all",
|
|
9
|
+
label: "All Files",
|
|
10
|
+
icon: /* @__PURE__ */ a(n, { className: "size-5" })
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: "recent",
|
|
14
|
+
label: "Recent",
|
|
15
|
+
icon: /* @__PURE__ */ a(t, { className: "size-5" })
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "starred",
|
|
19
|
+
label: "Starred",
|
|
20
|
+
icon: /* @__PURE__ */ a(r, { className: "size-5" })
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: "bin",
|
|
24
|
+
label: "Bin",
|
|
25
|
+
icon: /* @__PURE__ */ a(i, { className: "size-5" })
|
|
26
|
+
}
|
|
27
|
+
];
|
|
28
|
+
function l({ activeTab: t, onTabChange: n, tabs: r = [
|
|
29
|
+
"all",
|
|
30
|
+
"recent",
|
|
31
|
+
"starred",
|
|
32
|
+
"bin"
|
|
33
|
+
] }) {
|
|
34
|
+
let { t: i } = s(), l = c.filter((e) => r.includes(e.id)), u = {
|
|
35
|
+
all: e(i, "files.browser.tabs.all", "All Files"),
|
|
36
|
+
recent: e(i, "files.browser.tabs.recent", "Recent"),
|
|
37
|
+
starred: e(i, "files.browser.tabs.starred", "Starred"),
|
|
38
|
+
bin: e(i, "files.browser.tabs.bin", "Bin")
|
|
39
|
+
};
|
|
40
|
+
return /* @__PURE__ */ a("div", {
|
|
41
|
+
className: "bg-bg-surface border-b border-border-default",
|
|
42
|
+
children: /* @__PURE__ */ a("div", {
|
|
43
|
+
className: "overflow-x-auto px-4 sm:px-6",
|
|
44
|
+
children: /* @__PURE__ */ a("nav", {
|
|
45
|
+
className: "-mb-px flex min-w-max gap-1",
|
|
46
|
+
role: "tablist",
|
|
47
|
+
"aria-label": e(i, "files.browser.tabs.ariaLabel", "Files sections"),
|
|
48
|
+
children: l.map((e) => /* @__PURE__ */ o("button", {
|
|
49
|
+
onClick: () => n(e.id),
|
|
50
|
+
role: "tab",
|
|
51
|
+
"aria-selected": t === e.id,
|
|
52
|
+
className: `
|
|
53
|
+
flex items-center gap-2 whitespace-nowrap px-4 py-3 text-sm font-medium border-b-2 transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-border focus-visible:ring-offset-2
|
|
54
|
+
${t === e.id ? "border-action-primary-bg text-text-primary bg-action-ghost-bg-hover" : "border-transparent text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover"}
|
|
55
|
+
`,
|
|
56
|
+
children: [e.icon, u[e.id] ?? e.label]
|
|
57
|
+
}, e.id))
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { l as TabBar };
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=TabBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabBar.js","names":[],"sources":["../../../src/files/components/TabBar.tsx"],"sourcesContent":["import { Clock, Star, Trash2, Folder } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { tWithFallback } from \"../utils/i18n\";\n\nexport type TabView = \"all\" | \"recent\" | \"starred\" | \"bin\";\n\ninterface TabBarProps {\n activeTab: TabView;\n onTabChange: (tab: TabView) => void;\n /**\n * Which tabs to render. Order is preserved. Parent filters out\n * feature-flag-gated tabs (e.g. bin/starred) before passing.\n * @default [\"all\", \"recent\", \"starred\", \"bin\"]\n */\n tabs?: TabView[];\n}\n\nconst ALL_TABS: { id: TabView; label: string; icon: React.ReactNode }[] = [\n { id: \"all\", label: \"All Files\", icon: <Folder className=\"size-5\" /> },\n { id: \"recent\", label: \"Recent\", icon: <Clock className=\"size-5\" /> },\n { id: \"starred\", label: \"Starred\", icon: <Star className=\"size-5\" /> },\n { id: \"bin\", label: \"Bin\", icon: <Trash2 className=\"size-5\" /> },\n];\n\nexport function TabBar({\n activeTab,\n onTabChange,\n tabs = [\"all\", \"recent\", \"starred\", \"bin\"],\n}: TabBarProps) {\n const { t } = useI18n();\n const visibleTabs = ALL_TABS.filter((tab) => tabs.includes(tab.id));\n const labels: Record<TabView, string> = {\n all: tWithFallback(t, \"files.browser.tabs.all\", \"All Files\"),\n recent: tWithFallback(t, \"files.browser.tabs.recent\", \"Recent\"),\n starred: tWithFallback(t, \"files.browser.tabs.starred\", \"Starred\"),\n bin: tWithFallback(t, \"files.browser.tabs.bin\", \"Bin\"),\n };\n\n return (\n <div className=\"bg-bg-surface border-b border-border-default\">\n <div className=\"overflow-x-auto px-4 sm:px-6\">\n <nav\n className=\"-mb-px flex min-w-max gap-1\"\n role=\"tablist\"\n aria-label={tWithFallback(\n t,\n \"files.browser.tabs.ariaLabel\",\n \"Files sections\",\n )}\n >\n {visibleTabs.map((tab) => (\n <button\n key={tab.id}\n onClick={() => onTabChange(tab.id)}\n role=\"tab\"\n aria-selected={activeTab === tab.id}\n className={`\n flex items-center gap-2 whitespace-nowrap px-4 py-3 text-sm font-medium border-b-2 transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-border focus-visible:ring-offset-2\n ${\n activeTab === tab.id\n ? \"border-action-primary-bg text-text-primary bg-action-ghost-bg-hover\"\n : \"border-transparent text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover\"\n }\n `}\n >\n {tab.icon}\n {labels[tab.id] ?? tab.label}\n </button>\n ))}\n </nav>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAiBA,IAAM,IAAoE;CACxE;EAAE,IAAI;EAAO,OAAO;EAAa,MAAM,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA;EAAE;CACtE;EAAE,IAAI;EAAU,OAAO;EAAU,MAAM,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA;EAAE;CACrE;EAAE,IAAI;EAAW,OAAO;EAAW,MAAM,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA;EAAE;CACtE;EAAE,IAAI;EAAO,OAAO;EAAO,MAAM,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA;EAAE;CACjE;AAED,SAAgB,EAAO,EACrB,cACA,gBACA,UAAO;CAAC;CAAO;CAAU;CAAW;CAAM,IAC5B;CACd,IAAM,EAAE,SAAM,GAAS,EACjB,IAAc,EAAS,QAAQ,MAAQ,EAAK,SAAS,EAAI,GAAG,CAAC,EAC7D,IAAkC;EACtC,KAAK,EAAc,GAAG,0BAA0B,YAAY;EAC5D,QAAQ,EAAc,GAAG,6BAA6B,SAAS;EAC/D,SAAS,EAAc,GAAG,8BAA8B,UAAU;EAClE,KAAK,EAAc,GAAG,0BAA0B,MAAM;EACvD;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IACE,WAAU;IACV,MAAK;IACL,cAAY,EACV,GACA,gCACA,iBACD;cAEA,EAAY,KAAK,MAChB,kBAAC,UAAD;KAEE,eAAe,EAAY,EAAI,GAAG;KAClC,MAAK;KACL,iBAAe,MAAc,EAAI;KACjC,WAAW;;kBAGP,MAAc,EAAI,KACd,wEACA,gGACL;;eAXL,CAcG,EAAI,MACJ,EAAO,EAAI,OAAO,EAAI,MAChB;OAfF,EAAI,GAeF,CACT;IACE,CAAA;GACF,CAAA;EACF,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type ToastType = "success" | "error" | "warning" | "info";
|
|
2
|
+
export interface Toast {
|
|
3
|
+
id: string;
|
|
4
|
+
type: ToastType;
|
|
5
|
+
message: string;
|
|
6
|
+
duration?: number;
|
|
7
|
+
}
|
|
8
|
+
interface ToastContainerProps {
|
|
9
|
+
toasts: Toast[];
|
|
10
|
+
onClose: (id: string) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function ToastContainer({ toasts, onClose }: ToastContainerProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=Toast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../src/files/components/Toast.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjE,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAiDD,UAAU,mBAAmB;IAC3B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,mBAAmB,2CAQtE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useEffect as e } from "react";
|
|
2
|
+
import { AlertCircle as t, CheckCircle as n, Info as r, X as i, XCircle as a } from "lucide-react";
|
|
3
|
+
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
4
|
+
//#region src/files/components/Toast.tsx
|
|
5
|
+
function c({ toast: c, onClose: l }) {
|
|
6
|
+
e(() => {
|
|
7
|
+
let e = c.duration || 5e3, t = setTimeout(() => {
|
|
8
|
+
l(c.id);
|
|
9
|
+
}, e);
|
|
10
|
+
return () => clearTimeout(t);
|
|
11
|
+
}, [c, l]);
|
|
12
|
+
let u = {
|
|
13
|
+
success: /* @__PURE__ */ o(n, { className: "size-5 text-status-success-bg" }),
|
|
14
|
+
error: /* @__PURE__ */ o(a, { className: "size-5 text-status-error-bg" }),
|
|
15
|
+
warning: /* @__PURE__ */ o(t, { className: "size-5 text-status-warning-bg" }),
|
|
16
|
+
info: /* @__PURE__ */ o(r, { className: "size-5 text-status-info-bg" })
|
|
17
|
+
};
|
|
18
|
+
return /* @__PURE__ */ s("div", {
|
|
19
|
+
className: `flex items-center gap-3 p-4 rounded-lg shadow-lg border ${{
|
|
20
|
+
success: "bg-status-success-bg-subtle border-status-success-border",
|
|
21
|
+
error: "bg-status-error-bg-subtle border-status-error-border",
|
|
22
|
+
warning: "bg-status-warning-bg-subtle border-status-warning-border",
|
|
23
|
+
info: "bg-status-info-bg-subtle border-status-info-border"
|
|
24
|
+
}[c.type]} min-w-80 max-w-md animate-in slide-in-from-right duration-300`,
|
|
25
|
+
children: [
|
|
26
|
+
u[c.type],
|
|
27
|
+
/* @__PURE__ */ o("p", {
|
|
28
|
+
className: "flex-1 text-sm font-medium text-text-primary",
|
|
29
|
+
children: c.message
|
|
30
|
+
}),
|
|
31
|
+
/* @__PURE__ */ o("button", {
|
|
32
|
+
onClick: () => l(c.id),
|
|
33
|
+
className: "text-text-muted hover:text-text-secondary transition-colors",
|
|
34
|
+
children: /* @__PURE__ */ o(i, { className: "size-4" })
|
|
35
|
+
})
|
|
36
|
+
]
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function l({ toasts: e, onClose: t }) {
|
|
40
|
+
return /* @__PURE__ */ o("div", {
|
|
41
|
+
className: "fixed bottom-4 right-4 z-50 flex flex-col gap-2",
|
|
42
|
+
children: e.map((e) => /* @__PURE__ */ o(c, {
|
|
43
|
+
toast: e,
|
|
44
|
+
onClose: t
|
|
45
|
+
}, e.id))
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { l as ToastContainer };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=Toast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toast.js","names":[],"sources":["../../../src/files/components/Toast.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport { X, CheckCircle, XCircle, AlertCircle, Info } from \"lucide-react\";\n\nexport type ToastType = \"success\" | \"error\" | \"warning\" | \"info\";\n\nexport interface Toast {\n id: string;\n type: ToastType;\n message: string;\n duration?: number;\n}\n\ninterface ToastItemProps {\n toast: Toast;\n onClose: (id: string) => void;\n}\n\nfunction ToastItem({ toast, onClose }: ToastItemProps) {\n useEffect(() => {\n const duration = toast.duration || 5000;\n const timer = setTimeout(() => {\n onClose(toast.id);\n }, duration);\n\n return () => clearTimeout(timer);\n }, [toast, onClose]);\n\n const icons = {\n success: <CheckCircle className=\"size-5 text-status-success-bg\" />,\n error: <XCircle className=\"size-5 text-status-error-bg\" />,\n warning: <AlertCircle className=\"size-5 text-status-warning-bg\" />,\n info: <Info className=\"size-5 text-status-info-bg\" />,\n };\n\n const colors = {\n success: \"bg-status-success-bg-subtle border-status-success-border\",\n error: \"bg-status-error-bg-subtle border-status-error-border\",\n warning: \"bg-status-warning-bg-subtle border-status-warning-border\",\n info: \"bg-status-info-bg-subtle border-status-info-border\",\n };\n\n return (\n <div\n className={`flex items-center gap-3 p-4 rounded-lg shadow-lg border ${colors[toast.type]} min-w-80 max-w-md animate-in slide-in-from-right duration-300`}\n >\n {icons[toast.type]}\n <p className=\"flex-1 text-sm font-medium text-text-primary\">\n {toast.message}\n </p>\n <button\n onClick={() => onClose(toast.id)}\n className=\"text-text-muted hover:text-text-secondary transition-colors\"\n >\n <X className=\"size-4\" />\n </button>\n </div>\n );\n}\n\ninterface ToastContainerProps {\n toasts: Toast[];\n onClose: (id: string) => void;\n}\n\nexport function ToastContainer({ toasts, onClose }: ToastContainerProps) {\n return (\n <div className=\"fixed bottom-4 right-4 z-50 flex flex-col gap-2\">\n {toasts.map((toast) => (\n <ToastItem key={toast.id} toast={toast} onClose={onClose} />\n ))}\n </div>\n );\n}\n"],"mappings":";;;;AAiBA,SAAS,EAAU,EAAE,UAAO,cAA2B;AACrD,SAAgB;EACd,IAAM,IAAW,EAAM,YAAY,KAC7B,IAAQ,iBAAiB;AAC7B,KAAQ,EAAM,GAAG;KAChB,EAAS;AAEZ,eAAa,aAAa,EAAM;IAC/B,CAAC,GAAO,EAAQ,CAAC;CAEpB,IAAM,IAAQ;EACZ,SAAS,kBAAC,GAAD,EAAa,WAAU,iCAAkC,CAAA;EAClE,OAAO,kBAAC,GAAD,EAAS,WAAU,+BAAgC,CAAA;EAC1D,SAAS,kBAAC,GAAD,EAAa,WAAU,iCAAkC,CAAA;EAClE,MAAM,kBAAC,GAAD,EAAM,WAAU,8BAA+B,CAAA;EACtD;AASD,QACE,kBAAC,OAAD;EACE,WAAW,2DATA;GACb,SAAS;GACT,OAAO;GACP,SAAS;GACT,MAAM;GACP,CAIgF,EAAM,MAAM;YAD3F;GAGG,EAAM,EAAM;GACb,kBAAC,KAAD;IAAG,WAAU;cACV,EAAM;IACL,CAAA;GACJ,kBAAC,UAAD;IACE,eAAe,EAAQ,EAAM,GAAG;IAChC,WAAU;cAEV,kBAAC,GAAD,EAAG,WAAU,UAAW,CAAA;IACjB,CAAA;GACL;;;AASV,SAAgB,EAAe,EAAE,WAAQ,cAAgC;AACvE,QACE,kBAAC,OAAD;EAAK,WAAU;YACZ,EAAO,KAAK,MACX,kBAAC,GAAD;GAAiC;GAAgB;GAAW,EAA5C,EAAM,GAAsC,CAC5D;EACE,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { UploadItem } from '../types';
|
|
2
|
+
interface UploadProgressBarProps {
|
|
3
|
+
item: UploadItem;
|
|
4
|
+
onPause: (id: string) => void;
|
|
5
|
+
onResume: (id: string) => void;
|
|
6
|
+
onRetry: (id: string) => void;
|
|
7
|
+
onCancel: (id: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function UploadProgressBar({ item, onPause, onResume, onRetry, onCancel, }: UploadProgressBarProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
interface UploadQueueProps {
|
|
11
|
+
items: UploadItem[];
|
|
12
|
+
isOpen: boolean;
|
|
13
|
+
onClose: () => void;
|
|
14
|
+
onPause: (id: string) => void;
|
|
15
|
+
onResume: (id: string) => void;
|
|
16
|
+
onRetry: (id: string) => void;
|
|
17
|
+
onCancel: (id: string) => void;
|
|
18
|
+
}
|
|
19
|
+
export declare function UploadQueue({ items, isOpen, onClose, onPause, onResume, onRetry, onCancel, }: UploadQueueProps): import("react/jsx-runtime").JSX.Element | null;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=UploadQueue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UploadQueue.d.ts","sourceRoot":"","sources":["../../../src/files/components/UploadQueue.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,UAAU,sBAAsB;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,OAAO,EACP,QAAQ,GACT,EAAE,sBAAsB,2CAoJxB;AAED,UAAU,gBAAgB;IACxB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,QAAQ,EACR,OAAO,EACP,QAAQ,GACT,EAAE,gBAAgB,kDA0DlB"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { isImageType as e } from "../utils/thumbnail.js";
|
|
2
|
+
import "../utils/index.js";
|
|
3
|
+
import { tWithFallback as t } from "../utils/i18n.js";
|
|
4
|
+
import { useEffect as n, useRef as r } from "react";
|
|
5
|
+
import { Image as i, Pause as a, Play as o, RotateCcw as s, X as c } from "lucide-react";
|
|
6
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
7
|
+
import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
8
|
+
//#region src/files/components/UploadQueue.tsx
|
|
9
|
+
function f({ item: f, onPause: p, onResume: m, onRetry: h, onCancel: g }) {
|
|
10
|
+
let { t: _ } = d(), v = r(null), y = e(f.file.type);
|
|
11
|
+
return n(() => {
|
|
12
|
+
v.current && (v.current.style.width = `${f.progress}%`);
|
|
13
|
+
}, [f.progress]), /* @__PURE__ */ l("div", {
|
|
14
|
+
className: "bg-bg-elevated border border-border-default rounded-lg p-3",
|
|
15
|
+
children: /* @__PURE__ */ u("div", {
|
|
16
|
+
className: "flex items-center gap-3",
|
|
17
|
+
children: [
|
|
18
|
+
/* @__PURE__ */ l("div", {
|
|
19
|
+
className: "flex-shrink-0 w-10 h-10 bg-bg-muted rounded flex items-center justify-center overflow-hidden",
|
|
20
|
+
children: f.thumbnailUrl ? /* @__PURE__ */ l("img", {
|
|
21
|
+
src: f.thumbnailUrl,
|
|
22
|
+
alt: f.file.name,
|
|
23
|
+
className: "w-full h-full object-cover"
|
|
24
|
+
}) : y ? /* @__PURE__ */ l(i, { className: "size-5 text-text-tertiary" }) : /* @__PURE__ */ l("div", { className: "w-full h-full bg-bg-accent" })
|
|
25
|
+
}),
|
|
26
|
+
/* @__PURE__ */ u("div", {
|
|
27
|
+
className: "flex-1 min-w-0",
|
|
28
|
+
children: [
|
|
29
|
+
/* @__PURE__ */ u("div", {
|
|
30
|
+
className: "flex items-center justify-between gap-2 mb-1.5",
|
|
31
|
+
children: [/* @__PURE__ */ l("span", {
|
|
32
|
+
className: "text-sm font-medium text-text-primary truncate",
|
|
33
|
+
children: f.file.name
|
|
34
|
+
}), /* @__PURE__ */ l("span", {
|
|
35
|
+
className: "text-xs text-text-secondary whitespace-nowrap",
|
|
36
|
+
children: ((e) => {
|
|
37
|
+
if (e === 0) return "0 B";
|
|
38
|
+
let t = 1024, n = [
|
|
39
|
+
"B",
|
|
40
|
+
"KB",
|
|
41
|
+
"MB",
|
|
42
|
+
"GB"
|
|
43
|
+
], r = Math.floor(Math.log(e) / Math.log(t));
|
|
44
|
+
return `${parseFloat((e / t ** +r).toFixed(1))} ${n[r]}`;
|
|
45
|
+
})(f.file.size)
|
|
46
|
+
})]
|
|
47
|
+
}),
|
|
48
|
+
/* @__PURE__ */ l("div", {
|
|
49
|
+
className: "relative h-1.5 bg-bg-muted rounded-full overflow-hidden",
|
|
50
|
+
children: /* @__PURE__ */ l("div", {
|
|
51
|
+
ref: v,
|
|
52
|
+
className: `absolute inset-y-0 left-0 ${(() => {
|
|
53
|
+
switch (f.status) {
|
|
54
|
+
case "uploading": return "bg-action-primary-bg";
|
|
55
|
+
case "paused": return "bg-status-warning-bg";
|
|
56
|
+
case "completed": return "bg-status-success-bg";
|
|
57
|
+
case "failed": return "bg-status-error-bg";
|
|
58
|
+
default: return "bg-text-tertiary";
|
|
59
|
+
}
|
|
60
|
+
})()} transition-all duration-300 ease-out rounded-full`,
|
|
61
|
+
style: { width: `${f.progress}%` }
|
|
62
|
+
})
|
|
63
|
+
}),
|
|
64
|
+
/* @__PURE__ */ l("div", {
|
|
65
|
+
className: "flex items-center justify-between mt-1.5",
|
|
66
|
+
children: /* @__PURE__ */ u("span", {
|
|
67
|
+
className: "text-xs text-text-secondary",
|
|
68
|
+
children: [
|
|
69
|
+
f.status === "paused" && t(_, "files.upload.paused", "Paused"),
|
|
70
|
+
f.status === "uploading" && `${f.progress}%`,
|
|
71
|
+
f.status === "completed" && t(_, "files.upload.completed", "Completed"),
|
|
72
|
+
f.status === "failed" && (f.error || t(_, "files.upload.failed", "Failed")),
|
|
73
|
+
f.status === "pending" && t(_, "files.upload.pending", "Pending...")
|
|
74
|
+
]
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
]
|
|
78
|
+
}),
|
|
79
|
+
/* @__PURE__ */ u("div", {
|
|
80
|
+
className: "flex items-center gap-1 flex-shrink-0",
|
|
81
|
+
children: [
|
|
82
|
+
f.status === "uploading" && /* @__PURE__ */ l("button", {
|
|
83
|
+
onClick: () => p(f.id),
|
|
84
|
+
className: "p-1.5 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors",
|
|
85
|
+
title: t(_, "files.upload.pause", "Pause"),
|
|
86
|
+
children: /* @__PURE__ */ l(a, { className: "size-4" })
|
|
87
|
+
}),
|
|
88
|
+
f.status === "paused" && /* @__PURE__ */ l("button", {
|
|
89
|
+
onClick: () => m(f.id),
|
|
90
|
+
className: "p-1.5 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors",
|
|
91
|
+
title: t(_, "files.upload.resume", "Resume"),
|
|
92
|
+
children: /* @__PURE__ */ l(o, { className: "size-4" })
|
|
93
|
+
}),
|
|
94
|
+
f.status === "failed" && /* @__PURE__ */ l("button", {
|
|
95
|
+
onClick: () => h(f.id),
|
|
96
|
+
className: "p-1.5 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors",
|
|
97
|
+
title: t(_, "files.upload.retry", "Retry"),
|
|
98
|
+
children: /* @__PURE__ */ l(s, { className: "size-4" })
|
|
99
|
+
}),
|
|
100
|
+
(f.status === "pending" || f.status === "paused" || f.status === "failed") && /* @__PURE__ */ l("button", {
|
|
101
|
+
onClick: () => g(f.id),
|
|
102
|
+
className: "p-1.5 text-text-secondary hover:text-status-error-text hover:bg-status-error-bg-subtle rounded transition-colors",
|
|
103
|
+
title: t(_, "files.upload.cancel", "Cancel"),
|
|
104
|
+
children: /* @__PURE__ */ l(c, { className: "size-4" })
|
|
105
|
+
})
|
|
106
|
+
]
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
})
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function p({ items: e, isOpen: n, onClose: r, onPause: i, onResume: a, onRetry: o, onCancel: s }) {
|
|
113
|
+
let { t: p } = d();
|
|
114
|
+
if (!n) return null;
|
|
115
|
+
let m = e.filter((e) => e.status === "completed").length, h = e.filter((e) => e.status === "failed").length, g = e.filter((e) => e.status === "uploading" || e.status === "pending").length;
|
|
116
|
+
return /* @__PURE__ */ u("div", {
|
|
117
|
+
className: "fixed bottom-4 right-4 w-80 bg-bg-elevated border border-border-default rounded-lg shadow-xl z-50",
|
|
118
|
+
children: [/* @__PURE__ */ u("div", {
|
|
119
|
+
className: "flex items-center justify-between p-3 border-b border-border-default",
|
|
120
|
+
children: [/* @__PURE__ */ u("div", { children: [
|
|
121
|
+
/* @__PURE__ */ u("h3", {
|
|
122
|
+
className: "text-sm font-semibold text-text-primary",
|
|
123
|
+
children: [
|
|
124
|
+
t(p, "files.upload.uploads", "Uploads"),
|
|
125
|
+
" (",
|
|
126
|
+
g,
|
|
127
|
+
" ",
|
|
128
|
+
t(p, "files.upload.active", "active"),
|
|
129
|
+
")"
|
|
130
|
+
]
|
|
131
|
+
}),
|
|
132
|
+
m > 0 && /* @__PURE__ */ u("p", {
|
|
133
|
+
className: "text-xs text-status-success-text",
|
|
134
|
+
children: [
|
|
135
|
+
m,
|
|
136
|
+
" ",
|
|
137
|
+
t(p, "files.upload.completed", "completed")
|
|
138
|
+
]
|
|
139
|
+
}),
|
|
140
|
+
h > 0 && /* @__PURE__ */ u("p", {
|
|
141
|
+
className: "text-xs text-status-error-text",
|
|
142
|
+
children: [
|
|
143
|
+
h,
|
|
144
|
+
" ",
|
|
145
|
+
t(p, "files.upload.failed", "failed")
|
|
146
|
+
]
|
|
147
|
+
})
|
|
148
|
+
] }), /* @__PURE__ */ l("button", {
|
|
149
|
+
onClick: r,
|
|
150
|
+
className: "p-1 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors",
|
|
151
|
+
children: /* @__PURE__ */ l(c, { className: "size-4" })
|
|
152
|
+
})]
|
|
153
|
+
}), /* @__PURE__ */ l("div", {
|
|
154
|
+
className: "max-h-64 overflow-y-auto p-2 space-y-2",
|
|
155
|
+
children: e.length === 0 ? /* @__PURE__ */ l("p", {
|
|
156
|
+
className: "text-sm text-text-secondary text-center py-4",
|
|
157
|
+
children: t(p, "files.upload.noUploads", "No uploads")
|
|
158
|
+
}) : e.map((e) => /* @__PURE__ */ l(f, {
|
|
159
|
+
item: e,
|
|
160
|
+
onPause: i,
|
|
161
|
+
onResume: a,
|
|
162
|
+
onRetry: o,
|
|
163
|
+
onCancel: s
|
|
164
|
+
}, e.id))
|
|
165
|
+
})]
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
169
|
+
export { p as UploadQueue };
|
|
170
|
+
|
|
171
|
+
//# sourceMappingURL=UploadQueue.js.map
|