Skip to content

Commit

Permalink
[frontend] Fix security platform not filled after full reload when up…
Browse files Browse the repository at this point in the history
…dating manual expectation (#1181)
  • Loading branch information
RomuDeuxfois authored Aug 2, 2024
1 parent 56f145f commit 82285a5
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
const theme = useTheme<Theme>();
const { nsdt, t } = useFormatter();
const [anchorEls, setAnchorEls] = useState<Record<string, Element | null>>({});
const [selectedExpectationForCreation, setSelectedExpectationForCreation] = useState<InjectExpectationsStore | null>(null);
const [selectedExpectationForCreation, setSelectedExpectationForCreation] = useState<{ injectExpectation: InjectExpectationsStore, sourceIds: string[] } | null>(null);
const [selectedResultEdition, setSelectedResultEdition] = useState<{ injectExpectation: InjectExpectationsStore, expectationResult: InjectExpectationResult } | null>(null);
const [selectedResultDeletion, setSelectedResultDeletion] = useState<{ injectExpectation: InjectExpectationsStore, expectationResult: InjectExpectationResult } | null>(null);
const [initialized, setInitialized] = useState(false);
Expand Down Expand Up @@ -174,6 +174,17 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
return { ...step, status: lastExecutionEndDate ? 'SUCCESS' : 'PENDING' };
});
};

const computeExistingSourceIds = (results: InjectExpectationResult[]) => {
const sourceIds: string[] = [];
results.forEach((result) => {
if (result.sourceId) {
sourceIds.push(result.sourceId);
}
});
return sourceIds;
};

