Skip to content

Commit

Permalink
[frontend/backend] Chaining injects logically
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimfacion committed Sep 12, 2024
1 parent 4ff3eb7 commit b9b5fce
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 30 deletions.
5 changes: 3 additions & 2 deletions openbas-front/src/admin/components/common/injects/Injects.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { CSSProperties, FunctionComponent, useContext, useMemo, useState } from 'react';
import { Checkbox, Chip, List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material';
import { makeStyles } from '@mui/styles';
import { Connection } from '@xyflow/react';
import { Link } from 'react-router-dom';
import * as R from 'ramda';
import { splitDuration } from '../../../../utils/Time';
Expand Down Expand Up @@ -95,7 +94,6 @@ interface Props {
exerciseOrScenarioId: string

setViewMode?: (mode: string) => void
onConnectInjects: (connection: Connection) => void

availableButtons: string[]

Expand Down Expand Up @@ -512,6 +510,9 @@ const Injects: FunctionComponent<Props> = ({
setSelectedInjectId(inject?.inject_id);
}
}}
onCreate={onCreate}
onUpdate={onUpdate}
onDelete={onDelete}
/>
<div className="clearfix" />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { FunctionComponent, useState } from 'react';
import { useParams } from 'react-router-dom';
import * as R from 'ramda';
import { ArticleContext, TeamContext, ViewModeContext } from '../../../common/Context';
import { useAppDispatch } from '../../../../../utils/hooks';
import { useHelper } from '../../../../../store';
Expand All @@ -12,10 +11,9 @@ import type { ScenariosHelper } from '../../../../../actions/scenarios/scenario-
import useDataLoader from '../../../../../utils/hooks/useDataLoader';
import { fetchVariablesForScenario } from '../../../../../actions/variables/variable-actions';
import { fetchScenarioTeams } from '../../../../../actions/scenarios/scenario-actions';
import type { Inject, Scenario } from '../../../../../utils/api-types';
import type { Scenario } from '../../../../../utils/api-types';
import { articleContextForScenario } from '../articles/ScenarioArticles';
import { teamContextForScenario } from '../teams/ScenarioTeams';
import injectContextForScenario from '../ScenarioContext';
import { fetchScenarioInjectsSimple } from '../../../../../actions/injects/inject-action';
import Injects from '../../../common/injects/Injects';

Expand All @@ -28,7 +26,9 @@ const ScenarioInjects: FunctionComponent<Props> = () => {
const dispatch = useAppDispatch();
const { scenarioId } = useParams() as { scenarioId: Scenario['scenario_id'] };

const { injects, scenario, teams, articles, variables } = useHelper(
const availableButtons = ['chain', 'list'];

const { scenario, teams, articles, variables } = useHelper(
(helper: InjectHelper & ScenariosHelper & ArticlesHelper & ChallengeHelper & VariablesHelper) => {
return {
injects: helper.getScenarioInjects(scenarioId),
Expand All @@ -49,26 +49,13 @@ const ScenarioInjects: FunctionComponent<Props> = () => {
const teamContext = teamContextForScenario(scenarioId, []);

const [viewMode, setViewMode] = useState(() => {
const storedValue = localStorage.getItem('scenario_view_mode');
return storedValue === null ? 'list' : storedValue;
const storedValue = localStorage.getItem('scenario_or_exercise_view_mode');
return storedValue === null || !availableButtons.includes(storedValue) ? 'list' : storedValue;
});

const handleViewMode = (mode: string) => {
setViewMode(mode);
localStorage.setItem('scenario_view_mode', mode);
};

const injectContext = injectContextForScenario(scenario);

const handleConnectInjects = async (connection: Connection) => {
const updateFields = [
'inject_title',
'inject_depends_from_another',
'inject_depends_duration',
];
const sourceInject = injects.find((inject: Inject) => inject.inject_id === connection.source);
sourceInject.inject_depends_from_another = connection.target;
await injectContext.onUpdateInject(sourceInject.inject_id, R.pick(updateFields, sourceInject));
localStorage.setItem('scenario_or_exercise_view_mode', mode);
};

return (
Expand All @@ -86,9 +73,8 @@ const ScenarioInjects: FunctionComponent<Props> = () => {
usersNumber={scenario.scenario_users_number}
// @ts-expect-error typing
teamsUsers={scenario.scenario_teams_users}
onConnectInjects={handleConnectInjects}
setViewMode={handleViewMode}
availableButtons={['chain', 'list']}
availableButtons={availableButtons}
/>
</TeamContext.Provider>
</ArticleContext.Provider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ const ExerciseInjects: FunctionComponent<Props> = () => {
const { exerciseId } = useParams() as { exerciseId: Exercise['exercise_id'] };

const [viewMode, setViewMode] = useState(() => {
const storedValue = localStorage.getItem('exercise_view_mode');
const storedValue = localStorage.getItem('scenario_or_exercise_view_mode');
return storedValue === null ? 'list' : storedValue;
});

const handleViewMode = (mode: string) => {
setViewMode(mode);
localStorage.setItem('exercise_view_mode', mode);
localStorage.setItem('scenario_or_exercise_view_mode', mode);
};

const { injects, exercise, teams, articles, variables } = useHelper(
Expand Down
18 changes: 16 additions & 2 deletions openbas-front/src/components/ChainedTimeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
import { Tooltip } from '@mui/material';
import moment from 'moment-timezone';
import { UnfoldLess, UnfoldMore, CropFree } from '@mui/icons-material';
import type { InjectOutputType } from '../actions/injects/Inject';
import type { InjectOutputType, InjectStore } from '../actions/injects/Inject';
import type { Theme } from './Theme';
import nodeTypes from './nodes';
import CustomTimelineBackground from './CustomTimelineBackground';
Expand Down Expand Up @@ -64,9 +64,20 @@ interface Props {
inject_depends_duration_hours: number
}): void,
onUpdateInject: (data: Inject[]) => void
onCreate: (result: { result: string, entities: { injects: Record<string, InjectStore> } }) => void,
onUpdate: (result: { result: string, entities: { injects: Record<string, InjectStore> } }) => void,
onDelete: (result: string) => void,
}

const ChainedTimelineFlow: FunctionComponent<Props> = ({ injects, exerciseOrScenarioId, onSelectedInject, openCreateInjectDrawer, onUpdateInject }) => {
const ChainedTimelineFlow: FunctionComponent<Props> = ({
injects,
exerciseOrScenarioId,
onSelectedInject,
openCreateInjectDrawer,
onUpdateInject,
onCreate,
onUpdate,
onDelete }) => {
// Standard hooks
const classes = useStyles();
const theme = useTheme<Theme>();
Expand Down Expand Up @@ -209,6 +220,9 @@ const ChainedTimelineFlow: FunctionComponent<Props> = ({ injects, exerciseOrScen
.concat(inject.inject_asset_groups!.map((assetGroup) => assetGroups[assetGroup]?.asset_group_name))
.concat(inject.inject_teams!.map((team) => teams[team]?.team_name)),
exerciseOrScenarioId,
onCreate,
onUpdate,
onDelete,
},
position: {
x: (inject.inject_depends_duration / 60) * (gapSize / minutesPerGapAllowed[minutesPerGapIndex]),
Expand Down
10 changes: 8 additions & 2 deletions openbas-front/src/components/nodes/NodeInject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { Theme } from '../Theme';
import { isNotEmptyField } from '../../utils/utils';
import InjectIcon from '../../admin/components/common/injects/InjectIcon';
import InjectPopover from '../../admin/components/common/injects/InjectPopover';
import type { InjectOutputType } from '../../actions/injects/Inject';
import type { InjectOutputType, InjectStore } from '../../actions/injects/Inject';

// Deprecated - https://mui.com/system/styles/basics/
// Do not use it for new code.
Expand Down Expand Up @@ -90,6 +90,9 @@ export type NodeInject = Node<{
targets: string[],
exerciseOrScenarioId: string,
onSelectedInject(inject?: InjectOutputType): void,
onCreate: (result: { result: string, entities: { injects: Record<string, InjectStore> } }) => void,
onUpdate: (result: { result: string, entities: { injects: Record<string, InjectStore> } }) => void,
onDelete: (result: string) => void,
}

>;
Expand Down Expand Up @@ -146,7 +149,7 @@ const NodeInjectComponent = ({ data }: NodeProps<NodeInject>) => {
if (data.inject) data.onSelectedInject(data.inject);
};

const isDisabled = !data.inject?.inject_injector_contract?.injector_contract_content_parsed?.config.expose;
const isDisabled = !data.inject?.inject_injector_contract?.convertedContent?.config.expose;

const dimNode = !data.inject?.inject_enabled || !data.inject?.inject_injector_contract?.convertedContent?.config.expose;

Expand Down Expand Up @@ -203,6 +206,9 @@ const NodeInjectComponent = ({ data }: NodeProps<NodeInject>) => {
canBeTested={data.inject?.inject_testable}
isDisabled={isDisabled}
exerciseOrScenarioId={data.exerciseOrScenarioId}
onDelete={data.onDelete}
onUpdate={data.onUpdate}
onCreate={data.onCreate}
/>
</span>
</div>
Expand Down

0 comments on commit b9b5fce

Please sign in to comment.