@parallelworks/ui 0.25.0 → 0.26.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.
@@ -179,9 +179,11 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
179
179
  const findStorage = (storageId) => storages.find((s) => s.id === storageId);
180
180
  const storageCanWrite = (storageId) => findStorage(storageId)?.canWrite === true;
181
181
  const storageCanUpload = (storageId) => findStorage(storageId)?.canUpload !== false;
182
+ const storageCanDelete = (storage) => (storage?.canDelete ?? storage?.canWrite) === true;
182
183
  const selectedStorage = findStorage(selectedNode?.storageId);
183
184
  const selectedNodeCanWrite = selectedStorage?.canWrite === true;
184
185
  const selectedNodeCanUpload = selectedStorage?.canUpload !== false;
186
+ const selectedNodeCanDelete = storageCanDelete(selectedStorage);
185
187
  const selectedNodeCanShare = selectedStorage?.canShare !== false;
186
188
  const selectedNodeCanManageAccess = selectedStorage?.canManageAccess !== false;
187
189
  const [accessDrawerOpen, setAccessDrawerOpen] = useState(false);
@@ -587,7 +589,7 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
587
589
  triggerBrowserDownload(presignedUrl, node.name);
588
590
  };
589
591
  const deleteNode = (node) => {
590
- if (findStorage(node.storageId)?.canWrite !== true) {
592
+ if (!storageCanDelete(findStorage(node.storageId))) {
591
593
  notify.error(t.messages.noWriteAccess);
592
594
  return;
593
595
  }
@@ -610,7 +612,7 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
610
612
  };
611
613
  const buildRowMenu = (node) => {
612
614
  const storage = findStorage(node.storageId);
613
- const nodeCanWrite = storage?.canWrite === true;
615
+ const nodeCanDelete = storageCanDelete(storage);
614
616
  const nodeCanShare = storage?.canShare !== false;
615
617
  const isFile = node.type === "file";
616
618
  const uris = getNodeUris(node);
@@ -637,7 +639,7 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
637
639
  }
638
640
  actions.push(...getCreateFolderActions(node, storage));
639
641
  actions.push(...extraRowActions?.(node, storage) ?? []);
640
- if (nodeCanWrite && !node.root) actions.push({
642
+ if (nodeCanDelete && !node.root) actions.push({
641
643
  key: "delete",
642
644
  label: t.preview.delete,
643
645
  icon: /* @__PURE__ */ jsx(BiSolidTrashAlt, {}),
@@ -716,7 +718,7 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
716
718
  return downloadCommand.build(objects);
717
719
  };
718
720
  const onDeleteClick = () => {
719
- if (!selectedNodeCanWrite) {
721
+ if (!selectedNodeCanDelete) {
720
722
  notify.error(t.messages.noWriteAccess);
721
723
  return;
722
724
  }
@@ -1135,7 +1137,7 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
1135
1137
  children: t.chrome.manageAccess
1136
1138
  })]
1137
1139
  }),
1138
- selectedNodeCanWrite && /* @__PURE__ */ jsxs("button", {
1140
+ selectedNodeCanDelete && /* @__PURE__ */ jsxs("button", {
1139
1141
  type: "button",
1140
1142
  "aria-label": t.chrome.delete,
1141
1143
  className: "btn btn-destructive cursor-pointer flex items-center justify-center",
@@ -1,10 +1,12 @@
1
1
  import { useNotify, useStrings } from "../components/Provider.js";
2
2
  import { keyedByContent } from "../components/keys.js";
3
+ import { mapWithConcurrency } from "./lib/batch.js";
3
4
  import { calculateUploadNodesTotalSize, getUploadSessionETA, removeLeadingSlash } from "./lib/utils.js";
4
5
  import { UploadSessionToast } from "./toasts.js";
5
6
  import { createContext, use, useRef } from "react";
6
7
  import { jsx, jsxs } from "react/jsx-runtime";
7
8
  //#region src/file-explorer/FileExplorerContext.tsx
9
+ var UPLOAD_CONCURRENCY = 3;
8
10
  var FileExplorerContext = createContext(void 0);
9
11
  var permissionMessagePattern = /not authorized|access denied|status code 403/i;
10
12
  function isPermissionDenied(reason) {
@@ -157,7 +159,7 @@ function FileExplorerProvider({ children }) {
157
159
  closeButton: false,
158
160
  autoClose: false
159
161
  });
160
- const results = await Promise.allSettled(session.uploadNodes.map(async (node) => {
162
+ const results = await mapWithConcurrency(session.uploadNodes, UPLOAD_CONCURRENCY, async (node) => {
161
163
  const fileProgress = session.progress?.allFiles?.get(node.relativePath);
162
164
  if (!fileProgress) return;
163
165
  if (fileProgress.status === "cancelled") throw new Error("Upload cancelled by user");
@@ -228,7 +230,7 @@ function FileExplorerProvider({ children }) {
228
230
  });
229
231
  throw error;
230
232
  }
231
- }));
233
+ });
232
234
  try {
233
235
  await session.refreshTargetNode(session.targetNode);
234
236
  } catch (err) {
@@ -1,8 +1,8 @@
1
+ import { chunk, mapWithConcurrency, paginate } from "./lib/batch.js";
1
2
  import { attachmentDisposition, collectObjectKeysToDelete, getObjectKeyFromNode, isClientValid, removeLeadingAndTrailingSlashes } from "./lib/utils.js";
2
3
  import { FileExplorerProvider, useFileExplorer } from "./FileExplorerContext.js";
3
4
  import { CorsError } from "./lib/errors.js";
4
5
  import { NoDataAvailablePreview, SkeletonPreview } from "./helpers.js";
5
6
  import { LIST_PAGE_SIZE } from "./lib/paging.js";
6
7
  import FileExplorer from "./FileExplorer.js";
7
- import { chunk, mapWithConcurrency, paginate } from "./lib/batch.js";
8
8
  export { CorsError, FileExplorer, FileExplorerProvider, LIST_PAGE_SIZE, NoDataAvailablePreview, SkeletonPreview, attachmentDisposition, chunk, collectObjectKeysToDelete, getObjectKeyFromNode, isClientValid, mapWithConcurrency, paginate, removeLeadingAndTrailingSlashes, useFileExplorer };
@@ -22,6 +22,7 @@ export type TStorage = {
22
22
  imageUrl?: string;
23
23
  canWrite?: boolean | undefined;
24
24
  canUpload?: boolean | undefined;
25
+ canDelete?: boolean | undefined;
25
26
  canShare?: boolean | undefined;
26
27
  canManageAccess?: boolean | undefined;
27
28
  previewLimits?: Partial<PreviewLimits> | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parallelworks/ui",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "description": "React UI components: a theme contract, icons, primitives, lists, forms, a job graph, a code editor, a log viewer, a file explorer and an AI chat, each on its own subpath",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {