Skip to content

Commit

Permalink
feat: add starting and stopping states to ActivityDesignerCard
Browse files Browse the repository at this point in the history
  • Loading branch information
Extheoisah committed Jun 11, 2024
1 parent c9fd338 commit 3296a71
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 72 deletions.
150 changes: 78 additions & 72 deletions src/components/designer/default/cards/ActivityDesignerCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react';
import React, { useState } from 'react';
import { useAsyncCallback } from 'react-async-hook';
import {
ArrowDownOutlined,
ArrowRightOutlined,
Expand All @@ -11,7 +12,6 @@ import { Alert, Button, Tooltip } from 'antd';
import { usePrefixedTranslation } from 'hooks';
import { useTheme } from 'hooks/useTheme';
import { Status } from 'shared/types';
import { getDocker } from 'lib/docker/dockerService';
import { useStoreActions } from 'store';
import { ThemeColors } from 'theme/colors';
import { ActivityInfo, Network, SimulationActivity } from 'types';
Expand Down Expand Up @@ -152,7 +152,7 @@ const defaultActivityInfo: ActivityInfo = {
};

const ActivityDesignerCard: React.FC<Props> = ({ visible, network }) => {
const [isSimulationActive, setIsStartSimulationActive] = React.useState(false);
const [isSimulationActive, setIsSimulationActive] = React.useState(false);
const [isAddActivityActive, setIsAddActivityActive] = React.useState(false);
const [addActivityInvalidState, setAddActivityInvalidState] =
useState<AddActivityInvalidState | null>(null);
Expand All @@ -168,81 +168,72 @@ const ActivityDesignerCard: React.FC<Props> = ({ visible, network }) => {
startSimulation,
stopSimulation,
} = useStoreActions(s => s.network);
const { notify } = useStoreActions(s => s.app);
const { lightning } = network.nodes;

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

const isSimulationContainerRunning = async () => {
const docker = await getDocker();
const containers = await docker.listContainers();
const simContainer = containers.find(c => {
// remove the leading '/' from the container name
const name = c.Names[0].substring(1);
return name === `polar-n${network.id}-simln`;
});
return simContainer?.State === 'restarting' || simContainer?.State === 'running';
};

useEffect(() => {
isSimulationContainerRunning().then(isRunning => {
console.log('isRunning', isRunning);
setIsStartSimulationActive(isRunning);
});
}, [isSimulationContainerRunning]);

const startSimulationActivity = () => {
if (network.status !== Status.Started) {
setAddActivityInvalidState({
state: 'warning',
message: l('startWarning'),
action: 'start',
});
setIsStartSimulationActive(false);
return;
}
if (numberOfActivities === 0) {
setIsAddActivityActive(true);
setAddActivityInvalidState({
state: 'warning',
message: l('NoActivityAddedWarning'),
action: 'start',
});
setIsStartSimulationActive(false);
return;
}
const allNotStartedNodesSet = new Set();
const nodes = network.simulationActivities.flatMap(activity => {
const activityNodes = new Set([activity.source.label, activity.destination.label]);
return lightning
.filter(node => node.status !== Status.Started && activityNodes.has(node.name))
.filter(node => {
const notStarted = !allNotStartedNodesSet.has(node.name);
if (notStarted) {
allNotStartedNodesSet.add(node.name);
}
return notStarted;
const startSimulationActivity = useAsyncCallback(async () => {
try {
if (network.status !== Status.Started) {
setAddActivityInvalidState({
state: 'warning',
message: l('startWarning'),
action: 'start',
});
});
if (nodes.length > 0) {
setIsAddActivityActive(true);
setAddActivityInvalidState({
state: 'warning',
message: l('startWarning'),
action: 'start',
setIsSimulationActive(false);
return;
}
if (numberOfActivities === 0) {
setIsAddActivityActive(true);
setAddActivityInvalidState({
state: 'warning',
message: l('NoActivityAddedWarning'),
action: 'start',
});
setIsSimulationActive(false);
return;
}
const allNotStartedNodesSet = new Set();
const nodes = network.simulationActivities.flatMap(activity => {
const activityNodes = new Set([
activity.source.label,
activity.destination.label,
]);
return lightning
.filter(node => node.status !== Status.Started && activityNodes.has(node.name))
.filter(node => {
const notStarted = !allNotStartedNodesSet.has(node.name);
if (notStarted) {
allNotStartedNodesSet.add(node.name);
}
return notStarted;
});
});
setIsStartSimulationActive(false);
return;
}
setAddActivityInvalidState(null);
if (isSimulationActive) {
setIsStartSimulationActive(false);
stopSimulation({ id: network.id });
return;
if (nodes.length > 0) {
setIsAddActivityActive(true);
setAddActivityInvalidState({
state: 'warning',
message: l('startWarning'),
action: 'start',
});
setIsSimulationActive(false);
return;
}
setAddActivityInvalidState(null);
if (isSimulationActive) {
setIsSimulationActive(false);
await stopSimulation({ id: network.id });
return;
}
setIsSimulationActive(true);
await startSimulation({ id: network.id });
} catch (error: any) {
setIsSimulationActive(false);
notify({ message: l('startError'), error });
}
setIsStartSimulationActive(true);
startSimulation({ id: network.id });
};
});

const toggleAddActivity = () => {
setIsAddActivityActive(prev => !prev);
Expand Down Expand Up @@ -295,6 +286,19 @@ const ActivityDesignerCard: React.FC<Props> = ({ visible, network }) => {
setActivityInfo(defaultActivityInfo);
};

const primaryCtaText = () => {
if (!isSimulationActive && startSimulationActivity.loading) {
return l('stopping');
}
if (isSimulationActive && startSimulationActivity.loading) {
return l('starting');
}
if (isSimulationActive && !startSimulationActivity.loading) {
return l('stop');
}
return l('start');
};

if (!visible) return null;
return (
<>
Expand Down Expand Up @@ -367,9 +371,11 @@ const ActivityDesignerCard: React.FC<Props> = ({ visible, network }) => {
<Styled.StartStopButton
colors={theme.dragNode}
active={isSimulationActive}
onClick={startSimulationActivity}
onClick={startSimulationActivity.execute}
loading={startSimulationActivity.loading}
disabled={startSimulationActivity.loading}
>
{isSimulationActive ? l('stop') : l('start')}
{primaryCtaText()}
</Styled.StartStopButton>
</>
);
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,15 @@
"cmps.designer.default.cards.NetworkDesignerCard.addNodesTitle": "Add Nodes",
"cmps.designer.default.cards.NetworkDesignerCard.addNodesDesc": "Drag a node below onto the canvas to add it to the network",
"cmps.designer.default.cards.ActivityDesignerCard.mainDesc": "Click on an element in the designer to see details",
"cmps.designer.default.cards.ActivityDesignerCard.startError": "Unable to start the simulation for the network",
"cmps.designer.default.cards.ActivityDesignerCard.addActivitiesTitle": "Add Activities",
"cmps.designer.default.cards.ActivityDesignerCard.addActivitiesDesc": "Run a simulation between running nodes in the network",
"cmps.designer.default.cards.ActivityDesignerCard.activities": "Activities",
"cmps.designer.default.cards.ActivityDesignerCard.duplicateBtnTip": "Duplicate",
"cmps.designer.default.cards.ActivityDesignerCard.start": "Start",
"cmps.designer.default.cards.ActivityDesignerCard.stop": "Stop",
"cmps.designer.default.cards.ActivityDesignerCard.stopping": "Stopping",
"cmps.designer.default.cards.ActivityDesignerCard.starting": "Starting",
"cmps.designer.default.cards.ActivityDesignerCard.startWarning": "The network and activity nodes must be started to run simulations",
"cmps.designer.default.cards.ActivityDesignerCard.NoActivityAddedWarning": "Please add at least one activity to run simulations",
"cmps.designer.default.cards.NetworkDesignerCard.showVersions": "Show All Versions",
Expand Down

0 comments on commit 3296a71

Please sign in to comment.