@parallelworks/ui 0.13.0 → 0.15.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/chunks/{CodePreviewEditor-67A_SKgE.js → CodePreviewEditor-DuMZMA_k.js} +1 -1
- package/dist/chunks/{CreateModal-k_e1dI8c.js → CreateModal-B7smkHkv.js} +26 -10
- package/dist/chunks/{Monaco-H56KyEdb.js → Monaco-BXDH2jVj.js} +1 -1
- package/dist/chunks/{PageHeader-FhtphHGc.js → PageHeader-CoZWF0pJ.js} +22 -9
- package/dist/chunks/{StatusBadge-RRUI78iS.js → StatusBadge-zvEtK16a.js} +1 -1
- package/dist/chunks/{SwitchToggle-DbW0Q__L.js → SwitchToggle-3V836Cn7.js} +23 -15
- package/dist/chunks/{editor-BZ9Buwi4.js → editor-Ko3zX22Y.js} +2 -2
- package/dist/chunks/{lib-DyJvmbzj.js → lib-CUTRDpa6.js} +3 -5
- package/dist/chunks/{list-3jZW8rmM.js → list-CduoUsMW.js} +13 -10
- package/dist/components/CollapsiblePanel.d.ts +3 -1
- package/dist/components/CreateModal.d.ts +6 -0
- package/dist/components/PageHeader.d.ts +5 -1
- package/dist/components/dropdownUtils.d.ts +2 -0
- package/dist/editor/index.js +1 -1
- package/dist/file-explorer/FileExplorer.d.ts +19 -2
- package/dist/file-explorer/index.js +65 -35
- package/dist/form/Form.d.ts +12 -8
- package/dist/form/index.d.ts +1 -1
- package/dist/form/index.js +84 -32
- package/dist/icons.d.ts +3 -3
- package/dist/icons.js +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -8
- package/dist/list/HoverCard.d.ts +3 -1
- package/dist/list/ListPage.d.ts +2 -0
- package/dist/list/ListTable.d.ts +2 -1
- package/dist/list/RowContextMenu.d.ts +5 -0
- package/dist/list/index.js +2 -2
- package/dist/styles/theme.css +40 -0
- package/dist/styles.css +1 -1
- package/dist/workflow/index.js +50 -2
- package/dist/workflow/types.d.ts +2 -0
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as useCssIsDark } from "./useCssIsDark-DHr05dG2.js";
|
|
2
|
-
import { n as defineEditorThemes, r as getThemeName, t as setupMonacoWorkers } from "./editor-
|
|
2
|
+
import { n as defineEditorThemes, r as getThemeName, t as setupMonacoWorkers } from "./editor-Ko3zX22Y.js";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { useEffect, useRef } from "react";
|
|
5
5
|
import * as monaco from "monaco-editor";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { AlertIcon, CheckIcon, ChevronDownIcon, ChevronRightIcon, ClipboardIcon, CopyIcon, FavoriteIcon, FavoriteOutlineIcon, HiddenFalseIcon, HiddenTrueIcon, InfoIcon, TooltipIcon } from "../icons.js";
|
|
2
2
|
import { c as useStrings, i as useNotify } from "./Provider-CbFVFB7O.js";
|
|
3
3
|
import { n as TOOLTIP_ID } from "./Tooltip-n9w7Tkt1.js";
|
|
4
|
-
import { i as filterOption, l as toggleSetMember } from "./StatusBadge-
|
|
4
|
+
import { i as filterOption, l as toggleSetMember } from "./StatusBadge-zvEtK16a.js";
|
|
5
5
|
import { n as modalPanelClasses, t as BareModal } from "./BareModal-BqroLbZ5.js";
|
|
6
|
-
import {
|
|
6
|
+
import { w as AddMenu } from "./PageHeader-CoZWF0pJ.js";
|
|
7
7
|
import cx from "classnames";
|
|
8
8
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
import { Suspense, lazy, useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -280,7 +280,7 @@ function CreateModal({ open, onClose, typeIcon, typeLabel, typeMenu, namePlaceho
|
|
|
280
280
|
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) handleSubmit();
|
|
281
281
|
},
|
|
282
282
|
onPanelMouseDown: (e) => {
|
|
283
|
-
if (e.target instanceof Element && !e.target.closest("input, textarea, button, a, select, label")) e.preventDefault();
|
|
283
|
+
if (e.target instanceof Element && !e.target.closest("input, textarea, button, a, select, label, code, pre, .select-all")) e.preventDefault();
|
|
284
284
|
},
|
|
285
285
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
286
286
|
className: "flex-1 min-h-0 overflow-y-auto overscroll-contain",
|
|
@@ -514,7 +514,7 @@ function pushToggleRowOnce(nodes, toggledGroups, group, count, collapse) {
|
|
|
514
514
|
function buildOptionNodes(options, query, onChange, collapse) {
|
|
515
515
|
const trimmed = query.trim();
|
|
516
516
|
const q = trimmed.toLowerCase().replace(/-/g, "");
|
|
517
|
-
const filtered = q ? options.filter((o) => filterOption({
|
|
517
|
+
const filtered = q ? options.filter((o) => o.pinned || filterOption({
|
|
518
518
|
label: o.label,
|
|
519
519
|
value: o.value,
|
|
520
520
|
secondaryValue: o.group
|
|
@@ -536,12 +536,28 @@ function buildOptionNodes(options, query, onChange, collapse) {
|
|
|
536
536
|
pushToggleRowOnce(nodes, toggledGroups, group, collapsibleCounts.get(group) ?? 0, collapse);
|
|
537
537
|
if (!collapse.expanded.has(group)) continue;
|
|
538
538
|
}
|
|
539
|
-
nodes.push(/* @__PURE__ */ jsx(MenuItem, {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
539
|
+
nodes.push(/* @__PURE__ */ jsx(MenuItem, {
|
|
540
|
+
disabled: option.disabled ?? false,
|
|
541
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
542
|
+
type: "button",
|
|
543
|
+
disabled: option.disabled,
|
|
544
|
+
"aria-disabled": option.disabled,
|
|
545
|
+
"aria-label": option.description ? option.label : void 0,
|
|
546
|
+
"aria-description": option.description,
|
|
547
|
+
onClick: () => onChange(option.value),
|
|
548
|
+
className: cx("flex w-full items-center gap-2 px-3 py-1.5 text-left text-[13px] data-[focus]:bg-(--theme-muted-panel-bg)", option.disabled ? "cursor-not-allowed text-(--theme-muted-text-color)" : "cursor-pointer text-(--theme-app)", option.pinned && "mt-1 border-t border-(--theme-border) pt-2 font-medium"),
|
|
549
|
+
children: [option.icon, option.description ? /* @__PURE__ */ jsxs("span", {
|
|
550
|
+
className: "flex min-w-0 flex-col",
|
|
551
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
552
|
+
className: "truncate",
|
|
553
|
+
children: option.label
|
|
554
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
555
|
+
className: "truncate text-[11px] font-normal text-(--theme-muted-text-color)",
|
|
556
|
+
children: option.description
|
|
557
|
+
})]
|
|
558
|
+
}) : option.label]
|
|
559
|
+
})
|
|
560
|
+
}, option.value));
|
|
545
561
|
}
|
|
546
562
|
return nodes;
|
|
547
563
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { l as useWorkflowJsonResolver } from "./Provider-CbFVFB7O.js";
|
|
2
2
|
import { t as useCssIsDark } from "./useCssIsDark-DHr05dG2.js";
|
|
3
|
-
import { n as defineEditorThemes, r as getThemeName, t as setupMonacoWorkers } from "./editor-
|
|
3
|
+
import { n as defineEditorThemes, r as getThemeName, t as setupMonacoWorkers } from "./editor-Ko3zX22Y.js";
|
|
4
4
|
import cx from "classnames";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
import { useEffect, useRef } from "react";
|
|
@@ -128,7 +128,8 @@ function toRowMenuItem(action) {
|
|
|
128
128
|
icon: action.icon,
|
|
129
129
|
onSelect: action.onSelect ?? (() => {}),
|
|
130
130
|
disabled: action.disabled,
|
|
131
|
-
destructive: action.destructive
|
|
131
|
+
destructive: action.destructive,
|
|
132
|
+
tooltip: action.tooltip
|
|
132
133
|
};
|
|
133
134
|
}
|
|
134
135
|
/** Bridges a toolbar action (icon component, `onClick`/`href`) onto the shared
|
|
@@ -143,7 +144,8 @@ function toolbarActionToRowAction(action) {
|
|
|
143
144
|
onSelect: action.onClick,
|
|
144
145
|
to: action.href,
|
|
145
146
|
disabled: action.disabled,
|
|
146
|
-
destructive: action.key === "delete" || action.key === "destroy"
|
|
147
|
+
destructive: action.key === "delete" || action.key === "destroy",
|
|
148
|
+
tooltip: action.disabledTooltip
|
|
147
149
|
};
|
|
148
150
|
}
|
|
149
151
|
/** Assembles a row's context menu in the shared order: leading link(s) → middle
|
|
@@ -344,8 +346,14 @@ function MenuRow({ item, onClose, side }) {
|
|
|
344
346
|
});
|
|
345
347
|
return /* @__PURE__ */ jsxs("button", {
|
|
346
348
|
type: "button",
|
|
347
|
-
disabled: item.disabled,
|
|
349
|
+
disabled: item.disabled && !item.tooltip,
|
|
350
|
+
"aria-disabled": item.disabled,
|
|
351
|
+
...item.disabled && item.tooltip ? {
|
|
352
|
+
"data-tooltip-id": TOOLTIP_ID,
|
|
353
|
+
"data-tooltip-content": item.tooltip
|
|
354
|
+
} : {},
|
|
348
355
|
onClick: () => {
|
|
356
|
+
if (item.disabled) return;
|
|
349
357
|
if (item.copy) {
|
|
350
358
|
const { text, label } = item.copy;
|
|
351
359
|
navigator.clipboard?.writeText(text).then(() => notify.success(t.copied(label)), () => notify.error(t.couldntCopy(label)));
|
|
@@ -440,7 +448,7 @@ var headerAddButtonClasses = "inline-flex h-[26px] shrink-0 items-center gap-1.5
|
|
|
440
448
|
/** With menu, the plus opens a chooser; otherwise navigates to or calls the
|
|
441
449
|
* single action. `word` is the visible verb; `label` stays the full action for
|
|
442
450
|
* the tooltip and screen readers. */
|
|
443
|
-
function HeaderAddButton({ to, onClick, label, word = "add", menu }) {
|
|
451
|
+
function HeaderAddButton({ to, onClick, label, word = "add", menu, disabled = false, disabledHint }) {
|
|
444
452
|
const { common } = useStrings();
|
|
445
453
|
const Link = useLink();
|
|
446
454
|
const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(AddIcon, { className: "w-3 h-3" }), /* @__PURE__ */ jsx("span", { children: word === "create" ? common.create : common.add })] });
|
|
@@ -457,12 +465,17 @@ function HeaderAddButton({ to, onClick, label, word = "add", menu }) {
|
|
|
457
465
|
className: headerAddButtonClasses,
|
|
458
466
|
children: content
|
|
459
467
|
});
|
|
468
|
+
const hint = disabled ? disabledHint : void 0;
|
|
460
469
|
return /* @__PURE__ */ jsx("button", {
|
|
461
470
|
type: "button",
|
|
462
|
-
onClick,
|
|
463
|
-
"aria-label": label,
|
|
464
|
-
|
|
465
|
-
|
|
471
|
+
onClick: disabled ? void 0 : onClick,
|
|
472
|
+
"aria-label": hint ? `${label}. ${hint}` : label,
|
|
473
|
+
"aria-disabled": disabled || void 0,
|
|
474
|
+
...hint ? {
|
|
475
|
+
"data-tooltip-id": TOOLTIP_ID,
|
|
476
|
+
"data-tooltip-content": hint
|
|
477
|
+
} : { title: label },
|
|
478
|
+
className: cx(headerAddButtonClasses, "aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:hover:bg-transparent aria-disabled:hover:text-(--theme-muted-text-color)"),
|
|
466
479
|
children: content
|
|
467
480
|
});
|
|
468
481
|
}
|
|
@@ -611,4 +624,4 @@ function PageHeader({ breadcrumbs, title, titleAction, actions, toolbar, classNa
|
|
|
611
624
|
});
|
|
612
625
|
}
|
|
613
626
|
//#endregion
|
|
614
|
-
export {
|
|
627
|
+
export { useSetDefaultBreadcrumbs as C, useSetBreadcrumbs as S, useRowMenuActive as _, HeaderAddButton as a, useClearBreadcrumbs as b, PageHeader as c, assembleRowMenu as d, copySubmenu as f, useRowMenu as g, toolbarActionToRowAction as h, HeaderActionMenu as i, headerActionButtonClasses as l, toRowMenuItem as m, BreadcrumbsRightAction as n, HeaderEditButton as o, rowContextMenuProps as p, BreadcrumbsTitleAction as r, HeaderRowMenu as s, BreadcrumbsActionButton as t, MoreButton as u, BreadcrumbProvider as v, AddMenu as w, useHideBreadcrumbs as x, useBreadcrumb as y };
|
|
@@ -67,7 +67,7 @@ function collapsedCategoryRows(category, filtered, collapsibleCount, expanded, c
|
|
|
67
67
|
}
|
|
68
68
|
function flattenDisplayOptions({ options, query, expandedCategories, collapsedLabel, selectedValue, allowCustomValue, customValueLabel }) {
|
|
69
69
|
const flatOptions = options.flatMap((option) => {
|
|
70
|
-
if (!isCategory(option)) return filterOption(option, query) ? [option] : [];
|
|
70
|
+
if (!isCategory(option)) return option.pinned || filterOption(option, query) ? [option] : [];
|
|
71
71
|
const filtered = option.options.filter((opt) => filterOption(opt, query));
|
|
72
72
|
if (filtered.length === 0) return [];
|
|
73
73
|
const category = option.category || "";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AngleDownIcon, AngleRightIcon, CaretDownIcon } from "../icons.js";
|
|
2
2
|
import { c as useStrings } from "./Provider-CbFVFB7O.js";
|
|
3
3
|
import { a as truncationTooltipProps, n as TOOLTIP_ID } from "./Tooltip-n9w7Tkt1.js";
|
|
4
|
-
import { a as flattenDisplayOptions, c as isOption, i as filterOption, l as toggleSetMember, o as flattenOptions, r as DropdownCaret, s as isCategory } from "./StatusBadge-
|
|
4
|
+
import { a as flattenDisplayOptions, c as isOption, i as filterOption, l as toggleSetMember, o as flattenOptions, r as DropdownCaret, s as isCategory } from "./StatusBadge-zvEtK16a.js";
|
|
5
5
|
import cx from "classnames";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
@@ -263,6 +263,7 @@ function DropdownHelper({ wrapperClassName = "w-full", className, textBoxClassNa
|
|
|
263
263
|
const optionDescription = typeof option !== "string" ? option.description : void 0;
|
|
264
264
|
const isCategoryRow = typeof option !== "string" && Boolean(option.category);
|
|
265
265
|
const toggleTarget = typeof option !== "string" ? option.toggle : void 0;
|
|
266
|
+
const isPinned = typeof option !== "string" && Boolean(option.pinned);
|
|
266
267
|
if (toggleTarget !== void 0) return /* @__PURE__ */ jsx(ToggleOption, {
|
|
267
268
|
option,
|
|
268
269
|
category: toggleTarget,
|
|
@@ -272,7 +273,7 @@ function DropdownHelper({ wrapperClassName = "w-full", className, textBoxClassNa
|
|
|
272
273
|
return /* @__PURE__ */ jsx(ComboboxOption, {
|
|
273
274
|
"data-testid": "combobox-option",
|
|
274
275
|
value: option,
|
|
275
|
-
className: cx("w-full group relative flex", optionDescription ? "min-h-10 py-2" : "h-10", isCategoryRow ? "text-[14px] font-bold pl-1 items-center" : "data-disabled:text-(--theme-muted-text-color) data-disabled:bg-(--theme-muted-panel-bg) data-disabled:cursor-not-allowed cursor-pointer items-center pr-9 pl-3 leading-5 data-focus:bg-(--theme-muted-panel-bg) data-focus:text-(--theme-app) data-focus:outline-hidden", "data-selected:border-l-2 data-selected:border-(--theme-link) data-selected:bg-(--theme-muted-panel-bg) data-selected:text-(--theme-app)"),
|
|
276
|
+
className: cx("w-full group relative flex", optionDescription ? "min-h-10 py-2" : "h-10", isCategoryRow ? "text-[14px] font-bold pl-1 items-center" : "data-disabled:text-(--theme-muted-text-color) data-disabled:bg-(--theme-muted-panel-bg) data-disabled:cursor-not-allowed cursor-pointer items-center pr-9 pl-3 leading-5 data-focus:bg-(--theme-muted-panel-bg) data-focus:text-(--theme-app) data-focus:outline-hidden", "data-selected:border-l-2 data-selected:border-(--theme-link) data-selected:bg-(--theme-muted-panel-bg) data-selected:text-(--theme-app)", isPinned && "border-t border-(--theme-border) font-medium"),
|
|
276
277
|
children: /* @__PURE__ */ jsx(OptionContent, {
|
|
277
278
|
label: optionLabel,
|
|
278
279
|
description: optionDescription,
|
|
@@ -619,7 +620,7 @@ function MultiSelectDropdown({ options, value, onChange, id, "aria-labelledby":
|
|
|
619
620
|
//#endregion
|
|
620
621
|
//#region src/components/CollapsiblePanel.tsx
|
|
621
622
|
var noop = () => {};
|
|
622
|
-
function ControlledCollapsiblePanel({ title = "", children, open, setOpen, onClick = noop, wrapperElement, customizedButton = null, className }) {
|
|
623
|
+
function ControlledCollapsiblePanel({ title = "", children, open, setOpen, onClick = noop, wrapperElement, customizedButton = null, titleAction, className }) {
|
|
623
624
|
const toggleOpen = useCallback(() => {
|
|
624
625
|
if (onClick) onClick();
|
|
625
626
|
setOpen?.((open) => !open);
|
|
@@ -633,18 +634,25 @@ function ControlledCollapsiblePanel({ title = "", children, open, setOpen, onCli
|
|
|
633
634
|
}) })] }) : /* @__PURE__ */ jsxs("div", {
|
|
634
635
|
className: cx("border border-solid rounded-2xl border-(--theme-border) bg-(--theme-panel-bg) text-(--theme-panel) mb-1 w-full", className),
|
|
635
636
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
636
|
-
className: cx(!open && "text-(--theme-muted-text-color)", "w-full flex items-center
|
|
637
|
-
children: [
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
className: "px-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
637
|
+
className: cx(!open && "text-(--theme-muted-text-color)", "w-full flex items-center transform ease-in transition text-sm py-3 px-2 cursor-pointer"),
|
|
638
|
+
children: [
|
|
639
|
+
/* @__PURE__ */ jsxs("button", {
|
|
640
|
+
type: "button",
|
|
641
|
+
"aria-expanded": !!open,
|
|
642
|
+
"aria-controls": contentId,
|
|
643
|
+
className: cx("flex items-center text-left cursor-pointer", !titleAction && "w-full"),
|
|
644
|
+
onClick: toggleOpen,
|
|
645
|
+
children: [/* @__PURE__ */ jsx(AngleRightIcon, { className: cx(open && "transform rotate-90", "px-1 ml-1 text-[1.25rem] transition ease-in") }), /* @__PURE__ */ jsx("span", {
|
|
646
|
+
className: "px-2 font-bold select-none",
|
|
647
|
+
children: title?.toString()
|
|
648
|
+
})]
|
|
649
|
+
}),
|
|
650
|
+
titleAction,
|
|
651
|
+
/* @__PURE__ */ jsx("div", {
|
|
652
|
+
className: "ml-auto",
|
|
653
|
+
children: customizedButton
|
|
654
|
+
})
|
|
655
|
+
]
|
|
648
656
|
}), /* @__PURE__ */ jsx(AnimateHeight, {
|
|
649
657
|
id: contentId,
|
|
650
658
|
duration: 300,
|
|
@@ -2,14 +2,14 @@ import { CheckIcon, CopyIcon, EyeIcon, EyeOffIcon } from "../icons.js";
|
|
|
2
2
|
import { c as useStrings, i as useNotify } from "./Provider-CbFVFB7O.js";
|
|
3
3
|
import { t as Loader } from "./Loader-BXoXTZGc.js";
|
|
4
4
|
import { t as SwitchToggleSmall } from "./SwitchToggleSmall-FcsaYSTs.js";
|
|
5
|
-
import { c as FieldWrapper, n as flattenGroups, r as impureSetValueFromPath } from "./lib-
|
|
5
|
+
import { c as FieldWrapper, n as flattenGroups, r as impureSetValueFromPath } from "./lib-CUTRDpa6.js";
|
|
6
6
|
import cx from "classnames";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { Suspense, lazy, useId, useMemo, useRef, useState } from "react";
|
|
9
9
|
import { convertToDynamicForm, parseStringsOfObj, parseStringsOfObjReady } from "@parallelworks/workflow-parser";
|
|
10
10
|
import { useField, useFormikContext } from "formik";
|
|
11
11
|
//#region src/editor/Editor.tsx
|
|
12
|
-
var MonacoEditor = lazy(() => import("./Monaco-
|
|
12
|
+
var MonacoEditor = lazy(() => import("./Monaco-BXDH2jVj.js"));
|
|
13
13
|
function Editor({ ...props }) {
|
|
14
14
|
return /* @__PURE__ */ jsx(Suspense, {
|
|
15
15
|
fallback: /* @__PURE__ */ jsx(Loader, { text: "Loading editor..." }),
|
|
@@ -115,11 +115,9 @@ function enforceOneMustBeTrue(items, options, promoteIndex) {
|
|
|
115
115
|
const oneMustBeTrueFields = Object.keys(options).filter((key) => typeof options[key] === "object" && options[key] !== null && "one_must_be_true" in options[key] && options[key].one_must_be_true);
|
|
116
116
|
for (const fieldKey of oneMustBeTrueFields) {
|
|
117
117
|
const fieldSchema = options[fieldKey];
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (!items.some((item) => item[fieldKey] === trueOption)) items[clampedIndex][fieldKey] = trueOption;
|
|
122
|
-
}
|
|
118
|
+
const opts = typeof fieldSchema === "object" && fieldSchema && "options" in fieldSchema ? fieldSchema.options : void 0;
|
|
119
|
+
const trueOption = typeof opts === "object" && opts && !Array.isArray(opts) && "onOption" in opts ? opts.onOption || true : true;
|
|
120
|
+
if (!items.some((item) => item[fieldKey] === trueOption)) items[clampedIndex][fieldKey] = trueOption;
|
|
123
121
|
}
|
|
124
122
|
return items;
|
|
125
123
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, DisplayIcon, ErrorIcon, FilterIcon, MenuIcon, SearchIcon, XIcon } from "../icons.js";
|
|
2
2
|
import { c as useStrings, n as useLink, r as useNavigation } from "./Provider-CbFVFB7O.js";
|
|
3
3
|
import { n as TOOLTIP_ID, r as TooltipInfo } from "./Tooltip-n9w7Tkt1.js";
|
|
4
|
-
import {
|
|
4
|
+
import { _ as useRowMenuActive, c as PageHeader, p as rowContextMenuProps, u as MoreButton } from "./PageHeader-CoZWF0pJ.js";
|
|
5
5
|
import { n as Table } from "./Table-CutP1bRt.js";
|
|
6
6
|
import cx from "classnames";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -203,13 +203,16 @@ var listTableFixedProps = {
|
|
|
203
203
|
...listTableProps,
|
|
204
204
|
className: listTableProps.className.replace("table-auto", "table-fixed")
|
|
205
205
|
};
|
|
206
|
-
function NameCell({ icon, name, subtitle, href }) {
|
|
206
|
+
function NameCell({ icon, name, subtitle, href, badge }) {
|
|
207
207
|
const Link = useLink();
|
|
208
208
|
const inner = /* @__PURE__ */ jsxs(Fragment, { children: [icon, /* @__PURE__ */ jsxs("div", {
|
|
209
209
|
className: "min-w-0",
|
|
210
|
-
children: [/* @__PURE__ */
|
|
211
|
-
className:
|
|
212
|
-
children:
|
|
210
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
211
|
+
className: "flex min-w-0 items-center gap-1.5",
|
|
212
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
213
|
+
className: cx(NAME_TEXT, href && "group-hover/namecell:text-(--theme-link)"),
|
|
214
|
+
children: name
|
|
215
|
+
}), badge]
|
|
213
216
|
}), subtitle && /* @__PURE__ */ jsx("div", {
|
|
214
217
|
className: SUBTITLE_TEXT,
|
|
215
218
|
children: subtitle
|
|
@@ -219,7 +222,7 @@ function NameCell({ icon, name, subtitle, href }) {
|
|
|
219
222
|
className: "py-2.5",
|
|
220
223
|
children: href ? /* @__PURE__ */ jsx(Link, {
|
|
221
224
|
to: href,
|
|
222
|
-
className: "flex items-center gap-2.5 min-w-0 cursor-pointer",
|
|
225
|
+
className: "group/namecell flex items-center gap-2.5 min-w-0 cursor-pointer",
|
|
223
226
|
children: inner
|
|
224
227
|
}) : /* @__PURE__ */ jsx("div", {
|
|
225
228
|
className: "flex items-center gap-2.5 min-w-0",
|
|
@@ -390,7 +393,7 @@ function ListPage({ section = "main", shellPadded, embedded = false, breadcrumbs
|
|
|
390
393
|
actions,
|
|
391
394
|
toolbar
|
|
392
395
|
}), /* @__PURE__ */ jsx("div", {
|
|
393
|
-
className: "@container min-h-0 flex-1 overflow-auto",
|
|
396
|
+
className: "relative @container min-h-0 flex-1 overflow-auto",
|
|
394
397
|
children: /* @__PURE__ */ jsx(ListRowActionsProvider, {
|
|
395
398
|
view,
|
|
396
399
|
children
|
|
@@ -434,7 +437,7 @@ function ListRow({ href, items, goTo, openMenu, pinnedActions, selected, selecti
|
|
|
434
437
|
type: "button",
|
|
435
438
|
"aria-label": action.label,
|
|
436
439
|
"data-tooltip-id": "global-tooltip",
|
|
437
|
-
"data-tooltip-content": action.label,
|
|
440
|
+
"data-tooltip-content": action.disabled && action.tooltip ? action.tooltip : action.label,
|
|
438
441
|
"data-tooltip-place": "bottom",
|
|
439
442
|
"aria-disabled": action.disabled,
|
|
440
443
|
onClick: (e) => {
|
|
@@ -1259,7 +1262,7 @@ function useHoverCard() {
|
|
|
1259
1262
|
keepOpen
|
|
1260
1263
|
};
|
|
1261
1264
|
}
|
|
1262
|
-
function HoverCardSurface({ x, y, widthClassName, relayoutKey, onKeepOpen, onLeave, children }) {
|
|
1265
|
+
function HoverCardSurface({ x, y, widthClassName, padded = true, relayoutKey, onKeepOpen, onLeave, children }) {
|
|
1263
1266
|
const ref = useRef(null);
|
|
1264
1267
|
const [pos, setPos] = useState(null);
|
|
1265
1268
|
useLayoutEffect(() => {
|
|
@@ -1282,7 +1285,7 @@ function HoverCardSurface({ x, y, widthClassName, relayoutKey, onKeepOpen, onLea
|
|
|
1282
1285
|
onMouseLeave: onLeave,
|
|
1283
1286
|
onFocus: onKeepOpen,
|
|
1284
1287
|
onBlur: onLeave,
|
|
1285
|
-
className: cx("fixed z-[9999] rounded-xl border border-(--theme-border) bg-(--theme-panel-bg)
|
|
1288
|
+
className: cx("fixed z-[9999] overflow-hidden rounded-xl border border-(--theme-border) bg-(--theme-panel-bg) shadow-xl backdrop-blur-xl", padded && "p-3", widthClassName),
|
|
1286
1289
|
style: {
|
|
1287
1290
|
left: pos?.left ?? x,
|
|
1288
1291
|
top: pos?.top ?? y + 8,
|
|
@@ -9,9 +9,11 @@ interface IControlledCollapsiblePanelProps {
|
|
|
9
9
|
shown?: boolean;
|
|
10
10
|
setShown?: (shown: boolean) => void;
|
|
11
11
|
customizedButton?: React.ReactNode;
|
|
12
|
+
/** Rendered right after the title, outside the toggle button. */
|
|
13
|
+
titleAction?: React.ReactNode;
|
|
12
14
|
className?: string | undefined;
|
|
13
15
|
}
|
|
14
|
-
export declare function ControlledCollapsiblePanel({ title, children, open, setOpen, onClick, wrapperElement, customizedButton, className, }: IControlledCollapsiblePanelProps): React.JSX.Element;
|
|
16
|
+
export declare function ControlledCollapsiblePanel({ title, children, open, setOpen, onClick, wrapperElement, customizedButton, titleAction, className, }: IControlledCollapsiblePanelProps): React.JSX.Element;
|
|
15
17
|
export declare function UncontrolledCollapsiblePanel({ title, children, onClick, wrapperElement, initialState, className, customizedButton, }: Omit<IControlledCollapsiblePanelProps, 'setOpen' | 'open'> & {
|
|
16
18
|
initialState?: boolean | undefined;
|
|
17
19
|
}): React.JSX.Element;
|
|
@@ -75,6 +75,12 @@ export interface CreateModalSelectOption {
|
|
|
75
75
|
group?: string;
|
|
76
76
|
/** Hidden behind the group's toggle row until the group is expanded. */
|
|
77
77
|
collapsible?: boolean;
|
|
78
|
+
/** Always listed regardless of the typed filter (e.g. a trailing "Create new…" action). */
|
|
79
|
+
pinned?: boolean;
|
|
80
|
+
/** Muted second line under the label (e.g. the allocation a group bills to). */
|
|
81
|
+
description?: string;
|
|
82
|
+
/** Listed but not selectable (e.g. a group whose allocation is exhausted). */
|
|
83
|
+
disabled?: boolean;
|
|
78
84
|
}
|
|
79
85
|
/** Callers gating collapse on list size must use this same threshold so
|
|
80
86
|
* collapsed rows always come with a filter to find them. */
|
|
@@ -10,15 +10,19 @@ export interface PageHeaderCrumb {
|
|
|
10
10
|
label: ReactNode;
|
|
11
11
|
href?: string;
|
|
12
12
|
}
|
|
13
|
+
export declare const headerActionButtonClasses = "flex items-center justify-center w-6 h-6 rounded-md shrink-0 cursor-pointer text-(--theme-muted-text-color) hover:text-(--theme-app) hover:bg-(--theme-muted-panel-bg) transition-colors";
|
|
13
14
|
/** With menu, the plus opens a chooser; otherwise navigates to or calls the
|
|
14
15
|
* single action. `word` is the visible verb; `label` stays the full action for
|
|
15
16
|
* the tooltip and screen readers. */
|
|
16
|
-
export declare function HeaderAddButton({ to, onClick, label, word, menu, }: {
|
|
17
|
+
export declare function HeaderAddButton({ to, onClick, label, word, menu, disabled, disabledHint, }: {
|
|
17
18
|
to?: string;
|
|
18
19
|
onClick?: () => void;
|
|
19
20
|
label: string;
|
|
20
21
|
word?: 'add' | 'create';
|
|
21
22
|
menu?: HeaderAddMenuItem[];
|
|
23
|
+
/** Button mode only. */
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
disabledHint?: string;
|
|
22
26
|
}): import("react").JSX.Element;
|
|
23
27
|
export declare function HeaderActionMenu({ items, label, }: {
|
|
24
28
|
items: HeaderAddMenuItem[];
|
|
@@ -8,6 +8,8 @@ export interface IOptions<T = unknown> {
|
|
|
8
8
|
description?: string | undefined;
|
|
9
9
|
/** Hidden behind the category's toggle row until the category is expanded. */
|
|
10
10
|
collapsible?: boolean | undefined;
|
|
11
|
+
/** Always listed regardless of the typed query (e.g. a trailing "Create new…" action). */
|
|
12
|
+
pinned?: boolean | undefined;
|
|
11
13
|
}
|
|
12
14
|
export interface ICategory<T = unknown> {
|
|
13
15
|
category?: string | undefined;
|
package/dist/editor/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as EditorField, i as FormCodePanel, n as defineEditorThemes, o as Editor, r as getThemeName, t as setupMonacoWorkers } from "../chunks/editor-
|
|
1
|
+
import { a as EditorField, i as FormCodePanel, n as defineEditorThemes, o as Editor, r as getThemeName, t as setupMonacoWorkers } from "../chunks/editor-Ko3zX22Y.js";
|
|
2
2
|
export { Editor, EditorField, FormCodePanel, defineEditorThemes, getThemeName, setupMonacoWorkers };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IFileExplorerClient, IFileExplorerProvider } from './lib/fileExplorer.js';
|
|
2
|
-
import type { TStorage } from './lib/types.js';
|
|
2
|
+
import type { TreeNode, TStorage } from './lib/types.js';
|
|
3
3
|
interface IFileExplorerProps {
|
|
4
4
|
storages: TStorage[];
|
|
5
5
|
/** Resolves the storage's injected provider pair; the host owns caching. */
|
|
@@ -8,6 +8,10 @@ interface IFileExplorerProps {
|
|
|
8
8
|
client: IFileExplorerClient | null;
|
|
9
9
|
}>;
|
|
10
10
|
onRefresh?: () => void;
|
|
11
|
+
/** Handles activating a file instead of previewing it. Lets a host embed the
|
|
12
|
+
* explorer as a file picker (the notebook editor opens .ipynb this way);
|
|
13
|
+
* return false to fall through to the built-in preview. */
|
|
14
|
+
onOpenFile?: ((node: TreeNode, storage: TStorage | undefined) => boolean) | undefined;
|
|
11
15
|
showUserHierarchy?: boolean;
|
|
12
16
|
groups?: {
|
|
13
17
|
name: string;
|
|
@@ -16,6 +20,19 @@ interface IFileExplorerProps {
|
|
|
16
20
|
groupsLoading?: boolean;
|
|
17
21
|
selectedPath: string;
|
|
18
22
|
onPathChange: (path: string) => void;
|
|
23
|
+
/** Renders only the tree, for a host that embeds it as a navigator and owns
|
|
24
|
+
* the pane beside it (the notebooks page puts its editor there). The host
|
|
25
|
+
* also owns the width, so the tree fills its container instead of carrying
|
|
26
|
+
* its own resize handle. */
|
|
27
|
+
treeOnly?: boolean;
|
|
28
|
+
/** Changes when the host has written into the selected folder outside the
|
|
29
|
+
* explorer's own upload flow, so the folder is re-listed and shows the file. */
|
|
30
|
+
refreshKey?: unknown;
|
|
31
|
+
/** Seeds the expanded folders on mount, so a host can restore the tree's open
|
|
32
|
+
* state across reloads. Read once; the explorer owns the set from then on. */
|
|
33
|
+
initialExpandedPaths?: readonly string[];
|
|
34
|
+
/** Fires whenever the expanded folders change, for the host to persist. */
|
|
35
|
+
onExpandedPathsChange?: (paths: string[]) => void;
|
|
19
36
|
}
|
|
20
|
-
export default function FileExplorer({ storages, onRefresh, showUserHierarchy, groups, groupsLoading, selectedPath, onPathChange, getProviderAndClient, }: IFileExplorerProps): import("react").JSX.Element;
|
|
37
|
+
export default function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHierarchy, groups, groupsLoading, selectedPath, onPathChange, getProviderAndClient, treeOnly, initialExpandedPaths, onExpandedPathsChange, }: IFileExplorerProps): import("react").JSX.Element;
|
|
21
38
|
export {};
|
|
@@ -1,12 +1,12 @@
|
|
|
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-B7smkHkv.js";
|
|
3
3
|
import { a as useProvisionCorsRules, c as useStrings, i as useNotify, s as useSlots } from "../chunks/Provider-CbFVFB7O.js";
|
|
4
4
|
import { n as TOOLTIP_ID, r as TooltipInfo } from "../chunks/Tooltip-n9w7Tkt1.js";
|
|
5
|
-
import { t as StatusBadge } from "../chunks/StatusBadge-
|
|
5
|
+
import { t as StatusBadge } from "../chunks/StatusBadge-zvEtK16a.js";
|
|
6
6
|
import { t as Loader } from "../chunks/Loader-BXoXTZGc.js";
|
|
7
|
-
import {
|
|
7
|
+
import { _ as useRowMenuActive, d as assembleRowMenu, f as copySubmenu, g as useRowMenu, u as MoreButton } from "../chunks/PageHeader-CoZWF0pJ.js";
|
|
8
8
|
import { n as Table } from "../chunks/Table-CutP1bRt.js";
|
|
9
|
-
import { C as ListSkeleton, E as RowSelectCheckbox, O as listTableFixedProps, k as listTableProps, x as ListActionsHeader } from "../chunks/list-
|
|
9
|
+
import { C as ListSkeleton, E as RowSelectCheckbox, O as listTableFixedProps, k as listTableProps, x as ListActionsHeader } from "../chunks/list-CduoUsMW.js";
|
|
10
10
|
import cx from "classnames";
|
|
11
11
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
12
|
import { Suspense, createContext, lazy, memo, use, useCallback, useEffect, useEffectEvent, useId, useLayoutEffect, useMemo, useRef, useState, useTransition } from "react";
|
|
@@ -2537,7 +2537,7 @@ function useObjectText(url, { enabled, maxBytes, maxLines, knownSize, cacheKey,
|
|
|
2537
2537
|
}
|
|
2538
2538
|
//#endregion
|
|
2539
2539
|
//#region src/file-explorer/FilePreview/Viewer.tsx
|
|
2540
|
-
var CodePreviewEditor = lazy(() => import("../chunks/CodePreviewEditor-
|
|
2540
|
+
var CodePreviewEditor = lazy(() => import("../chunks/CodePreviewEditor-DuMZMA_k.js"));
|
|
2541
2541
|
var PREVIEW_MARKDOWN_CONTROLS = {
|
|
2542
2542
|
table: { fullscreen: false },
|
|
2543
2543
|
mermaid: { fullscreen: false }
|
|
@@ -4313,7 +4313,37 @@ function getAncestorDirPaths(path) {
|
|
|
4313
4313
|
for (let i = 1; i <= dirSegmentCount; i++) ancestors.push(segments.slice(0, i).join("/") + "/");
|
|
4314
4314
|
return ancestors;
|
|
4315
4315
|
}
|
|
4316
|
-
|
|
4316
|
+
/** The tree's width is the host's when the tree is embedded on its own, and this
|
|
4317
|
+
* component's when it is showing the details pane beside it. */
|
|
4318
|
+
function TreeFrame({ treeOnly, sidebarWidth, onWidthChange, children }) {
|
|
4319
|
+
if (treeOnly) return /* @__PURE__ */ jsx("div", {
|
|
4320
|
+
className: "h-full w-full min-w-0",
|
|
4321
|
+
children
|
|
4322
|
+
});
|
|
4323
|
+
return /* @__PURE__ */ jsx(Resizable, {
|
|
4324
|
+
size: {
|
|
4325
|
+
width: sidebarWidth,
|
|
4326
|
+
height: "100%"
|
|
4327
|
+
},
|
|
4328
|
+
minWidth: 200,
|
|
4329
|
+
maxWidth: 800,
|
|
4330
|
+
enable: {
|
|
4331
|
+
top: false,
|
|
4332
|
+
right: true,
|
|
4333
|
+
bottom: false,
|
|
4334
|
+
left: false,
|
|
4335
|
+
topRight: false,
|
|
4336
|
+
bottomRight: false,
|
|
4337
|
+
bottomLeft: false,
|
|
4338
|
+
topLeft: false
|
|
4339
|
+
},
|
|
4340
|
+
onResizeStop: (_e, _direction, _ref, d) => {
|
|
4341
|
+
onWidthChange((prev) => prev + d.width);
|
|
4342
|
+
},
|
|
4343
|
+
children
|
|
4344
|
+
});
|
|
4345
|
+
}
|
|
4346
|
+
function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHierarchy = false, groups = [], groupsLoading = false, selectedPath, onPathChange, getProviderAndClient, treeOnly = false, initialExpandedPaths, onExpandedPathsChange }) {
|
|
4317
4347
|
const t = useStrings().fileExplorer;
|
|
4318
4348
|
const notify = useNotify();
|
|
4319
4349
|
const slots = useSlots();
|
|
@@ -4348,8 +4378,19 @@ function FileExplorer({ storages, onRefresh, showUserHierarchy = false, groups =
|
|
|
4348
4378
|
return `${selectedPath}/`;
|
|
4349
4379
|
}, [selectedPath, treeMap]);
|
|
4350
4380
|
const setSelectedPath = onPathChange;
|
|
4351
|
-
const [expandedPaths, setExpandedPaths] = useState(() => new Set([""]));
|
|
4381
|
+
const [expandedPaths, setExpandedPaths] = useState(() => new Set(["", ...initialExpandedPaths ?? []]));
|
|
4382
|
+
const onExpandedPathsChangeRef = useRef(onExpandedPathsChange);
|
|
4383
|
+
onExpandedPathsChangeRef.current = onExpandedPathsChange;
|
|
4384
|
+
useEffect(() => {
|
|
4385
|
+
onExpandedPathsChangeRef.current?.([...expandedPaths]);
|
|
4386
|
+
}, [expandedPaths]);
|
|
4352
4387
|
const selectedNode = useMemo(() => normalizedSelectedPath ? treeMap[normalizedSelectedPath] ?? null : null, [normalizedSelectedPath, treeMap]);
|
|
4388
|
+
const seenRefreshKey = useRef(refreshKey);
|
|
4389
|
+
useEffect(() => {
|
|
4390
|
+
if (refreshKey === seenRefreshKey.current) return;
|
|
4391
|
+
seenRefreshKey.current = refreshKey;
|
|
4392
|
+
if (selectedNode?.type === "directory" && selectedNode.storageId) fetchNodeChildren(selectedNode, { replace: true });
|
|
4393
|
+
}, [refreshKey, selectedNode]);
|
|
4353
4394
|
const [checkedItems, setCheckedItems] = useState(/* @__PURE__ */ new Set());
|
|
4354
4395
|
const [checkedItemsPath, setCheckedItemsPath] = useState(selectedPath);
|
|
4355
4396
|
if (checkedItemsPath !== selectedPath) {
|
|
@@ -4714,6 +4755,7 @@ function FileExplorer({ storages, onRefresh, showUserHierarchy = false, groups =
|
|
|
4714
4755
|
const previewSiblings = useMemo(() => previewNode ? getNodeChildren(parentToChildrenMap, getParentPath(previewNode.path)).filter((n) => n.type === "file") : [], [previewNode, parentToChildrenMap]);
|
|
4715
4756
|
const openPreview = (node) => {
|
|
4716
4757
|
if (node.type !== "file") return;
|
|
4758
|
+
if (onOpenFile?.(node, storages.find((s) => s.id === node.storageId))) return;
|
|
4717
4759
|
setPreviewNode(node);
|
|
4718
4760
|
setPreviewOpen(true);
|
|
4719
4761
|
};
|
|
@@ -5073,12 +5115,13 @@ function FileExplorer({ storages, onRefresh, showUserHierarchy = false, groups =
|
|
|
5073
5115
|
}
|
|
5074
5116
|
};
|
|
5075
5117
|
const handleRefresh = async (opts) => {
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
}
|
|
5118
|
+
const dirs = [...expandedPaths].map((path) => treeMap[path]).filter((node) => !!node && node.type === "directory" && !!node.storageId);
|
|
5119
|
+
if (selectedNode?.type === "directory" && selectedNode.storageId && !dirs.some((dir) => dir.path === selectedNode.path)) dirs.push(selectedNode);
|
|
5120
|
+
if (dirs.length > 0) return { corsError: (await Promise.all(dirs.map((dir) => fetchNodeChildren(dir, {
|
|
5121
|
+
replace: true,
|
|
5122
|
+
silent: opts?.silent
|
|
5123
|
+
})))).some((result) => result.corsError) };
|
|
5124
|
+
if (onRefresh) onRefresh();
|
|
5082
5125
|
return { corsError: false };
|
|
5083
5126
|
};
|
|
5084
5127
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -5086,26 +5129,10 @@ function FileExplorer({ storages, onRefresh, showUserHierarchy = false, groups =
|
|
|
5086
5129
|
children: [
|
|
5087
5130
|
/* @__PURE__ */ jsxs("div", {
|
|
5088
5131
|
className: "w-full h-full flex",
|
|
5089
|
-
children: [/* @__PURE__ */ jsx(
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
},
|
|
5094
|
-
minWidth: 200,
|
|
5095
|
-
maxWidth: 800,
|
|
5096
|
-
enable: {
|
|
5097
|
-
top: false,
|
|
5098
|
-
right: true,
|
|
5099
|
-
bottom: false,
|
|
5100
|
-
left: false,
|
|
5101
|
-
topRight: false,
|
|
5102
|
-
bottomRight: false,
|
|
5103
|
-
bottomLeft: false,
|
|
5104
|
-
topLeft: false
|
|
5105
|
-
},
|
|
5106
|
-
onResizeStop: (e, direction, ref, d) => {
|
|
5107
|
-
setSidebarWidth((prev) => prev + d.width);
|
|
5108
|
-
},
|
|
5132
|
+
children: [/* @__PURE__ */ jsx(TreeFrame, {
|
|
5133
|
+
treeOnly,
|
|
5134
|
+
sidebarWidth,
|
|
5135
|
+
onWidthChange: setSidebarWidth,
|
|
5109
5136
|
children: /* @__PURE__ */ jsxs("div", {
|
|
5110
5137
|
className: "h-full flex flex-col border-r theme-border bg-(--theme-panel-bg)/60",
|
|
5111
5138
|
children: [/* @__PURE__ */ jsx("div", {
|
|
@@ -5139,14 +5166,17 @@ function FileExplorer({ storages, onRefresh, showUserHierarchy = false, groups =
|
|
|
5139
5166
|
selectedPath: normalizedSelectedPath,
|
|
5140
5167
|
loadingPaths,
|
|
5141
5168
|
onToggleExpand: handleToggleExpand,
|
|
5142
|
-
onSelect:
|
|
5169
|
+
onSelect: (path, node) => {
|
|
5170
|
+
handleSelectTreeItem(path, node);
|
|
5171
|
+
if (treeOnly && node.type === "file") openPreview(node);
|
|
5172
|
+
},
|
|
5143
5173
|
onDropToFolder: onDropFiles,
|
|
5144
5174
|
onContextMenu: openNodeContextMenu,
|
|
5145
5175
|
onPreviewFile: openPreview,
|
|
5146
5176
|
paging: treePaging
|
|
5147
5177
|
})]
|
|
5148
5178
|
})
|
|
5149
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
5179
|
+
}), !treeOnly && /* @__PURE__ */ jsx("div", {
|
|
5150
5180
|
className: "h-full flex flex-col flex-1 min-w-0",
|
|
5151
5181
|
children: !selectedNode && normalizedSelectedPath ? hydrationStuck ? /* @__PURE__ */ jsx(NotFoundPreview, {
|
|
5152
5182
|
path: normalizedSelectedPath,
|