@xyne/workflow-ui 0.4.3 → 0.5.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/automations/AutomationListView.d.ts.map +1 -1
- package/dist/components/automations/AutomationListView.js +68 -31
- package/dist/components/automations/AutomationListView.js.map +1 -1
- package/dist/components/browser/EntryGrid.d.ts +17 -0
- package/dist/components/browser/EntryGrid.d.ts.map +1 -0
- package/dist/components/browser/EntryGrid.js +90 -0
- package/dist/components/browser/EntryGrid.js.map +1 -0
- package/dist/components/browser/EntryList.d.ts +19 -0
- package/dist/components/browser/EntryList.d.ts.map +1 -0
- package/dist/components/browser/EntryList.js +75 -0
- package/dist/components/browser/EntryList.js.map +1 -0
- package/dist/components/browser/FolderCard.d.ts +6 -0
- package/dist/components/browser/FolderCard.d.ts.map +1 -0
- package/dist/components/browser/FolderCard.js +8 -0
- package/dist/components/browser/FolderCard.js.map +1 -0
- package/dist/components/browser/MoveDialog.d.ts +16 -0
- package/dist/components/browser/MoveDialog.d.ts.map +1 -0
- package/dist/components/browser/MoveDialog.js +102 -0
- package/dist/components/browser/MoveDialog.js.map +1 -0
- package/dist/components/browser/NameDialog.d.ts +16 -0
- package/dist/components/browser/NameDialog.d.ts.map +1 -0
- package/dist/components/browser/NameDialog.js +76 -0
- package/dist/components/browser/NameDialog.js.map +1 -0
- package/dist/components/browser/SearchField.d.ts +11 -0
- package/dist/components/browser/SearchField.d.ts.map +1 -0
- package/dist/components/browser/SearchField.js +14 -0
- package/dist/components/browser/SearchField.js.map +1 -0
- package/dist/components/browser/ViewToggle.d.ts +8 -0
- package/dist/components/browser/ViewToggle.d.ts.map +1 -0
- package/dist/components/browser/ViewToggle.js +10 -0
- package/dist/components/browser/ViewToggle.js.map +1 -0
- package/dist/components/browser/constants.d.ts +4 -0
- package/dist/components/browser/constants.d.ts.map +1 -0
- package/dist/components/browser/constants.js +4 -0
- package/dist/components/browser/constants.js.map +1 -0
- package/dist/components/browser/types.d.ts +29 -0
- package/dist/components/browser/types.d.ts.map +1 -0
- package/dist/components/browser/types.js +2 -0
- package/dist/components/browser/types.js.map +1 -0
- package/dist/components/browser/utils.d.ts +8 -0
- package/dist/components/browser/utils.d.ts.map +1 -0
- package/dist/components/browser/utils.js +36 -0
- package/dist/components/browser/utils.js.map +1 -0
- package/dist/components/execution/ApprovalsView.d.ts +7 -0
- package/dist/components/execution/ApprovalsView.d.ts.map +1 -0
- package/dist/components/execution/ApprovalsView.js +133 -0
- package/dist/components/execution/ApprovalsView.js.map +1 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +3 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/workflows/WorkflowBrowser.d.ts +14 -0
- package/dist/components/workflows/WorkflowBrowser.d.ts.map +1 -0
- package/dist/components/workflows/WorkflowBrowser.js +300 -0
- package/dist/components/workflows/WorkflowBrowser.js.map +1 -0
- package/dist/hooks/use-approval-count.d.ts +3 -0
- package/dist/hooks/use-approval-count.d.ts.map +1 -0
- package/dist/hooks/use-approval-count.js +29 -0
- package/dist/hooks/use-approval-count.js.map +1 -0
- package/dist/hooks/use-folder-list.d.ts +2 -1
- package/dist/hooks/use-folder-list.d.ts.map +1 -1
- package/dist/hooks/use-folder-list.js +7 -3
- package/dist/hooks/use-folder-list.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useMemo } from 'react';
|
|
3
|
+
import { Check, ChevronRight, Folder, Search, X } from 'lucide-react';
|
|
4
|
+
import { createPortal } from 'react-dom';
|
|
5
|
+
import { cn } from '../shared/cn.js';
|
|
6
|
+
function getDescendantIds(id, folders) {
|
|
7
|
+
const result = new Set([id]);
|
|
8
|
+
const queue = [id];
|
|
9
|
+
while (queue.length > 0) {
|
|
10
|
+
const cur = queue.shift();
|
|
11
|
+
for (const f of folders) {
|
|
12
|
+
if (f.parentId === cur) {
|
|
13
|
+
result.add(f.id);
|
|
14
|
+
queue.push(f.id);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
export function MoveDialog({ entries, folders, currentParentId, onMove, onClose }) {
|
|
21
|
+
// If any selected entry is a workflow, Root is not a valid destination
|
|
22
|
+
const hasFolderOnly = entries.every((e) => e.kind === 'folder');
|
|
23
|
+
const entry = entries[0]; // used for display title
|
|
24
|
+
const [query, setQuery] = useState('');
|
|
25
|
+
// Navigation path: array of {id, name} representing the drill-down trail.
|
|
26
|
+
// Empty = browsing root.
|
|
27
|
+
const [browsePath, setBrowsePath] = useState([]);
|
|
28
|
+
// Selected destination: undefined = nothing, null = root, string = folder id.
|
|
29
|
+
const [selected, setSelected] = useState(undefined);
|
|
30
|
+
const browsedFolderId = browsePath.at(-1)?.id ?? null;
|
|
31
|
+
const excludedIds = useMemo(() => {
|
|
32
|
+
const result = new Set();
|
|
33
|
+
for (const e of entries) {
|
|
34
|
+
if (e.kind === 'folder') {
|
|
35
|
+
for (const id of getDescendantIds(e.id, folders))
|
|
36
|
+
result.add(id);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}, [entries, folders]);
|
|
41
|
+
const hasChildren = (folderId) => folders.some((f) => f.parentId === folderId && !excludedIds.has(f.id));
|
|
42
|
+
// In search mode: flat filtered list. Otherwise: children of browsedFolderId.
|
|
43
|
+
const visibleFolders = useMemo(() => {
|
|
44
|
+
const q = query.trim().toLowerCase();
|
|
45
|
+
const pool = folders.filter((f) => !excludedIds.has(f.id));
|
|
46
|
+
if (q) {
|
|
47
|
+
return pool.filter((f) => f.name.toLowerCase().includes(q));
|
|
48
|
+
}
|
|
49
|
+
return pool.filter((f) => browsedFolderId ? f.parentId === browsedFolderId : !f.parentId);
|
|
50
|
+
}, [folders, excludedIds, query, browsedFolderId]);
|
|
51
|
+
const isCurrentLocation = (id) => id === currentParentId;
|
|
52
|
+
const selectedLabel = useMemo(() => {
|
|
53
|
+
if (selected === undefined)
|
|
54
|
+
return null;
|
|
55
|
+
if (selected === null)
|
|
56
|
+
return 'Root';
|
|
57
|
+
return folders.find((f) => f.id === selected)?.name ?? null;
|
|
58
|
+
}, [selected, folders]);
|
|
59
|
+
const canMove = selected !== undefined && selected !== currentParentId;
|
|
60
|
+
const drillInto = (folder) => {
|
|
61
|
+
setQuery('');
|
|
62
|
+
setBrowsePath((prev) => [...prev, { id: folder.id, name: folder.name }]);
|
|
63
|
+
};
|
|
64
|
+
const goToPathIndex = (index) => {
|
|
65
|
+
setBrowsePath((prev) => (index < 0 ? [] : prev.slice(0, index + 1)));
|
|
66
|
+
};
|
|
67
|
+
const handleBackdrop = (e) => {
|
|
68
|
+
if (e.target === e.currentTarget)
|
|
69
|
+
onClose();
|
|
70
|
+
};
|
|
71
|
+
if (typeof document === 'undefined')
|
|
72
|
+
return null;
|
|
73
|
+
return createPortal(_jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center px-4", onMouseDown: handleBackdrop, children: [_jsx("div", { "aria-hidden": true, className: "absolute inset-0 bg-black/40 backdrop-blur-sm" }), _jsxs("div", { className: "relative z-10 flex w-full max-w-2xl flex-col overflow-hidden rounded-2xl border border-border bg-background shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [_jsx("h2", { className: "text-[15px] font-semibold text-foreground", children: entries.length === 1
|
|
74
|
+
? _jsxs(_Fragment, { children: ["Move \u201C", entry.name, "\u201D"] })
|
|
75
|
+
: _jsxs(_Fragment, { children: ["Move ", entries.length, " items"] }) }), _jsx("button", { type: "button", onClick: onClose, className: "grid h-7 w-7 place-items-center rounded-md text-muted-foreground transition hover:bg-secondary hover:text-foreground", children: _jsx(X, { className: "h-4 w-4", strokeWidth: 1.75 }) })] }), _jsx("div", { className: "border-t border-border" }), _jsx("div", { className: "px-6 py-4", children: _jsxs("div", { className: "flex items-center gap-2.5 rounded-full border border-border bg-surface-elevated px-4 py-2.5", children: [_jsx(Search, { className: "h-4 w-4 shrink-0 text-muted-foreground", strokeWidth: 1.75 }), _jsx("input", { autoFocus: true, type: "text", placeholder: "Search folders\u2026", value: query, onChange: (e) => { setQuery(e.target.value); }, className: "flex-1 bg-transparent text-[13.5px] text-foreground placeholder:text-muted-foreground/70 outline-none" }), query && (_jsx("button", { type: "button", onClick: () => { setQuery(''); }, className: "grid h-4 w-4 place-items-center text-muted-foreground transition hover:text-foreground", children: _jsx(X, { className: "h-3 w-3", strokeWidth: 2 }) }))] }) }), _jsx("div", { className: "border-t border-border" }), !query && browsePath.length > 0 && (_jsxs("div", { className: "flex items-center gap-1 border-b border-border px-6 py-2 text-[12px] text-muted-foreground", children: [_jsx("button", { type: "button", onClick: () => { goToPathIndex(-1); }, className: "rounded px-1 py-0.5 transition hover:bg-secondary hover:text-foreground", children: "Root" }), browsePath.map((seg, i) => {
|
|
76
|
+
const isLast = i === browsePath.length - 1;
|
|
77
|
+
return (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx("span", { className: "text-muted-foreground/50", children: "\u203A" }), isLast ? (_jsx("span", { className: "px-1 py-0.5 font-medium text-foreground", children: seg.name })) : (_jsx("button", { type: "button", onClick: () => { goToPathIndex(i); }, className: "rounded px-1 py-0.5 transition hover:bg-secondary hover:text-foreground", children: seg.name }))] }, seg.id));
|
|
78
|
+
})] })), _jsx("div", { className: "min-h-[200px] max-h-[360px] overflow-y-auto px-6 py-4", children: visibleFolders.length === 0 && !(hasFolderOnly && !query && browsePath.length === 0) ? (_jsx("div", { className: "flex h-40 items-center justify-center text-[13px] text-muted-foreground", children: query ? 'No folders match your search' : 'No folders here' })) : (_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [hasFolderOnly && !query && browsePath.length === 0 && (() => {
|
|
79
|
+
const isCurrent = currentParentId === null;
|
|
80
|
+
const isSelected = selected === null;
|
|
81
|
+
return (_jsxs("button", { type: "button", disabled: isCurrent, onClick: () => { setSelected(isSelected ? undefined : null); }, className: cn('flex items-center gap-3 rounded-xl border px-4 py-3 text-left transition', isCurrent
|
|
82
|
+
? 'cursor-default border-border opacity-40'
|
|
83
|
+
: isSelected
|
|
84
|
+
? 'border-ring bg-secondary/60'
|
|
85
|
+
: 'border-border hover:border-ring/50 hover:bg-secondary/40'), children: [_jsx("div", { className: cn('flex h-9 w-9 shrink-0 items-center justify-center rounded-lg transition', isSelected ? 'bg-foreground/10' : 'bg-surface-muted'), children: isSelected
|
|
86
|
+
? _jsx(Check, { className: "h-4 w-4 text-foreground", strokeWidth: 2 })
|
|
87
|
+
: _jsx(Folder, { className: "h-4 w-4 text-muted-foreground", strokeWidth: 1.5 }) }), _jsxs("span", { className: "truncate text-[13px] font-medium text-foreground", children: ["Root", isCurrent && _jsx("span", { className: "ml-1 text-[11px] font-normal text-muted-foreground", children: "(current)" })] })] }, "__root__"));
|
|
88
|
+
})(), visibleFolders.map((f) => {
|
|
89
|
+
const isCurrent = isCurrentLocation(f.id);
|
|
90
|
+
const isSelected = selected === f.id;
|
|
91
|
+
const hasKids = hasChildren(f.id);
|
|
92
|
+
return (_jsxs("div", { className: "flex overflow-hidden rounded-xl border border-border transition hover:border-ring/50", children: [_jsxs("button", { type: "button", disabled: isCurrent, onClick: () => { setSelected(isSelected ? undefined : f.id); }, className: cn('flex flex-1 items-center gap-3 px-4 py-3 text-left transition', isCurrent
|
|
93
|
+
? 'cursor-default opacity-40'
|
|
94
|
+
: isSelected
|
|
95
|
+
? 'bg-secondary/60'
|
|
96
|
+
: 'hover:bg-secondary/40'), children: [_jsx("div", { className: cn('flex h-9 w-9 shrink-0 items-center justify-center rounded-lg transition', isSelected ? 'bg-foreground/10' : 'bg-surface-muted'), children: isSelected ? (_jsx(Check, { className: "h-4 w-4 text-foreground", strokeWidth: 2 })) : (_jsx(Folder, { className: "h-4 w-4 text-muted-foreground", strokeWidth: 1.5 })) }), _jsxs("span", { className: "truncate text-[13px] font-medium text-foreground", children: [f.name, isCurrent && (_jsx("span", { className: "ml-1 text-[11px] font-normal text-muted-foreground", children: "(current)" }))] })] }), hasKids && (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-px self-stretch bg-border" }), _jsx("button", { type: "button", onClick: () => { drillInto(f); }, title: `Open ${f.name}`, className: "flex items-center px-3 text-muted-foreground/60 transition hover:bg-secondary/60 hover:text-foreground", children: _jsx(ChevronRight, { className: "h-4 w-4", strokeWidth: 1.75 }) })] }))] }, f.id));
|
|
97
|
+
})] })) }), _jsx("div", { className: "border-t border-border" }), _jsxs("div", { className: "flex items-center justify-between gap-4 px-6 py-4", children: [_jsx("p", { className: "min-w-0 truncate text-[13px] text-muted-foreground", children: selectedLabel
|
|
98
|
+
? (_jsxs(_Fragment, { children: ["Moving to:", ' ', _jsx("span", { className: "font-medium text-foreground", children: selectedLabel })] }))
|
|
99
|
+
: (_jsx("span", { className: "italic", children: "Select a destination folder" })) }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [_jsx("button", { type: "button", onClick: onClose, className: "inline-flex h-9 items-center rounded-full border border-border px-4 text-[13px] text-foreground transition hover:bg-secondary", children: "Cancel" }), _jsx("button", { type: "button", disabled: !canMove, onClick: () => { if (selected !== undefined)
|
|
100
|
+
onMove(selected); }, className: "inline-flex h-9 items-center rounded-full bg-foreground px-5 text-[13px] font-medium text-background transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40", children: "Move here" })] })] })] })] }), document.body);
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=MoveDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MoveDialog.js","sourceRoot":"","sources":["../../../src/components/browser/MoveDialog.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
open: boolean;
|
|
3
|
+
title: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
label: string;
|
|
6
|
+
placeholder?: string;
|
|
7
|
+
helper?: string;
|
|
8
|
+
submitLabel?: string;
|
|
9
|
+
initialValue?: string;
|
|
10
|
+
onSubmit: (name: string) => Promise<void> | void;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
maxLength?: number;
|
|
13
|
+
};
|
|
14
|
+
export declare function NameDialog({ open, title, description, label, placeholder, helper, submitLabel, initialValue, onSubmit, onClose, maxLength, }: Props): import("react").ReactPortal | null;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=NameDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NameDialog.d.ts","sourceRoot":"","sources":["../../../src/components/browser/NameDialog.tsx"],"names":[],"mappings":"AAKA,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,KAAK,EACL,WAAW,EACX,KAAK,EACL,WAAW,EACX,MAAM,EACN,WAAsB,EACtB,YAAiB,EACjB,QAAQ,EACR,OAAO,EACP,SAAe,GAChB,EAAE,KAAK,sCA8KP"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { Loader2, X } from 'lucide-react';
|
|
5
|
+
import { cn } from '../shared/cn.js';
|
|
6
|
+
export function NameDialog({ open, title, description, label, placeholder, helper, submitLabel = 'Create', initialValue = '', onSubmit, onClose, maxLength = 255, }) {
|
|
7
|
+
const [value, setValue] = useState(initialValue);
|
|
8
|
+
const [error, setError] = useState(null);
|
|
9
|
+
const [busy, setBusy] = useState(false);
|
|
10
|
+
const inputRef = useRef(null);
|
|
11
|
+
const labelId = useId();
|
|
12
|
+
const descId = useId();
|
|
13
|
+
const helperId = useId();
|
|
14
|
+
const errorId = useId();
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (open) {
|
|
17
|
+
setValue(initialValue);
|
|
18
|
+
setError(null);
|
|
19
|
+
setBusy(false);
|
|
20
|
+
}
|
|
21
|
+
}, [open, initialValue]);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (!open)
|
|
24
|
+
return undefined;
|
|
25
|
+
const id = window.setTimeout(() => {
|
|
26
|
+
inputRef.current?.focus();
|
|
27
|
+
inputRef.current?.select();
|
|
28
|
+
}, 10);
|
|
29
|
+
return () => { window.clearTimeout(id); };
|
|
30
|
+
}, [open]);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (!open)
|
|
33
|
+
return undefined;
|
|
34
|
+
const onKey = (e) => {
|
|
35
|
+
if (e.key === 'Escape' && !busy) {
|
|
36
|
+
e.stopPropagation();
|
|
37
|
+
onClose();
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
window.addEventListener('keydown', onKey);
|
|
41
|
+
return () => { window.removeEventListener('keydown', onKey); };
|
|
42
|
+
}, [open, busy, onClose]);
|
|
43
|
+
if (!open || typeof document === 'undefined')
|
|
44
|
+
return null;
|
|
45
|
+
const trimmed = value.trim();
|
|
46
|
+
const isValid = trimmed.length > 0 && trimmed.length <= maxLength;
|
|
47
|
+
const handleSubmit = async () => {
|
|
48
|
+
if (!isValid || busy)
|
|
49
|
+
return;
|
|
50
|
+
setBusy(true);
|
|
51
|
+
setError(null);
|
|
52
|
+
try {
|
|
53
|
+
await onSubmit(trimmed);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
const msg = err instanceof Error ? err.message : 'Something went wrong';
|
|
57
|
+
setError(msg);
|
|
58
|
+
setBusy(false);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const onBackdropMouseDown = (e) => {
|
|
62
|
+
if (e.target === e.currentTarget && !busy)
|
|
63
|
+
onClose();
|
|
64
|
+
};
|
|
65
|
+
const describedBy = [description ? descId : null, helper ? helperId : null, error ? errorId : null]
|
|
66
|
+
.filter((x) => x !== null)
|
|
67
|
+
.join(' ');
|
|
68
|
+
return createPortal(_jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center px-4", role: "presentation", onMouseDown: onBackdropMouseDown, children: [_jsx("div", { "aria-hidden": true, className: "absolute inset-0 bg-black/50 backdrop-blur-sm animate-fade-in" }), _jsxs("div", { role: "dialog", "aria-modal": "true", "aria-labelledby": labelId, "aria-describedby": describedBy || undefined, className: cn('relative z-10 w-full max-w-[420px] overflow-hidden rounded-2xl border border-border bg-surface-elevated shadow-2xl', 'animate-scale-in'), onMouseDown: (e) => { e.stopPropagation(); }, children: [_jsxs("div", { className: "flex items-start justify-between gap-3 px-5 pb-2 pt-4", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h2", { id: labelId, className: "text-[15px] font-semibold leading-tight text-foreground", children: title }), description ? (_jsx("p", { id: descId, className: "mt-1 text-[12.5px] leading-snug text-muted-foreground", children: description })) : null] }), _jsx("button", { type: "button", "aria-label": "Close", disabled: busy, onClick: onClose, className: "grid h-7 w-7 flex-shrink-0 place-items-center rounded-md text-muted-foreground transition hover:bg-secondary hover:text-foreground disabled:opacity-40", children: _jsx(X, { className: "h-3.5 w-3.5", strokeWidth: 1.75 }) })] }), _jsxs("form", { onSubmit: (e) => { e.preventDefault(); void handleSubmit(); }, className: "px-5 pb-4 pt-2", children: [_jsx("label", { htmlFor: `${labelId}-input`, className: "mb-1.5 block text-[12px] font-medium text-foreground", children: label }), _jsx("input", { id: `${labelId}-input`, ref: inputRef, type: "text", value: value, disabled: busy, maxLength: maxLength, placeholder: placeholder, "aria-invalid": error !== null, "aria-describedby": describedBy || undefined, onChange: (e) => {
|
|
69
|
+
setValue(e.target.value);
|
|
70
|
+
if (error)
|
|
71
|
+
setError(null);
|
|
72
|
+
}, className: cn('block w-full rounded-lg border bg-surface px-3 py-2 text-[13.5px] text-foreground transition placeholder:text-muted-foreground/70 focus:outline-none focus:ring-2 disabled:opacity-60', error
|
|
73
|
+
? 'border-red-400 focus:border-red-500 focus:ring-red-500/30 dark:border-red-700/60'
|
|
74
|
+
: 'border-border focus:border-ring focus:ring-ring/30') }), error ? (_jsx("p", { id: errorId, role: "alert", className: "mt-1.5 text-[11.5px] leading-snug text-red-600 dark:text-red-400", children: error })) : helper ? (_jsx("p", { id: helperId, className: "mt-1.5 text-[11.5px] leading-snug text-muted-foreground", children: helper })) : null, _jsxs("div", { className: "mt-4 flex items-center justify-end gap-2", children: [_jsx("button", { type: "button", onClick: onClose, disabled: busy, className: "inline-flex h-8 items-center rounded-md px-3 text-[12.5px] text-muted-foreground transition hover:bg-secondary hover:text-foreground disabled:opacity-50", children: "Cancel" }), _jsxs("button", { type: "submit", disabled: !isValid || busy, className: cn('inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-[12.5px] font-medium transition', 'bg-foreground text-background hover:opacity-90', 'disabled:cursor-not-allowed disabled:opacity-50'), children: [busy ? _jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin", strokeWidth: 1.75 }) : null, submitLabel] })] })] })] })] }), document.body);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=NameDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NameDialog.js","sourceRoot":"","sources":["../../../src/components/browser/NameDialog.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
value: string;
|
|
3
|
+
onChange: (next: string) => void;
|
|
4
|
+
placeholder?: string;
|
|
5
|
+
autoFocus?: boolean;
|
|
6
|
+
className?: string;
|
|
7
|
+
ariaLabel?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function SearchField({ value, onChange, placeholder, autoFocus, className, ariaLabel, }: Props): import("react").JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=SearchField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchField.d.ts","sourceRoot":"","sources":["../../../src/components/browser/SearchField.tsx"],"names":[],"mappings":"AAIA,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,WAAsB,EACtB,SAAS,EACT,SAAS,EACT,SAAS,GACV,EAAE,KAAK,+BAmCP"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Search, X } from 'lucide-react';
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import { cn } from '../shared/cn.js';
|
|
5
|
+
export function SearchField({ value, onChange, placeholder = 'Search', autoFocus, className, ariaLabel, }) {
|
|
6
|
+
const inputRef = useRef(null);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (autoFocus) {
|
|
9
|
+
inputRef.current?.focus();
|
|
10
|
+
}
|
|
11
|
+
}, [autoFocus]);
|
|
12
|
+
return (_jsxs("div", { className: cn('relative flex items-center', className), children: [_jsx(Search, { className: "pointer-events-none absolute left-2.5 h-3.5 w-3.5 text-muted-foreground", "aria-hidden": true, strokeWidth: 1.75 }), _jsx("input", { ref: inputRef, type: "search", value: value, onChange: (e) => { onChange(e.target.value); }, placeholder: placeholder, "aria-label": ariaLabel ?? placeholder, className: "h-8 w-full rounded-full border border-border bg-surface-elevated pl-7 pr-7 text-[12.5px] text-foreground placeholder:text-muted-foreground/80 focus:border-ring focus:outline-none [&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden" }), value !== '' ? (_jsx("button", { type: "button", "aria-label": "Clear search", onClick: () => { onChange(''); }, className: "absolute right-2 grid h-4 w-4 place-items-center rounded-full text-muted-foreground transition hover:text-foreground", children: _jsx(X, { className: "h-3 w-3", "aria-hidden": true, strokeWidth: 2 }) })) : null] }));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=SearchField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchField.js","sourceRoot":"","sources":["../../../src/components/browser/SearchField.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAWrC,MAAM,UAAU,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,WAAW,GAAG,QAAQ,EACtB,SAAS,EACT,SAAS,EACT,SAAS,GACH;IACN,MAAM,QAAQ,GAAG,MAAM,CAA0B,IAAI,CAAC,CAAC;IACvD,SAAS,CAAC,GAAS,EAAE;QACnB,IAAI,SAAS,EAAE,CAAC;YACd,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAChB,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,4BAA4B,EAAE,SAAS,CAAC,aACzD,KAAC,MAAM,IACL,SAAS,EAAC,yEAAyE,uBAEnF,WAAW,EAAE,IAAI,GACjB,EACF,gBACE,GAAG,EAAE,QAAQ,EACb,IAAI,EAAC,QAAQ,EACb,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAC9C,WAAW,EAAE,WAAW,gBACZ,SAAS,IAAI,WAAW,EACpC,SAAS,EAAC,mQAAmQ,GAC7Q,EACD,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,CACd,iBACE,IAAI,EAAC,QAAQ,gBACF,cAAc,EACzB,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAChC,SAAS,EAAC,sHAAsH,YAEhI,KAAC,CAAC,IAAC,SAAS,EAAC,SAAS,uBAAa,WAAW,EAAE,CAAC,GAAI,GAC9C,CACV,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ViewMode } from './types.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
value: ViewMode;
|
|
4
|
+
onChange: (mode: ViewMode) => void;
|
|
5
|
+
};
|
|
6
|
+
export declare function ViewToggle({ value, onChange }: Props): import("react").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=ViewToggle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ViewToggle.d.ts","sourceRoot":"","sources":["../../../src/components/browser/ViewToggle.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;CACpC,CAAC;AAEF,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,+BAmCpD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { LayoutGrid, List } from 'lucide-react';
|
|
3
|
+
export function ViewToggle({ value, onChange }) {
|
|
4
|
+
return (_jsxs("div", { role: "group", "aria-label": "View mode", className: "inline-flex items-center rounded-full border border-border bg-surface-elevated p-0.5", children: [_jsx("button", { type: "button", "aria-label": "Grid view", "aria-pressed": value === 'grid', onClick: () => { onChange('grid'); }, className: value === 'grid'
|
|
5
|
+
? 'inline-flex h-7 w-7 items-center justify-center rounded-full bg-secondary text-foreground'
|
|
6
|
+
: 'inline-flex h-7 w-7 items-center justify-center rounded-full text-muted-foreground transition hover:text-foreground', children: _jsx(LayoutGrid, { className: "h-3.5 w-3.5", "aria-hidden": true, strokeWidth: 1.75 }) }), _jsx("button", { type: "button", "aria-label": "List view", "aria-pressed": value === 'list', onClick: () => { onChange('list'); }, className: value === 'list'
|
|
7
|
+
? 'inline-flex h-7 w-7 items-center justify-center rounded-full bg-secondary text-foreground'
|
|
8
|
+
: 'inline-flex h-7 w-7 items-center justify-center rounded-full text-muted-foreground transition hover:text-foreground', children: _jsx(List, { className: "h-3.5 w-3.5", "aria-hidden": true, strokeWidth: 1.75 }) })] }));
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=ViewToggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ViewToggle.js","sourceRoot":"","sources":["../../../src/components/browser/ViewToggle.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAQhD,MAAM,UAAU,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAS;IACnD,OAAO,CACL,eACE,IAAI,EAAC,OAAO,gBACD,WAAW,EACtB,SAAS,EAAC,sFAAsF,aAEhG,iBACE,IAAI,EAAC,QAAQ,gBACF,WAAW,kBACR,KAAK,KAAK,MAAM,EAC9B,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EACpC,SAAS,EACP,KAAK,KAAK,MAAM;oBACd,CAAC,CAAC,2FAA2F;oBAC7F,CAAC,CAAC,qHAAqH,YAG3H,KAAC,UAAU,IAAC,SAAS,EAAC,aAAa,uBAAa,WAAW,EAAE,IAAI,GAAI,GAC9D,EACT,iBACE,IAAI,EAAC,QAAQ,gBACF,WAAW,kBACR,KAAK,KAAK,MAAM,EAC9B,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EACpC,SAAS,EACP,KAAK,KAAK,MAAM;oBACd,CAAC,CAAC,2FAA2F;oBAC7F,CAAC,CAAC,qHAAqH,YAG3H,KAAC,IAAI,IAAC,SAAS,EAAC,aAAa,uBAAa,WAAW,EAAE,IAAI,GAAI,GACxD,IACL,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/components/browser/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,UAAU,CAAC;AACzC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,oBAAoB,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/components/browser/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AACzC,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AACvC,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export type FileEntry = {
|
|
3
|
+
kind: 'file';
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
format: string;
|
|
7
|
+
caption?: string;
|
|
8
|
+
columns?: Readonly<Record<string, string>>;
|
|
9
|
+
status?: string;
|
|
10
|
+
};
|
|
11
|
+
export type FolderEntry = {
|
|
12
|
+
kind: 'folder';
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
caption?: string;
|
|
16
|
+
columns?: Readonly<Record<string, string>>;
|
|
17
|
+
status?: string;
|
|
18
|
+
};
|
|
19
|
+
export type BrowserEntry = FileEntry | FolderEntry;
|
|
20
|
+
export type ColumnDef = {
|
|
21
|
+
key: string;
|
|
22
|
+
header: string;
|
|
23
|
+
width?: string;
|
|
24
|
+
render?: (entry: BrowserEntry) => ReactNode;
|
|
25
|
+
mdOnly?: boolean;
|
|
26
|
+
};
|
|
27
|
+
export type LeadingRenderer = (entry: BrowserEntry, size: 'sm' | 'md') => ReactNode;
|
|
28
|
+
export type ViewMode = 'grid' | 'list';
|
|
29
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/browser/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,CAAC;AAEnD,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,SAAS,CAAC;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,SAAS,CAAC;AAEpF,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/browser/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BrowserEntry, LeadingRenderer } from './types.js';
|
|
2
|
+
export declare const defaultLeading: LeadingRenderer;
|
|
3
|
+
export declare function isEntryDisabled(entry: BrowserEntry, disableFiles: boolean, disableFolders: boolean): boolean;
|
|
4
|
+
export declare function useScrollMargin(scrollParentRef: React.RefObject<HTMLElement | null>): {
|
|
5
|
+
listRef: React.RefObject<HTMLDivElement | null>;
|
|
6
|
+
scrollMargin: number;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/browser/utils.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEhE,eAAO,MAAM,cAAc,EAAE,eACgC,CAAC;AAE9D,wBAAgB,eAAe,CAC7B,KAAK,EAAE,YAAY,EACnB,YAAY,EAAE,OAAO,EACrB,cAAc,EAAE,OAAO,GACtB,OAAO,CAKT;AAED,wBAAgB,eAAe,CAC7B,eAAe,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GACnD;IACD,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAChD,YAAY,EAAE,MAAM,CAAC;CACtB,CA0BA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useLayoutEffect, useRef, useState } from 'react';
|
|
3
|
+
import { FolderCard } from './FolderCard.js';
|
|
4
|
+
export const defaultLeading = (entry, size) => entry.kind === 'folder' ? _jsx(FolderCard, { size: size }) : null;
|
|
5
|
+
export function isEntryDisabled(entry, disableFiles, disableFolders) {
|
|
6
|
+
return ((entry.kind === 'file' && disableFiles) ||
|
|
7
|
+
(entry.kind === 'folder' && disableFolders));
|
|
8
|
+
}
|
|
9
|
+
export function useScrollMargin(scrollParentRef) {
|
|
10
|
+
const listRef = useRef(null);
|
|
11
|
+
const [scrollMargin, setScrollMargin] = useState(0);
|
|
12
|
+
useLayoutEffect(() => {
|
|
13
|
+
const list = listRef.current;
|
|
14
|
+
const scroller = scrollParentRef.current;
|
|
15
|
+
if (!list || !scroller) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
const measure = () => {
|
|
19
|
+
const lr = list.getBoundingClientRect();
|
|
20
|
+
const sr = scroller.getBoundingClientRect();
|
|
21
|
+
const next = lr.top - sr.top + scroller.scrollTop;
|
|
22
|
+
setScrollMargin((prev) => (prev === next ? prev : next));
|
|
23
|
+
};
|
|
24
|
+
measure();
|
|
25
|
+
const ro = new ResizeObserver(measure);
|
|
26
|
+
ro.observe(scroller);
|
|
27
|
+
if (list.parentElement) {
|
|
28
|
+
ro.observe(list.parentElement);
|
|
29
|
+
}
|
|
30
|
+
return () => {
|
|
31
|
+
ro.disconnect();
|
|
32
|
+
};
|
|
33
|
+
}, [scrollParentRef]);
|
|
34
|
+
return { listRef, scrollMargin };
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/components/browser/utils.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,MAAM,CAAC,MAAM,cAAc,GAAoB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAC7D,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAC,UAAU,IAAC,IAAI,EAAE,IAAI,GAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAE9D,MAAM,UAAU,eAAe,CAC7B,KAAmB,EACnB,YAAqB,EACrB,cAAuB;IAEvB,OAAO,CACL,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,YAAY,CAAC;QACvC,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,cAAc,CAAC,CAC5C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,eAAoD;IAKpD,MAAM,OAAO,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpD,eAAe,CAAC,GAA6B,EAAE;QAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;QAC7B,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC;QACzC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;YACxC,MAAM,EAAE,GAAG,QAAQ,CAAC,qBAAqB,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC;YAClD,eAAe,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC;QACF,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;QACvC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACrB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,GAAS,EAAE;YAChB,EAAE,CAAC,UAAU,EAAE,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IACtB,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ApprovalsViewProps {
|
|
2
|
+
onCountChange?: (count: number) => void;
|
|
3
|
+
onViewRun?: (executionId: string, workflowName: string) => void;
|
|
4
|
+
className?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function ApprovalsView({ onCountChange, onViewRun, className }: ApprovalsViewProps): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=ApprovalsView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApprovalsView.d.ts","sourceRoot":"","sources":["../../../src/components/execution/ApprovalsView.tsx"],"names":[],"mappings":"AAmGA,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,aAAa,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,kBAAkB,+BAwExF"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { useWorkflowClient } from '../../hooks/use-workflow-client.js';
|
|
4
|
+
import { PauseInteractionPanel } from './PauseInteractionPanel.js';
|
|
5
|
+
import { cn } from '../shared/cn.js';
|
|
6
|
+
// ─── helpers ─────────────────────────────────────────────────────────────────
|
|
7
|
+
function timeAgo(date) {
|
|
8
|
+
const ms = Date.now() - new Date(date).getTime();
|
|
9
|
+
const mins = Math.floor(ms / 60_000);
|
|
10
|
+
if (mins < 1)
|
|
11
|
+
return 'just now';
|
|
12
|
+
if (mins < 60)
|
|
13
|
+
return `${String(mins)}m ago`;
|
|
14
|
+
const hrs = Math.floor(mins / 60);
|
|
15
|
+
if (hrs < 24)
|
|
16
|
+
return `${String(hrs)}h ago`;
|
|
17
|
+
return `${String(Math.floor(hrs / 24))}d ago`;
|
|
18
|
+
}
|
|
19
|
+
function extractPauseState(execution) {
|
|
20
|
+
const step = execution.steps.find((s) => s.status === 'EXTERNAL_WAIT');
|
|
21
|
+
if (!step?.data)
|
|
22
|
+
return null;
|
|
23
|
+
try {
|
|
24
|
+
const parsed = JSON.parse(step.data);
|
|
25
|
+
return parsed['pauseState'] ?? null;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// ─── inline SVG icons (no lucide dependency) ─────────────────────────────────
|
|
32
|
+
function IconWorkflow({ className }) {
|
|
33
|
+
return (_jsxs("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("rect", { width: "8", height: "8", x: "3", y: "3", rx: "2" }), _jsx("path", { d: "M7 11v4a2 2 0 0 0 2 2h4" }), _jsx("rect", { width: "8", height: "8", x: "13", y: "13", rx: "2" })] }));
|
|
34
|
+
}
|
|
35
|
+
function IconClock({ className }) {
|
|
36
|
+
return (_jsxs("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("polyline", { points: "12 6 12 12 16 14" })] }));
|
|
37
|
+
}
|
|
38
|
+
function IconCheck({ className }) {
|
|
39
|
+
return (_jsxs("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }), _jsx("polyline", { points: "22 4 12 14.01 9 11.01" })] }));
|
|
40
|
+
}
|
|
41
|
+
function IconX({ className }) {
|
|
42
|
+
return (_jsxs("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("line", { x1: "15", y1: "9", x2: "9", y2: "15" }), _jsx("line", { x1: "9", y1: "9", x2: "15", y2: "15" })] }));
|
|
43
|
+
}
|
|
44
|
+
function IconClose({ className }) {
|
|
45
|
+
return (_jsxs("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }));
|
|
46
|
+
}
|
|
47
|
+
function IconExternalLink({ className }) {
|
|
48
|
+
return (_jsxs("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }), _jsx("polyline", { points: "15 3 21 3 21 9" }), _jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })] }));
|
|
49
|
+
}
|
|
50
|
+
function IconSpinner({ className }) {
|
|
51
|
+
return (_jsx("svg", { className: cn('animate-spin', className), viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, children: _jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) }));
|
|
52
|
+
}
|
|
53
|
+
// ─── component ────────────────────────────────────────────────────────────────
|
|
54
|
+
export function ApprovalsView({ onCountChange, onViewRun, className }) {
|
|
55
|
+
const client = useWorkflowClient();
|
|
56
|
+
const [executions, setExecutions] = useState([]);
|
|
57
|
+
const [loading, setLoading] = useState(false);
|
|
58
|
+
const [selected, setSelected] = useState(null);
|
|
59
|
+
const load = async () => {
|
|
60
|
+
setLoading(true);
|
|
61
|
+
try {
|
|
62
|
+
const result = await client.executions.list({ status: 'EXTERNAL_WAIT', limit: 50 });
|
|
63
|
+
const details = await Promise.all(result.items.map((e) => client.executions.get(e.id)));
|
|
64
|
+
setExecutions(details);
|
|
65
|
+
onCountChange?.(details.length);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// ignore
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
setLoading(false);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
useEffect(() => { void load(); }, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
75
|
+
const remove = (id) => {
|
|
76
|
+
setExecutions((prev) => {
|
|
77
|
+
const next = prev.filter((e) => e.id !== id);
|
|
78
|
+
onCountChange?.(next.length);
|
|
79
|
+
return next;
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
const handleResumed = () => {
|
|
83
|
+
const id = selected?.id;
|
|
84
|
+
setSelected(null);
|
|
85
|
+
if (id)
|
|
86
|
+
remove(id);
|
|
87
|
+
};
|
|
88
|
+
if (loading) {
|
|
89
|
+
return (_jsx("div", { className: cn('flex h-52 items-center justify-center', className), children: _jsx(IconSpinner, { className: "h-5 w-5 text-[var(--wui-fg-muted)]" }) }));
|
|
90
|
+
}
|
|
91
|
+
if (executions.length === 0) {
|
|
92
|
+
return (_jsxs("div", { className: cn('flex h-52 flex-col items-center justify-center gap-2 text-sm text-[var(--wui-fg-muted)]', className), children: [_jsx(IconCheck, { className: "h-9 w-9 opacity-25" }), _jsx("span", { children: "No pending approvals" })] }));
|
|
93
|
+
}
|
|
94
|
+
return (_jsxs("div", { className: className, children: [_jsx("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(200px,1fr))] gap-3", children: executions.map((ex) => (_jsx(ApprovalCard, { execution: ex, onClick: () => setSelected(ex) }, ex.id))) }), selected && (_jsx(ApprovalDialog, { execution: selected, onClose: () => setSelected(null), onResumed: handleResumed, ...(onViewRun ? { onViewRun } : {}), client: client }))] }));
|
|
95
|
+
}
|
|
96
|
+
// ─── card ─────────────────────────────────────────────────────────────────────
|
|
97
|
+
function ApprovalCard({ execution, onClick }) {
|
|
98
|
+
const pausedStep = execution.steps.find((s) => s.status === 'EXTERNAL_WAIT');
|
|
99
|
+
return (_jsxs("button", { type: "button", onClick: onClick, className: "flex flex-col rounded-[var(--wui-radius)] border border-[var(--wui-border)] bg-[var(--wui-bg-subtle)] p-4 text-left shadow-sm transition hover:border-[var(--wui-status-paused)] hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--wui-status-paused)]", children: [_jsx("div", { className: "mb-3 flex h-12 w-12 items-center justify-center self-start rounded-[var(--wui-radius-sm)] bg-[var(--wui-status-paused)]/10", children: _jsx(IconWorkflow, { className: "h-8 w-8 text-[var(--wui-status-paused)]" }) }), _jsx("p", { className: "truncate w-full text-[13.5px] font-medium text-[var(--wui-fg)]", title: execution.name ?? execution.workflowId, children: execution.name ?? execution.workflowId }), pausedStep && (_jsxs("p", { className: "mt-0.5 truncate w-full text-[11.5px] text-[var(--wui-fg-muted)]", title: pausedStep.stepName, children: ["Waiting at: ", pausedStep.stepName] })), _jsxs("div", { className: "mt-1 flex items-center gap-1 text-[11px] text-[var(--wui-fg-muted)]", children: [_jsx(IconClock, { className: "h-3 w-3 shrink-0" }), _jsx("span", { children: timeAgo(execution.createdAt) })] })] }));
|
|
100
|
+
}
|
|
101
|
+
// ─── dialog ───────────────────────────────────────────────────────────────────
|
|
102
|
+
function ApprovalDialog({ execution, onClose, onResumed, onViewRun, client, }) {
|
|
103
|
+
const pauseState = extractPauseState(execution);
|
|
104
|
+
const [acting, setActing] = useState(null);
|
|
105
|
+
const doApprove = async () => {
|
|
106
|
+
setActing('approve');
|
|
107
|
+
try {
|
|
108
|
+
await client.executions.resume(execution.id);
|
|
109
|
+
onResumed();
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// ignore
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
setActing(null);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const doReject = async () => {
|
|
119
|
+
setActing('reject');
|
|
120
|
+
try {
|
|
121
|
+
await client.executions.cancel(execution.id);
|
|
122
|
+
onResumed();
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// ignore
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
setActing(null);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/30 backdrop-blur-[2px]", onClick: onClose }), _jsxs("div", { className: "fixed left-1/2 top-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-[var(--wui-radius)] border border-[var(--wui-border)] bg-[var(--wui-bg)] p-5 shadow-2xl", children: [_jsxs("div", { className: "mb-4 flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "truncate text-[14px] font-semibold text-[var(--wui-fg)]", title: execution.name ?? execution.workflowId, children: execution.name ?? execution.workflowId }), _jsxs("div", { className: "mt-0.5 flex items-center gap-1 text-[11px] text-[var(--wui-fg-muted)]", children: [_jsx(IconClock, { className: "h-3 w-3 shrink-0" }), _jsx("span", { children: timeAgo(execution.createdAt) })] })] }), _jsx("button", { type: "button", onClick: onClose, className: "grid h-7 w-7 shrink-0 place-items-center rounded-[var(--wui-radius-sm)] text-[var(--wui-fg-muted)] hover:bg-[var(--wui-bg-subtle)] transition-colors", children: _jsx(IconClose, { className: "h-4 w-4" }) })] }), pauseState && (_jsx("div", { className: "mb-4", children: _jsx(PauseInteractionPanel, { executionId: execution.id, pauseState: pauseState, onResumed: onResumed }) })), !pauseState && (_jsxs("div", { className: "mb-4 flex gap-2", children: [_jsxs("button", { type: "button", disabled: acting !== null, onClick: () => void doApprove(), className: cn('flex flex-1 items-center justify-center gap-1.5 rounded-[var(--wui-radius-sm)] border py-2', 'border-[var(--wui-status-completed)]/30 bg-[var(--wui-status-completed)]/5', 'text-[12px] font-medium text-[var(--wui-status-completed)] transition hover:bg-[var(--wui-status-completed)]/10', 'disabled:cursor-not-allowed disabled:opacity-50'), children: [acting === 'approve' ? _jsx(IconSpinner, { className: "h-3.5 w-3.5" }) : _jsx(IconCheck, { className: "h-3.5 w-3.5" }), "Approve"] }), _jsxs("button", { type: "button", disabled: acting !== null, onClick: () => void doReject(), className: cn('flex flex-1 items-center justify-center gap-1.5 rounded-[var(--wui-radius-sm)] border py-2', 'border-[var(--wui-status-failed)]/30 bg-[var(--wui-status-failed)]/5', 'text-[12px] font-medium text-[var(--wui-status-failed)] transition hover:bg-[var(--wui-status-failed)]/10', 'disabled:cursor-not-allowed disabled:opacity-50'), children: [_jsx(IconX, { className: "h-3.5 w-3.5" }), "Reject"] })] })), onViewRun && (_jsxs("button", { type: "button", onClick: () => { onClose(); onViewRun(execution.id, execution.name ?? execution.workflowId); }, className: "flex w-full items-center justify-center gap-1.5 rounded-[var(--wui-radius-sm)] border border-[var(--wui-border)] bg-[var(--wui-bg-subtle)] px-3 py-2 text-[12px] font-medium text-[var(--wui-fg-muted)] transition hover:bg-[var(--wui-border)]", children: [_jsx(IconExternalLink, { className: "h-3.5 w-3.5" }), "View run"] }))] })] }));
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=ApprovalsView.js.map
|