Basic flowchart without branching is working.
This commit is contained in:
parent
03a5e5bcea
commit
5fb218908d
@ -34,6 +34,7 @@ $color-mode-type: media-query; // or "class" if you prefer manual control
|
||||
@import "./addTaskButton.scss";
|
||||
@import "./selectableList.scss";
|
||||
@import "./checklist.scss";
|
||||
@import "./visualiser.scss";
|
||||
|
||||
//Changes needed to make MS Edge behave the same as other browsers
|
||||
input::-ms-reveal {
|
||||
|
||||
109
src/Sass/visualiser.scss
Normal file
109
src/Sass/visualiser.scss
Normal file
@ -0,0 +1,109 @@
|
||||
.visualiser-root {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: $spacePadding;
|
||||
}
|
||||
|
||||
.visualiser-flow {
|
||||
width: 320px;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba($blue, 0.12),
|
||||
rgba($mode--light-bg, 0.9)
|
||||
);
|
||||
border: 1px solid rgba($blue, 0.25);
|
||||
border-radius: 16px;
|
||||
padding: 20px 16px;
|
||||
box-shadow: 0 10px 24px rgba($leftMenu-background, 0.15);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.visualiser-node {
|
||||
width: 220px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
lighten($mode--light-bg, 2%),
|
||||
lighten($blue, 38%)
|
||||
);
|
||||
border: 1px solid rgba($blue, 0.28);
|
||||
color: $leftMenu-background;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
letter-spacing: 0.2px;
|
||||
box-shadow: 0 6px 14px rgba($blue, 0.2);
|
||||
}
|
||||
|
||||
.visualiser-node-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.visualiser-connector {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.visualiser-connector-line {
|
||||
width: 2px;
|
||||
height: 18px;
|
||||
background: linear-gradient(180deg, rgba($blue, 0.6), rgba($blue, 0.2));
|
||||
}
|
||||
|
||||
.visualiser-connector-arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 8px solid rgba($blue, 0.6);
|
||||
}
|
||||
|
||||
.visualiser-connector-tail {
|
||||
width: 2px;
|
||||
height: 10px;
|
||||
background: rgba($blue, 0.2);
|
||||
}
|
||||
|
||||
@include color-mode(dark) {
|
||||
.visualiser-flow {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba($blue, 0.18),
|
||||
rgba($mode--dark-bg, 0.95)
|
||||
);
|
||||
border: 1px solid rgba($blue, 0.35);
|
||||
box-shadow: 0 12px 28px rgba($leftMenu-background, 0.35);
|
||||
}
|
||||
|
||||
.visualiser-node {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
lighten($mode--dark-bg, 6%),
|
||||
rgba($blue, 0.35)
|
||||
);
|
||||
border: 1px solid rgba($blue, 0.45);
|
||||
color: $leftMenu-color;
|
||||
box-shadow: 0 8px 18px rgba($blue, 0.28);
|
||||
}
|
||||
|
||||
.visualiser-connector-line {
|
||||
background: linear-gradient(180deg, rgba($blue, 0.8), rgba($blue, 0.3));
|
||||
}
|
||||
|
||||
.visualiser-connector-arrow {
|
||||
border-top-color: rgba($blue, 0.8);
|
||||
}
|
||||
|
||||
.visualiser-connector-tail {
|
||||
background: rgba($blue, 0.3);
|
||||
}
|
||||
}
|
||||
@ -194,7 +194,7 @@ const WorkflowTemplateDetails: React.FC<{ editMode: boolean }> = ({
|
||||
</Tab>,
|
||||
|
||||
<Tab key="visualFlow" id="visualFlow" label={t("Visual Flow")}>
|
||||
<VisualiserTab data={data} />
|
||||
<VisualiserTab data={data} taskValidation={taskValidation} />
|
||||
</Tab>,
|
||||
];
|
||||
|
||||
|
||||
@ -1,13 +1,95 @@
|
||||
import React from "react";
|
||||
import { CreateWorkflowTemplateVersion } from "../services/WorkflowTemplateService";
|
||||
import ValidationErrorIcon from "../../../../components/validationErrorIcon";
|
||||
|
||||
interface VisualiserTabProps {
|
||||
data: CreateWorkflowTemplateVersion;
|
||||
taskValidation: Record<string, boolean>;
|
||||
}
|
||||
|
||||
const VisualiserTab: React.FC<VisualiserTabProps> = ({ data }) => {
|
||||
const VisualiserTab: React.FC<VisualiserTabProps> = ({
|
||||
data,
|
||||
taskValidation,
|
||||
}) => {
|
||||
const tasks = data.tasks;
|
||||
const orderedTasks: CreateWorkflowTemplateVersion["tasks"] = [];
|
||||
|
||||
return <div>Visualiser</div>;
|
||||
if (tasks.length > 0) {
|
||||
const byGuid = new Map<string, CreateWorkflowTemplateVersion["tasks"][0]>();
|
||||
tasks.forEach((task) => {
|
||||
byGuid.set(task.config.guid as string, task);
|
||||
});
|
||||
|
||||
const startTask = tasks.find(
|
||||
(task) =>
|
||||
!task.config.predecessors ||
|
||||
(task.config.predecessors as string[]).length === 0,
|
||||
);
|
||||
|
||||
if (startTask) {
|
||||
const visited = new Set<string>();
|
||||
let current: CreateWorkflowTemplateVersion["tasks"][0] | undefined =
|
||||
startTask;
|
||||
|
||||
while (current && !visited.has(current.config.guid as string)) {
|
||||
orderedTasks.push(current);
|
||||
visited.add(current.config.guid as string);
|
||||
|
||||
const currentGuid = current.config.guid as string;
|
||||
const nextTask = tasks.find((task) => {
|
||||
const predecessors = task.config.predecessors as string[] | undefined;
|
||||
return predecessors?.length === 1 && predecessors[0] === currentGuid;
|
||||
});
|
||||
|
||||
current = nextTask;
|
||||
}
|
||||
}
|
||||
|
||||
tasks.forEach((task) => {
|
||||
if (!orderedTasks.includes(task)) {
|
||||
orderedTasks.push(task);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const nodes = [
|
||||
{ key: "start", label: "Start", isTask: false },
|
||||
...orderedTasks.map((task) => ({
|
||||
key: task.config.guid as string,
|
||||
guid: task.config.guid as string,
|
||||
label: (task.config.name as string) || task.type,
|
||||
isTask: true,
|
||||
})),
|
||||
{ key: "end", label: "End", isTask: false },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="visualiser-root">
|
||||
<div className="visualiser-flow">
|
||||
{nodes.map((node, index) => (
|
||||
<React.Fragment key={node.key}>
|
||||
<div className="visualiser-node">
|
||||
<div className="visualiser-node-content">
|
||||
{node.isTask && (
|
||||
<ValidationErrorIcon
|
||||
visible={taskValidation[node.guid as string] === false}
|
||||
/>
|
||||
)}
|
||||
<span>{node.label}</span>
|
||||
</div>
|
||||
</div>
|
||||
{index < nodes.length - 1 && (
|
||||
<div aria-hidden="true" className="visualiser-connector">
|
||||
<div className="visualiser-connector-line" />
|
||||
<div className="visualiser-connector-arrow" />
|
||||
<div className="visualiser-connector-tail" />
|
||||
</div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default VisualiserTab;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user