@parallelworks/ui 0.12.0 → 0.12.1
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/chunks/{CreateModal-g6c-9-6N.js → CreateModal-DLCC8t_x.js} +4 -3
- package/dist/file-explorer/index.d.ts +1 -1
- package/dist/file-explorer/index.js +9 -6
- package/dist/file-explorer/lib/fileExplorer.d.ts +3 -1
- package/dist/file-explorer/lib/utils.d.ts +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -581,12 +581,13 @@ function CreateModalSelectPanel({ open, options, label, value, collapsedLabel, o
|
|
|
581
581
|
* icons and group headers (e.g. Clusters vs Kubernetes). */
|
|
582
582
|
function CreateModalSelect({ label, icon, value, options, onChange, disabled = false, disabledHint, tooltip, collapsedLabel }) {
|
|
583
583
|
const selected = options.find((o) => o.value === value);
|
|
584
|
+
const selectedLabel = selected?.label ?? (value || void 0);
|
|
584
585
|
const pillContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
585
586
|
selected?.icon ?? icon,
|
|
586
|
-
|
|
587
|
+
selectedLabel ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
587
588
|
className: "font-normal text-(--theme-muted-text-color)",
|
|
588
589
|
children: label
|
|
589
|
-
}),
|
|
590
|
+
}), selectedLabel] }) : label,
|
|
590
591
|
/* @__PURE__ */ jsx(ChevronDownIcon, { className: "w-3 h-3 opacity-60" })
|
|
591
592
|
] });
|
|
592
593
|
if (disabled) return /* @__PURE__ */ jsx("button", {
|
|
@@ -602,7 +603,7 @@ function CreateModalSelect({ label, icon, value, options, onChange, disabled = f
|
|
|
602
603
|
});
|
|
603
604
|
return /* @__PURE__ */ jsx(Menu, { children: ({ open }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MenuButton, {
|
|
604
605
|
"aria-label": label,
|
|
605
|
-
className: cx("inline-flex h-7 rounded-md border border-(--theme-border) text-xs font-medium transition-colors hover:bg-(--theme-muted-panel-bg)",
|
|
606
|
+
className: cx("inline-flex h-7 rounded-md border border-(--theme-border) text-xs font-medium transition-colors hover:bg-(--theme-muted-panel-bg)", selectedLabel ? "text-(--theme-app)" : "text-(--theme-muted-text-color)"),
|
|
606
607
|
children: /* @__PURE__ */ jsx(PillTooltip, {
|
|
607
608
|
content: tooltip,
|
|
608
609
|
className: "px-2",
|
|
@@ -7,4 +7,4 @@ export { LIST_PAGE_SIZE } from './lib/paging.js';
|
|
|
7
7
|
export type { TreeNode, TStorage, TStorageObject } from './lib/types.js';
|
|
8
8
|
export { CorsError } from './lib/errors.js';
|
|
9
9
|
export { chunk, mapWithConcurrency, paginate } from './lib/batch.js';
|
|
10
|
-
export { collectObjectKeysToDelete, getObjectKeyFromNode, isClientValid, removeLeadingAndTrailingSlashes, } from './lib/utils.js';
|
|
10
|
+
export { attachmentDisposition, collectObjectKeysToDelete, getObjectKeyFromNode, isClientValid, removeLeadingAndTrailingSlashes, } from './lib/utils.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AccessIcon, AlertIcon, AngleDownIcon, AngleRightIcon, AngleUpIcon, ChevronLeftIcon, ChevronRightIcon, ClipboardIcon, CloseIcon, CloudUploadIcon, CollapseIcon, CustomizeIcon, DiskIcon, DocumentIcon, DownloadFileIcon, ExpandIcon, ExpandVerticalIcon, EyeIcon, FileIcon, FileTextIcon, FolderIcon, FolderOpenIcon, ImageIcon, LinkIcon, LockIcon, MinimizeIcon, MusicIcon, PdfIcon, RefreshIcon, ShareIcon, SpreadsheetIcon, SuccessIcon, TrashIcon, UploadIcon, UserIcon, VideoIcon, ZipIcon, ZoomInIcon, ZoomOutIcon } from "../icons.js";
|
|
2
|
-
import { c as ConfirmModal, f as Markdown, h as Callout, m as CopyToClipboard, n as CreateModal, p as CopyCodeBlock } from "../chunks/CreateModal-
|
|
2
|
+
import { c as ConfirmModal, f as Markdown, h as Callout, m as CopyToClipboard, n as CreateModal, p as CopyCodeBlock } from "../chunks/CreateModal-DLCC8t_x.js";
|
|
3
3
|
import { a as useProvisionCorsRules, c as useStrings, i as useNotify, s as useSlots } from "../chunks/Provider-CfFV-vc5.js";
|
|
4
4
|
import { n as TOOLTIP_ID, r as TooltipInfo } from "../chunks/Tooltip-WgbiC_nd.js";
|
|
5
5
|
import { t as StatusBadge } from "../chunks/StatusBadge-P6C2tv7Z.js";
|
|
@@ -239,6 +239,9 @@ function calculateUploadNodesTotalSize(uploadNodes) {
|
|
|
239
239
|
function getObjectKeyFromNode(node) {
|
|
240
240
|
return node.relativePath || node.path.split("/").filter(Boolean).slice(1).join("/");
|
|
241
241
|
}
|
|
242
|
+
function attachmentDisposition(filename) {
|
|
243
|
+
return `attachment; filename="${filename.replace(/[^\x20-\x7e]|["\\]/g, "_")}"; filename*=UTF-8''${encodeURIComponent(filename).replace(/['()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`)}`;
|
|
244
|
+
}
|
|
242
245
|
function getDirectoryPrefixFromNode(node) {
|
|
243
246
|
const key = getObjectKeyFromNode(node);
|
|
244
247
|
if (!key) throw new Error(`Cannot resolve an object prefix for ${node.path}`);
|
|
@@ -4641,7 +4644,7 @@ function FileExplorer({ storages, onRefresh, showUserHierarchy = false, groups =
|
|
|
4641
4644
|
return;
|
|
4642
4645
|
}
|
|
4643
4646
|
for (const [index, node] of filesToDownload.entries()) {
|
|
4644
|
-
const input = provider.getFileInput(node.storageName ?? "", node);
|
|
4647
|
+
const input = provider.getFileInput(node.storageName ?? "", node, void 0, node.name);
|
|
4645
4648
|
const [presignedUrl, error] = await client.getFile(input);
|
|
4646
4649
|
if (error || !presignedUrl) {
|
|
4647
4650
|
notify.error(error?.message ?? t.messages.downloadLinkFailed);
|
|
@@ -4679,12 +4682,12 @@ function FileExplorer({ storages, onRefresh, showUserHierarchy = false, groups =
|
|
|
4679
4682
|
document.body.removeChild(a);
|
|
4680
4683
|
}, 300);
|
|
4681
4684
|
};
|
|
4682
|
-
const getPresignedUrl = async (node) => {
|
|
4685
|
+
const getPresignedUrl = async (node, downloadFilename) => {
|
|
4683
4686
|
const factory = await getStorageProviderAndClient(node.storageId);
|
|
4684
4687
|
if (!factory) return [null, /* @__PURE__ */ new Error("Failed to connect to storage provider.")];
|
|
4685
4688
|
const { provider, client } = factory;
|
|
4686
4689
|
if (!provider?.getFileInput) return [null, /* @__PURE__ */ new Error("Preview is not supported for this storage.")];
|
|
4687
|
-
const input = provider.getFileInput(node.storageName ?? "", node, PREVIEW_URL_EXPIRES_IN);
|
|
4690
|
+
const input = provider.getFileInput(node.storageName ?? "", node, PREVIEW_URL_EXPIRES_IN, downloadFilename);
|
|
4688
4691
|
return client.getFile(input);
|
|
4689
4692
|
};
|
|
4690
4693
|
const previewSiblings = useMemo(() => previewNode ? getNodeChildren(parentToChildrenMap, getParentPath(previewNode.path)).filter((n) => n.type === "file") : [], [previewNode, parentToChildrenMap]);
|
|
@@ -4723,7 +4726,7 @@ function FileExplorer({ storages, onRefresh, showUserHierarchy = false, groups =
|
|
|
4723
4726
|
}
|
|
4724
4727
|
};
|
|
4725
4728
|
const downloadNode = async (node) => {
|
|
4726
|
-
const [presignedUrl, error] = await getPresignedUrl(node);
|
|
4729
|
+
const [presignedUrl, error] = await getPresignedUrl(node, node.name);
|
|
4727
4730
|
if (error || !presignedUrl) {
|
|
4728
4731
|
notify.error(error?.message ?? t.messages.downloadLinkFailed);
|
|
4729
4732
|
return;
|
|
@@ -5641,4 +5644,4 @@ async function mapWithConcurrency(items, limit, worker) {
|
|
|
5641
5644
|
return results;
|
|
5642
5645
|
}
|
|
5643
5646
|
//#endregion
|
|
5644
|
-
export { CorsError, FileExplorer, FileExplorerProvider, LIST_PAGE_SIZE, NoDataAvailablePreview, SkeletonPreview, chunk, collectObjectKeysToDelete, getObjectKeyFromNode, isClientValid, mapWithConcurrency, paginate, removeLeadingAndTrailingSlashes, useFileExplorer };
|
|
5647
|
+
export { CorsError, FileExplorer, FileExplorerProvider, LIST_PAGE_SIZE, NoDataAvailablePreview, SkeletonPreview, attachmentDisposition, chunk, collectObjectKeysToDelete, getObjectKeyFromNode, isClientValid, mapWithConcurrency, paginate, removeLeadingAndTrailingSlashes, useFileExplorer };
|
|
@@ -26,7 +26,9 @@ export interface IFileExplorerProvider {
|
|
|
26
26
|
* the same bivariance reason as the two above. */
|
|
27
27
|
nextPageCursor?(data: unknown): string | undefined;
|
|
28
28
|
listDirectoryInput?: ((storage: TStorage, dir_path?: string, page?: TListPageRequest) => unknown) | null;
|
|
29
|
-
|
|
29
|
+
/** `downloadFilename` asks for a URL that saves under that name. Omit it for a
|
|
30
|
+
* link the user keeps, or for a read the app parses itself. */
|
|
31
|
+
getFileInput?: ((storageName: string, node: TreeNode, presignedUrlExpiresIn?: number, downloadFilename?: string) => unknown) | null;
|
|
30
32
|
deleteFilesInput?: ((storageName: string, nodes: TreeNode[]) => unknown) | null;
|
|
31
33
|
uploadFileInput?: ((storageName: string, objectPath: string, file: File | Blob) => unknown) | null;
|
|
32
34
|
}
|
|
@@ -20,6 +20,7 @@ export declare function getUploadNodesFromDataTransferItems(items: DataTransferI
|
|
|
20
20
|
}>;
|
|
21
21
|
export declare function calculateUploadNodesTotalSize(uploadNodes: UploadNode[]): number;
|
|
22
22
|
export declare function getObjectKeyFromNode(node: TreeNode): string;
|
|
23
|
+
export declare function attachmentDisposition(filename: string): string;
|
|
23
24
|
export declare function getDirectoryPrefixFromNode(node: TreeNode): string;
|
|
24
25
|
export declare function pruneNodesInsideSelectedDirectories(nodes: TreeNode[]): TreeNode[];
|
|
25
26
|
export declare function collectObjectKeysToDelete(nodes: TreeNode[], listKeysUnderPrefix: (prefix: string) => Promise<string[]>): Promise<string[]>;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_PRESET, THEME_PRESETS, THEME_TOKENS, applyTheme, contrastRatio, deriveTheme, isDarkColor } from "./theme/index.js";
|
|
2
2
|
import { AlertIcon, AngleRightIcon, EyeIcon, EyeOffIcon, FilterIcon, LoaderIcon, SortDownIcon, SortUnsortedIcon, SortUpIcon } from "./icons.js";
|
|
3
|
-
import { a as CreateModalSelect, c as ConfirmModal, d as primaryButtonClasses, f as Markdown, h as Callout, i as CreateModalField, l as dangerButtonClasses, m as CopyToClipboard, n as CreateModal, o as CreateModalSwitch, p as CopyCodeBlock, r as CreateModalAutocompleteField, s as CreateModalTextarea, t as CREATE_MODAL_SELECT_FILTER_THRESHOLD, u as ghostButtonClasses } from "./chunks/CreateModal-
|
|
3
|
+
import { a as CreateModalSelect, c as ConfirmModal, d as primaryButtonClasses, f as Markdown, h as Callout, i as CreateModalField, l as dangerButtonClasses, m as CopyToClipboard, n as CreateModal, o as CreateModalSwitch, p as CopyCodeBlock, r as CreateModalAutocompleteField, s as CreateModalTextarea, t as CREATE_MODAL_SELECT_FILTER_THRESHOLD, u as ghostButtonClasses } from "./chunks/CreateModal-DLCC8t_x.js";
|
|
4
4
|
import { a as useProvisionCorsRules, c as useStrings, i as useNotify, l as useWorkflowJsonResolver, n as useLink, o as useRunFile, r as useNavigation, s as useSlots, t as UIProvider } from "./chunks/Provider-CfFV-vc5.js";
|
|
5
5
|
import { i as formatTooltipContent, n as TOOLTIP_ID, r as TooltipInfo, t as GlobalTooltip } from "./chunks/Tooltip-WgbiC_nd.js";
|
|
6
6
|
import { c as isOption, i as filterOption, l as toggleSetMember, n as StatusDot, o as flattenOptions, r as DropdownCaret, s as isCategory, t as StatusBadge } from "./chunks/StatusBadge-P6C2tv7Z.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parallelworks/ui",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "Shared UI foundation for Parallel Works packages: theme contract, icons, and core primitives",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Parallel Works <support@parallelworks.com>",
|