// Fetching data
const { injectResultDto, updateInjectResultDto } = useContext<InjectResultDtoContextType>(InjectResultDtoContext);
useEffect(() => {
Expand Down Expand Up @@ -461,7 +472,7 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
</Typography>
<Grid container={true} spacing={2}>
{injectExpectation.inject_expectation_results && injectExpectation.inject_expectation_results.map((expectationResult, index) => (
<Grid key={index} item={true} xs={4}>
<Grid key={index} item xs={4}>
<Card key={injectExpectation.inject_expectation_id} classes={{ root: classes.resultCard }}>
<CardHeader
avatar={getAvatar(injectExpectation, expectationResult)}
Expand Down Expand Up @@ -502,15 +513,22 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
</Card>
</Grid>
))}
{(['DETECTION', 'PREVENTION'].includes(injectExpectation.inject_expectation_type) || (injectExpectation.inject_expectation_type === 'MANUAL' && injectExpectation.inject_expectation_results && injectExpectation.inject_expectation_results.length === 0)) && (
<Grid item={true} xs={4}>
<Card classes={{ root: classes.resultCardDummy }}>
<CardActionArea classes={{ root: classes.area }} onClick={() => setSelectedExpectationForCreation(injectExpectation)}>
<AddBoxOutlined />
</CardActionArea>
</Card>
</Grid>
)}
{(['DETECTION', 'PREVENTION'].includes(injectExpectation.inject_expectation_type)
|| (injectExpectation.inject_expectation_type === 'MANUAL' && injectExpectation.inject_expectation_results && injectExpectation.inject_expectation_results.length === 0))
&& (
<Grid item xs={4}>
<Card classes={{ root: classes.resultCardDummy }}>
<CardActionArea
classes={{ root: classes.area }}
onClick={() => setSelectedExpectationForCreation(
{ injectExpectation, sourceIds: computeExistingSourceIds(injectExpectation.inject_expectation_results ?? []) },
)}
>
<AddBoxOutlined />
</CardActionArea>
</Card>
</Grid>
)}
</Grid>
<Divider style={{ marginTop: 20 }} />
</div>
Expand All @@ -526,8 +544,14 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
<DialogContent>
{selectedExpectationForCreation && (
<>
{selectedExpectationForCreation.inject_expectation_type === 'MANUAL' && <ManualExpectationsValidationForm expectation={selectedExpectationForCreation as InjectExpectationsStore} onUpdate={onUpdateValidation} />}
{['DETECTION', 'PREVENTION'].includes(selectedExpectationForCreation.inject_expectation_type) && <DetectionPreventionExpectationsValidationForm expectation={selectedExpectationForCreation as InjectExpectationsStore} onUpdate={onUpdateValidation} />}
{selectedExpectationForCreation.injectExpectation.inject_expectation_type === 'MANUAL'
&& <ManualExpectationsValidationForm expectation={selectedExpectationForCreation.injectExpectation} onUpdate={onUpdateValidation} />}
{['DETECTION', 'PREVENTION'].includes(selectedExpectationForCreation.injectExpectation.inject_expectation_type)
&& <DetectionPreventionExpectationsValidationForm
expectation={selectedExpectationForCreation.injectExpectation}
sourceIds={selectedExpectationForCreation.sourceIds}
onUpdate={onUpdateValidation}
/>}
</>
)}
</DialogContent>
Expand All @@ -543,8 +567,19 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
<DialogContent>
{selectedResultEdition && selectedResultEdition.injectExpectation && (
<>
{selectedResultEdition.injectExpectation.inject_expectation_type === 'MANUAL' && <ManualExpectationsValidationForm expectation={selectedResultEdition.injectExpectation as InjectExpectationsStore} onUpdate={onUpdateValidation} />}
{['DETECTION', 'PREVENTION'].includes(selectedResultEdition.injectExpectation.inject_expectation_type) && <DetectionPreventionExpectationsValidationForm expectation={selectedResultEdition.injectExpectation as InjectExpectationsStore} result={selectedResultEdition.expectationResult as InjectExpectationResult} onUpdate={onUpdateValidation} />}
{selectedResultEdition.injectExpectation.inject_expectation_type === 'MANUAL'
&& <ManualExpectationsValidationForm
expectation={selectedResultEdition.injectExpectation}
onUpdate={onUpdateValidation}
/>
}
{['DETECTION', 'PREVENTION'].includes(selectedResultEdition.injectExpectation.inject_expectation_type)
&& <DetectionPreventionExpectationsValidationForm
expectation={selectedResultEdition.injectExpectation}
result={selectedResultEdition.expectationResult}
onUpdate={onUpdateValidation}
/>
}
</>
)}
</DialogContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ const useStyles = makeStyles((theme: Theme) => ({
interface FormProps {
expectation: InjectExpectationsStore;
result?: InjectExpectationResult;
sourceIds?: string[];
onUpdate?: () => void;
}

const DetectionPreventionExpectationsValidationForm: FunctionComponent<FormProps> = ({ expectation, result, onUpdate }) => {
const DetectionPreventionExpectationsValidationForm: FunctionComponent<FormProps> = ({ expectation, result, sourceIds = [], onUpdate }) => {
const classes = useStyles();
const { t } = useFormatter();
const dispatch = useAppDispatch();
Expand Down Expand Up @@ -69,10 +70,14 @@ const DetectionPreventionExpectationsValidationForm: FunctionComponent<FormProps
security_platform: z.string().min(1, { message: t('Should not be empty') }),
})),
defaultValues: {
expectation_score: result?.score ?? expectation.inject_expectation_score ?? expectation.inject_expectation_expected_score ?? 0,
expectation_score: result?.score ?? expectation.inject_expectation_expected_score ?? 0,
security_platform: result?.sourceId ?? '',
},
});

// Security Platform Options
const filterOptions = (n: SecurityPlatform) => (n.asset_external_reference === null && !sourceIds.includes(n.asset_id));

return (
<form id="expectationForm" onSubmit={handleSubmit(onSubmit)}>
{result && (
Expand All @@ -96,8 +101,9 @@ const DetectionPreventionExpectationsValidationForm: FunctionComponent<FormProps
fieldValue={value ?? ''}
fieldOnChange={onChange}
errors={errors}
filterOptions={filterOptions}
style={{ marginTop: 20 }}
onlyManual={true}
editing={!!result}
/>
)}
/>
Expand Down
40 changes: 22 additions & 18 deletions openbas-front/src/components/fields/SecurityPlatformField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,58 +31,62 @@ interface Props {
fieldValue: string;
fieldOnChange: (value: string) => void;
errors: FieldErrors;
filterOptions: (securityPlatform: SecurityPlatform) => boolean;
style: CSSProperties;
onlyManual?: boolean;
editing: boolean;
}

const securityPlatformsToOptions = (securityPlatforms: SecurityPlatform[], filterOptions: (securityPlatform: SecurityPlatform) => boolean) => {
return securityPlatforms
.filter(filterOptions)
.map((n) => ({
id: n.asset_id,
label: n.asset_name,
logo_dark: n.security_platform_logo_dark,
logo_light: n.security_platform_logo_light,
}));
};

const SecurityPlatformField: FunctionComponent<Props> = ({
name,
label,
fieldValue,
fieldOnChange,
errors,
filterOptions,
style,
onlyManual,
editing,
}) => {
// Standard hooks
const theme = useTheme<Theme>();
const classes = useStyles();
const dispatch = useAppDispatch();

// Fetching data
const { securityPlatforms }: { securityPlatforms: [SecurityPlatform]; } = useHelper((helper: SecurityPlatformHelper) => ({
const { securityPlatforms }: { securityPlatforms: SecurityPlatform[]; } = useHelper((helper: SecurityPlatformHelper) => ({
securityPlatforms: helper.getSecurityPlatforms(),
}));
const dispatch = useAppDispatch();
useDataLoader(() => {
dispatch(fetchSecurityPlatforms());
});

// Form
const securityPlatformsOptions = securityPlatforms
.filter((n) => (onlyManual ? n.asset_external_reference === null : true))
.map(
(n) => ({
id: n.asset_id,
label: n.asset_name,
logo_dark: n.security_platform_logo_dark,
logo_light: n.security_platform_logo_light,
}),
);
const valueResolver = () => {
return securityPlatformsOptions.filter((securityPlatform) => fieldValue === securityPlatform.id).at(0);
};
const securityPlatformsOptions = securityPlatformsToOptions(securityPlatforms, filterOptions);

const selectedValue = securityPlatformsOptions.find((option) => option.id === fieldValue) || null;

return (
<div style={{ position: 'relative' }}>
<MuiAutocomplete
value={valueResolver()}
value={selectedValue}
size="small"
multiple={false}
selectOnFocus
autoHighlight
clearOnBlur={false}
clearOnEscape={false}
options={securityPlatformsOptions}
disabled={editing}
onChange={(_, value) => {
fieldOnChange(value?.id ?? '');
}}
Expand Down

0 comments on commit 82285a5

Please sign in to comment.