Skip to content

Commit fd6aee1

Browse files
committed
feat: add starting and stopping states to ActivityDesignerCard
1 parent bfafb44 commit fd6aee1

File tree

3 files changed

+82
-73
lines changed

3 files changed

+82
-73
lines changed

src/components/designer/custom/NodeInner.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import React from 'react';
22
import styled from '@emotion/styled';
33
import { INodeInnerDefaultProps, ISize } from '@mrblenny/react-flow-chart';
44
import { useTheme } from 'hooks/useTheme';
5+
import { useStoreState } from 'store';
56
import { ThemeColors } from 'theme/colors';
67
import { LOADING_NODE_ID } from 'utils/constants';
78
import { Loader, StatusBadge } from 'components/common';
89
import NodeContextMenu from '../NodeContextMenu';
9-
import { useStoreState } from 'store';
1010

1111
const Styled = {
1212
Node: styled.div<{ size?: ISize; colors: ThemeColors['node']; isSelected: boolean }>`

src/components/designer/default/cards/ActivityDesignerCard.tsx

Lines changed: 78 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React, { useState } from 'react';
2+
import { useAsyncCallback } from 'react-async-hook';
23
import {
34
ArrowDownOutlined,
45
ArrowRightOutlined,
@@ -11,7 +12,6 @@ import { Alert, Button, Tooltip } from 'antd';
1112
import { usePrefixedTranslation } from 'hooks';
1213
import { useTheme } from 'hooks/useTheme';
1314
import { Status } from 'shared/types';
14-
import { getDocker } from 'lib/docker/dockerService';
1515
import { useStoreActions } from 'store';
1616
import { ThemeColors } from 'theme/colors';
1717
import { ActivityInfo, Network, SimulationActivity } from 'types';
@@ -152,7 +152,7 @@ const defaultActivityInfo: ActivityInfo = {
152152
};
153153

154154
const ActivityDesignerCard: React.FC<Props> = ({ visible, network }) => {
155-
const [isSimulationActive, setIsStartSimulationActive] = React.useState(false);
155+
const [isSimulationActive, setIsSimulationActive] = React.useState(false);
156156
const [isAddActivityActive, setIsAddActivityActive] = React.useState(false);
157157
const [addActivityInvalidState, setAddActivityInvalidState] =
158158
useState<AddActivityInvalidState | null>(null);
@@ -168,81 +168,72 @@ const ActivityDesignerCard: React.FC<Props> = ({ visible, network }) => {
168168
startSimulation,
169169
stopSimulation,
170170
} = useStoreActions(s => s.network);
171+
const { notify } = useStoreActions(s => s.app);
171172
const { lightning } = network.nodes;
172173

173174
const activities = network.simulationActivities ?? [];
174175
const numberOfActivities = activities.length;
175176

176-
const isSimulationContainerRunning = async () => {
177-
const docker = await getDocker();
178-
const containers = await docker.listContainers();
179-
const simContainer = containers.find(c => {
180-
// remove the leading '/' from the container name
181-
const name = c.Names[0].substring(1);
182-
return name === `polar-n${network.id}-simln`;
183-
});
184-
return simContainer?.State === 'restarting' || simContainer?.State === 'running';
185-
};
186-
187-
useEffect(() => {
188-
isSimulationContainerRunning().then(isRunning => {
189-
console.log('isRunning', isRunning);
190-
setIsStartSimulationActive(isRunning);
191-
});
192-
}, [isSimulationContainerRunning]);
193-
194-
const startSimulationActivity = () => {
195-
if (network.status !== Status.Started) {
196-
setAddActivityInvalidState({
197-
state: 'warning',
198-
message: l('startWarning'),
199-
action: 'start',
200-
});
201-
setIsStartSimulationActive(false);
202-
return;
203-
}
204-
if (numberOfActivities === 0) {
205-
setIsAddActivityActive(true);
206-
setAddActivityInvalidState({
207-
state: 'warning',
208-
message: l('NoActivityAddedWarning'),
209-
action: 'start',
210-
});
211-
setIsStartSimulationActive(false);
212-
return;
213-
}
214-
const allNotStartedNodesSet = new Set();
215-
const nodes = network.simulationActivities.flatMap(activity => {
216-
const activityNodes = new Set([activity.source.label, activity.destination.label]);
217-
return lightning
218-
.filter(node => node.status !== Status.Started && activityNodes.has(node.name))
219-
.filter(node => {
220-
const notStarted = !allNotStartedNodesSet.has(node.name);
221-
if (notStarted) {
222-
allNotStartedNodesSet.add(node.name);
223-
}
224-
return notStarted;
177+
const startSimulationActivity = useAsyncCallback(async () => {
178+
try {
179+
if (network.status !== Status.Started) {
180+
setAddActivityInvalidState({
181+
state: 'warning',
182+
message: l('startWarning'),
183+
action: 'start',
225184
});
226-
});
227-
if (nodes.length > 0) {
228-
setIsAddActivityActive(true);
229-
setAddActivityInvalidState({
230-
state: 'warning',
231-
message: l('startWarning'),
232-
action: 'start',
185+
setIsSimulationActive(false);
186+
return;
187+
}
188+
if (numberOfActivities === 0) {
189+
setIsAddActivityActive(true);
190+
setAddActivityInvalidState({
191+
state: 'warning',
192+
message: l('NoActivityAddedWarning'),
193+
action: 'start',
194+
});
195+
setIsSimulationActive(false);
196+
return;
197+
}
198+
const allNotStartedNodesSet = new Set();
199+
const nodes = network.simulationActivities.flatMap(activity => {
200+
const activityNodes = new Set([
201+
activity.source.label,
202+
activity.destination.label,
203+
]);
204+
return lightning
205+
.filter(node => node.status !== Status.Started && activityNodes.has(node.name))
206+
.filter(node => {
207+
const notStarted = !allNotStartedNodesSet.has(node.name);
208+
if (notStarted) {
209+
allNotStartedNodesSet.add(node.name);
210+
}
211+
return notStarted;
212+
});
233213
});
234-
setIsStartSimulationActive(false);
235-
return;
236-
}
237-
setAddActivityInvalidState(null);
238-
if (isSimulationActive) {
239-
setIsStartSimulationActive(false);
240-
stopSimulation({ id: network.id });
241-
return;
214+
if (nodes.length > 0) {
215+
setIsAddActivityActive(true);
216+
setAddActivityInvalidState({
217+
state: 'warning',
218+
message: l('startWarning'),
219+
action: 'start',
220+
});
221+
setIsSimulationActive(false);
222+
return;
223+
}
224+
setAddActivityInvalidState(null);
225+
if (isSimulationActive) {
226+
setIsSimulationActive(false);
227+
await stopSimulation({ id: network.id });
228+
return;
229+
}
230+
setIsSimulationActive(true);
231+
await startSimulation({ id: network.id });
232+
} catch (error: any) {
233+
setIsSimulationActive(false);
234+
notify({ message: l('startError'), error });
242235
}
243-
setIsStartSimulationActive(true);
244-
startSimulation({ id: network.id });
245-
};
236+
});
246237

247238
const toggleAddActivity = () => {
248239
setIsAddActivityActive(prev => !prev);
@@ -295,6 +286,19 @@ const ActivityDesignerCard: React.FC<Props> = ({ visible, network }) => {
295286
setActivityInfo(defaultActivityInfo);
296287
};
297288

289+
const primaryCtaText = () => {
290+
if (!isSimulationActive && startSimulationActivity.loading) {
291+
return l('stopping');
292+
}
293+
if (isSimulationActive && startSimulationActivity.loading) {
294+
return l('starting');
295+
}
296+
if (isSimulationActive && !startSimulationActivity.loading) {
297+
return l('stop');
298+
}
299+
return l('start');
300+
};
301+
298302
if (!visible) return null;
299303
return (
300304
<>
@@ -367,9 +371,11 @@ const ActivityDesignerCard: React.FC<Props> = ({ visible, network }) => {
367371
<Styled.StartStopButton
368372
colors={theme.dragNode}
369373
active={isSimulationActive}
370-
onClick={startSimulationActivity}
374+
onClick={startSimulationActivity.execute}
375+
loading={startSimulationActivity.loading}
376+
disabled={startSimulationActivity.loading}
371377
>
372-
{isSimulationActive ? l('stop') : l('start')}
378+
{primaryCtaText()}
373379
</Styled.StartStopButton>
374380
</>
375381
);

src/i18n/locales/en-US.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,15 @@
9898
"cmps.designer.default.cards.NetworkDesignerCard.addNodesTitle": "Add Nodes",
9999
"cmps.designer.default.cards.NetworkDesignerCard.addNodesDesc": "Drag a node below onto the canvas to add it to the network",
100100
"cmps.designer.default.cards.ActivityDesignerCard.mainDesc": "Click on an element in the designer to see details",
101+
"cmps.designer.default.cards.ActivityDesignerCard.startError": "Unable to start the simulation for the network",
101102
"cmps.designer.default.cards.ActivityDesignerCard.addActivitiesTitle": "Add Activities",
102103
"cmps.designer.default.cards.ActivityDesignerCard.addActivitiesDesc": "Run a simulation between running nodes in the network",
103104
"cmps.designer.default.cards.ActivityDesignerCard.activities": "Activities",
104105
"cmps.designer.default.cards.ActivityDesignerCard.duplicateBtnTip": "Duplicate",
105106
"cmps.designer.default.cards.ActivityDesignerCard.start": "Start",
106107
"cmps.designer.default.cards.ActivityDesignerCard.stop": "Stop",
108+
"cmps.designer.default.cards.ActivityDesignerCard.stopping": "Stopping",
109+
"cmps.designer.default.cards.ActivityDesignerCard.starting": "Starting",
107110
"cmps.designer.default.cards.ActivityDesignerCard.startWarning": "The network and activity nodes must be started to run simulations",
108111
"cmps.designer.default.cards.ActivityDesignerCard.NoActivityAddedWarning": "Please add at least one activity to run simulations",
109112
"cmps.designer.default.cards.NetworkDesignerCard.showVersions": "Show All Versions",

0 commit comments

Comments
 (0)