Skip to content

Commit

Permalink
[frontend] fix: bulk delete and update now ignores store
Browse files Browse the repository at this point in the history
[frontend] fix: bulk update now correctly refreshes the data table
[frontend] feat: bulk test and delete now display a loading animation
  • Loading branch information
impolitepanda committed Jan 15, 2025
1 parent d5401bf commit 9bfca3a
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 35 deletions.
20 changes: 19 additions & 1 deletion openbas-front/src/actions/Inject.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { bulkDeleteReferential, delReferential, getReferential, postReferential, putReferential } from '../utils/Action';
import {
bulkDeleteReferential,
delReferential,
getReferential,
postReferential,
putReferential,
simpleDelCall,
simplePutCall,
} from '../utils/Action';
import * as schema from './Schema';

// -- INJECTS --
Expand All @@ -13,11 +21,21 @@ export const bulkDeleteInjects = data => (dispatch) => {
return bulkDeleteReferential(uri, 'injects', data)(dispatch);
};

export const bulkDeleteInjectsSimple = (data) => {
const uri = `/api/injects`;
return simpleDelCall(uri, data);
};

export const bulkUpdateInject = data => (dispatch) => {
const uri = `/api/injects`;
return putReferential(schema.inject, uri, data)(dispatch);
};

export const bulkUpdateInjectSimple = (data) => {
const uri = `/api/injects`;
return simplePutCall(uri, data);
};

// -- EXERCISES --

