@burdenoff/microfe-files 2026.1014.3 → 2026.1014.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/files/components/UploadQueue.d.ts.map +1 -1
- package/dist/files/components/UploadQueue.js +8 -17
- package/dist/files/components/UploadQueue.js.map +1 -1
- package/dist/files/hooks/useUploadFile.d.ts.map +1 -1
- package/dist/files/hooks/useUploadFile.js +9 -6
- package/dist/files/hooks/useUploadFile.js.map +1 -1
- package/dist/translations/en.d.ts +4 -0
- package/dist/translations/en.d.ts.map +1 -1
- package/dist/translations/en.js +4 -0
- package/dist/translations/en.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadQueue.d.ts","sourceRoot":"","sources":["../../../src/files/components/UploadQueue.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AA4K3C,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,
|
|
1
|
+
{"version":3,"file":"UploadQueue.d.ts","sourceRoot":"","sources":["../../../src/files/components/UploadQueue.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AA4K3C,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,sCAsFlB"}
|
|
@@ -69,9 +69,9 @@ function p({ item: f, onPause: p, onResume: m, onRetry: h, onCancel: g }) {
|
|
|
69
69
|
children: [
|
|
70
70
|
f.status === "paused" && t(_, "files.upload.paused", "Paused"),
|
|
71
71
|
f.status === "uploading" && `${f.progress}%`,
|
|
72
|
-
f.status === "completed" && t(_, "files.upload.
|
|
72
|
+
f.status === "completed" && t(_, "files.upload.completedStatus", "Completed"),
|
|
73
73
|
f.status === "failed" && (f.error || t(_, "files.upload.failed", "Failed")),
|
|
74
|
-
f.status === "pending" && t(_, "files.upload.
|
|
74
|
+
f.status === "pending" && t(_, "files.upload.pendingStatus", "Pending...")
|
|
75
75
|
]
|
|
76
76
|
})
|
|
77
77
|
})
|
|
@@ -134,31 +134,22 @@ function m({ items: e, isOpen: n, onClose: r, onPause: i, onResume: a, onRetry:
|
|
|
134
134
|
}),
|
|
135
135
|
t(m, "files.upload.uploads", "Uploads"),
|
|
136
136
|
" (",
|
|
137
|
-
_,
|
|
138
|
-
" ",
|
|
139
|
-
t(m, "files.upload.active", "active"),
|
|
137
|
+
t(m, "files.upload.active", "{{count}} uploading", { count: _ }),
|
|
140
138
|
")"
|
|
141
139
|
]
|
|
142
140
|
}),
|
|
143
|
-
h > 0 && /* @__PURE__ */
|
|
141
|
+
h > 0 && /* @__PURE__ */ l("p", {
|
|
144
142
|
className: "text-xs text-status-success-text",
|
|
145
|
-
children:
|
|
146
|
-
h,
|
|
147
|
-
" ",
|
|
148
|
-
t(m, "files.upload.completed", "completed")
|
|
149
|
-
]
|
|
143
|
+
children: t(m, "files.upload.completed", "{{count}} completed", { count: h })
|
|
150
144
|
}),
|
|
151
|
-
g > 0 && /* @__PURE__ */
|
|
145
|
+
g > 0 && /* @__PURE__ */ l("p", {
|
|
152
146
|
className: "text-xs text-status-error-text",
|
|
153
|
-
children:
|
|
154
|
-
g,
|
|
155
|
-
" ",
|
|
156
|
-
t(m, "files.upload.failed", "failed")
|
|
157
|
-
]
|
|
147
|
+
children: t(m, "files.upload.failedCount", "{{count}} failed", { count: g })
|
|
158
148
|
})
|
|
159
149
|
] }), /* @__PURE__ */ l("button", {
|
|
160
150
|
type: "button",
|
|
161
151
|
onClick: r,
|
|
152
|
+
"aria-label": t(m, "files.upload.close", "Close uploads"),
|
|
162
153
|
className: "p-1 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors",
|
|
163
154
|
children: /* @__PURE__ */ l(c, { className: "size-4" })
|
|
164
155
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadQueue.js","names":[],"sources":["../../../src/files/components/UploadQueue.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport {\n Pause,\n Play,\n RotateCcw,\n X,\n CheckCircle,\n AlertCircle,\n Loader2,\n Image as ImageIcon,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport type { UploadItem } from \"../types\";\nimport { isImageType } from \"../utils\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ninterface UploadProgressBarProps {\n item: UploadItem;\n onPause: (id: string) => void;\n onResume: (id: string) => void;\n onRetry: (id: string) => void;\n onCancel: (id: string) => void;\n}\n\nfunction UploadProgressBar({\n item,\n onPause,\n onResume,\n onRetry,\n onCancel,\n}: UploadProgressBarProps) {\n const { t } = useI18n();\n const progressRef = useRef<HTMLDivElement>(null);\n const isImage = isImageType(item.file.type);\n\n useEffect(() => {\n if (progressRef.current) {\n progressRef.current.style.width = `${item.progress}%`;\n }\n }, [item.progress]);\n\n const getStatusIcon = () => {\n switch (item.status) {\n case \"uploading\":\n return (\n <Loader2 className=\"size-4 animate-spin text-action-primary-bg\" />\n );\n case \"paused\":\n return <Pause className=\"size-4 text-status-warning-text\" />;\n case \"completed\":\n return <CheckCircle className=\"size-4 text-status-success-text\" />;\n case \"failed\":\n return <AlertCircle className=\"size-4 text-status-error-text\" />;\n default:\n return <Loader2 className=\"size-4 animate-spin text-text-tertiary\" />;\n }\n };\n\n const getStatusColor = () => {\n switch (item.status) {\n case \"uploading\":\n return \"bg-action-primary-bg\";\n case \"paused\":\n return \"bg-status-warning-bg\";\n case \"completed\":\n return \"bg-status-success-bg\";\n case \"failed\":\n return \"bg-status-error-bg\";\n default:\n return \"bg-text-tertiary\";\n }\n };\n\n const formatFileSize = (bytes: number) => {\n if (bytes === 0) return \"0 B\";\n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n };\n\n return (\n <div className=\"bg-bg-elevated border border-border-default rounded-lg p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex-shrink-0 size-10 bg-bg-sunken rounded flex items-center justify-center overflow-hidden\">\n {item.thumbnailUrl ? (\n <img\n src={item.thumbnailUrl}\n alt={item.file.name}\n className=\"w-full h-full object-cover\"\n />\n ) : isImage ? (\n <ImageIcon className=\"size-5 text-text-tertiary\" />\n ) : (\n <div className=\"w-full h-full bg-bg-accent\" />\n )}\n </div>\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center justify-between gap-2 mb-1.5\">\n <span className=\"text-sm font-medium text-text-primary truncate\">\n {item.file.name}\n </span>\n <span className=\"text-xs text-text-secondary whitespace-nowrap\">\n {formatFileSize(item.file.size)}\n </span>\n </div>\n\n <div className=\"relative h-1.5 bg-bg-sunken rounded-full overflow-hidden\">\n <div\n ref={progressRef}\n className={`absolute inset-y-0 left-0 ${getStatusColor()} transition-all duration-300 ease-out rounded-full`}\n style={{ width: `${item.progress}%` }}\n />\n </div>\n\n <div className=\"flex items-center justify-between mt-1.5\">\n <span className=\"text-xs text-text-secondary\">\n {item.status === \"paused\" &&\n tWithFallback(t, \"files.upload.paused\", \"Paused\")}\n {item.status === \"uploading\" && `${item.progress}%`}\n {item.status === \"completed\" &&\n tWithFallback(t, \"files.upload.completed\", \"Completed\")}\n {item.status === \"failed\" &&\n (item.error ||\n tWithFallback(t, \"files.upload.failed\", \"Failed\"))}\n {item.status === \"pending\" &&\n tWithFallback(t, \"files.upload.pending\", \"Pending...\")}\n </span>\n </div>\n </div>\n\n <div className=\"flex items-center gap-1 flex-shrink-0\">\n {item.status === \"uploading\" && (\n <button\n type=\"button\"\n onClick={() => onPause(item.id)}\n className=\"p-1.5 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors\"\n title={tWithFallback(t, \"files.upload.pause\", \"Pause\")}\n >\n <Pause className=\"size-4\" />\n </button>\n )}\n\n {item.status === \"paused\" && (\n <button\n type=\"button\"\n onClick={() => onResume(item.id)}\n className=\"p-1.5 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors\"\n title={tWithFallback(t, \"files.upload.resume\", \"Resume\")}\n >\n <Play className=\"size-4\" />\n </button>\n )}\n\n {item.status === \"failed\" && (\n <button\n type=\"button\"\n onClick={() => onRetry(item.id)}\n className=\"p-1.5 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors\"\n title={tWithFallback(t, \"files.upload.retry\", \"Retry\")}\n >\n <RotateCcw className=\"size-4\" />\n </button>\n )}\n\n {(item.status === \"pending\" ||\n item.status === \"paused\" ||\n item.status === \"failed\") && (\n <button\n type=\"button\"\n onClick={() => onCancel(item.id)}\n className=\"p-1.5 text-text-secondary hover:text-status-error-text hover:bg-status-error-bg-subtle rounded transition-colors\"\n title={tWithFallback(t, \"files.upload.cancel\", \"Cancel\")}\n >\n <X className=\"size-4\" />\n </button>\n )}\n </div>\n </div>\n </div>\n );\n}\n\ninterface UploadQueueProps {\n items: UploadItem[];\n isOpen: boolean;\n onClose: () => void;\n onPause: (id: string) => void;\n onResume: (id: string) => void;\n onRetry: (id: string) => void;\n onCancel: (id: string) => void;\n}\n\nexport function UploadQueue({\n items,\n isOpen,\n onClose,\n onPause,\n onResume,\n onRetry,\n onCancel,\n}: UploadQueueProps) {\n const { t } = useI18n();\n if (!isOpen) return null;\n\n const completedCount = items.filter((i) => i.status === \"completed\").length;\n const failedCount = items.filter((i) => i.status === \"failed\").length;\n const activeCount = items.filter(\n (i) => i.status === \"uploading\" || i.status === \"pending\",\n ).length;\n\n return (\n <GlassCard\n treatment=\"glass\"\n glow\n className=\"fixed bottom-4 right-4 z-50 w-80 max-w-[90vw] md:w-96\"\n >\n <div className=\"flex items-center justify-between p-3 border-b border-border-seam\">\n <div>\n <h3 className=\"flex items-center gap-2 text-sm font-semibold text-text-primary\">\n {activeCount > 0 && (\n <span\n className=\"size-2 shrink-0 rounded-full bg-action-primary-bg motion-safe:animate-vc-glow-pulse\"\n aria-hidden=\"true\"\n />\n )}\n {tWithFallback(t, \"files.upload.uploads\", \"Uploads\")} ({activeCount}{\" \"}\n {tWithFallback(t, \"files.upload.active\", \"active\")})\n </h3>\n {completedCount > 0 && (\n <p className=\"text-xs text-status-success-text\">\n {completedCount}{\" \"}\n {tWithFallback(t, \"files.upload.completed\", \"completed\")}\n </p>\n )}\n {failedCount > 0 && (\n <p className=\"text-xs text-status-error-text\">\n {failedCount} {tWithFallback(t, \"files.upload.failed\", \"failed\")}\n </p>\n )}\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"p-1 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors\"\n >\n <X className=\"size-4\" />\n </button>\n </div>\n\n <div className=\"max-h-64 overflow-y-auto p-2 space-y-2\">\n {items.length === 0 ? (\n <p className=\"text-sm text-text-secondary text-center py-4\">\n {tWithFallback(t, \"files.upload.noUploads\", \"No uploads\")}\n </p>\n ) : (\n items.map((item) => (\n <UploadProgressBar\n key={item.id}\n item={item}\n onPause={onPause}\n onResume={onResume}\n onRetry={onRetry}\n onCancel={onCancel}\n />\n ))\n )}\n </div>\n </GlassCard>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UploadQueue.js","names":[],"sources":["../../../src/files/components/UploadQueue.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport {\n Pause,\n Play,\n RotateCcw,\n X,\n CheckCircle,\n AlertCircle,\n Loader2,\n Image as ImageIcon,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport type { UploadItem } from \"../types\";\nimport { isImageType } from \"../utils\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ninterface UploadProgressBarProps {\n item: UploadItem;\n onPause: (id: string) => void;\n onResume: (id: string) => void;\n onRetry: (id: string) => void;\n onCancel: (id: string) => void;\n}\n\nfunction UploadProgressBar({\n item,\n onPause,\n onResume,\n onRetry,\n onCancel,\n}: UploadProgressBarProps) {\n const { t } = useI18n();\n const progressRef = useRef<HTMLDivElement>(null);\n const isImage = isImageType(item.file.type);\n\n useEffect(() => {\n if (progressRef.current) {\n progressRef.current.style.width = `${item.progress}%`;\n }\n }, [item.progress]);\n\n const getStatusIcon = () => {\n switch (item.status) {\n case \"uploading\":\n return (\n <Loader2 className=\"size-4 animate-spin text-action-primary-bg\" />\n );\n case \"paused\":\n return <Pause className=\"size-4 text-status-warning-text\" />;\n case \"completed\":\n return <CheckCircle className=\"size-4 text-status-success-text\" />;\n case \"failed\":\n return <AlertCircle className=\"size-4 text-status-error-text\" />;\n default:\n return <Loader2 className=\"size-4 animate-spin text-text-tertiary\" />;\n }\n };\n\n const getStatusColor = () => {\n switch (item.status) {\n case \"uploading\":\n return \"bg-action-primary-bg\";\n case \"paused\":\n return \"bg-status-warning-bg\";\n case \"completed\":\n return \"bg-status-success-bg\";\n case \"failed\":\n return \"bg-status-error-bg\";\n default:\n return \"bg-text-tertiary\";\n }\n };\n\n const formatFileSize = (bytes: number) => {\n if (bytes === 0) return \"0 B\";\n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n };\n\n return (\n <div className=\"bg-bg-elevated border border-border-default rounded-lg p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex-shrink-0 size-10 bg-bg-sunken rounded flex items-center justify-center overflow-hidden\">\n {item.thumbnailUrl ? (\n <img\n src={item.thumbnailUrl}\n alt={item.file.name}\n className=\"w-full h-full object-cover\"\n />\n ) : isImage ? (\n <ImageIcon className=\"size-5 text-text-tertiary\" />\n ) : (\n <div className=\"w-full h-full bg-bg-accent\" />\n )}\n </div>\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center justify-between gap-2 mb-1.5\">\n <span className=\"text-sm font-medium text-text-primary truncate\">\n {item.file.name}\n </span>\n <span className=\"text-xs text-text-secondary whitespace-nowrap\">\n {formatFileSize(item.file.size)}\n </span>\n </div>\n\n <div className=\"relative h-1.5 bg-bg-sunken rounded-full overflow-hidden\">\n <div\n ref={progressRef}\n className={`absolute inset-y-0 left-0 ${getStatusColor()} transition-all duration-300 ease-out rounded-full`}\n style={{ width: `${item.progress}%` }}\n />\n </div>\n\n <div className=\"flex items-center justify-between mt-1.5\">\n <span className=\"text-xs text-text-secondary\">\n {item.status === \"paused\" &&\n tWithFallback(t, \"files.upload.paused\", \"Paused\")}\n {item.status === \"uploading\" && `${item.progress}%`}\n {item.status === \"completed\" &&\n tWithFallback(t, \"files.upload.completedStatus\", \"Completed\")}\n {item.status === \"failed\" &&\n (item.error ||\n tWithFallback(t, \"files.upload.failed\", \"Failed\"))}\n {item.status === \"pending\" &&\n tWithFallback(t, \"files.upload.pendingStatus\", \"Pending...\")}\n </span>\n </div>\n </div>\n\n <div className=\"flex items-center gap-1 flex-shrink-0\">\n {item.status === \"uploading\" && (\n <button\n type=\"button\"\n onClick={() => onPause(item.id)}\n className=\"p-1.5 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors\"\n title={tWithFallback(t, \"files.upload.pause\", \"Pause\")}\n >\n <Pause className=\"size-4\" />\n </button>\n )}\n\n {item.status === \"paused\" && (\n <button\n type=\"button\"\n onClick={() => onResume(item.id)}\n className=\"p-1.5 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors\"\n title={tWithFallback(t, \"files.upload.resume\", \"Resume\")}\n >\n <Play className=\"size-4\" />\n </button>\n )}\n\n {item.status === \"failed\" && (\n <button\n type=\"button\"\n onClick={() => onRetry(item.id)}\n className=\"p-1.5 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors\"\n title={tWithFallback(t, \"files.upload.retry\", \"Retry\")}\n >\n <RotateCcw className=\"size-4\" />\n </button>\n )}\n\n {(item.status === \"pending\" ||\n item.status === \"paused\" ||\n item.status === \"failed\") && (\n <button\n type=\"button\"\n onClick={() => onCancel(item.id)}\n className=\"p-1.5 text-text-secondary hover:text-status-error-text hover:bg-status-error-bg-subtle rounded transition-colors\"\n title={tWithFallback(t, \"files.upload.cancel\", \"Cancel\")}\n >\n <X className=\"size-4\" />\n </button>\n )}\n </div>\n </div>\n </div>\n );\n}\n\ninterface UploadQueueProps {\n items: UploadItem[];\n isOpen: boolean;\n onClose: () => void;\n onPause: (id: string) => void;\n onResume: (id: string) => void;\n onRetry: (id: string) => void;\n onCancel: (id: string) => void;\n}\n\nexport function UploadQueue({\n items,\n isOpen,\n onClose,\n onPause,\n onResume,\n onRetry,\n onCancel,\n}: UploadQueueProps) {\n const { t } = useI18n();\n if (!isOpen) return null;\n\n const completedCount = items.filter((i) => i.status === \"completed\").length;\n const failedCount = items.filter((i) => i.status === \"failed\").length;\n const activeCount = items.filter(\n (i) => i.status === \"uploading\" || i.status === \"pending\",\n ).length;\n\n return (\n <GlassCard\n treatment=\"glass\"\n glow\n className=\"fixed bottom-4 right-4 z-50 w-80 max-w-[90vw] md:w-96\"\n >\n <div className=\"flex items-center justify-between p-3 border-b border-border-seam\">\n <div>\n <h3 className=\"flex items-center gap-2 text-sm font-semibold text-text-primary\">\n {activeCount > 0 && (\n <span\n className=\"size-2 shrink-0 rounded-full bg-action-primary-bg motion-safe:animate-vc-glow-pulse\"\n aria-hidden=\"true\"\n />\n )}\n {tWithFallback(t, \"files.upload.uploads\", \"Uploads\")} (\n {tWithFallback(t, \"files.upload.active\", \"{{count}} uploading\", {\n count: activeCount,\n })}\n )\n </h3>\n {completedCount > 0 && (\n <p className=\"text-xs text-status-success-text\">\n {tWithFallback(\n t,\n \"files.upload.completed\",\n \"{{count}} completed\",\n {\n count: completedCount,\n },\n )}\n </p>\n )}\n {failedCount > 0 && (\n <p className=\"text-xs text-status-error-text\">\n {tWithFallback(\n t,\n \"files.upload.failedCount\",\n \"{{count}} failed\",\n {\n count: failedCount,\n },\n )}\n </p>\n )}\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label={tWithFallback(t, \"files.upload.close\", \"Close uploads\")}\n className=\"p-1 text-text-secondary hover:text-text-primary hover:bg-action-ghost-bg-hover rounded transition-colors\"\n >\n <X className=\"size-4\" />\n </button>\n </div>\n\n <div className=\"max-h-64 overflow-y-auto p-2 space-y-2\">\n {items.length === 0 ? (\n <p className=\"text-sm text-text-secondary text-center py-4\">\n {tWithFallback(t, \"files.upload.noUploads\", \"No uploads\")}\n </p>\n ) : (\n items.map((item) => (\n <UploadProgressBar\n key={item.id}\n item={item}\n onPause={onPause}\n onResume={onResume}\n onRetry={onRetry}\n onCancel={onCancel}\n />\n ))\n )}\n </div>\n </GlassCard>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUploadFile.d.ts","sourceRoot":"","sources":["../../../src/files/hooks/useUploadFile.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,EAAE,MAAM,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,aAAa;
|
|
1
|
+
{"version":3,"file":"useUploadFile.d.ts","sourceRoot":"","sources":["../../../src/files/hooks/useUploadFile.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,EAAE,MAAM,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,aAAa;0BA+BW;QACjC,IAAI,EAAE,IAAI,CAAC;QACX,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;KACzC;;;;;CA4KF,CAAC"}
|
|
@@ -5,12 +5,15 @@ import { computeUploadSha256 as i } from "../utils/uploadDigest.js";
|
|
|
5
5
|
import { useCallback as a, useRef as o, useState as s } from "react";
|
|
6
6
|
//#region src/files/hooks/useUploadFile.ts
|
|
7
7
|
var c = () => {
|
|
8
|
-
let { workspaceId: c } = e(), [l, u] = s(!1), [d, f] = s(null), p = o(null), m = o(!1), [h] = n(), [g] = t({
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
let { workspaceId: c } = e(), [l, u] = s(!1), [d, f] = s(null), p = o(null), m = o(!1), [h] = n(), [g] = t({
|
|
9
|
+
refetchQueries: [
|
|
10
|
+
"GetFilesRootBrowsePage",
|
|
11
|
+
"GetFilesFolderBrowsePage",
|
|
12
|
+
"GetFilesRecentPage",
|
|
13
|
+
"GetFiles"
|
|
14
|
+
],
|
|
15
|
+
onQueryUpdated: (e) => e.options.fetchPolicy !== "standby"
|
|
16
|
+
});
|
|
14
17
|
return {
|
|
15
18
|
mutateAsync: async (e) => {
|
|
16
19
|
let { file: t, folderId: n, onProgress: a } = e, o = t.name.split(".").pop() || "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUploadFile.js","names":[],"sources":["../../../src/files/hooks/useUploadFile.ts"],"sourcesContent":["import { useState, useRef, useCallback } from \"react\";\nimport {\n useInitiateUploadMutation,\n useCompleteUploadMutation,\n} from \"../../generated/wspace-operations\";\nimport { useFilesContext } from \"../providers/FilesProvider\";\nimport { isQuotaExhaustedError } from \"../utils/quotaUtils\";\nimport { computeUploadSha256 } from \"../utils/uploadDigest\";\n\nexport interface InitiateUploadInput {\n fileName: string;\n fileSize: number;\n mimeType: string;\n folderId?: string;\n}\n\nexport interface CompleteUploadInput {\n sessionId: string;\n fileSize: string;\n}\n\nexport interface UploadController {\n pause: () => void;\n isPaused: () => boolean;\n}\n\nexport const useUploadFile = () => {\n const { workspaceId } = useFilesContext();\n const [isUploading, setIsUploading] = useState(false);\n const [uploadError, setUploadError] = useState<Error | null>(null);\n\n const activeXhrRef = useRef<XMLHttpRequest | null>(null);\n const isPausedRef = useRef(false);\n\n const [initiateUploadMutation] = useInitiateUploadMutation();\n const [completeUploadMutation] = useCompleteUploadMutation({\n refetchQueries: [\n \"GetFilesRootBrowsePage\",\n \"GetFilesFolderBrowsePage\",\n \"GetFilesRecentPage\",\n \"GetFiles\",\n ],\n });\n\n const pause = useCallback(() => {\n if (!isPausedRef.current) {\n isPausedRef.current = true;\n activeXhrRef.current?.abort();\n activeXhrRef.current = null;\n }\n }, []);\n\n const isPaused = useCallback(() => isPausedRef.current, []);\n\n const mutateAsync = async (params: {\n file: File;\n folderId?: string;\n onProgress?: (progress: number) => void;\n }) => {\n const { file, folderId, onProgress } = params;\n const extension = file.name.split(\".\").pop() || \"\";\n\n try {\n setIsUploading(true);\n setUploadError(null);\n isPausedRef.current = false;\n\n onProgress?.(0);\n\n // Declare the same exact-byte digest before creating a session and on completion.\n // The Files owner separately records whether storage verified this declaration.\n const sha256Hash = await computeUploadSha256(\n file,\n () => isPausedRef.current,\n );\n if (isPausedRef.current) {\n throw new Error(\"Upload paused\");\n }\n\n const initiateResult = await initiateUploadMutation({\n variables: {\n input: {\n fileName: file.name,\n fileSize: file.size.toString(),\n mimeType: file.type || \"application/octet-stream\",\n extension: extension,\n sha256Hash,\n folderId: folderId || null,\n },\n },\n });\n\n // Check for GraphQL errors FIRST - before checking data\n // This ensures backend error messages are properly surfaced to the user\n if (initiateResult.error) {\n if (isQuotaExhaustedError(initiateResult.error)) {\n throw initiateResult.error;\n }\n const errorMsg = initiateResult.error.message || \"\";\n throw new Error(errorMsg || \"Failed to initiate upload\");\n }\n\n const result = initiateResult.data?.initiateUpload;\n const session = result?.session;\n const uploadUrl = result?.uploadUrl;\n\n if (!session || !uploadUrl) {\n throw new Error(\"Failed to initiate upload session\");\n }\n\n if (isPausedRef.current) {\n throw new Error(\"Upload paused\");\n }\n\n onProgress?.(10);\n\n const uploadResponse = await new Promise<Response>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n activeXhrRef.current = xhr;\n\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable && !isPausedRef.current) {\n const percentComplete = 10 + Math.round((e.loaded / e.total) * 80);\n onProgress?.(percentComplete);\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n if (!isPausedRef.current) {\n onProgress?.(90);\n }\n resolve(\n new Response(xhr.response, {\n status: xhr.status,\n statusText: xhr.statusText,\n headers: new Headers(\n xhr\n .getAllResponseHeaders()\n .split(\"\\r\\n\")\n .reduce(\n (acc, current) => {\n const parts = current.split(\": \");\n if (parts[0]) acc[parts[0]] = parts[1] || \"\";\n return acc;\n },\n {} as Record<string, string>,\n ),\n ),\n }),\n );\n } else {\n reject(new Error(`Upload failed with status ${xhr.status}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n if (!isPausedRef.current) {\n reject(new Error(\"Upload failed\"));\n }\n });\n\n xhr.addEventListener(\"abort\", () => {\n if (isPausedRef.current) {\n reject(new Error(\"Upload paused\"));\n } else {\n reject(new Error(\"Upload aborted\"));\n }\n });\n\n xhr.open(\"PUT\", uploadUrl);\n xhr.setRequestHeader(\"Content-Type\", file.type);\n xhr.send(file);\n });\n\n if (!uploadResponse.ok) {\n throw new Error(\"Failed to upload file to S3\");\n }\n\n if (isPausedRef.current) {\n throw new Error(\"Upload paused\");\n }\n\n const completeResult = await completeUploadMutation({\n variables: {\n input: {\n sessionId: session.id,\n fileSize: file.size.toString(),\n sha256Hash,\n folderId: folderId || null,\n },\n },\n });\n\n if (completeResult.error) {\n if (isQuotaExhaustedError(completeResult.error)) {\n throw completeResult.error;\n }\n const errorMsg = completeResult.error.message || \"\";\n throw new Error(\n completeResult.error.message || \"Failed to complete upload\",\n );\n }\n\n const uploadedFile = completeResult.data?.completeUpload?.file;\n if (!uploadedFile) {\n throw new Error(\n \"Upload completed but file data was not returned. The file may not have been created properly.\",\n );\n }\n\n onProgress?.(100);\n return uploadedFile;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(\"Upload failed\");\n setUploadError(err);\n throw err;\n } finally {\n setIsUploading(false);\n activeXhrRef.current = null;\n }\n };\n\n return {\n mutateAsync,\n isPending: isUploading,\n error: uploadError,\n pause,\n isPaused,\n };\n};\n"],"mappings":";;;;;;AA0BA,IAAa,UAAsB;CACjC,IAAM,EAAE,mBAAgB,GAAiB,EACnC,CAAC,GAAa,KAAkB,EAAS,GAAM,EAC/C,CAAC,GAAa,KAAkB,EAAuB,KAAK,EAE5D,IAAe,EAA8B,KAAK,EAClD,IAAc,EAAO,GAAM,EAE3B,CAAC,KAA0B,GAA2B,EACtD,CAAC,KAA0B,EAA0B
|
|
1
|
+
{"version":3,"file":"useUploadFile.js","names":[],"sources":["../../../src/files/hooks/useUploadFile.ts"],"sourcesContent":["import { useState, useRef, useCallback } from \"react\";\nimport {\n useInitiateUploadMutation,\n useCompleteUploadMutation,\n} from \"../../generated/wspace-operations\";\nimport { useFilesContext } from \"../providers/FilesProvider\";\nimport { isQuotaExhaustedError } from \"../utils/quotaUtils\";\nimport { computeUploadSha256 } from \"../utils/uploadDigest\";\n\nexport interface InitiateUploadInput {\n fileName: string;\n fileSize: number;\n mimeType: string;\n folderId?: string;\n}\n\nexport interface CompleteUploadInput {\n sessionId: string;\n fileSize: string;\n}\n\nexport interface UploadController {\n pause: () => void;\n isPaused: () => boolean;\n}\n\nexport const useUploadFile = () => {\n const { workspaceId } = useFilesContext();\n const [isUploading, setIsUploading] = useState(false);\n const [uploadError, setUploadError] = useState<Error | null>(null);\n\n const activeXhrRef = useRef<XMLHttpRequest | null>(null);\n const isPausedRef = useRef(false);\n\n const [initiateUploadMutation] = useInitiateUploadMutation();\n const [completeUploadMutation] = useCompleteUploadMutation({\n refetchQueries: [\n \"GetFilesRootBrowsePage\",\n \"GetFilesFolderBrowsePage\",\n \"GetFilesRecentPage\",\n \"GetFiles\",\n ],\n // Named refetches also include skipped (standby) Apollo observables.\n // The root browser keeps a skipped folder query with an empty folder ID.\n onQueryUpdated: (query) => query.options.fetchPolicy !== \"standby\",\n });\n\n const pause = useCallback(() => {\n if (!isPausedRef.current) {\n isPausedRef.current = true;\n activeXhrRef.current?.abort();\n activeXhrRef.current = null;\n }\n }, []);\n\n const isPaused = useCallback(() => isPausedRef.current, []);\n\n const mutateAsync = async (params: {\n file: File;\n folderId?: string;\n onProgress?: (progress: number) => void;\n }) => {\n const { file, folderId, onProgress } = params;\n const extension = file.name.split(\".\").pop() || \"\";\n\n try {\n setIsUploading(true);\n setUploadError(null);\n isPausedRef.current = false;\n\n onProgress?.(0);\n\n // Declare the same exact-byte digest before creating a session and on completion.\n // The Files owner separately records whether storage verified this declaration.\n const sha256Hash = await computeUploadSha256(\n file,\n () => isPausedRef.current,\n );\n if (isPausedRef.current) {\n throw new Error(\"Upload paused\");\n }\n\n const initiateResult = await initiateUploadMutation({\n variables: {\n input: {\n fileName: file.name,\n fileSize: file.size.toString(),\n mimeType: file.type || \"application/octet-stream\",\n extension: extension,\n sha256Hash,\n folderId: folderId || null,\n },\n },\n });\n\n // Check for GraphQL errors FIRST - before checking data\n // This ensures backend error messages are properly surfaced to the user\n if (initiateResult.error) {\n if (isQuotaExhaustedError(initiateResult.error)) {\n throw initiateResult.error;\n }\n const errorMsg = initiateResult.error.message || \"\";\n throw new Error(errorMsg || \"Failed to initiate upload\");\n }\n\n const result = initiateResult.data?.initiateUpload;\n const session = result?.session;\n const uploadUrl = result?.uploadUrl;\n\n if (!session || !uploadUrl) {\n throw new Error(\"Failed to initiate upload session\");\n }\n\n if (isPausedRef.current) {\n throw new Error(\"Upload paused\");\n }\n\n onProgress?.(10);\n\n const uploadResponse = await new Promise<Response>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n activeXhrRef.current = xhr;\n\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable && !isPausedRef.current) {\n const percentComplete = 10 + Math.round((e.loaded / e.total) * 80);\n onProgress?.(percentComplete);\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n if (!isPausedRef.current) {\n onProgress?.(90);\n }\n resolve(\n new Response(xhr.response, {\n status: xhr.status,\n statusText: xhr.statusText,\n headers: new Headers(\n xhr\n .getAllResponseHeaders()\n .split(\"\\r\\n\")\n .reduce(\n (acc, current) => {\n const parts = current.split(\": \");\n if (parts[0]) acc[parts[0]] = parts[1] || \"\";\n return acc;\n },\n {} as Record<string, string>,\n ),\n ),\n }),\n );\n } else {\n reject(new Error(`Upload failed with status ${xhr.status}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n if (!isPausedRef.current) {\n reject(new Error(\"Upload failed\"));\n }\n });\n\n xhr.addEventListener(\"abort\", () => {\n if (isPausedRef.current) {\n reject(new Error(\"Upload paused\"));\n } else {\n reject(new Error(\"Upload aborted\"));\n }\n });\n\n xhr.open(\"PUT\", uploadUrl);\n xhr.setRequestHeader(\"Content-Type\", file.type);\n xhr.send(file);\n });\n\n if (!uploadResponse.ok) {\n throw new Error(\"Failed to upload file to S3\");\n }\n\n if (isPausedRef.current) {\n throw new Error(\"Upload paused\");\n }\n\n const completeResult = await completeUploadMutation({\n variables: {\n input: {\n sessionId: session.id,\n fileSize: file.size.toString(),\n sha256Hash,\n folderId: folderId || null,\n },\n },\n });\n\n if (completeResult.error) {\n if (isQuotaExhaustedError(completeResult.error)) {\n throw completeResult.error;\n }\n const errorMsg = completeResult.error.message || \"\";\n throw new Error(\n completeResult.error.message || \"Failed to complete upload\",\n );\n }\n\n const uploadedFile = completeResult.data?.completeUpload?.file;\n if (!uploadedFile) {\n throw new Error(\n \"Upload completed but file data was not returned. The file may not have been created properly.\",\n );\n }\n\n onProgress?.(100);\n return uploadedFile;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(\"Upload failed\");\n setUploadError(err);\n throw err;\n } finally {\n setIsUploading(false);\n activeXhrRef.current = null;\n }\n };\n\n return {\n mutateAsync,\n isPending: isUploading,\n error: uploadError,\n pause,\n isPaused,\n };\n};\n"],"mappings":"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"}
|
|
@@ -359,16 +359,20 @@ export declare const enTranslations: {
|
|
|
359
359
|
upload: {
|
|
360
360
|
active: string;
|
|
361
361
|
cancel: string;
|
|
362
|
+
close: string;
|
|
362
363
|
completed: string;
|
|
364
|
+
completedStatus: string;
|
|
363
365
|
errors: {
|
|
364
366
|
failed: string;
|
|
365
367
|
quotaExceeded: string;
|
|
366
368
|
};
|
|
367
369
|
failed: string;
|
|
370
|
+
failedCount: string;
|
|
368
371
|
noUploads: string;
|
|
369
372
|
pause: string;
|
|
370
373
|
paused: string;
|
|
371
374
|
pending: string;
|
|
375
|
+
pendingStatus: string;
|
|
372
376
|
resume: string;
|
|
373
377
|
retry: string;
|
|
374
378
|
uploads: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/translations/en.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/translations/en.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgZ1B,CAAC"}
|
package/dist/translations/en.js
CHANGED
|
@@ -307,16 +307,20 @@ var e = { files: {
|
|
|
307
307
|
upload: {
|
|
308
308
|
active: "{{count}} uploading",
|
|
309
309
|
cancel: "Cancel",
|
|
310
|
+
close: "Close uploads",
|
|
310
311
|
completed: "{{count}} completed",
|
|
312
|
+
completedStatus: "Completed",
|
|
311
313
|
errors: {
|
|
312
314
|
failed: "Upload failed",
|
|
313
315
|
quotaExceeded: "Storage quota exceeded. Please upgrade your plan or delete files."
|
|
314
316
|
},
|
|
315
317
|
failed: "Upload failed",
|
|
318
|
+
failedCount: "{{count}} failed",
|
|
316
319
|
noUploads: "No uploads in progress",
|
|
317
320
|
pause: "Pause",
|
|
318
321
|
paused: "Paused",
|
|
319
322
|
pending: "{{count}} pending",
|
|
323
|
+
pendingStatus: "Pending...",
|
|
320
324
|
resume: "Resume",
|
|
321
325
|
retry: "Retry",
|
|
322
326
|
uploads: "Uploads"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.js","names":[],"sources":["../../src/translations/en.ts"],"sourcesContent":["/**\n * English fallback translations for microfe-files.\n *\n * Keys use dot-notation (e.g., 'files.browser.loading') which the\n * I18nProvider resolves against this nested object structure.\n *\n * This file is the source of truth for all translation keys used in this MFE.\n * Register it with the host shell's AppShellProvider.fallbackTranslations\n * to enable offline/fallback support.\n */\nexport const enTranslations = {\n files: {\n actionMenu: {\n moreActions: \"More actions\",\n },\n nav: {\n allFiles: \"All Files\",\n statusReady: \"Files Ready\",\n },\n root: {\n errorFallback:\n \"Something went wrong loading this module. Please refresh the page.\",\n },\n storage: {\n almostFull: \"Storage almost full.\",\n almostFullNoLimit: \"{{used}} used.\",\n almostFullWithLimit: \"{{used}} of {{limit}} used ({{percent}}%).\",\n deleteOrUpgrade: \"Consider deleting files or upgrading your plan.\",\n freeUpOrUpgrade: \"Delete files to free up space or upgrade your plan.\",\n full: \"Storage full.\",\n fullNoLimit: \"{{used}} used — no space left.\",\n fullWithLimit: \"{{used}} of {{limit}} used — no space left.\",\n label: \"Storage\",\n unit: \"MB\",\n },\n browser: {\n actions: {\n export: \"Export\",\n exportTitle: \"Export selected items\",\n goToRoot: \"Go to root folder\",\n newFolder: \"New Folder\",\n selectAll: \"Select all\",\n uploadFiles: \"Upload files\",\n uploadFolder: \"Upload folder\",\n uploadFolderTitle: \"Upload folder\",\n },\n delete: \"Delete\",\n items: \"items\",\n loading: \"Loading files…\",\n modified: \"Modified\",\n name: \"Name\",\n openFolder: \"Open folder\",\n owner: \"Owner\",\n rename: \"Rename\",\n retry: \"Retry\",\n rootLabel: \"My Drive\",\n search: {\n clear: \"Clear search\",\n showingResults: 'Showing {{count}} results for \"{{query}}\"',\n },\n selection: {\n selectedCount: \"{{count}} selected\",\n actions: {\n restore: \"Restore\",\n },\n },\n size: \"Size\",\n tabs: {\n all: \"All Files\",\n bin: \"Bin\",\n recent: \"Recent\",\n starred: \"Starred\",\n },\n view: {\n grid: \"Grid view\",\n list: \"List view\",\n },\n workspace: {\n notSelected: \"No workspace selected\",\n waiting: \"Waiting for workspace...\",\n },\n loadError: \"Failed to load files\",\n unexpectedError: \"An unexpected error occurred\",\n },\n card: {\n activity: \"Activity\",\n addToStarred: \"Add to starred\",\n delete: \"Delete\",\n details: \"Details\",\n download: \"Download\",\n favorite: \"Favorite\",\n makeCopy: \"Make a copy\",\n moveTo: \"Move to\",\n rename: \"Rename\",\n restore: \"Restore\",\n share: \"Share\",\n shared: \"Shared\",\n unfavorite: \"Remove from starred\",\n },\n common: {\n actions: {\n cancel: \"Cancel\",\n clear: \"Clear\",\n close: \"Close\",\n create: \"Create\",\n delete: \"Delete\",\n deletePermanently: \"Delete permanently\",\n done: \"Done\",\n move: \"Move\",\n rename: \"Rename\",\n share: \"Share\",\n },\n },\n confirm: {\n bulkPermanentDelete: {\n description:\n \"This action cannot be undone. All selected items will be permanently deleted.\",\n title: \"Permanently delete {{count}} items\",\n },\n deleteFile: {\n description:\n \"Are you sure you want to delete this file? It will be moved to the bin.\",\n title: \"Delete file\",\n },\n deleteFolder: {\n description:\n \"Are you sure you want to delete this folder? It will be moved to the bin.\",\n title: \"Delete folder\",\n },\n permanentDeleteFile: {\n description:\n \"This file will be permanently deleted. This action cannot be undone.\",\n title: \"Permanently delete file\",\n },\n permanentDeleteFolder: {\n description:\n \"This folder and all its contents will be permanently deleted. This action cannot be undone.\",\n title: \"Permanently delete folder\",\n },\n },\n contextMenu: {\n activity: \"Activity\",\n addToStarred: \"Add to starred\",\n delete: \"Delete\",\n download: \"Download\",\n fileInfo: \"File information\",\n folderInfo: \"Folder information\",\n moveTo: \"Move to\",\n removeStar: \"Remove star\",\n rename: \"Rename\",\n restore: \"Restore\",\n share: \"Share\",\n },\n copyDialog: {\n copy: \"Copy\",\n copyHere: \"Copy here\",\n copyOf: \"Copy of\",\n copying: \"Copying...\",\n makeCopyOf: 'Make a copy of \"{{name}}\"',\n myDrive: \"My Drive\",\n name: \"Name\",\n title: \"Copy item\",\n },\n empty: {\n all: {\n description: \"Upload files or create folders to get started\",\n title: \"No files or folders yet\",\n },\n bin: {\n description: \"Deleted files and folders will appear here\",\n title: \"Bin is empty\",\n },\n newFolder: \"New Folder\",\n recent: {\n description: \"Files you recently opened will appear here\",\n title: \"No recent files\",\n },\n starred: {\n description: \"Star files and folders to find them easily\",\n title: \"No starred items\",\n },\n uploadFiles: \"Upload Files\",\n },\n file: {\n copy: {\n success: '\"{{name}}\" copied',\n },\n delete: {\n success: '\"{{name}}\" deleted',\n },\n download: {\n success: \"Downloaded {{name}}\",\n },\n errors: {\n copyFailed: \"Failed to copy file\",\n deleteFailed: \"Failed to delete file\",\n downloadFailed: \"Failed to download file\",\n downloadUrlUnavailable: \"Download URL is not available\",\n moveFailed: \"Failed to move file\",\n permanentDeleteFailed: \"Failed to permanently delete file\",\n renameFailed: \"Failed to rename file\",\n restoreFailed: \"Failed to restore file\",\n starFailed: \"Failed to update star status\",\n },\n move: {\n success: '\"{{name}}\" moved',\n },\n permanentDelete: {\n success: '\"{{name}}\" permanently deleted',\n },\n rename: {\n success: 'Renamed \"{{name}}\"',\n },\n restore: {\n success: '\"{{name}}\" restored',\n },\n },\n folder: {\n errors: {\n copyUnsupported: \"Copying folders is not supported\",\n createFailed: \"Failed to create folder\",\n deleteFailed: \"Failed to delete folder\",\n moveFailed: \"Failed to move folder\",\n permanentDeleteFailed: \"Failed to permanently delete folder\",\n renameFailed: \"Failed to rename folder\",\n restoreFailed: \"Failed to restore folder\",\n starFailed: \"Failed to update star status\",\n },\n item: \"item\",\n move: {\n success: '\"{{name}}\" moved',\n },\n delete: {\n success: '\"{{name}}\" deleted',\n },\n permanentDelete: {\n success: '\"{{name}}\" permanently deleted',\n },\n restore: {\n success: '\"{{name}}\" restored',\n },\n rename: {\n success: 'Renamed \"{{name}}\"',\n },\n },\n info: {\n contents: \"Contents\",\n created: \"Created\",\n fileInfo: \"File information\",\n files: \"Files\",\n folder: \"Folder\",\n folderInfo: \"Folder information\",\n folders: \"Folders\",\n modified: \"Modified\",\n no: \"No\",\n owner: \"Owner\",\n path: \"Path\",\n properties: \"Properties\",\n size: \"Size\",\n starred: \"Starred\",\n status: \"Status\",\n type: \"Type\",\n unknown: \"Unknown\",\n visibility: \"Visibility\",\n yes: \"Yes\",\n },\n item: {\n errors: {\n moveFailed: \"Failed to move item\",\n renameFailed: \"Failed to rename item\",\n },\n },\n moveDialog: {\n actions: {\n moving: \"Moving...\",\n },\n title: \"Move item\",\n },\n preview: {\n addStar: \"Add to starred\",\n removeStar: \"Remove from starred\",\n image: {\n failedToLoad: \"Failed to load image\",\n fitToScreen: \"Fit to screen\",\n loadError: \"Failed to load image from URL\",\n openInNewTab: \"Open in new tab\",\n rotate: \"Rotate 90°\",\n zoomIn: \"Zoom in\",\n zoomOut: \"Zoom out\",\n },\n pdf: {\n browserUnsupported:\n \"Your browser may not support embedded PDF viewing.\",\n documentLabel: \"PDF Document\",\n download: \"Download PDF\",\n unableToDisplay: \"Unable to display PDF\",\n zoomIn: \"Zoom in\",\n zoomOut: \"Zoom out\",\n },\n video: {\n fullscreen: \"Fullscreen\",\n mute: \"Mute\",\n muteVideo: \"Mute video\",\n openFullscreen: \"Open fullscreen\",\n pause: \"Pause\",\n pauseVideo: \"Pause video\",\n play: \"Play\",\n playVideo: \"Play video\",\n seek: \"Seek\",\n unmute: \"Unmute\",\n unmuteVideo: \"Unmute video\",\n volume: \"Volume\",\n },\n audio: {\n mute: \"Mute\",\n pause: \"Pause\",\n play: \"Play\",\n seek: \"Seek\",\n unmute: \"Unmute\",\n volume: \"Volume\",\n },\n code: {\n copied: \"Copied!\",\n copy: \"Copy\",\n copyCode: \"Copy code\",\n copyCodeContent: \"Copy code content\",\n disableWordWrap: \"Disable word wrap\",\n enableWordWrap: \"Enable word wrap\",\n lines: \"lines\",\n loading: \"Loading code...\",\n text: \"Text\",\n },\n text: {\n copied: \"Copied!\",\n copy: \"Copy\",\n copyText: \"Copy text\",\n copyTextContent: \"Copy text content\",\n disableWordWrap: \"Disable word wrap\",\n enableWordWrap: \"Enable word wrap\",\n lines: \"lines\",\n loading: \"Loading text...\",\n match: \"match\",\n matches: \"matches\",\n search: \"Search\",\n searchAria: \"Search text\",\n searchPlaceholder: \"Search...\",\n searchWithinFile: \"Search within text file\",\n },\n },\n search: {\n filters: {\n title: \"Search filters\",\n },\n input: {\n placeholder: \"Search files...\",\n },\n },\n share: {\n back: \"Back to files\",\n password: {\n label: \"Password\",\n },\n title: \"Share\",\n unlock: \"Enter password to access\",\n },\n upload: {\n active: \"{{count}} uploading\",\n cancel: \"Cancel\",\n completed: \"{{count}} completed\",\n errors: {\n failed: \"Upload failed\",\n quotaExceeded:\n \"Storage quota exceeded. Please upgrade your plan or delete files.\",\n },\n failed: \"Upload failed\",\n noUploads: \"No uploads in progress\",\n pause: \"Pause\",\n paused: \"Paused\",\n pending: \"{{count}} pending\",\n resume: \"Resume\",\n retry: \"Retry\",\n uploads: \"Uploads\",\n },\n version: {\n deleteVersion: \"Delete version\",\n major: \"Major version\",\n restore: \"Restore\",\n restoreVersion: \"Restore this version\",\n restoredFrom: \"Restored from version {{version}}\",\n total: \"{{count}} versions\",\n version: \"Version\",\n versionDeleted: \"Version deleted\",\n versionRestored: \"Version restored\",\n versions: \"Versions\",\n },\n workspace: {\n errors: {\n notSelected: \"No workspace selected\",\n },\n },\n bulk: {\n permanentDelete: {\n success: \"Permanently deleted {{count}} items\",\n },\n },\n },\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"en.js","names":[],"sources":["../../src/translations/en.ts"],"sourcesContent":["/**\n * English fallback translations for microfe-files.\n *\n * Keys use dot-notation (e.g., 'files.browser.loading') which the\n * I18nProvider resolves against this nested object structure.\n *\n * This file is the source of truth for all translation keys used in this MFE.\n * Register it with the host shell's AppShellProvider.fallbackTranslations\n * to enable offline/fallback support.\n */\nexport const enTranslations = {\n files: {\n actionMenu: {\n moreActions: \"More actions\",\n },\n nav: {\n allFiles: \"All Files\",\n statusReady: \"Files Ready\",\n },\n root: {\n errorFallback:\n \"Something went wrong loading this module. Please refresh the page.\",\n },\n storage: {\n almostFull: \"Storage almost full.\",\n almostFullNoLimit: \"{{used}} used.\",\n almostFullWithLimit: \"{{used}} of {{limit}} used ({{percent}}%).\",\n deleteOrUpgrade: \"Consider deleting files or upgrading your plan.\",\n freeUpOrUpgrade: \"Delete files to free up space or upgrade your plan.\",\n full: \"Storage full.\",\n fullNoLimit: \"{{used}} used — no space left.\",\n fullWithLimit: \"{{used}} of {{limit}} used — no space left.\",\n label: \"Storage\",\n unit: \"MB\",\n },\n browser: {\n actions: {\n export: \"Export\",\n exportTitle: \"Export selected items\",\n goToRoot: \"Go to root folder\",\n newFolder: \"New Folder\",\n selectAll: \"Select all\",\n uploadFiles: \"Upload files\",\n uploadFolder: \"Upload folder\",\n uploadFolderTitle: \"Upload folder\",\n },\n delete: \"Delete\",\n items: \"items\",\n loading: \"Loading files…\",\n modified: \"Modified\",\n name: \"Name\",\n openFolder: \"Open folder\",\n owner: \"Owner\",\n rename: \"Rename\",\n retry: \"Retry\",\n rootLabel: \"My Drive\",\n search: {\n clear: \"Clear search\",\n showingResults: 'Showing {{count}} results for \"{{query}}\"',\n },\n selection: {\n selectedCount: \"{{count}} selected\",\n actions: {\n restore: \"Restore\",\n },\n },\n size: \"Size\",\n tabs: {\n all: \"All Files\",\n bin: \"Bin\",\n recent: \"Recent\",\n starred: \"Starred\",\n },\n view: {\n grid: \"Grid view\",\n list: \"List view\",\n },\n workspace: {\n notSelected: \"No workspace selected\",\n waiting: \"Waiting for workspace...\",\n },\n loadError: \"Failed to load files\",\n unexpectedError: \"An unexpected error occurred\",\n },\n card: {\n activity: \"Activity\",\n addToStarred: \"Add to starred\",\n delete: \"Delete\",\n details: \"Details\",\n download: \"Download\",\n favorite: \"Favorite\",\n makeCopy: \"Make a copy\",\n moveTo: \"Move to\",\n rename: \"Rename\",\n restore: \"Restore\",\n share: \"Share\",\n shared: \"Shared\",\n unfavorite: \"Remove from starred\",\n },\n common: {\n actions: {\n cancel: \"Cancel\",\n clear: \"Clear\",\n close: \"Close\",\n create: \"Create\",\n delete: \"Delete\",\n deletePermanently: \"Delete permanently\",\n done: \"Done\",\n move: \"Move\",\n rename: \"Rename\",\n share: \"Share\",\n },\n },\n confirm: {\n bulkPermanentDelete: {\n description:\n \"This action cannot be undone. All selected items will be permanently deleted.\",\n title: \"Permanently delete {{count}} items\",\n },\n deleteFile: {\n description:\n \"Are you sure you want to delete this file? It will be moved to the bin.\",\n title: \"Delete file\",\n },\n deleteFolder: {\n description:\n \"Are you sure you want to delete this folder? It will be moved to the bin.\",\n title: \"Delete folder\",\n },\n permanentDeleteFile: {\n description:\n \"This file will be permanently deleted. This action cannot be undone.\",\n title: \"Permanently delete file\",\n },\n permanentDeleteFolder: {\n description:\n \"This folder and all its contents will be permanently deleted. This action cannot be undone.\",\n title: \"Permanently delete folder\",\n },\n },\n contextMenu: {\n activity: \"Activity\",\n addToStarred: \"Add to starred\",\n delete: \"Delete\",\n download: \"Download\",\n fileInfo: \"File information\",\n folderInfo: \"Folder information\",\n moveTo: \"Move to\",\n removeStar: \"Remove star\",\n rename: \"Rename\",\n restore: \"Restore\",\n share: \"Share\",\n },\n copyDialog: {\n copy: \"Copy\",\n copyHere: \"Copy here\",\n copyOf: \"Copy of\",\n copying: \"Copying...\",\n makeCopyOf: 'Make a copy of \"{{name}}\"',\n myDrive: \"My Drive\",\n name: \"Name\",\n title: \"Copy item\",\n },\n empty: {\n all: {\n description: \"Upload files or create folders to get started\",\n title: \"No files or folders yet\",\n },\n bin: {\n description: \"Deleted files and folders will appear here\",\n title: \"Bin is empty\",\n },\n newFolder: \"New Folder\",\n recent: {\n description: \"Files you recently opened will appear here\",\n title: \"No recent files\",\n },\n starred: {\n description: \"Star files and folders to find them easily\",\n title: \"No starred items\",\n },\n uploadFiles: \"Upload Files\",\n },\n file: {\n copy: {\n success: '\"{{name}}\" copied',\n },\n delete: {\n success: '\"{{name}}\" deleted',\n },\n download: {\n success: \"Downloaded {{name}}\",\n },\n errors: {\n copyFailed: \"Failed to copy file\",\n deleteFailed: \"Failed to delete file\",\n downloadFailed: \"Failed to download file\",\n downloadUrlUnavailable: \"Download URL is not available\",\n moveFailed: \"Failed to move file\",\n permanentDeleteFailed: \"Failed to permanently delete file\",\n renameFailed: \"Failed to rename file\",\n restoreFailed: \"Failed to restore file\",\n starFailed: \"Failed to update star status\",\n },\n move: {\n success: '\"{{name}}\" moved',\n },\n permanentDelete: {\n success: '\"{{name}}\" permanently deleted',\n },\n rename: {\n success: 'Renamed \"{{name}}\"',\n },\n restore: {\n success: '\"{{name}}\" restored',\n },\n },\n folder: {\n errors: {\n copyUnsupported: \"Copying folders is not supported\",\n createFailed: \"Failed to create folder\",\n deleteFailed: \"Failed to delete folder\",\n moveFailed: \"Failed to move folder\",\n permanentDeleteFailed: \"Failed to permanently delete folder\",\n renameFailed: \"Failed to rename folder\",\n restoreFailed: \"Failed to restore folder\",\n starFailed: \"Failed to update star status\",\n },\n item: \"item\",\n move: {\n success: '\"{{name}}\" moved',\n },\n delete: {\n success: '\"{{name}}\" deleted',\n },\n permanentDelete: {\n success: '\"{{name}}\" permanently deleted',\n },\n restore: {\n success: '\"{{name}}\" restored',\n },\n rename: {\n success: 'Renamed \"{{name}}\"',\n },\n },\n info: {\n contents: \"Contents\",\n created: \"Created\",\n fileInfo: \"File information\",\n files: \"Files\",\n folder: \"Folder\",\n folderInfo: \"Folder information\",\n folders: \"Folders\",\n modified: \"Modified\",\n no: \"No\",\n owner: \"Owner\",\n path: \"Path\",\n properties: \"Properties\",\n size: \"Size\",\n starred: \"Starred\",\n status: \"Status\",\n type: \"Type\",\n unknown: \"Unknown\",\n visibility: \"Visibility\",\n yes: \"Yes\",\n },\n item: {\n errors: {\n moveFailed: \"Failed to move item\",\n renameFailed: \"Failed to rename item\",\n },\n },\n moveDialog: {\n actions: {\n moving: \"Moving...\",\n },\n title: \"Move item\",\n },\n preview: {\n addStar: \"Add to starred\",\n removeStar: \"Remove from starred\",\n image: {\n failedToLoad: \"Failed to load image\",\n fitToScreen: \"Fit to screen\",\n loadError: \"Failed to load image from URL\",\n openInNewTab: \"Open in new tab\",\n rotate: \"Rotate 90°\",\n zoomIn: \"Zoom in\",\n zoomOut: \"Zoom out\",\n },\n pdf: {\n browserUnsupported:\n \"Your browser may not support embedded PDF viewing.\",\n documentLabel: \"PDF Document\",\n download: \"Download PDF\",\n unableToDisplay: \"Unable to display PDF\",\n zoomIn: \"Zoom in\",\n zoomOut: \"Zoom out\",\n },\n video: {\n fullscreen: \"Fullscreen\",\n mute: \"Mute\",\n muteVideo: \"Mute video\",\n openFullscreen: \"Open fullscreen\",\n pause: \"Pause\",\n pauseVideo: \"Pause video\",\n play: \"Play\",\n playVideo: \"Play video\",\n seek: \"Seek\",\n unmute: \"Unmute\",\n unmuteVideo: \"Unmute video\",\n volume: \"Volume\",\n },\n audio: {\n mute: \"Mute\",\n pause: \"Pause\",\n play: \"Play\",\n seek: \"Seek\",\n unmute: \"Unmute\",\n volume: \"Volume\",\n },\n code: {\n copied: \"Copied!\",\n copy: \"Copy\",\n copyCode: \"Copy code\",\n copyCodeContent: \"Copy code content\",\n disableWordWrap: \"Disable word wrap\",\n enableWordWrap: \"Enable word wrap\",\n lines: \"lines\",\n loading: \"Loading code...\",\n text: \"Text\",\n },\n text: {\n copied: \"Copied!\",\n copy: \"Copy\",\n copyText: \"Copy text\",\n copyTextContent: \"Copy text content\",\n disableWordWrap: \"Disable word wrap\",\n enableWordWrap: \"Enable word wrap\",\n lines: \"lines\",\n loading: \"Loading text...\",\n match: \"match\",\n matches: \"matches\",\n search: \"Search\",\n searchAria: \"Search text\",\n searchPlaceholder: \"Search...\",\n searchWithinFile: \"Search within text file\",\n },\n },\n search: {\n filters: {\n title: \"Search filters\",\n },\n input: {\n placeholder: \"Search files...\",\n },\n },\n share: {\n back: \"Back to files\",\n password: {\n label: \"Password\",\n },\n title: \"Share\",\n unlock: \"Enter password to access\",\n },\n upload: {\n active: \"{{count}} uploading\",\n cancel: \"Cancel\",\n close: \"Close uploads\",\n completed: \"{{count}} completed\",\n completedStatus: \"Completed\",\n errors: {\n failed: \"Upload failed\",\n quotaExceeded:\n \"Storage quota exceeded. Please upgrade your plan or delete files.\",\n },\n failed: \"Upload failed\",\n failedCount: \"{{count}} failed\",\n noUploads: \"No uploads in progress\",\n pause: \"Pause\",\n paused: \"Paused\",\n pending: \"{{count}} pending\",\n pendingStatus: \"Pending...\",\n resume: \"Resume\",\n retry: \"Retry\",\n uploads: \"Uploads\",\n },\n version: {\n deleteVersion: \"Delete version\",\n major: \"Major version\",\n restore: \"Restore\",\n restoreVersion: \"Restore this version\",\n restoredFrom: \"Restored from version {{version}}\",\n total: \"{{count}} versions\",\n version: \"Version\",\n versionDeleted: \"Version deleted\",\n versionRestored: \"Version restored\",\n versions: \"Versions\",\n },\n workspace: {\n errors: {\n notSelected: \"No workspace selected\",\n },\n },\n bulk: {\n permanentDelete: {\n success: \"Permanently deleted {{count}} items\",\n },\n },\n },\n};\n"],"mappings":"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"}
|