@pallasoft/ps-file-components 1.0.0 → 1.2.0
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/components/index.d.ts +12 -0
- package/dist/components/index.js +28 -0
- package/dist/components/ps-file-delete-confirm.js +1 -1
- package/dist/components/ps-file-icon-button.d.ts +12 -0
- package/dist/components/ps-file-icon-button.js +13 -0
- package/dist/components/ps-file-list.js +2 -2
- package/dist/components/ps-file-viewer-button.d.ts +2 -1
- package/dist/components/ps-progress-bar.d.ts +2 -1
- package/dist/components/ps-progress-bar.js +2 -6
- package/dist/components/ps-upload-modal.js +2 -5
- package/dist/components/ps-upload-row.js +6 -10
- package/dist/components/viewers/index.d.ts +8 -0
- package/dist/components/viewers/index.js +24 -0
- package/dist/components/viewers/ps-pdf-viewer.js +0 -4
- package/dist/constants/index.d.ts +15 -0
- package/dist/constants/index.js +31 -0
- package/dist/constants/ps-file-icon-button-classes.d.ts +2 -0
- package/dist/constants/ps-file-icon-button-classes.js +7 -0
- package/dist/constants/ps-file-viewer-labels.d.ts +2 -2
- package/dist/constants/ps-file-viewer-labels.js +2 -2
- package/dist/constants/ps-progress-tone-classes.d.ts +2 -0
- package/dist/constants/ps-progress-tone-classes.js +8 -0
- package/dist/constants/ps-upload-labels.d.ts +7 -5
- package/dist/constants/ps-upload-labels.js +7 -5
- package/dist/constants/ps-upload-status-tones.d.ts +2 -1
- package/dist/esm/components/index.js +12 -0
- package/dist/esm/components/ps-file-delete-confirm.js +1 -1
- package/dist/esm/components/ps-file-icon-button.js +9 -0
- package/dist/esm/components/ps-file-list.js +3 -3
- package/dist/esm/components/ps-progress-bar.js +2 -6
- package/dist/esm/components/ps-upload-modal.js +2 -5
- package/dist/esm/components/ps-upload-row.js +6 -10
- package/dist/esm/components/viewers/index.js +8 -0
- package/dist/esm/components/viewers/ps-pdf-viewer.js +0 -4
- package/dist/esm/constants/index.js +15 -0
- package/dist/esm/constants/ps-file-icon-button-classes.js +4 -0
- package/dist/esm/constants/ps-file-viewer-labels.js +2 -2
- package/dist/esm/constants/ps-progress-tone-classes.js +5 -0
- package/dist/esm/constants/ps-upload-labels.js +7 -5
- package/dist/esm/hooks/index.js +4 -0
- package/dist/esm/index.js +5 -62
- package/dist/esm/models/index.js +23 -0
- package/dist/esm/models/ps-file-icon-button-tone.js +1 -0
- package/dist/esm/models/ps-file-viewer-button-tone.js +1 -0
- package/dist/esm/models/ps-progress-tone.js +1 -0
- package/dist/esm/models/ps-xhr-response-type.js +1 -0
- package/dist/esm/services/index.js +8 -0
- package/dist/esm/services/ps-pdf-service.js +5 -2
- package/dist/esm/services/ps-xhr-upload-service.js +3 -2
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.js +20 -0
- package/dist/index.d.ts +5 -62
- package/dist/index.js +5 -62
- package/dist/models/index.d.ts +23 -0
- package/dist/models/index.js +39 -0
- package/dist/models/ps-file-icon-button-tone.d.ts +1 -0
- package/dist/models/ps-file-icon-button-tone.js +2 -0
- package/dist/models/ps-file-viewer-button-tone.d.ts +1 -0
- package/dist/models/ps-file-viewer-button-tone.js +2 -0
- package/dist/models/ps-progress-tone.d.ts +1 -0
- package/dist/models/ps-progress-tone.js +2 -0
- package/dist/models/ps-xhr-response-type.d.ts +1 -0
- package/dist/models/ps-xhr-response-type.js +2 -0
- package/dist/models/ps-xhr-upload-request.d.ts +2 -0
- package/dist/models/ps-xhr-upload-response.d.ts +1 -0
- package/dist/services/index.d.ts +8 -0
- package/dist/services/index.js +24 -0
- package/dist/services/ps-pdf-service.d.ts +2 -2
- package/dist/services/ps-pdf-service.js +5 -2
- package/dist/services/ps-xhr-upload-service.js +3 -2
- package/package.json +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from './viewers';
|
|
2
|
+
export * from './ps-file-delete-confirm';
|
|
3
|
+
export * from './ps-file-icon-button';
|
|
4
|
+
export * from './ps-file-kind-icon';
|
|
5
|
+
export * from './ps-file-list';
|
|
6
|
+
export * from './ps-file-picker';
|
|
7
|
+
export * from './ps-file-viewer';
|
|
8
|
+
export * from './ps-file-viewer-button';
|
|
9
|
+
export * from './ps-file-viewer-content';
|
|
10
|
+
export * from './ps-progress-bar';
|
|
11
|
+
export * from './ps-upload-modal';
|
|
12
|
+
export * from './ps-upload-row';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./viewers"), exports);
|
|
18
|
+
__exportStar(require("./ps-file-delete-confirm"), exports);
|
|
19
|
+
__exportStar(require("./ps-file-icon-button"), exports);
|
|
20
|
+
__exportStar(require("./ps-file-kind-icon"), exports);
|
|
21
|
+
__exportStar(require("./ps-file-list"), exports);
|
|
22
|
+
__exportStar(require("./ps-file-picker"), exports);
|
|
23
|
+
__exportStar(require("./ps-file-viewer"), exports);
|
|
24
|
+
__exportStar(require("./ps-file-viewer-button"), exports);
|
|
25
|
+
__exportStar(require("./ps-file-viewer-content"), exports);
|
|
26
|
+
__exportStar(require("./ps-progress-bar"), exports);
|
|
27
|
+
__exportStar(require("./ps-upload-modal"), exports);
|
|
28
|
+
__exportStar(require("./ps-upload-row"), exports);
|
|
@@ -4,5 +4,5 @@ exports.PsFileDeleteConfirm = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const ps_core_components_1 = require("@pallasoft/ps-core-components");
|
|
6
6
|
const ps_popovers_1 = require("@pallasoft/ps-popovers");
|
|
7
|
-
const PsFileDeleteConfirm = ({ fileName, isDeleting, isOpen, labels, onCancel, onConfirm, }) => ((0, jsx_runtime_1.jsx)(ps_popovers_1.PsModal, { eyebrow: fileName, isOpen: isOpen, onClose: onCancel, size: 'sm', title: labels.deleteConfirm, children: (0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-col gap-5', children: [(0, jsx_runtime_1.
|
|
7
|
+
const PsFileDeleteConfirm = ({ fileName, isDeleting, isOpen, labels, onCancel, onConfirm, }) => ((0, jsx_runtime_1.jsx)(ps_popovers_1.PsModal, { eyebrow: fileName, isOpen: isOpen, onClose: onCancel, size: 'sm', title: labels.deleteConfirm, children: (0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-col gap-5', children: [(0, jsx_runtime_1.jsxs)("p", { className: 'text-sm text-ink/70', children: [(0, jsx_runtime_1.jsx)("span", { className: 'font-medium text-ink', children: fileName }), " ", labels.deleteConfirmBody] }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex justify-end gap-2 border-t border-line pt-4', children: [(0, jsx_runtime_1.jsx)(ps_core_components_1.PsButton, { disabled: isDeleting, onClick: onCancel, type: 'button', variant: 'ghost', children: labels.deleteCancel }), (0, jsx_runtime_1.jsx)(ps_core_components_1.PsButton, { isLoading: isDeleting, onClick: onConfirm, type: 'button', variant: 'danger', children: labels.delete })] })] }) }));
|
|
8
8
|
exports.PsFileDeleteConfirm = PsFileDeleteConfirm;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type PsIconKey } from '@pallasoft/ps-icons';
|
|
2
|
+
import type { PsFileIconButtonTone } from '../models/ps-file-icon-button-tone';
|
|
3
|
+
export interface PsFileIconButtonProps {
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
href?: string;
|
|
6
|
+
download?: string;
|
|
7
|
+
iconKey: PsIconKey;
|
|
8
|
+
label: string;
|
|
9
|
+
onClick?: () => void;
|
|
10
|
+
tone?: PsFileIconButtonTone;
|
|
11
|
+
}
|
|
12
|
+
export declare const PsFileIconButton: ({ disabled, download, href, iconKey, label, onClick, tone, }: PsFileIconButtonProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsFileIconButton = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
|
+
const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
7
|
+
const ps_file_icon_button_classes_1 = require("../constants/ps-file-icon-button-classes");
|
|
8
|
+
const PsFileIconButton = ({ disabled = false, download, href, iconKey, label, onClick, tone = 'neutral', }) => {
|
|
9
|
+
const className = ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-ink/55 transition disabled:pointer-events-none disabled:opacity-40', ps_file_icon_button_classes_1.PsFileIconButtonClasses[tone]);
|
|
10
|
+
const icon = (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: iconKey });
|
|
11
|
+
return href === undefined ? ((0, jsx_runtime_1.jsx)("button", { "aria-label": label, className: className, disabled: disabled, onClick: onClick, title: label, type: 'button', children: icon })) : ((0, jsx_runtime_1.jsx)("a", { "aria-label": label, className: className, download: download, href: href, title: label, children: icon }));
|
|
12
|
+
};
|
|
13
|
+
exports.PsFileIconButton = PsFileIconButton;
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PsFileList = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const ps_core_components_1 = require("@pallasoft/ps-core-components");
|
|
6
5
|
const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
7
6
|
const ps_file_kind_1 = require("../constants/ps-file-kind");
|
|
8
7
|
const ps_file_list_labels_1 = require("../constants/ps-file-list-labels");
|
|
9
8
|
const ps_file_size_service_1 = require("../services/ps-file-size-service");
|
|
10
9
|
const ps_file_type_service_1 = require("../services/ps-file-type-service");
|
|
10
|
+
const ps_file_icon_button_1 = require("./ps-file-icon-button");
|
|
11
11
|
const ps_file_kind_icon_1 = require("./ps-file-kind-icon");
|
|
12
12
|
const PsFileList = ({ busyIds = [], files, formatDate, labels, onDelete, onOpen, }) => {
|
|
13
13
|
const text = { ...ps_file_list_labels_1.PsFileListLabels, ...labels };
|
|
@@ -21,7 +21,7 @@ const PsFileList = ({ busyIds = [], files, formatDate, labels, onDelete, onOpen,
|
|
|
21
21
|
? null
|
|
22
22
|
: formatDate(file.createdAt),
|
|
23
23
|
].filter((value) => value !== null);
|
|
24
|
-
return ((0, jsx_runtime_1.jsxs)("li", { className: 'group flex min-w-0 items-center gap-3 rounded-ps-control border border-line bg-surface p-2 transition hover:border-primary/40', children: [(0, jsx_runtime_1.jsxs)("button", { "aria-label": `${text.open} ${file.name}`, className: 'ps-focus-ring flex min-w-0 flex-1 items-center gap-3 rounded-ps-control text-left', onClick: () => onOpen(index), type: 'button', children: [isImage ? ((0, jsx_runtime_1.jsx)("img", { alt: '', className: 'h-12 w-12 shrink-0 rounded-ps-control border border-line object-cover', loading: 'lazy', src: file.url })) : ((0, jsx_runtime_1.jsx)(ps_file_kind_icon_1.PsFileKindIcon, { className: 'h-12 w-12', contentType: file.contentType, name: file.name })), (0, jsx_runtime_1.jsxs)("span", { className: 'flex min-w-0 flex-col', children: [(0, jsx_runtime_1.jsx)("span", { className: 'truncate text-sm font-medium text-ink group-hover:text-primary', children: file.name }), meta.length > 0 ? ((0, jsx_runtime_1.jsx)("span", { className: 'truncate text-xs text-ink/55', children: meta.join(' · ') })) : null] })] }), (0, jsx_runtime_1.
|
|
24
|
+
return ((0, jsx_runtime_1.jsxs)("li", { className: 'group flex min-w-0 items-center gap-3 rounded-ps-control border border-line bg-surface p-2 transition hover:border-primary/40', children: [(0, jsx_runtime_1.jsxs)("button", { "aria-label": `${text.open} ${file.name}`, className: 'ps-focus-ring flex min-w-0 flex-1 items-center gap-3 rounded-ps-control text-left', onClick: () => onOpen(index), type: 'button', children: [isImage ? ((0, jsx_runtime_1.jsx)("img", { alt: '', className: 'h-12 w-12 shrink-0 rounded-ps-control border border-line object-cover', loading: 'lazy', src: file.url })) : ((0, jsx_runtime_1.jsx)(ps_file_kind_icon_1.PsFileKindIcon, { className: 'h-12 w-12', contentType: file.contentType, name: file.name })), (0, jsx_runtime_1.jsxs)("span", { className: 'flex min-w-0 flex-col', children: [(0, jsx_runtime_1.jsx)("span", { className: 'truncate text-sm font-medium text-ink group-hover:text-primary', children: file.name }), meta.length > 0 ? ((0, jsx_runtime_1.jsx)("span", { className: 'truncate text-xs text-ink/55', children: meta.join(' · ') })) : null] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex shrink-0 items-center gap-0.5', children: [(0, jsx_runtime_1.jsx)(ps_file_icon_button_1.PsFileIconButton, { download: file.name, href: file.downloadUrl === undefined ? file.url : file.downloadUrl, iconKey: ps_icons_1.PsIconKey.Download, label: `${text.download} ${file.name}` }), onDelete ? ((0, jsx_runtime_1.jsx)(ps_file_icon_button_1.PsFileIconButton, { disabled: busyIds.includes(file.id), iconKey: ps_icons_1.PsIconKey.Trash, label: `${text.delete} ${file.name}`, onClick: () => onDelete(file), tone: 'danger' })) : null] })] }, file.id));
|
|
25
25
|
}) }));
|
|
26
26
|
};
|
|
27
27
|
exports.PsFileList = PsFileList;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
import type { PsFileViewerButtonTone } from '../models/ps-file-viewer-button-tone';
|
|
2
3
|
export interface PsFileViewerButtonProps {
|
|
3
4
|
children: ReactNode;
|
|
4
5
|
className?: string;
|
|
5
6
|
disabled?: boolean;
|
|
6
7
|
label: string;
|
|
7
8
|
onClick: () => void;
|
|
8
|
-
tone?:
|
|
9
|
+
tone?: PsFileViewerButtonTone;
|
|
9
10
|
}
|
|
10
11
|
export declare const PsFileViewerButton: ({ children, className, disabled, label, onClick, tone, }: PsFileViewerButtonProps) => import("react").JSX.Element;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { PsProgressTone } from '../models/ps-progress-tone';
|
|
1
2
|
export interface PsProgressBarProps {
|
|
2
3
|
className?: string;
|
|
3
4
|
label: string;
|
|
4
|
-
tone?:
|
|
5
|
+
tone?: PsProgressTone;
|
|
5
6
|
value: number;
|
|
6
7
|
}
|
|
7
8
|
export declare const PsProgressBar: ({ className, label, tone, value, }: PsProgressBarProps) => import("react").JSX.Element;
|
|
@@ -3,13 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.PsProgressBar = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
|
-
const
|
|
7
|
-
danger: 'bg-danger',
|
|
8
|
-
primary: 'bg-primary',
|
|
9
|
-
success: 'bg-success',
|
|
10
|
-
};
|
|
6
|
+
const ps_progress_tone_classes_1 = require("../constants/ps-progress-tone-classes");
|
|
11
7
|
const PsProgressBar = ({ className, label, tone = 'primary', value, }) => {
|
|
12
8
|
const percent = Math.round(Math.min(1, Math.max(0, value)) * 100);
|
|
13
|
-
return ((0, jsx_runtime_1.jsx)("div", { "aria-label": label, "aria-valuemax": 100, "aria-valuemin": 0, "aria-valuenow": percent, className: ps_design_system_1.PallasoftClassNameService.merge('h-1.5 w-full overflow-hidden rounded-full bg-line/70', className), role: 'progressbar', children: (0, jsx_runtime_1.jsx)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('h-full rounded-full transition-[width] duration-200 ease-out',
|
|
9
|
+
return ((0, jsx_runtime_1.jsx)("div", { "aria-label": label, "aria-valuemax": 100, "aria-valuemin": 0, "aria-valuenow": percent, className: ps_design_system_1.PallasoftClassNameService.merge('h-1.5 w-full overflow-hidden rounded-full bg-line/70', className), role: 'progressbar', children: (0, jsx_runtime_1.jsx)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('h-full rounded-full transition-[width] duration-200 ease-out', ps_progress_tone_classes_1.PsProgressToneClasses[tone]), style: { width: `${percent}%` } }) }));
|
|
14
10
|
};
|
|
15
11
|
exports.PsProgressBar = PsProgressBar;
|
|
@@ -6,14 +6,11 @@ const ps_core_components_1 = require("@pallasoft/ps-core-components");
|
|
|
6
6
|
const ps_popovers_1 = require("@pallasoft/ps-popovers");
|
|
7
7
|
const ps_upload_labels_1 = require("../constants/ps-upload-labels");
|
|
8
8
|
const ps_upload_queue_service_1 = require("../services/ps-upload-queue-service");
|
|
9
|
-
const ps_progress_bar_1 = require("./ps-progress-bar");
|
|
10
9
|
const ps_upload_row_1 = require("./ps-upload-row");
|
|
11
10
|
const PsUploadModal = ({ isOpen, labels, onClose, queue }) => {
|
|
12
11
|
const text = { ...ps_upload_labels_1.PsUploadLabels, ...labels };
|
|
13
12
|
const summary = ps_upload_queue_service_1.PsUploadQueueService.summary(queue.items);
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
: queue.items.reduce((total, item) => total + item.progress, 0) / queue.items.length;
|
|
17
|
-
return ((0, jsx_runtime_1.jsx)(ps_popovers_1.PsModal, { eyebrow: `${summary.done} / ${summary.total}`, isOpen: isOpen, onClose: onClose, size: 'md', title: queue.isBusy ? text.title : text.titleDone, children: (0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-col gap-4', children: [(0, jsx_runtime_1.jsx)(ps_progress_bar_1.PsProgressBar, { label: text.title, tone: summary.failed > 0 ? 'danger' : queue.isBusy ? 'primary' : 'success', value: overall }), (0, jsx_runtime_1.jsx)("ul", { className: 'flex max-h-[50vh] flex-col divide-y divide-line/70 overflow-y-auto', children: queue.items.map((item) => ((0, jsx_runtime_1.jsx)(ps_upload_row_1.PsUploadRow, { item: item, labels: text, onCancel: () => queue.cancel(item.id), onRemove: () => queue.remove(item.id), onRetry: () => queue.retry(item.id) }, item.id))) }), (0, jsx_runtime_1.jsx)("div", { className: 'flex justify-end', children: (0, jsx_runtime_1.jsx)(ps_core_components_1.PsButton, { onClick: onClose, type: 'button', variant: queue.isBusy ? 'ghost' : 'primary', children: text.close }) })] }) }));
|
|
13
|
+
const title = queue.isBusy ? text.title : summary.failed > 0 ? text.titleFailed : text.titleDone;
|
|
14
|
+
return ((0, jsx_runtime_1.jsx)(ps_popovers_1.PsModal, { isOpen: isOpen, onClose: onClose, size: 'md', title: title, children: (0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-col gap-5', children: [(0, jsx_runtime_1.jsx)("ul", { className: 'flex max-h-[50vh] flex-col gap-2 overflow-y-auto', children: queue.items.map((item) => ((0, jsx_runtime_1.jsx)(ps_upload_row_1.PsUploadRow, { item: item, labels: text, onCancel: () => queue.cancel(item.id), onRemove: () => queue.remove(item.id), onRetry: () => queue.retry(item.id) }, item.id))) }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-wrap items-center justify-end gap-2 border-t border-line pt-4', children: [queue.isBusy ? ((0, jsx_runtime_1.jsx)(ps_core_components_1.PsButton, { onClick: () => queue.items.forEach((item) => queue.cancel(item.id)), type: 'button', variant: 'ghost', children: text.cancelAll })) : null, (0, jsx_runtime_1.jsx)(ps_core_components_1.PsButton, { onClick: onClose, type: 'button', variant: 'primary', children: text.finish })] })] }) }));
|
|
18
15
|
};
|
|
19
16
|
exports.PsUploadModal = PsUploadModal;
|
|
@@ -2,27 +2,23 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PsUploadRow = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const ps_core_components_1 = require("@pallasoft/ps-core-components");
|
|
6
5
|
const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
7
6
|
const ps_upload_status_1 = require("../constants/ps-upload-status");
|
|
8
7
|
const ps_upload_status_tones_1 = require("../constants/ps-upload-status-tones");
|
|
9
8
|
const ps_file_size_service_1 = require("../services/ps-file-size-service");
|
|
10
9
|
const ps_upload_queue_service_1 = require("../services/ps-upload-queue-service");
|
|
10
|
+
const ps_file_icon_button_1 = require("./ps-file-icon-button");
|
|
11
11
|
const ps_file_kind_icon_1 = require("./ps-file-kind-icon");
|
|
12
12
|
const ps_progress_bar_1 = require("./ps-progress-bar");
|
|
13
13
|
const PsUploadRow = ({ item, labels, onCancel, onRemove, onRetry }) => {
|
|
14
14
|
const isActive = ps_upload_queue_service_1.PsUploadQueueService.isActive(item);
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
? `${labels.uploading} ${
|
|
15
|
+
const isProblem = item.status === ps_upload_status_1.PsUploadStatus.failed || item.status === ps_upload_status_1.PsUploadStatus.cancelled;
|
|
16
|
+
const size = ps_file_size_service_1.PsFileSizeService.format(item.file.size);
|
|
17
|
+
const status = item.status === ps_upload_status_1.PsUploadStatus.uploading
|
|
18
|
+
? `${labels.uploading} · ${Math.round(item.progress * 100)}%`
|
|
19
19
|
: item.status === ps_upload_status_1.PsUploadStatus.failed && item.error
|
|
20
20
|
? item.error
|
|
21
21
|
: labels[item.status];
|
|
22
|
-
return ((0, jsx_runtime_1.jsxs)("li", { className: 'flex items-center gap-3 py-
|
|
23
|
-
? 'text-xs text-danger'
|
|
24
|
-
: item.status === ps_upload_status_1.PsUploadStatus.done
|
|
25
|
-
? 'flex items-center gap-1 text-xs text-success'
|
|
26
|
-
: 'text-xs text-ink/60', role: item.status === ps_upload_status_1.PsUploadStatus.failed ? 'alert' : undefined, children: [item.status === ps_upload_status_1.PsUploadStatus.done ? ((0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-3.5 w-3.5', iconKey: ps_icons_1.PsIconKey.Check })) : null, statusText] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex shrink-0 items-center gap-1', children: [canRetry ? ((0, jsx_runtime_1.jsx)(ps_core_components_1.PsButton, { leadingIcon: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.Refresh }), onClick: onRetry, size: 'compact', type: 'button', variant: 'ghost', children: labels.retry })) : null, (0, jsx_runtime_1.jsx)(ps_core_components_1.PsButton, { "aria-label": `${isActive ? labels.cancel : labels.remove} ${item.file.name}`, onClick: isActive ? onCancel : onRemove, size: 'compact', type: 'button', variant: 'ghost', children: isActive ? labels.cancel : labels.remove })] })] }));
|
|
22
|
+
return ((0, jsx_runtime_1.jsxs)("li", { className: 'flex items-center gap-3 rounded-ps-control border border-line px-3 py-2.5', children: [(0, jsx_runtime_1.jsx)(ps_file_kind_icon_1.PsFileKindIcon, { contentType: item.file.type, name: item.file.name }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex min-w-0 flex-1 flex-col gap-1.5', children: [(0, jsx_runtime_1.jsx)("p", { className: 'truncate text-sm font-medium text-ink', children: item.file.name }), (0, jsx_runtime_1.jsx)(ps_progress_bar_1.PsProgressBar, { label: item.file.name, tone: ps_upload_status_tones_1.PsUploadStatusTones[item.status], value: isProblem ? 1 : item.progress }), (0, jsx_runtime_1.jsxs)("p", { className: `truncate text-xs ${isProblem ? 'text-danger' : item.status === ps_upload_status_1.PsUploadStatus.done ? 'text-success' : 'text-ink/55'}`, role: item.status === ps_upload_status_1.PsUploadStatus.failed ? 'alert' : undefined, children: [size, " \u00B7 ", status] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex w-16 shrink-0 items-center justify-end gap-0.5', children: [isProblem ? ((0, jsx_runtime_1.jsx)(ps_file_icon_button_1.PsFileIconButton, { iconKey: ps_icons_1.PsIconKey.Refresh, label: `${labels.retry} ${item.file.name}`, onClick: onRetry })) : null, isActive ? ((0, jsx_runtime_1.jsx)(ps_file_icon_button_1.PsFileIconButton, { iconKey: ps_icons_1.PsIconKey.Close, label: `${labels.cancel} ${item.file.name}`, onClick: onCancel, tone: 'danger' })) : item.status === ps_upload_status_1.PsUploadStatus.done ? ((0, jsx_runtime_1.jsx)("span", { className: 'inline-flex h-8 w-8 items-center justify-center text-success', children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-label": labels.done, className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.Check }) })) : ((0, jsx_runtime_1.jsx)(ps_file_icon_button_1.PsFileIconButton, { iconKey: ps_icons_1.PsIconKey.Close, label: `${labels.remove} ${item.file.name}`, onClick: onRemove }))] })] }));
|
|
27
23
|
};
|
|
28
24
|
exports.PsUploadRow = PsUploadRow;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './ps-highlighted-text';
|
|
2
|
+
export * from './ps-image-viewer';
|
|
3
|
+
export * from './ps-media-viewer';
|
|
4
|
+
export * from './ps-pdf-page';
|
|
5
|
+
export * from './ps-pdf-thumbnail';
|
|
6
|
+
export * from './ps-pdf-viewer';
|
|
7
|
+
export * from './ps-text-viewer';
|
|
8
|
+
export * from './ps-unsupported-viewer';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./ps-highlighted-text"), exports);
|
|
18
|
+
__exportStar(require("./ps-image-viewer"), exports);
|
|
19
|
+
__exportStar(require("./ps-media-viewer"), exports);
|
|
20
|
+
__exportStar(require("./ps-pdf-page"), exports);
|
|
21
|
+
__exportStar(require("./ps-pdf-thumbnail"), exports);
|
|
22
|
+
__exportStar(require("./ps-pdf-viewer"), exports);
|
|
23
|
+
__exportStar(require("./ps-text-viewer"), exports);
|
|
24
|
+
__exportStar(require("./ps-unsupported-viewer"), exports);
|
|
@@ -21,10 +21,6 @@ const PsPdfViewer = ({ activeMatch, file, labels, onMatchCount, pdfWorkerSrc, qu
|
|
|
21
21
|
let opened = null;
|
|
22
22
|
setDocument(null);
|
|
23
23
|
setHasFailed(false);
|
|
24
|
-
if (pdfWorkerSrc === undefined) {
|
|
25
|
-
setHasFailed(true);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
24
|
ps_pdf_service_1.PsPdfService.open(file.url, pdfWorkerSrc)
|
|
29
25
|
.then(async (loaded) => {
|
|
30
26
|
opened = loaded;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from './ps-file-icon-button-classes';
|
|
2
|
+
export * from './ps-file-kind';
|
|
3
|
+
export * from './ps-file-kind-icons';
|
|
4
|
+
export * from './ps-file-list-labels';
|
|
5
|
+
export * from './ps-file-picker-labels';
|
|
6
|
+
export * from './ps-file-type-config';
|
|
7
|
+
export * from './ps-file-viewer-config';
|
|
8
|
+
export * from './ps-file-viewer-kinds';
|
|
9
|
+
export * from './ps-file-viewer-labels';
|
|
10
|
+
export * from './ps-progress-tone-classes';
|
|
11
|
+
export * from './ps-upload-labels';
|
|
12
|
+
export * from './ps-upload-messages';
|
|
13
|
+
export * from './ps-upload-queue-config';
|
|
14
|
+
export * from './ps-upload-status';
|
|
15
|
+
export * from './ps-upload-status-tones';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./ps-file-icon-button-classes"), exports);
|
|
18
|
+
__exportStar(require("./ps-file-kind"), exports);
|
|
19
|
+
__exportStar(require("./ps-file-kind-icons"), exports);
|
|
20
|
+
__exportStar(require("./ps-file-list-labels"), exports);
|
|
21
|
+
__exportStar(require("./ps-file-picker-labels"), exports);
|
|
22
|
+
__exportStar(require("./ps-file-type-config"), exports);
|
|
23
|
+
__exportStar(require("./ps-file-viewer-config"), exports);
|
|
24
|
+
__exportStar(require("./ps-file-viewer-kinds"), exports);
|
|
25
|
+
__exportStar(require("./ps-file-viewer-labels"), exports);
|
|
26
|
+
__exportStar(require("./ps-progress-tone-classes"), exports);
|
|
27
|
+
__exportStar(require("./ps-upload-labels"), exports);
|
|
28
|
+
__exportStar(require("./ps-upload-messages"), exports);
|
|
29
|
+
__exportStar(require("./ps-upload-queue-config"), exports);
|
|
30
|
+
__exportStar(require("./ps-upload-status"), exports);
|
|
31
|
+
__exportStar(require("./ps-upload-status-tones"), exports);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsFileIconButtonClasses = void 0;
|
|
4
|
+
exports.PsFileIconButtonClasses = {
|
|
5
|
+
danger: 'hover:bg-danger-soft hover:text-danger',
|
|
6
|
+
neutral: 'hover:bg-primary-soft/60 hover:text-primary',
|
|
7
|
+
};
|
|
@@ -2,8 +2,8 @@ export declare const PsFileViewerLabels: {
|
|
|
2
2
|
readonly close: "Close";
|
|
3
3
|
readonly delete: "Delete";
|
|
4
4
|
readonly deleteConfirm: "Delete file";
|
|
5
|
-
readonly deleteConfirmBody: "
|
|
6
|
-
readonly deleteCancel: "
|
|
5
|
+
readonly deleteConfirmBody: "will be deleted. You cannot undo this.";
|
|
6
|
+
readonly deleteCancel: "Cancel";
|
|
7
7
|
readonly download: "Download";
|
|
8
8
|
readonly loadFailed: "This file could not be opened.";
|
|
9
9
|
readonly next: "Next file";
|
|
@@ -5,8 +5,8 @@ exports.PsFileViewerLabels = {
|
|
|
5
5
|
close: 'Close',
|
|
6
6
|
delete: 'Delete',
|
|
7
7
|
deleteConfirm: 'Delete file',
|
|
8
|
-
deleteConfirmBody: '
|
|
9
|
-
deleteCancel: '
|
|
8
|
+
deleteConfirmBody: 'will be deleted. You cannot undo this.',
|
|
9
|
+
deleteCancel: 'Cancel',
|
|
10
10
|
download: 'Download',
|
|
11
11
|
loadFailed: 'This file could not be opened.',
|
|
12
12
|
next: 'Next file',
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
export declare const PsUploadLabels: {
|
|
2
|
-
readonly cancel: "Cancel";
|
|
2
|
+
readonly cancel: "Cancel upload";
|
|
3
|
+
readonly cancelAll: "Cancel uploads";
|
|
3
4
|
readonly cancelled: "Cancelled";
|
|
4
|
-
readonly close: "Close";
|
|
5
5
|
readonly done: "Uploaded";
|
|
6
6
|
readonly failed: "Failed";
|
|
7
|
+
readonly finish: "Done";
|
|
7
8
|
readonly processing: "Saving";
|
|
8
|
-
readonly remove: "Remove";
|
|
9
|
-
readonly retry: "
|
|
9
|
+
readonly remove: "Remove from list";
|
|
10
|
+
readonly retry: "Try again";
|
|
10
11
|
readonly title: "Uploading files";
|
|
11
|
-
readonly titleDone: "
|
|
12
|
+
readonly titleDone: "Files uploaded";
|
|
13
|
+
readonly titleFailed: "Some files did not upload";
|
|
12
14
|
readonly uploading: "Uploading";
|
|
13
15
|
readonly waiting: "Waiting";
|
|
14
16
|
};
|
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PsUploadLabels = void 0;
|
|
4
4
|
exports.PsUploadLabels = {
|
|
5
|
-
cancel: 'Cancel',
|
|
5
|
+
cancel: 'Cancel upload',
|
|
6
|
+
cancelAll: 'Cancel uploads',
|
|
6
7
|
cancelled: 'Cancelled',
|
|
7
|
-
close: 'Close',
|
|
8
8
|
done: 'Uploaded',
|
|
9
9
|
failed: 'Failed',
|
|
10
|
+
finish: 'Done',
|
|
10
11
|
processing: 'Saving',
|
|
11
|
-
remove: 'Remove',
|
|
12
|
-
retry: '
|
|
12
|
+
remove: 'Remove from list',
|
|
13
|
+
retry: 'Try again',
|
|
13
14
|
title: 'Uploading files',
|
|
14
|
-
titleDone: '
|
|
15
|
+
titleDone: 'Files uploaded',
|
|
16
|
+
titleFailed: 'Some files did not upload',
|
|
15
17
|
uploading: 'Uploading',
|
|
16
18
|
waiting: 'Waiting',
|
|
17
19
|
};
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
+
import type { PsProgressTone } from '../models/ps-progress-tone';
|
|
1
2
|
import { PsUploadStatus } from './ps-upload-status';
|
|
2
|
-
export declare const PsUploadStatusTones: Record<PsUploadStatus,
|
|
3
|
+
export declare const PsUploadStatusTones: Record<PsUploadStatus, PsProgressTone>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from './viewers';
|
|
2
|
+
export * from './ps-file-delete-confirm';
|
|
3
|
+
export * from './ps-file-icon-button';
|
|
4
|
+
export * from './ps-file-kind-icon';
|
|
5
|
+
export * from './ps-file-list';
|
|
6
|
+
export * from './ps-file-picker';
|
|
7
|
+
export * from './ps-file-viewer';
|
|
8
|
+
export * from './ps-file-viewer-button';
|
|
9
|
+
export * from './ps-file-viewer-content';
|
|
10
|
+
export * from './ps-progress-bar';
|
|
11
|
+
export * from './ps-upload-modal';
|
|
12
|
+
export * from './ps-upload-row';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { PsButton } from '@pallasoft/ps-core-components';
|
|
3
3
|
import { PsModal } from '@pallasoft/ps-popovers';
|
|
4
|
-
export const PsFileDeleteConfirm = ({ fileName, isDeleting, isOpen, labels, onCancel, onConfirm, }) => (_jsx(PsModal, { eyebrow: fileName, isOpen: isOpen, onClose: onCancel, size: 'sm', title: labels.deleteConfirm, children: _jsxs("div", { className: 'flex flex-col gap-5', children: [
|
|
4
|
+
export const PsFileDeleteConfirm = ({ fileName, isDeleting, isOpen, labels, onCancel, onConfirm, }) => (_jsx(PsModal, { eyebrow: fileName, isOpen: isOpen, onClose: onCancel, size: 'sm', title: labels.deleteConfirm, children: _jsxs("div", { className: 'flex flex-col gap-5', children: [_jsxs("p", { className: 'text-sm text-ink/70', children: [_jsx("span", { className: 'font-medium text-ink', children: fileName }), " ", labels.deleteConfirmBody] }), _jsxs("div", { className: 'flex justify-end gap-2 border-t border-line pt-4', children: [_jsx(PsButton, { disabled: isDeleting, onClick: onCancel, type: 'button', variant: 'ghost', children: labels.deleteCancel }), _jsx(PsButton, { isLoading: isDeleting, onClick: onConfirm, type: 'button', variant: 'danger', children: labels.delete })] })] }) }));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
|
+
import { PsIcon } from '@pallasoft/ps-icons';
|
|
4
|
+
import { PsFileIconButtonClasses } from '../constants/ps-file-icon-button-classes';
|
|
5
|
+
export const PsFileIconButton = ({ disabled = false, download, href, iconKey, label, onClick, tone = 'neutral', }) => {
|
|
6
|
+
const className = PallasoftClassNameService.merge('ps-focus-ring inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-ink/55 transition disabled:pointer-events-none disabled:opacity-40', PsFileIconButtonClasses[tone]);
|
|
7
|
+
const icon = _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: iconKey });
|
|
8
|
+
return href === undefined ? (_jsx("button", { "aria-label": label, className: className, disabled: disabled, onClick: onClick, title: label, type: 'button', children: icon })) : (_jsx("a", { "aria-label": label, className: className, download: download, href: href, title: label, children: icon }));
|
|
9
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
2
|
+
import { PsIconKey } from '@pallasoft/ps-icons';
|
|
4
3
|
import { PsFileKind } from '../constants/ps-file-kind';
|
|
5
4
|
import { PsFileListLabels } from '../constants/ps-file-list-labels';
|
|
6
5
|
import { PsFileSizeService } from '../services/ps-file-size-service';
|
|
7
6
|
import { PsFileTypeService } from '../services/ps-file-type-service';
|
|
7
|
+
import { PsFileIconButton } from './ps-file-icon-button';
|
|
8
8
|
import { PsFileKindIcon } from './ps-file-kind-icon';
|
|
9
9
|
export const PsFileList = ({ busyIds = [], files, formatDate, labels, onDelete, onOpen, }) => {
|
|
10
10
|
const text = { ...PsFileListLabels, ...labels };
|
|
@@ -18,6 +18,6 @@ export const PsFileList = ({ busyIds = [], files, formatDate, labels, onDelete,
|
|
|
18
18
|
? null
|
|
19
19
|
: formatDate(file.createdAt),
|
|
20
20
|
].filter((value) => value !== null);
|
|
21
|
-
return (_jsxs("li", { className: 'group flex min-w-0 items-center gap-3 rounded-ps-control border border-line bg-surface p-2 transition hover:border-primary/40', children: [_jsxs("button", { "aria-label": `${text.open} ${file.name}`, className: 'ps-focus-ring flex min-w-0 flex-1 items-center gap-3 rounded-ps-control text-left', onClick: () => onOpen(index), type: 'button', children: [isImage ? (_jsx("img", { alt: '', className: 'h-12 w-12 shrink-0 rounded-ps-control border border-line object-cover', loading: 'lazy', src: file.url })) : (_jsx(PsFileKindIcon, { className: 'h-12 w-12', contentType: file.contentType, name: file.name })), _jsxs("span", { className: 'flex min-w-0 flex-col', children: [_jsx("span", { className: 'truncate text-sm font-medium text-ink group-hover:text-primary', children: file.name }), meta.length > 0 ? (_jsx("span", { className: 'truncate text-xs text-ink/55', children: meta.join(' · ') })) : null] })] }),
|
|
21
|
+
return (_jsxs("li", { className: 'group flex min-w-0 items-center gap-3 rounded-ps-control border border-line bg-surface p-2 transition hover:border-primary/40', children: [_jsxs("button", { "aria-label": `${text.open} ${file.name}`, className: 'ps-focus-ring flex min-w-0 flex-1 items-center gap-3 rounded-ps-control text-left', onClick: () => onOpen(index), type: 'button', children: [isImage ? (_jsx("img", { alt: '', className: 'h-12 w-12 shrink-0 rounded-ps-control border border-line object-cover', loading: 'lazy', src: file.url })) : (_jsx(PsFileKindIcon, { className: 'h-12 w-12', contentType: file.contentType, name: file.name })), _jsxs("span", { className: 'flex min-w-0 flex-col', children: [_jsx("span", { className: 'truncate text-sm font-medium text-ink group-hover:text-primary', children: file.name }), meta.length > 0 ? (_jsx("span", { className: 'truncate text-xs text-ink/55', children: meta.join(' · ') })) : null] })] }), _jsxs("div", { className: 'flex shrink-0 items-center gap-0.5', children: [_jsx(PsFileIconButton, { download: file.name, href: file.downloadUrl === undefined ? file.url : file.downloadUrl, iconKey: PsIconKey.Download, label: `${text.download} ${file.name}` }), onDelete ? (_jsx(PsFileIconButton, { disabled: busyIds.includes(file.id), iconKey: PsIconKey.Trash, label: `${text.delete} ${file.name}`, onClick: () => onDelete(file), tone: 'danger' })) : null] })] }, file.id));
|
|
22
22
|
}) }));
|
|
23
23
|
};
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
|
-
|
|
4
|
-
danger: 'bg-danger',
|
|
5
|
-
primary: 'bg-primary',
|
|
6
|
-
success: 'bg-success',
|
|
7
|
-
};
|
|
3
|
+
import { PsProgressToneClasses } from '../constants/ps-progress-tone-classes';
|
|
8
4
|
export const PsProgressBar = ({ className, label, tone = 'primary', value, }) => {
|
|
9
5
|
const percent = Math.round(Math.min(1, Math.max(0, value)) * 100);
|
|
10
|
-
return (_jsx("div", { "aria-label": label, "aria-valuemax": 100, "aria-valuemin": 0, "aria-valuenow": percent, className: PallasoftClassNameService.merge('h-1.5 w-full overflow-hidden rounded-full bg-line/70', className), role: 'progressbar', children: _jsx("div", { className: PallasoftClassNameService.merge('h-full rounded-full transition-[width] duration-200 ease-out',
|
|
6
|
+
return (_jsx("div", { "aria-label": label, "aria-valuemax": 100, "aria-valuemin": 0, "aria-valuenow": percent, className: PallasoftClassNameService.merge('h-1.5 w-full overflow-hidden rounded-full bg-line/70', className), role: 'progressbar', children: _jsx("div", { className: PallasoftClassNameService.merge('h-full rounded-full transition-[width] duration-200 ease-out', PsProgressToneClasses[tone]), style: { width: `${percent}%` } }) }));
|
|
11
7
|
};
|
|
@@ -3,13 +3,10 @@ import { PsButton } from '@pallasoft/ps-core-components';
|
|
|
3
3
|
import { PsModal } from '@pallasoft/ps-popovers';
|
|
4
4
|
import { PsUploadLabels } from '../constants/ps-upload-labels';
|
|
5
5
|
import { PsUploadQueueService } from '../services/ps-upload-queue-service';
|
|
6
|
-
import { PsProgressBar } from './ps-progress-bar';
|
|
7
6
|
import { PsUploadRow } from './ps-upload-row';
|
|
8
7
|
export const PsUploadModal = ({ isOpen, labels, onClose, queue }) => {
|
|
9
8
|
const text = { ...PsUploadLabels, ...labels };
|
|
10
9
|
const summary = PsUploadQueueService.summary(queue.items);
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
: queue.items.reduce((total, item) => total + item.progress, 0) / queue.items.length;
|
|
14
|
-
return (_jsx(PsModal, { eyebrow: `${summary.done} / ${summary.total}`, isOpen: isOpen, onClose: onClose, size: 'md', title: queue.isBusy ? text.title : text.titleDone, children: _jsxs("div", { className: 'flex flex-col gap-4', children: [_jsx(PsProgressBar, { label: text.title, tone: summary.failed > 0 ? 'danger' : queue.isBusy ? 'primary' : 'success', value: overall }), _jsx("ul", { className: 'flex max-h-[50vh] flex-col divide-y divide-line/70 overflow-y-auto', children: queue.items.map((item) => (_jsx(PsUploadRow, { item: item, labels: text, onCancel: () => queue.cancel(item.id), onRemove: () => queue.remove(item.id), onRetry: () => queue.retry(item.id) }, item.id))) }), _jsx("div", { className: 'flex justify-end', children: _jsx(PsButton, { onClick: onClose, type: 'button', variant: queue.isBusy ? 'ghost' : 'primary', children: text.close }) })] }) }));
|
|
10
|
+
const title = queue.isBusy ? text.title : summary.failed > 0 ? text.titleFailed : text.titleDone;
|
|
11
|
+
return (_jsx(PsModal, { isOpen: isOpen, onClose: onClose, size: 'md', title: title, children: _jsxs("div", { className: 'flex flex-col gap-5', children: [_jsx("ul", { className: 'flex max-h-[50vh] flex-col gap-2 overflow-y-auto', children: queue.items.map((item) => (_jsx(PsUploadRow, { item: item, labels: text, onCancel: () => queue.cancel(item.id), onRemove: () => queue.remove(item.id), onRetry: () => queue.retry(item.id) }, item.id))) }), _jsxs("div", { className: 'flex flex-wrap items-center justify-end gap-2 border-t border-line pt-4', children: [queue.isBusy ? (_jsx(PsButton, { onClick: () => queue.items.forEach((item) => queue.cancel(item.id)), type: 'button', variant: 'ghost', children: text.cancelAll })) : null, _jsx(PsButton, { onClick: onClose, type: 'button', variant: 'primary', children: text.finish })] })] }) }));
|
|
15
12
|
};
|
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { PsButton } from '@pallasoft/ps-core-components';
|
|
3
2
|
import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
4
3
|
import { PsUploadStatus } from '../constants/ps-upload-status';
|
|
5
4
|
import { PsUploadStatusTones } from '../constants/ps-upload-status-tones';
|
|
6
5
|
import { PsFileSizeService } from '../services/ps-file-size-service';
|
|
7
6
|
import { PsUploadQueueService } from '../services/ps-upload-queue-service';
|
|
7
|
+
import { PsFileIconButton } from './ps-file-icon-button';
|
|
8
8
|
import { PsFileKindIcon } from './ps-file-kind-icon';
|
|
9
9
|
import { PsProgressBar } from './ps-progress-bar';
|
|
10
10
|
export const PsUploadRow = ({ item, labels, onCancel, onRemove, onRetry }) => {
|
|
11
11
|
const isActive = PsUploadQueueService.isActive(item);
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
? `${labels.uploading} ${
|
|
12
|
+
const isProblem = item.status === PsUploadStatus.failed || item.status === PsUploadStatus.cancelled;
|
|
13
|
+
const size = PsFileSizeService.format(item.file.size);
|
|
14
|
+
const status = item.status === PsUploadStatus.uploading
|
|
15
|
+
? `${labels.uploading} · ${Math.round(item.progress * 100)}%`
|
|
16
16
|
: item.status === PsUploadStatus.failed && item.error
|
|
17
17
|
? item.error
|
|
18
18
|
: labels[item.status];
|
|
19
|
-
return (_jsxs("li", { className: 'flex items-center gap-3 py-
|
|
20
|
-
? 'text-xs text-danger'
|
|
21
|
-
: item.status === PsUploadStatus.done
|
|
22
|
-
? 'flex items-center gap-1 text-xs text-success'
|
|
23
|
-
: 'text-xs text-ink/60', role: item.status === PsUploadStatus.failed ? 'alert' : undefined, children: [item.status === PsUploadStatus.done ? (_jsx(PsIcon, { "aria-hidden": 'true', className: 'h-3.5 w-3.5', iconKey: PsIconKey.Check })) : null, statusText] })] }), _jsxs("div", { className: 'flex shrink-0 items-center gap-1', children: [canRetry ? (_jsx(PsButton, { leadingIcon: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: PsIconKey.Refresh }), onClick: onRetry, size: 'compact', type: 'button', variant: 'ghost', children: labels.retry })) : null, _jsx(PsButton, { "aria-label": `${isActive ? labels.cancel : labels.remove} ${item.file.name}`, onClick: isActive ? onCancel : onRemove, size: 'compact', type: 'button', variant: 'ghost', children: isActive ? labels.cancel : labels.remove })] })] }));
|
|
19
|
+
return (_jsxs("li", { className: 'flex items-center gap-3 rounded-ps-control border border-line px-3 py-2.5', children: [_jsx(PsFileKindIcon, { contentType: item.file.type, name: item.file.name }), _jsxs("div", { className: 'flex min-w-0 flex-1 flex-col gap-1.5', children: [_jsx("p", { className: 'truncate text-sm font-medium text-ink', children: item.file.name }), _jsx(PsProgressBar, { label: item.file.name, tone: PsUploadStatusTones[item.status], value: isProblem ? 1 : item.progress }), _jsxs("p", { className: `truncate text-xs ${isProblem ? 'text-danger' : item.status === PsUploadStatus.done ? 'text-success' : 'text-ink/55'}`, role: item.status === PsUploadStatus.failed ? 'alert' : undefined, children: [size, " \u00B7 ", status] })] }), _jsxs("div", { className: 'flex w-16 shrink-0 items-center justify-end gap-0.5', children: [isProblem ? (_jsx(PsFileIconButton, { iconKey: PsIconKey.Refresh, label: `${labels.retry} ${item.file.name}`, onClick: onRetry })) : null, isActive ? (_jsx(PsFileIconButton, { iconKey: PsIconKey.Close, label: `${labels.cancel} ${item.file.name}`, onClick: onCancel, tone: 'danger' })) : item.status === PsUploadStatus.done ? (_jsx("span", { className: 'inline-flex h-8 w-8 items-center justify-center text-success', children: _jsx(PsIcon, { "aria-label": labels.done, className: 'h-4 w-4', iconKey: PsIconKey.Check }) })) : (_jsx(PsFileIconButton, { iconKey: PsIconKey.Close, label: `${labels.remove} ${item.file.name}`, onClick: onRemove }))] })] }));
|
|
24
20
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './ps-highlighted-text';
|
|
2
|
+
export * from './ps-image-viewer';
|
|
3
|
+
export * from './ps-media-viewer';
|
|
4
|
+
export * from './ps-pdf-page';
|
|
5
|
+
export * from './ps-pdf-thumbnail';
|
|
6
|
+
export * from './ps-pdf-viewer';
|
|
7
|
+
export * from './ps-text-viewer';
|
|
8
|
+
export * from './ps-unsupported-viewer';
|
|
@@ -18,10 +18,6 @@ export const PsPdfViewer = ({ activeMatch, file, labels, onMatchCount, pdfWorker
|
|
|
18
18
|
let opened = null;
|
|
19
19
|
setDocument(null);
|
|
20
20
|
setHasFailed(false);
|
|
21
|
-
if (pdfWorkerSrc === undefined) {
|
|
22
|
-
setHasFailed(true);
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
21
|
PsPdfService.open(file.url, pdfWorkerSrc)
|
|
26
22
|
.then(async (loaded) => {
|
|
27
23
|
opened = loaded;
|