export const fetchExerciseInjects = exerciseId => (dispatch) => {
Expand Down
12 changes: 3 additions & 9 deletions openbas-front/src/admin/components/common/Context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,7 @@ export type TeamContextType = {
export type InjectContextType = {
searchInjects: (input: SearchPaginationInput) => Promise<{ data: Page<InjectOutputType> }>;
onAddInject: (inject: Inject) => Promise<{ result: string; entities: { injects: Record<string, InjectStore> } }>;
onBulkUpdateInject: (param: InjectBulkUpdateInputs) => Promise<{
result: string;
entities: { injects: Record<string, InjectStore> };
}>;
onBulkUpdateInject: (param: InjectBulkUpdateInputs) => Promise<Inject[]>;
onUpdateInject: (injectId: Inject['inject_id'], inject: Inject) => Promise<{ result: string; entities: { injects: Record<string, InjectStore> } }>;
onUpdateInjectTrigger?: (injectId: Inject['inject_id']) => Promise<{ result: string; entities: { injects: Record<string, InjectStore> } }>;
onUpdateInjectActivation: (injectId: Inject['inject_id'], injectEnabled: { inject_enabled: boolean }) => Promise<{
Expand Down Expand Up @@ -203,11 +200,8 @@ export const InjectContext = createContext<InjectContextType>({
onAddInject(_inject: Inject): Promise<{ result: string; entities: { injects: Record<string, InjectStore> } }> {
return Promise.resolve({ result: '', entities: { injects: {} } });
},
onBulkUpdateInject(_param: InjectBulkUpdateInputs): Promise<{
result: string;
entities: { injects: Record<string, InjectStore> };
}> {
return Promise.resolve({ result: '', entities: { injects: {} } });
onBulkUpdateInject(_param: InjectBulkUpdateInputs): Promise<Inject[]> {
return Promise.resolve([]);
},
onUpdateInject(_injectId: Inject['inject_id'], _inject: Inject): Promise<{ result: string; entities: { injects: Record<string, InjectStore> } }> {
return Promise.resolve({ result: '', entities: { injects: {} } });
Expand Down
35 changes: 29 additions & 6 deletions openbas-front/src/admin/components/common/injects/Injects.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useQueryableWithLocalStorage } from '../../../../components/common/quer
import { useFormatter } from '../../../../components/i18n';
import ItemBoolean from '../../../../components/ItemBoolean';
import ItemTags from '../../../../components/ItemTags';
import Loader from '../../../../components/Loader';
import PlatformIcon from '../../../../components/PlatformIcon';
import type {
Article,
Expand Down Expand Up @@ -250,6 +251,8 @@ const Injects: FunctionComponent<Props> = ({

// Injects
const [injects, setInjects] = useState<InjectOutputType[]>([]);
// Bulk loading indcator for tests and delete
const [isBulkLoading, setIsBulkLoading] = useState<boolean>(false);
const [selectedInjectId, setSelectedInjectId] = useState<string | null>(null);
const [reloadInjectCount, setReloadInjectCount] = useState(0);

Expand All @@ -264,13 +267,24 @@ const Injects: FunctionComponent<Props> = ({

const onUpdate = (result: { result: string; entities: { injects: Record<string, InjectStore> } }) => {
if (result.entities) {
const updated = result.entities.injects[result.result];
setInjects(injects.map((i) => {
return (i.inject_id !== updated.inject_id ? i as InjectOutputType : (updated as InjectOutputType));
}));
const updatedResults = result.entities.injects[result.result];
if (Array.isArray(updatedResults)) {
// Case of bulk update
injects.map(originalInject => updatedResults.find(updatedInject => updatedInject.inject_id === originalInject.inject_id) || originalInject);
} else {
// Case of single update
injects.map(i => i.inject_id !== updatedResults.inject_id ? i : updatedResults as InjectOutputType);
}
setInjects(injects);
}
};

const onBulkUpdate = (updatedResults: Inject[]) => {
setInjects(injects.map((originalInject) => {
return updatedResults.find(updatedInject => updatedInject.inject_id === originalInject.inject_id) as unknown as InjectOutputType || originalInject;
}));
};

const onDelete = (result: string) => {
if (result) {
setInjects(injects.filter(i => (i.inject_id !== result)));
Expand Down Expand Up @@ -420,12 +434,13 @@ const Injects: FunctionComponent<Props> = ({
simulation_or_scenario_id: exerciseOrScenarioId,
update_operations: operationsToPerform,
})
.then((result: { result: string; entities: { injects: Record<string, InjectStore> } }) => {
onUpdate(result);
.then((result) => {
onBulkUpdate(result);
});
};

const bulkDeleteInjects = () => {
setIsBulkLoading(true);
const deleteIds = injectsToProcess.map((inject: InjectOutputType) => inject.inject_id);
const ignoreIds = injectsToIgnore.map((inject: InjectOutputType) => inject.inject_id);
injectContext.onBulkDeleteInjects({
Expand All @@ -440,10 +455,13 @@ const Injects: FunctionComponent<Props> = ({
const deletedIds = result.map(inject => inject.inject_id);
setInjects(newNumbers !== 0 ? injects.filter(inject => !deletedIds.includes(inject.inject_id)) : []);
queryableHelpers.paginationHelpers.handleChangeTotalElements(newNumbers);
}).finally(() => {
setIsBulkLoading(false);
});
};

const massTestInjects = () => {
setIsBulkLoading(true);
const testIds = injectsToProcess.map((inject: InjectOutputType) => inject.inject_id);
const ignoreIds = injectsToIgnore.map((inject: InjectOutputType) => inject.inject_id);
injectContext.bulkTestInjects({
Expand All @@ -461,6 +479,8 @@ const Injects: FunctionComponent<Props> = ({
itsDedicatedPage: <Link to={`${result.uri}`}>{t('its dedicated page')}</Link>,
}));
}
}).finally(() => {
setIsBulkLoading(false);
});
};

Expand All @@ -471,6 +491,9 @@ const Injects: FunctionComponent<Props> = ({

const atLeastOneValidInject = injects.some(inject => !inject.inject_injector_contract?.injector_contract_content_parsed);

if (isBulkLoading) {
return <Loader />;
}
return (
<>
<PaginationComponentV2
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
addInjectForScenario,
bulkDeleteInjects,
bulkUpdateInject,
bulkDeleteInjectsSimple,
bulkUpdateInjectSimple,
deleteInjectScenario,
fetchScenarioInjects,
updateInjectActivationForScenario,
Expand Down Expand Up @@ -38,11 +38,8 @@ const injectContextForScenario = (scenario: Scenario) => {
onAddInject(inject: Inject): Promise<{ result: string; entities: { injects: Record<string, InjectStore> } }> {
return dispatch(addInjectForScenario(scenario.scenario_id, inject));
},
onBulkUpdateInject(param: InjectBulkUpdateInputs): Promise<{
result: string;
entities: { injects: Record<string, InjectStore> };
}> {
return dispatch(bulkUpdateInject(param));
onBulkUpdateInject(param: InjectBulkUpdateInputs): Promise<Inject[] | void> {
return bulkUpdateInjectSimple(param).then((result: { data: Inject[] }) => result?.data);
},
onUpdateInject(injectId: Inject['inject_id'], inject: Inject): Promise<{ result: string; entities: { injects: Record<string, InjectStore> } }> {
return dispatch(updateInjectForScenario(scenario.scenario_id, injectId, inject));
Expand All @@ -68,7 +65,7 @@ const injectContextForScenario = (scenario: Scenario) => {
return dryImportXlsForScenario(scenario.scenario_id, importId, input).then(result => result.data);
},
onBulkDeleteInjects(param: InjectBulkProcessingInput): Promise<Inject[]> {
return dispatch(bulkDeleteInjects(param));
return bulkDeleteInjectsSimple(param).then((result: { data: Inject[] }) => result?.data);
},
bulkTestInjects(param: InjectBulkProcessingInput): Promise<{ uri: string; data: InjectTestStatus[] }> {
return bulkTestInjects(param).then(result => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { fetchExercise, fetchExerciseTeams } from '../../../../actions/Exercise'
import { dryImportXlsForExercise, importXlsForExercise } from '../../../../actions/exercises/exercise-action';
import {
addInjectForExercise,
bulkDeleteInjects,
bulkUpdateInject,
bulkDeleteInjectsSimple,
bulkUpdateInjectSimple,
deleteInjectForExercise,
fetchExerciseInjects,
injectDone,
Expand Down Expand Up @@ -36,12 +36,8 @@ const injectContextForExercise = (exercise: Exercise) => {
onAddInject(inject: Inject): Promise<{ result: string; entities: { injects: Record<string, InjectStore> } }> {
return dispatch(addInjectForExercise(exercise.exercise_id, inject));
},
onBulkUpdateInject(param: InjectBulkUpdateInputs): Promise<{
result: string;
entities: { injects: Record<string, InjectStore> };
}> {
// exercise.exercise_id
return dispatch(bulkUpdateInject(param));
onBulkUpdateInject(param: InjectBulkUpdateInputs): Promise<Inject[] | void> {
return bulkUpdateInjectSimple(param).then((result: { data: Inject[] }) => result?.data);
},
onUpdateInject(injectId: Inject['inject_id'], inject: Inject): Promise<{ result: string; entities: { injects: Record<string, InjectStore> } }> {
return dispatch(updateInjectForExercise(exercise.exercise_id, injectId, inject));
Expand Down Expand Up @@ -73,8 +69,7 @@ const injectContextForExercise = (exercise: Exercise) => {
return dryImportXlsForExercise(exercise.exercise_id, importId, input).then(result => result.data);
},
onBulkDeleteInjects(param: InjectBulkProcessingInput): Promise<Inject[]> {
// exercise.exercise_id
return dispatch(bulkDeleteInjects(param));
return bulkDeleteInjectsSimple(param).then((result: { data: Inject[] }) => result?.data);
},
bulkTestInjects(param: InjectBulkProcessingInput): Promise<{ uri: string; data: InjectTestStatus[] }> {
return bulkTestInjects(param).then(result => ({
Expand Down
3 changes: 2 additions & 1 deletion openbas-front/src/utils/Action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ export const simplePutCall = (uri: string, data?: unknown, defaultNotifyErrorBeh
}
throw error;
});
export const simpleDelCall = (uri: string, defaultNotifyErrorBehavior: boolean = true, defaultSuccessBehavior: boolean = true) => simpleApi.delete(buildUri(uri))
// eslint-disable-next-line max-len
export const simpleDelCall = (uri: string, data?: unknown, defaultNotifyErrorBehavior: boolean = true, defaultSuccessBehavior: boolean = true) => simpleApi.delete(buildUri(uri), data ? { data: data } : undefined)
.then((response) => {
if (defaultSuccessBehavior) {
notifySuccess('The element has been successfully deleted.');
Expand Down

0 comments on commit 9bfca3a

Please sign in to comment.