refactor(webui): adopt semantic workspace actions
This commit is contained in:
@@ -14,7 +14,6 @@ import {
|
|||||||
GitFork,
|
GitFork,
|
||||||
ListChecks,
|
ListChecks,
|
||||||
Plus,
|
Plus,
|
||||||
RefreshCw,
|
|
||||||
RotateCcw,
|
RotateCcw,
|
||||||
Save,
|
Save,
|
||||||
Settings2,
|
Settings2,
|
||||||
@@ -23,7 +22,7 @@ import {
|
|||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { ReactFlowProvider } from "@xyflow/react";
|
import { ReactFlowProvider } from "@xyflow/react";
|
||||||
import { useSearchParams } from "react-router";
|
import { useSearchParams } from "react-router";
|
||||||
import { ToolbarGroup, ActionToolbar,
|
import { ActionToolbar,
|
||||||
Button,
|
Button,
|
||||||
ConfirmDialog,
|
ConfirmDialog,
|
||||||
ContentGrid,
|
ContentGrid,
|
||||||
@@ -46,6 +45,7 @@ import { ToolbarGroup, ActionToolbar,
|
|||||||
StatePanel,
|
StatePanel,
|
||||||
StatusBadge,
|
StatusBadge,
|
||||||
ToggleSwitch,
|
ToggleSwitch,
|
||||||
|
WorkspaceActionBar,
|
||||||
WorkspaceFrame,
|
WorkspaceFrame,
|
||||||
WorkspaceLayout,
|
WorkspaceLayout,
|
||||||
hasScope,
|
hasScope,
|
||||||
@@ -111,7 +111,7 @@ export default function WorkflowPage({
|
|||||||
settings: ApiSettings;
|
settings: ApiSettings;
|
||||||
auth: AuthInfo;
|
auth: AuthInfo;
|
||||||
}) {
|
}) {
|
||||||
const { requestNavigation } = useUnsavedChanges();
|
const { requestDiscard, requestNavigation } = useUnsavedChanges();
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const requestedDefinitionId = searchParams.get("definition");
|
const requestedDefinitionId = searchParams.get("definition");
|
||||||
const requestedRunId = searchParams.get("run");
|
const requestedRunId = searchParams.get("run");
|
||||||
@@ -606,20 +606,13 @@ export default function WorkflowPage({
|
|||||||
contentLabel="Workflow editor"
|
contentLabel="Workflow editor"
|
||||||
contentClassName="workflow-workspace"
|
contentClassName="workflow-workspace"
|
||||||
primary={<>
|
primary={<>
|
||||||
<ActionToolbar surface="panel-header">
|
<WorkspaceActionBar
|
||||||
<strong>Workflows</strong>
|
scope="collection-pane"
|
||||||
<ToolbarGroup align="end" className="workflow-toolbar-actions">
|
variant="collection"
|
||||||
<DocumentationHelpLink
|
refreshable
|
||||||
reference={{ topicId: "workflow.editor", documentationType: "user" }}
|
reloadAction={{ onReload: () => void reload(draft?.id), loading: loading || working }}
|
||||||
label="Open Workflow documentation"
|
contextActions={<>
|
||||||
/>
|
<strong>Workflows</strong>
|
||||||
<IconButton
|
|
||||||
label="Refresh"
|
|
||||||
icon={<RefreshCw size={16} />}
|
|
||||||
variant="ghost"
|
|
||||||
onClick={() => void reload(draft?.id)}
|
|
||||||
disabled={loading || working}
|
|
||||||
/>
|
|
||||||
{hasScope(auth, "workflow:instance:admin") ? (
|
{hasScope(auth, "workflow:instance:admin") ? (
|
||||||
<IconButton
|
<IconButton
|
||||||
label="Reconcile module standards"
|
label="Reconcile module standards"
|
||||||
@@ -629,16 +622,20 @@ export default function WorkflowPage({
|
|||||||
disabled={loading || working}
|
disabled={loading || working}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<IconButton
|
</>}
|
||||||
|
helpAction={<DocumentationHelpLink
|
||||||
|
reference={{ topicId: "workflow.editor", documentationType: "user" }}
|
||||||
|
label="Open Workflow documentation"
|
||||||
|
/>}
|
||||||
|
createAction={<IconButton
|
||||||
label="New workflow"
|
label="New workflow"
|
||||||
icon={<Plus size={17} />}
|
icon={<Plus size={17} />}
|
||||||
variant="primary"
|
variant="primary"
|
||||||
onClick={createNew}
|
onClick={createNew}
|
||||||
disabled={!canWrite}
|
disabled={!canWrite}
|
||||||
disabledReason={!canWrite ? "Workflow definition write permission is required." : undefined}
|
disabledReason={!canWrite ? "Workflow definition write permission is required." : undefined}
|
||||||
/>
|
/>}
|
||||||
</ToolbarGroup>
|
/>
|
||||||
</ActionToolbar>
|
|
||||||
<FilterBar surface="panel">
|
<FilterBar surface="panel">
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
@@ -683,8 +680,12 @@ export default function WorkflowPage({
|
|||||||
>
|
>
|
||||||
{draft && displayedGraph ? (
|
{draft && displayedGraph ? (
|
||||||
<>
|
<>
|
||||||
<ActionToolbar surface="panel-header" className="workflow-workspace-toolbar">
|
<WorkspaceActionBar
|
||||||
<span className="workflow-identity-fields">
|
scope="editor-pane"
|
||||||
|
variant="editor"
|
||||||
|
state={working ? "saving" : dirty && !draft.name.trim() ? "invalid" : dirty ? "dirty" : "clean"}
|
||||||
|
className="workflow-workspace-toolbar"
|
||||||
|
contextActions={<span className="workflow-identity-fields">
|
||||||
<input
|
<input
|
||||||
className="workflow-name-input"
|
className="workflow-name-input"
|
||||||
value={draft.name}
|
value={draft.name}
|
||||||
@@ -706,8 +707,8 @@ export default function WorkflowPage({
|
|||||||
placeholder="Description"
|
placeholder="Description"
|
||||||
aria-label="Workflow description"
|
aria-label="Workflow description"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>}
|
||||||
<span className="workflow-command-bar">
|
primaryActions={<span className="workflow-command-bar">
|
||||||
{draft.id ? (
|
{draft.id ? (
|
||||||
<select
|
<select
|
||||||
className="workflow-revision-select"
|
className="workflow-revision-select"
|
||||||
@@ -851,26 +852,26 @@ export default function WorkflowPage({
|
|||||||
<CheckCircle2 size={16} /> Activate
|
<CheckCircle2 size={16} /> Activate
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
<Button
|
</span>}
|
||||||
variant="primary"
|
destructiveActions={draft.id && draft.standard?.kind !== "baseline" ? (
|
||||||
onClick={() => void saveDraft()}
|
<IconButton
|
||||||
disabled={
|
label="Delete workflow"
|
||||||
!canEdit || !dirty || working || readOnly
|
icon={<Trash2 size={16} />}
|
||||||
}
|
variant="danger"
|
||||||
>
|
onClick={() => setDeleteOpen(true)}
|
||||||
<Save size={16} /> Save
|
disabled={!canEdit || working}
|
||||||
</Button>
|
/>
|
||||||
{draft.id && draft.standard?.kind !== "baseline" ? (
|
) : undefined}
|
||||||
<IconButton
|
discardAction={{
|
||||||
label="Delete workflow"
|
label: <><RotateCcw size={16} /> Discard</>,
|
||||||
icon={<Trash2 size={16} />}
|
onClick: () => requestDiscard(() => void reload(draft.id))
|
||||||
variant="danger"
|
}}
|
||||||
onClick={() => setDeleteOpen(true)}
|
saveAction={{
|
||||||
disabled={!canEdit || working}
|
label: <><Save size={16} /> Save</>,
|
||||||
/>
|
onClick: () => void saveDraft(),
|
||||||
) : null}
|
disabled: !canEdit || readOnly
|
||||||
</span>
|
}}
|
||||||
</ActionToolbar>
|
/>
|
||||||
<div className="workflow-alerts">
|
<div className="workflow-alerts">
|
||||||
{error ? (
|
{error ? (
|
||||||
<DismissibleAlert tone="danger" resetKey={error}>
|
<DismissibleAlert tone="danger" resetKey={error}>
|
||||||
|
|||||||
Reference in New Issue
Block a user