Adopt shared WebUI structural primitives
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
|||||||
type Edge,
|
type Edge,
|
||||||
type ReactFlowInstance
|
type ReactFlowInstance
|
||||||
} from "@xyflow/react";
|
} from "@xyflow/react";
|
||||||
|
import { StatePanel } from "@govoplan/core-webui";
|
||||||
import { definitionConnectionError } from "@govoplan/core-webui/definition-graph";
|
import { definitionConnectionError } from "@govoplan/core-webui/definition-graph";
|
||||||
import type {
|
import type {
|
||||||
WorkflowDiagnostic,
|
WorkflowDiagnostic,
|
||||||
@@ -211,7 +212,7 @@ export default function WorkflowCanvas({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="workflow-canvas"
|
className="definition-graph-canvas workflow-canvas"
|
||||||
onDragOver={(event) => {
|
onDragOver={(event) => {
|
||||||
if (
|
if (
|
||||||
event.dataTransfer.types.includes(
|
event.dataTransfer.types.includes(
|
||||||
@@ -320,7 +321,7 @@ export default function WorkflowCanvas({
|
|||||||
<Controls showInteractive={false} />
|
<Controls showInteractive={false} />
|
||||||
</ReactFlow>
|
</ReactFlow>
|
||||||
{!graph.nodes.length ? (
|
{!graph.nodes.length ? (
|
||||||
<div className="workflow-canvas-empty">Drop a start node here</div>
|
<StatePanel className="definition-graph-canvas-empty" size="fill" description="Drop a start node here" />
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { Trash2 } from "lucide-react";
|
import { Trash2 } from "lucide-react";
|
||||||
import {
|
import {
|
||||||
|
ActionToolbar,
|
||||||
Button,
|
Button,
|
||||||
DismissibleAlert,
|
DismissibleAlert,
|
||||||
FormField,
|
FormField,
|
||||||
ReferenceMultiSelect,
|
ReferenceMultiSelect,
|
||||||
|
StatePanel,
|
||||||
useViewSurfaces,
|
useViewSurfaces,
|
||||||
type ReferenceOptionProvider
|
type ReferenceOptionProvider
|
||||||
} from "@govoplan/core-webui";
|
} from "@govoplan/core-webui";
|
||||||
@@ -87,7 +89,7 @@ export default function WorkflowInspector({
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<aside className="workflow-inspector" aria-label="Flow inspector">
|
<aside className="workflow-inspector" aria-label="Flow inspector">
|
||||||
<div className="workflow-panel-heading">
|
<ActionToolbar surface="section-header" className="workflow-panel-heading">
|
||||||
<span>
|
<span>
|
||||||
<strong>Flow</strong>
|
<strong>Flow</strong>
|
||||||
<small>{edge.type.replace(/^bpmn\./, "")}</small>
|
<small>{edge.type.replace(/^bpmn\./, "")}</small>
|
||||||
@@ -102,7 +104,7 @@ export default function WorkflowInspector({
|
|||||||
>
|
>
|
||||||
<Trash2 size={16} />
|
<Trash2 size={16} />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</ActionToolbar>
|
||||||
<div className="workflow-inspector-fields">
|
<div className="workflow-inspector-fields">
|
||||||
<FormField label="Flow type">
|
<FormField label="Flow type">
|
||||||
<select
|
<select
|
||||||
@@ -184,8 +186,8 @@ export default function WorkflowInspector({
|
|||||||
if (!node) {
|
if (!node) {
|
||||||
return (
|
return (
|
||||||
<aside className="workflow-inspector" aria-label="Node inspector">
|
<aside className="workflow-inspector" aria-label="Node inspector">
|
||||||
<div className="workflow-panel-heading"><strong>Inspector</strong></div>
|
<ActionToolbar surface="section-header" className="workflow-panel-heading"><strong>Inspector</strong></ActionToolbar>
|
||||||
<div className="workflow-inspector-empty">No node selected</div>
|
<StatePanel size="compact" description="No node selected" />
|
||||||
</aside>
|
</aside>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -200,7 +202,7 @@ export default function WorkflowInspector({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className="workflow-inspector" aria-label="Node inspector">
|
<aside className="workflow-inspector" aria-label="Node inspector">
|
||||||
<div className="workflow-panel-heading">
|
<ActionToolbar surface="section-header" className="workflow-panel-heading">
|
||||||
<span>
|
<span>
|
||||||
<strong>Inspector</strong>
|
<strong>Inspector</strong>
|
||||||
<small>{definition?.label ?? node.type}</small>
|
<small>{definition?.label ?? node.type}</small>
|
||||||
@@ -215,7 +217,7 @@ export default function WorkflowInspector({
|
|||||||
>
|
>
|
||||||
<Trash2 size={16} />
|
<Trash2 size={16} />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</ActionToolbar>
|
||||||
<div className="workflow-inspector-fields">
|
<div className="workflow-inspector-fields">
|
||||||
{error ? (
|
{error ? (
|
||||||
<DismissibleAlert tone="danger" resetKey={error}>
|
<DismissibleAlert tone="danger" resetKey={error}>
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import {
|
|||||||
type Node,
|
type Node,
|
||||||
type NodeProps
|
type NodeProps
|
||||||
} from "@xyflow/react";
|
} from "@xyflow/react";
|
||||||
|
import { DefinitionNodeIcon } from "@govoplan/core-webui";
|
||||||
import type { WorkflowNodeType } from "../../api/workflow";
|
import type { WorkflowNodeType } from "../../api/workflow";
|
||||||
|
|
||||||
export type WorkflowFlowNodeData = {
|
export type WorkflowFlowNodeData = {
|
||||||
@@ -127,13 +128,13 @@ export default function WorkflowNode({
|
|||||||
id={port.id}
|
id={port.id}
|
||||||
type="target"
|
type="target"
|
||||||
position={Position.Left}
|
position={Position.Left}
|
||||||
className="workflow-node-handle"
|
className="definition-node-handle"
|
||||||
style={{ top: portPosition(index, inputPorts.length) }}
|
style={{ top: portPosition(index, inputPorts.length) }}
|
||||||
isConnectable={isConnectable}
|
isConnectable={isConnectable}
|
||||||
title={port.label}
|
title={port.label}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<span className="workflow-node-icon"><Icon size={17} /></span>
|
<DefinitionNodeIcon className="workflow-node-icon"><Icon size={17} /></DefinitionNodeIcon>
|
||||||
<span className="workflow-node-copy">
|
<span className="workflow-node-copy">
|
||||||
<strong>{data.label}</strong>
|
<strong>{data.label}</strong>
|
||||||
<small>{data.definition.label}</small>
|
<small>{data.definition.label}</small>
|
||||||
@@ -144,7 +145,7 @@ export default function WorkflowNode({
|
|||||||
id={port.id}
|
id={port.id}
|
||||||
type="source"
|
type="source"
|
||||||
position={Position.Right}
|
position={Position.Right}
|
||||||
className="workflow-node-handle"
|
className="definition-node-handle"
|
||||||
style={{ top: portPosition(index, outputPorts.length) }}
|
style={{ top: portPosition(index, outputPorts.length) }}
|
||||||
isConnectable={isConnectable}
|
isConnectable={isConnectable}
|
||||||
title={port.label}
|
title={port.label}
|
||||||
|
|||||||
@@ -26,15 +26,28 @@ import { useSearchParams } from "react-router";
|
|||||||
import { ToolbarGroup, ActionToolbar,
|
import { ToolbarGroup, ActionToolbar,
|
||||||
Button,
|
Button,
|
||||||
ConfirmDialog,
|
ConfirmDialog,
|
||||||
|
ContentGrid,
|
||||||
|
ContentSection,
|
||||||
Dialog,
|
Dialog,
|
||||||
DocumentationHelpLink,
|
DocumentationHelpLink,
|
||||||
DismissibleAlert,
|
DismissibleAlert,
|
||||||
|
DefinitionPalette,
|
||||||
|
DefinitionPaletteGroup,
|
||||||
|
DefinitionPaletteItem,
|
||||||
|
FilterBar,
|
||||||
|
FloatingStatus,
|
||||||
FormField,
|
FormField,
|
||||||
IconButton,
|
IconButton,
|
||||||
LoadingFrame,
|
LoadingFrame,
|
||||||
ReferenceSelect,
|
ReferenceSelect,
|
||||||
|
SelectionList,
|
||||||
|
SelectionListItem,
|
||||||
|
SelectionListItemContent,
|
||||||
|
StatePanel,
|
||||||
StatusBadge,
|
StatusBadge,
|
||||||
ToggleSwitch,
|
ToggleSwitch,
|
||||||
|
WorkspaceFrame,
|
||||||
|
WorkspaceLayout,
|
||||||
hasScope,
|
hasScope,
|
||||||
isApiError,
|
isApiError,
|
||||||
useUnsavedChanges,
|
useUnsavedChanges,
|
||||||
@@ -582,10 +595,18 @@ export default function WorkflowPage({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="workflow-page">
|
<WorkspaceFrame as="main" height="viewport" surface="plain" className="workflow-page" label="Workflow workspace">
|
||||||
<div className="workflow-shell">
|
<WorkspaceLayout
|
||||||
<aside className="workflow-definition-panel">
|
variant="split"
|
||||||
<ActionToolbar className="workflow-panel-toolbar">
|
primarySize="compact"
|
||||||
|
surface="contained"
|
||||||
|
primaryScrollable={false}
|
||||||
|
contentScrollable={false}
|
||||||
|
primaryLabel="Workflows"
|
||||||
|
contentLabel="Workflow editor"
|
||||||
|
contentClassName="workflow-workspace"
|
||||||
|
primary={<>
|
||||||
|
<ActionToolbar surface="panel-header">
|
||||||
<strong>Workflows</strong>
|
<strong>Workflows</strong>
|
||||||
<ToolbarGroup align="end" className="workflow-toolbar-actions">
|
<ToolbarGroup align="end" className="workflow-toolbar-actions">
|
||||||
<DocumentationHelpLink
|
<DocumentationHelpLink
|
||||||
@@ -618,7 +639,7 @@ export default function WorkflowPage({
|
|||||||
/>
|
/>
|
||||||
</ToolbarGroup>
|
</ToolbarGroup>
|
||||||
</ActionToolbar>
|
</ActionToolbar>
|
||||||
<div className="workflow-definition-search">
|
<FilterBar surface="panel">
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
value={search}
|
value={search}
|
||||||
@@ -626,52 +647,43 @@ export default function WorkflowPage({
|
|||||||
placeholder="Search workflows"
|
placeholder="Search workflows"
|
||||||
aria-label="Search workflows"
|
aria-label="Search workflows"
|
||||||
/>
|
/>
|
||||||
</div>
|
</FilterBar>
|
||||||
<LoadingFrame loading={loading} className="workflow-definition-list-frame">
|
<LoadingFrame loading={loading} className="workflow-definition-list-frame">
|
||||||
<div className="workflow-definition-list">
|
<SelectionList variant="navigation" label="Workflows">
|
||||||
{visibleDefinitions.map((definition) => (
|
{visibleDefinitions.map((definition) => (
|
||||||
<button
|
<SelectionListItem
|
||||||
key={definition.id}
|
key={definition.id}
|
||||||
type="button"
|
selected={definition.id === draft?.id}
|
||||||
className={definition.id === draft?.id ? "is-selected" : ""}
|
|
||||||
onClick={() => selectDefinition(definition)}
|
onClick={() => selectDefinition(definition)}
|
||||||
>
|
>
|
||||||
<span>
|
<SelectionListItemContent
|
||||||
<strong>{definition.name}</strong>
|
title={definition.name}
|
||||||
<small>
|
description={[
|
||||||
{definition.key} · revision {definition.current_revision}
|
definition.key,
|
||||||
</small>
|
`revision ${definition.current_revision}`,
|
||||||
<small>
|
definition.governance.scope_type,
|
||||||
{definition.governance.scope_type} · {definition.governance.definition_kind}
|
definition.governance.definition_kind,
|
||||||
</small>
|
definition.standard
|
||||||
{definition.standard ? (
|
? `${definition.standard.kind === "baseline" ? "Standard" : "Override"} · ${definition.standard.origin_module_id}${definition.standard.update_available ? " · update available" : ""}`
|
||||||
<small>
|
: ""
|
||||||
{definition.standard.kind === "baseline"
|
].filter(Boolean).join(" · ")}
|
||||||
? `Standard · ${definition.standard.origin_module_id}`
|
/>
|
||||||
: `Override · ${definition.standard.origin_module_id}`}
|
|
||||||
{definition.standard.update_available ? " · update available" : ""}
|
|
||||||
</small>
|
|
||||||
) : null}
|
|
||||||
</span>
|
|
||||||
<StatusBadge
|
<StatusBadge
|
||||||
status={definition.status}
|
status={definition.status}
|
||||||
label={definition.status}
|
label={definition.status}
|
||||||
/>
|
/>
|
||||||
</button>
|
</SelectionListItem>
|
||||||
))}
|
))}
|
||||||
{!visibleDefinitions.length ? (
|
{!visibleDefinitions.length ? (
|
||||||
<div className="workflow-definition-empty">
|
<StatePanel size="compact" description="No workflow definitions" />
|
||||||
No workflow definitions
|
|
||||||
</div>
|
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</SelectionList>
|
||||||
</LoadingFrame>
|
</LoadingFrame>
|
||||||
</aside>
|
</>}
|
||||||
|
>
|
||||||
<section className="workflow-workspace">
|
|
||||||
{draft && displayedGraph ? (
|
{draft && displayedGraph ? (
|
||||||
<>
|
<>
|
||||||
<ActionToolbar className="workflow-workspace-toolbar">
|
<ActionToolbar surface="panel-header" className="workflow-workspace-toolbar">
|
||||||
<span className="workflow-identity-fields">
|
<span className="workflow-identity-fields">
|
||||||
<input
|
<input
|
||||||
className="workflow-name-input"
|
className="workflow-name-input"
|
||||||
@@ -872,21 +884,14 @@ export default function WorkflowPage({
|
|||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="workflow-editor">
|
<div className="workflow-editor">
|
||||||
<aside className="workflow-palette">
|
<DefinitionPalette label="Node library" description="Drag nodes onto the canvas">
|
||||||
<div className="workflow-panel-heading">
|
|
||||||
<span>
|
|
||||||
<strong>Node library</strong>
|
|
||||||
<small>Drag nodes onto the canvas</small>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="workflow-palette-items">
|
|
||||||
{paletteGroups.map((group) => (
|
{paletteGroups.map((group) => (
|
||||||
<section key={group.category} className="workflow-palette-group">
|
<DefinitionPaletteGroup key={group.category} label={group.label}>
|
||||||
<h3>{group.label}</h3>
|
|
||||||
{group.nodes.map((nodeType) => (
|
{group.nodes.map((nodeType) => (
|
||||||
<button
|
<DefinitionPaletteItem
|
||||||
key={nodeType.type}
|
key={nodeType.type}
|
||||||
type="button"
|
icon={<GitFork size={16} />}
|
||||||
|
label={nodeType.label}
|
||||||
draggable={!graphReadOnly}
|
draggable={!graphReadOnly}
|
||||||
disabled={graphReadOnly}
|
disabled={graphReadOnly}
|
||||||
onDragStart={(event) =>
|
onDragStart={(event) =>
|
||||||
@@ -894,17 +899,12 @@ export default function WorkflowPage({
|
|||||||
}
|
}
|
||||||
onClick={() => addNodeFromPalette(nodeType.type)}
|
onClick={() => addNodeFromPalette(nodeType.type)}
|
||||||
title={nodeType.description}
|
title={nodeType.description}
|
||||||
>
|
/>
|
||||||
<GitFork size={16} />
|
|
||||||
<span>{nodeType.label}</span>
|
|
||||||
<Plus size={13} className="workflow-palette-add" />
|
|
||||||
</button>
|
|
||||||
))}
|
))}
|
||||||
</section>
|
</DefinitionPaletteGroup>
|
||||||
))}
|
))}
|
||||||
</div>
|
</DefinitionPalette>
|
||||||
</aside>
|
<div className="definition-editor-surface workflow-editor-surface">
|
||||||
<div className="workflow-editor-surface">
|
|
||||||
<ReactFlowProvider>
|
<ReactFlowProvider>
|
||||||
<WorkflowCanvas
|
<WorkflowCanvas
|
||||||
graph={displayedGraph}
|
graph={displayedGraph}
|
||||||
@@ -936,7 +936,7 @@ export default function WorkflowPage({
|
|||||||
/>
|
/>
|
||||||
{diagnostics.length ? (
|
{diagnostics.length ? (
|
||||||
<div className="workflow-diagnostics">
|
<div className="workflow-diagnostics">
|
||||||
<div className="workflow-panel-heading">
|
<ActionToolbar surface="section-header" className="workflow-panel-heading">
|
||||||
<strong>Diagnostics</strong>
|
<strong>Diagnostics</strong>
|
||||||
<StatusBadge
|
<StatusBadge
|
||||||
status={
|
status={
|
||||||
@@ -946,7 +946,7 @@ export default function WorkflowPage({
|
|||||||
}
|
}
|
||||||
label={String(diagnostics.length)}
|
label={String(diagnostics.length)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</ActionToolbar>
|
||||||
<div>
|
<div>
|
||||||
{diagnostics.map((item, index) => (
|
{diagnostics.map((item, index) => (
|
||||||
<button
|
<button
|
||||||
@@ -965,25 +965,21 @@ export default function WorkflowPage({
|
|||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{working ? (
|
{working ? <FloatingStatus>Working...</FloatingStatus> : null}
|
||||||
<div className="workflow-working-indicator" role="status">
|
|
||||||
Working...
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="workflow-workspace-empty">
|
<StatePanel
|
||||||
<GitFork size={34} />
|
size="fill"
|
||||||
<strong>No workflow selected</strong>
|
icon={<GitFork size={34} />}
|
||||||
{canWrite ? (
|
title="No workflow selected"
|
||||||
|
actions={canWrite ? (
|
||||||
<Button variant="primary" onClick={createNew}>
|
<Button variant="primary" onClick={createNew}>
|
||||||
<Plus size={16} /> New workflow
|
<Plus size={16} /> New workflow
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : undefined}
|
||||||
</div>
|
/>
|
||||||
)}
|
)}
|
||||||
</section>
|
</WorkspaceLayout>
|
||||||
</div>
|
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
open={deleteOpen}
|
open={deleteOpen}
|
||||||
title="Delete workflow"
|
title="Delete workflow"
|
||||||
@@ -1052,7 +1048,7 @@ export default function WorkflowPage({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</main>
|
</WorkspaceFrame>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1336,7 +1332,7 @@ function WorkflowDefinitionSettingsDialog({
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</FormField>
|
</FormField>
|
||||||
<div className="workflow-definition-toggles">
|
<ContentGrid columns={2} gap="default" collapseAt="narrow">
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
label="Visible to lower scopes"
|
label="Visible to lower scopes"
|
||||||
checked={draft.inheritToLowerScopes}
|
checked={draft.inheritToLowerScopes}
|
||||||
@@ -1361,7 +1357,7 @@ function WorkflowDefinitionSettingsDialog({
|
|||||||
disabled={!editable || draft.executionMode === "guided"}
|
disabled={!editable || draft.executionMode === "guided"}
|
||||||
onChange={(value) => onChange({ allowAutomation: value })}
|
onChange={(value) => onChange({ allowAutomation: value })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</ContentGrid>
|
||||||
{draft.governance?.automation_runtime_reason ? (
|
{draft.governance?.automation_runtime_reason ? (
|
||||||
<DismissibleAlert
|
<DismissibleAlert
|
||||||
tone="warning"
|
tone="warning"
|
||||||
@@ -1371,7 +1367,7 @@ function WorkflowDefinitionSettingsDialog({
|
|||||||
</DismissibleAlert>
|
</DismissibleAlert>
|
||||||
) : null}
|
) : null}
|
||||||
{draft.governance?.derived_from_definition_id ? (
|
{draft.governance?.derived_from_definition_id ? (
|
||||||
<section className="workflow-provenance">
|
<ContentSection spacing="none" surface="subtle" density="compact" layout="stack" className="workflow-provenance">
|
||||||
<strong>Derived from</strong>
|
<strong>Derived from</strong>
|
||||||
<span>
|
<span>
|
||||||
{draft.governance.derived_from_definition_id}
|
{draft.governance.derived_from_definition_id}
|
||||||
@@ -1379,10 +1375,10 @@ function WorkflowDefinitionSettingsDialog({
|
|||||||
{draft.governance.derived_from_revision}
|
{draft.governance.derived_from_revision}
|
||||||
</span>
|
</span>
|
||||||
<code>{draft.governance.derived_from_hash}</code>
|
<code>{draft.governance.derived_from_hash}</code>
|
||||||
</section>
|
</ContentSection>
|
||||||
) : null}
|
) : null}
|
||||||
{provenance.length ? (
|
{provenance.length ? (
|
||||||
<section className="workflow-provenance">
|
<ContentSection spacing="none" surface="subtle" density="compact" layout="stack" className="workflow-provenance">
|
||||||
<strong>Effective Policy path</strong>
|
<strong>Effective Policy path</strong>
|
||||||
{provenance.map((item, index) => (
|
{provenance.map((item, index) => (
|
||||||
<span key={`${String(item.path ?? item.scope_type)}-${index}`}>
|
<span key={`${String(item.path ?? item.scope_type)}-${index}`}>
|
||||||
@@ -1392,7 +1388,7 @@ function WorkflowDefinitionSettingsDialog({
|
|||||||
{!editable && draft.governance?.actions.edit?.reason ? (
|
{!editable && draft.governance?.actions.edit?.reason ? (
|
||||||
<small>{draft.governance.actions.edit.reason}</small>
|
<small>{draft.governance.actions.edit.reason}</small>
|
||||||
) : null}
|
) : null}
|
||||||
</section>
|
</ContentSection>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { ActionToolbar,
|
|||||||
ConfirmDialog,
|
ConfirmDialog,
|
||||||
Dialog,
|
Dialog,
|
||||||
DismissibleAlert,
|
DismissibleAlert,
|
||||||
|
ContentGrid,
|
||||||
FormField,
|
FormField,
|
||||||
IconButton,
|
IconButton,
|
||||||
LoadingFrame,
|
LoadingFrame,
|
||||||
@@ -422,7 +423,7 @@ export default function WorkflowRunsDialog({
|
|||||||
</a>
|
</a>
|
||||||
) : null}
|
) : null}
|
||||||
{allowedActions.some((action) => action !== "cancel") ? (
|
{allowedActions.some((action) => action !== "cancel") ? (
|
||||||
<div className="workflow-run-action-form">
|
<ContentGrid columns={2} gap="compact" collapseAt="narrow" className="workflow-run-action-form">
|
||||||
<FormField label="Comment">
|
<FormField label="Comment">
|
||||||
<textarea
|
<textarea
|
||||||
value={comment}
|
value={comment}
|
||||||
@@ -466,7 +467,7 @@ export default function WorkflowRunsDialog({
|
|||||||
</Button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</ContentGrid>
|
||||||
) : null}
|
) : null}
|
||||||
</section>
|
</section>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -1,14 +1,3 @@
|
|||||||
.workflow-page {
|
|
||||||
position: relative;
|
|
||||||
height: calc(100vh - 115px);
|
|
||||||
min-width: 0;
|
|
||||||
min-height: 0;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
color: var(--text);
|
|
||||||
background: var(--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-dialog {
|
.workflow-definition-dialog {
|
||||||
width: min(620px, calc(100vw - 32px));
|
width: min(620px, calc(100vw - 32px));
|
||||||
}
|
}
|
||||||
@@ -109,21 +98,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-definition-toggles {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
||||||
gap: 10px 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-provenance {
|
|
||||||
display: grid;
|
|
||||||
gap: 6px;
|
|
||||||
padding: 10px;
|
|
||||||
border: var(--border-line);
|
|
||||||
border-radius: var(--radius-sm);
|
|
||||||
background: var(--panel-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-provenance span,
|
.workflow-provenance span,
|
||||||
.workflow-provenance small {
|
.workflow-provenance small {
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
@@ -136,34 +110,8 @@
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
|
||||||
.workflow-definition-toggles {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-page *,
|
|
||||||
.workflow-page *::before,
|
|
||||||
.workflow-page *::after {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-shell {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: minmax(250px, 300px) minmax(0, 1fr);
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
min-width: 0;
|
|
||||||
min-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
border: var(--border-line);
|
|
||||||
background: var(--panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-panel,
|
|
||||||
.workflow-workspace,
|
.workflow-workspace,
|
||||||
.workflow-editor,
|
.workflow-editor,
|
||||||
.workflow-editor-surface,
|
|
||||||
.workflow-canvas,
|
.workflow-canvas,
|
||||||
.workflow-definition-list-frame,
|
.workflow-definition-list-frame,
|
||||||
.workflow-inspector-column {
|
.workflow-inspector-column {
|
||||||
@@ -171,31 +119,6 @@
|
|||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-definition-panel {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
border-right: var(--border-line);
|
|
||||||
background: var(--panel-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-panel-toolbar,
|
|
||||||
.workflow-workspace-toolbar,
|
|
||||||
.workflow-panel-heading {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 10px;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
border-bottom: var(--border-line);
|
|
||||||
background: var(--panel-header);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-panel-toolbar {
|
|
||||||
min-height: 52px;
|
|
||||||
padding: 8px 10px 8px 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-toolbar-actions,
|
.workflow-toolbar-actions,
|
||||||
.workflow-command-bar,
|
.workflow-command-bar,
|
||||||
.workflow-identity-fields {
|
.workflow-identity-fields {
|
||||||
@@ -204,98 +127,12 @@
|
|||||||
gap: 7px;
|
gap: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-definition-search {
|
|
||||||
padding: 10px;
|
|
||||||
border-bottom: var(--border-line);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-search input {
|
|
||||||
min-height: 34px;
|
|
||||||
padding: 7px 9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-list-frame {
|
.workflow-definition-list-frame {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-definition-list {
|
|
||||||
height: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
padding: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-list > button {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: minmax(0, 1fr) auto;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
width: 100%;
|
|
||||||
min-height: 56px;
|
|
||||||
border: 0;
|
|
||||||
border-radius: var(--radius-sm);
|
|
||||||
background: transparent;
|
|
||||||
color: var(--text);
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 8px 9px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-list > button:hover,
|
|
||||||
.workflow-definition-list > button:focus-visible {
|
|
||||||
background: var(--primary-soft);
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-list > button.is-selected {
|
|
||||||
background: var(--primary-soft-strong);
|
|
||||||
box-shadow: inset 3px 0 0 var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-list > button > span:first-child {
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-list strong,
|
|
||||||
.workflow-definition-list small {
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-list strong {
|
|
||||||
color: var(--text-strong);
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-list small {
|
|
||||||
margin-top: 4px;
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-empty,
|
|
||||||
.workflow-inspector-empty {
|
|
||||||
display: grid;
|
|
||||||
min-height: 100px;
|
|
||||||
place-items: center;
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 13px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-workspace {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
background: var(--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-workspace-toolbar {
|
.workflow-workspace-toolbar {
|
||||||
min-height: 58px;
|
min-width: 0;
|
||||||
padding: 8px 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-identity-fields {
|
.workflow-identity-fields {
|
||||||
@@ -364,17 +201,12 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-palette,
|
|
||||||
.workflow-inspector,
|
.workflow-inspector,
|
||||||
.workflow-inspector-column {
|
.workflow-inspector-column {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: var(--panel-soft);
|
background: var(--panel-soft);
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-palette {
|
|
||||||
border-right: var(--border-line);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-inspector-column {
|
.workflow-inspector-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -388,11 +220,6 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-panel-heading {
|
|
||||||
min-height: 44px;
|
|
||||||
padding: 8px 10px 8px 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-panel-heading > span {
|
.workflow-panel-heading > span {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
@@ -416,132 +243,6 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-palette-items {
|
|
||||||
display: grid;
|
|
||||||
grid-auto-rows: max-content;
|
|
||||||
align-content: start;
|
|
||||||
height: calc(100% - 44px);
|
|
||||||
gap: 4px;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 8px;
|
|
||||||
scrollbar-gutter: stable;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette-group {
|
|
||||||
display: grid;
|
|
||||||
grid-auto-rows: max-content;
|
|
||||||
align-content: start;
|
|
||||||
gap: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette-group + .workflow-palette-group {
|
|
||||||
margin-top: 6px;
|
|
||||||
padding-top: 8px;
|
|
||||||
border-top: var(--border-line);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette-group h3 {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 10px;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0;
|
|
||||||
padding: 3px 8px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette-items button {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 18px minmax(0, 1fr) 14px;
|
|
||||||
align-items: center;
|
|
||||||
gap: 7px;
|
|
||||||
min-height: 38px;
|
|
||||||
border: 0;
|
|
||||||
border-radius: var(--radius-sm);
|
|
||||||
background: transparent;
|
|
||||||
color: var(--text);
|
|
||||||
cursor: grab;
|
|
||||||
font: inherit;
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 7px 8px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette-items button:hover:not(:disabled),
|
|
||||||
.workflow-palette-items button:focus-visible:not(:disabled) {
|
|
||||||
background: var(--primary-soft);
|
|
||||||
color: var(--text-strong);
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette-items button:disabled {
|
|
||||||
cursor: default;
|
|
||||||
opacity: .42;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette-add {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-editor-surface {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
background: var(--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-canvas {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-canvas .react-flow {
|
|
||||||
background: var(--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-canvas .react-flow__background {
|
|
||||||
color: var(--line-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-canvas .react-flow__controls,
|
|
||||||
.workflow-canvas .react-flow__minimap {
|
|
||||||
overflow: hidden;
|
|
||||||
border: var(--border-line);
|
|
||||||
border-radius: var(--radius-sm);
|
|
||||||
background: var(--panel);
|
|
||||||
box-shadow: var(--shadow-xs);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-canvas .react-flow__controls-button {
|
|
||||||
border-bottom: var(--border-line);
|
|
||||||
background: var(--panel);
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-canvas .react-flow__minimap-mask {
|
|
||||||
fill: color-mix(in srgb, var(--bg) 76%, transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-canvas .react-flow__edge-path {
|
|
||||||
stroke: var(--line-dark);
|
|
||||||
stroke-width: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-canvas .react-flow__edge.selected .react-flow__edge-path,
|
|
||||||
.workflow-canvas .react-flow__edge:hover .react-flow__edge-path {
|
|
||||||
stroke: var(--accent);
|
|
||||||
stroke-width: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-canvas-empty {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
display: grid;
|
|
||||||
place-items: center;
|
|
||||||
color: var(--muted);
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-node {
|
.workflow-node {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -671,17 +372,6 @@
|
|||||||
border-color: var(--danger-text);
|
border-color: var(--danger-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-node-icon {
|
|
||||||
display: grid;
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
flex: 0 0 28px;
|
|
||||||
place-items: center;
|
|
||||||
border-radius: 5px;
|
|
||||||
background: var(--panel-soft);
|
|
||||||
color: var(--text-strong);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-node-copy {
|
.workflow-node-copy {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
@@ -706,21 +396,6 @@
|
|||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-node-handle {
|
|
||||||
width: 13px;
|
|
||||||
height: 13px;
|
|
||||||
border: 3px solid var(--panel);
|
|
||||||
background: var(--line-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-node-handle:hover,
|
|
||||||
.workflow-node-handle.connectingto,
|
|
||||||
.workflow-node-handle.valid {
|
|
||||||
width: 17px;
|
|
||||||
height: 17px;
|
|
||||||
background: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-edge-bpmn-messageFlow .react-flow__edge-path,
|
.workflow-edge-bpmn-messageFlow .react-flow__edge-path,
|
||||||
.workflow-edge-bpmn-association .react-flow__edge-path,
|
.workflow-edge-bpmn-association .react-flow__edge-path,
|
||||||
.workflow-edge-bpmn-conversationLink .react-flow__edge-path {
|
.workflow-edge-bpmn-conversationLink .react-flow__edge-path {
|
||||||
@@ -821,39 +496,6 @@
|
|||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-workspace-empty {
|
|
||||||
display: grid;
|
|
||||||
height: 100%;
|
|
||||||
place-content: center;
|
|
||||||
justify-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
color: var(--muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-workspace-empty strong {
|
|
||||||
color: var(--text-strong);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-workspace-empty .btn {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-working-indicator {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 20;
|
|
||||||
right: 12px;
|
|
||||||
bottom: 10px;
|
|
||||||
border: var(--border-line-dark);
|
|
||||||
border-radius: var(--radius-sm);
|
|
||||||
background: var(--panel);
|
|
||||||
box-shadow: var(--shadow-popover);
|
|
||||||
color: var(--text-strong);
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 7px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-runs-dialog {
|
.workflow-runs-dialog {
|
||||||
width: min(1120px, calc(100vw - 32px));
|
width: min(1120px, calc(100vw - 32px));
|
||||||
height: min(760px, calc(100vh - 32px));
|
height: min(760px, calc(100vh - 32px));
|
||||||
@@ -1041,12 +683,6 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-run-action-form {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-run-action-form textarea {
|
.workflow-run-action-form textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
@@ -1107,10 +743,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1180px) {
|
@media (max-width: 1180px) {
|
||||||
.workflow-shell {
|
|
||||||
grid-template-columns: 240px minmax(0, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-workspace-toolbar {
|
.workflow-workspace-toolbar {
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -1127,10 +759,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 900px) {
|
@media (max-width: 900px) {
|
||||||
.workflow-shell {
|
|
||||||
grid-template-columns: 210px minmax(0, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-editor {
|
.workflow-editor {
|
||||||
grid-template-columns: 140px minmax(0, 1fr);
|
grid-template-columns: 140px minmax(0, 1fr);
|
||||||
grid-template-rows: minmax(0, 1fr) minmax(180px, 34%);
|
grid-template-rows: minmax(0, 1fr) minmax(180px, 34%);
|
||||||
@@ -1149,16 +777,6 @@
|
|||||||
height: calc(100vh - 94px);
|
height: calc(100vh - 94px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-shell {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-rows: minmax(150px, 24%) minmax(0, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-definition-panel {
|
|
||||||
border-right: 0;
|
|
||||||
border-bottom: var(--border-line);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-identity-fields,
|
.workflow-identity-fields,
|
||||||
.workflow-command-bar {
|
.workflow-command-bar {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@@ -1175,33 +793,6 @@
|
|||||||
grid-template-rows: auto minmax(0, 1fr) minmax(180px, 32%);
|
grid-template-rows: auto minmax(0, 1fr) minmax(180px, 32%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-palette {
|
|
||||||
border-right: 0;
|
|
||||||
border-bottom: var(--border-line);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette .workflow-panel-heading {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette-items {
|
|
||||||
display: flex;
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette-group {
|
|
||||||
display: flex;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette-group h3 {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-palette-items button {
|
|
||||||
min-width: 128px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-runs-layout {
|
.workflow-runs-layout {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
grid-template-rows: minmax(120px, 28%) minmax(0, 1fr);
|
grid-template-rows: minmax(120px, 28%) minmax(0, 1fr);
|
||||||
@@ -1212,10 +803,6 @@
|
|||||||
border-bottom: var(--border-line);
|
border-bottom: var(--border-line);
|
||||||
}
|
}
|
||||||
|
|
||||||
.workflow-run-action-form {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workflow-run-history > div > span,
|
.workflow-run-history > div > span,
|
||||||
.workflow-run-events > div > span {
|
.workflow-run-events > div > span {
|
||||||
grid-template-columns: minmax(0, 1fr) auto;
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
|
|||||||
Reference in New Issue
Block a user