diff --git a/openbas-front/src/admin/components/common/injects/Injects.tsx b/openbas-front/src/admin/components/common/injects/Injects.tsx index 111f4a8581..e430a9ffb5 100644 --- a/openbas-front/src/admin/components/common/injects/Injects.tsx +++ b/openbas-front/src/admin/components/common/injects/Injects.tsx @@ -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'; @@ -95,7 +94,6 @@ interface Props { exerciseOrScenarioId: string setViewMode?: (mode: string) => void - onConnectInjects: (connection: Connection) => void availableButtons: string[] @@ -512,6 +510,9 @@ const Injects: FunctionComponent = ({ setSelectedInjectId(inject?.inject_id); } }} + onCreate={onCreate} + onUpdate={onUpdate} + onDelete={onDelete} />
diff --git a/openbas-front/src/admin/components/scenarios/scenario/injects/ScenarioInjects.tsx b/openbas-front/src/admin/components/scenarios/scenario/injects/ScenarioInjects.tsx index 7e26672cd1..9eae25a81d 100644 --- a/openbas-front/src/admin/components/scenarios/scenario/injects/ScenarioInjects.tsx +++ b/openbas-front/src/admin/components/scenarios/scenario/injects/ScenarioInjects.tsx @@ -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'; @@ -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'; @@ -28,7 +26,9 @@ const ScenarioInjects: FunctionComponent = () => { 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), @@ -49,26 +49,13 @@ const ScenarioInjects: FunctionComponent = () => { 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 ( @@ -86,9 +73,8 @@ const ScenarioInjects: FunctionComponent = () => { usersNumber={scenario.scenario_users_number} // @ts-expect-error typing teamsUsers={scenario.scenario_teams_users} - onConnectInjects={handleConnectInjects} setViewMode={handleViewMode} - availableButtons={['chain', 'list']} + availableButtons={availableButtons} /> diff --git a/openbas-front/src/admin/components/simulations/simulation/injects/ExerciseInjects.tsx b/openbas-front/src/admin/components/simulations/simulation/injects/ExerciseInjects.tsx index 9023dbffff..2bb9eba74b 100644 --- a/openbas-front/src/admin/components/simulations/simulation/injects/ExerciseInjects.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/injects/ExerciseInjects.tsx @@ -49,13 +49,13 @@ const ExerciseInjects: FunctionComponent = () => { 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( diff --git a/openbas-front/src/components/ChainedTimeline.tsx b/openbas-front/src/components/ChainedTimeline.tsx index 2b572dd1be..c827f62d44 100644 --- a/openbas-front/src/components/ChainedTimeline.tsx +++ b/openbas-front/src/components/ChainedTimeline.tsx @@ -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'; @@ -64,9 +64,20 @@ interface Props { inject_depends_duration_hours: number }): void, onUpdateInject: (data: Inject[]) => void + onCreate: (result: { result: string, entities: { injects: Record } }) => void, + onUpdate: (result: { result: string, entities: { injects: Record } }) => void, + onDelete: (result: string) => void, } -const ChainedTimelineFlow: FunctionComponent = ({ injects, exerciseOrScenarioId, onSelectedInject, openCreateInjectDrawer, onUpdateInject }) => { +const ChainedTimelineFlow: FunctionComponent = ({ + injects, + exerciseOrScenarioId, + onSelectedInject, + openCreateInjectDrawer, + onUpdateInject, + onCreate, + onUpdate, + onDelete }) => { // Standard hooks const classes = useStyles(); const theme = useTheme(); @@ -209,6 +220,9 @@ const ChainedTimelineFlow: FunctionComponent = ({ 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]), diff --git a/openbas-front/src/components/nodes/NodeInject.tsx b/openbas-front/src/components/nodes/NodeInject.tsx index 80e1aa076c..c043cb40c1 100644 --- a/openbas-front/src/components/nodes/NodeInject.tsx +++ b/openbas-front/src/components/nodes/NodeInject.tsx @@ -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. @@ -90,6 +90,9 @@ export type NodeInject = Node<{ targets: string[], exerciseOrScenarioId: string, onSelectedInject(inject?: InjectOutputType): void, + onCreate: (result: { result: string, entities: { injects: Record } }) => void, + onUpdate: (result: { result: string, entities: { injects: Record } }) => void, + onDelete: (result: string) => void, } >; @@ -146,7 +149,7 @@ const NodeInjectComponent = ({ data }: NodeProps) => { 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; @@ -203,6 +206,9 @@ const NodeInjectComponent = ({ data }: NodeProps) => { canBeTested={data.inject?.inject_testable} isDisabled={isDisabled} exerciseOrScenarioId={data.exerciseOrScenarioId} + onDelete={data.onDelete} + onUpdate={data.onUpdate} + onCreate={data.onCreate} />