From 67fe32bd06cde0bc7f44857feb5b0022833df8d4 Mon Sep 17 00:00:00 2001 From: Cathia Archidoit Date: Wed, 30 Oct 2024 14:35:59 +0100 Subject: [PATCH] [frontend] fix entities creation from Relationship creation panel --- .../CreateRelationshipButtonComponent.tsx | 2 +- ...RelationshipCreationFromControlledDial.tsx | 265 +++++++++--------- .../StixCyberObservableEntities.tsx | 2 +- 3 files changed, 131 insertions(+), 138 deletions(-) diff --git a/opencti-platform/opencti-front/src/private/components/common/menus/CreateRelationshipButtonComponent.tsx b/opencti-platform/opencti-front/src/private/components/common/menus/CreateRelationshipButtonComponent.tsx index a8047d03fb7a..3b53482dec43 100644 --- a/opencti-platform/opencti-front/src/private/components/common/menus/CreateRelationshipButtonComponent.tsx +++ b/opencti-platform/opencti-front/src/private/components/common/menus/CreateRelationshipButtonComponent.tsx @@ -19,7 +19,7 @@ const CreateRelationshipButtonComponent: FunctionComponent diff --git a/opencti-platform/opencti-front/src/private/components/common/stix_core_relationships/StixCoreRelationshipCreationFromControlledDial.tsx b/opencti-platform/opencti-front/src/private/components/common/stix_core_relationships/StixCoreRelationshipCreationFromControlledDial.tsx index 47c9e9241a9d..445786111eb5 100644 --- a/opencti-platform/opencti-front/src/private/components/common/stix_core_relationships/StixCoreRelationshipCreationFromControlledDial.tsx +++ b/opencti-platform/opencti-front/src/private/components/common/stix_core_relationships/StixCoreRelationshipCreationFromControlledDial.tsx @@ -23,7 +23,6 @@ import { emptyFilterGroup, useBuildEntityTypeBasedFilterContext } from '../../.. import { useFormatter } from '../../../../components/i18n'; import { CreateRelationshipContext } from '../menus/CreateRelationshipContextProvider'; import { computeTargetStixCyberObservableTypes, computeTargetStixDomainObjectTypes } from '../../../../utils/stixTypeUtils'; -import { FilterGroup } from '../../../../utils/filters/filtersHelpers-types'; import { UserContext } from '../../../../utils/hooks/useAuth'; import useQueryLoading from '../../../../utils/hooks/useQueryLoading'; import { StixCoreRelationshipCreationFromEntityStixCoreObjectsLinesQuery$variables } from './__generated__/StixCoreRelationshipCreationFromEntityStixCoreObjectsLinesQuery.graphql'; @@ -36,13 +35,13 @@ import { StixCoreRelationshipCreationFromEntityStixCoreObjectsLines_data$data } import BulkRelationDialogContainer from '../bulk/dialog/BulkRelationDialogContainer'; import { UsePreloadedPaginationFragment } from '../../../../utils/hooks/usePreloadedPaginationFragment'; import { PaginationOptions } from '../../../../components/list_lines'; -import { ModuleHelper } from '../../../../utils/platformModulesHelper'; -import { usePaginationLocalStorage } from '../../../../utils/hooks/useLocalStorage'; +import { UseLocalStorageHelpers, usePaginationLocalStorage } from '../../../../utils/hooks/useLocalStorage'; import useEntityToggle from '../../../../utils/hooks/useEntityToggle'; import StixCoreRelationshipCreationForm from './StixCoreRelationshipCreationForm'; import { resolveRelationsTypes } from '../../../../utils/Relation'; import { isNodeInConnection } from '../../../../utils/store'; import { formatDate } from '../../../../utils/Time'; +import { FilterGroup } from '../../../../utils/filters/filtersHelpers-types'; export const CreateRelationshipControlledDial = ({ onOpen }: { onOpen: () => void @@ -66,11 +65,13 @@ export const CreateRelationshipControlledDial = ({ onOpen }: { interface HeaderProps { showCreates: boolean, + searchPaginationOptions?: any, } // Custom header prop for entity/observable creation buttons in initial step export const Header: FunctionComponent = ({ showCreates, + searchPaginationOptions, }) => { const { t_i18n } = useFormatter(); @@ -92,24 +93,6 @@ export const Header: FunctionComponent = ({ ...targetStixDomainObjectTypes, ...targetStixCyberObservableTypes, ]; - const filters: FilterGroup = { - mode: 'and', - filterGroups: [], - filters: [{ - id: uuid(), - key: 'entity_type', - values: entityTypes, - operator: 'eq', - mode: 'or', - }], - }; - const searchPaginationOptions = { - search: '', - // filters: useRemoveIdAndIncorrectKeysFromFilterGroupObject(filters, entityTypes), - filters: useBuildEntityTypeBasedFilterContext(entityTypes, filters), - orderBy: '_score', - orderMode: 'desc', - }; return (
, targetEntities: TargetEntity[], handleNextStep: () => void, + searchPaginationOptions: PaginationOptions, + localStorageKey: string, + helpers: UseLocalStorageHelpers, + contextFilters: FilterGroup, + virtualEntityTypes: string[], }) => { const { t_i18n } = useFormatter(); - const { state: { stixCoreObjectTypes } } = useContext(CreateRelationshipContext); - - const typeFilters = (stixCoreObjectTypes ?? []).length > 0 - ? { - mode: 'and', - filterGroups: [], - filters: [{ - id: uuid(), - key: 'entity_type', - values: stixCoreObjectTypes ?? [], - operator: 'eq', - mode: 'or', - }], - } - : emptyFilterGroup; - let virtualEntityTypes = stixCoreObjectTypes; - if (virtualEntityTypes === undefined || virtualEntityTypes.length < 1) { - virtualEntityTypes = ['Stix-Domain-Object', 'Stix-Cyber-Observable']; - } - const getLocalStorageKey = (entityId: string) => `${entityId}_stixCoreRelationshipCreationFromEntity`; - - const [sortBy, setSortBy] = useState('_score'); - const [orderAsc, setOrderAsc] = useState(false); - - const { viewStorage, helpers } = usePaginationLocalStorage( - getLocalStorageKey(entity_id), - { filters: typeFilters }, - ); - const { searchTerm = '', orderAsc: storageOrderAsc, sortBy: storageSortBy, filters } = viewStorage; - - useEffect(() => { - if (storageSortBy && (storageSortBy !== sortBy)) setSortBy(storageSortBy); - if (storageOrderAsc !== undefined && (storageOrderAsc !== orderAsc)) setOrderAsc(storageOrderAsc); - }, [storageOrderAsc, storageSortBy]); + const { platformModuleHelpers } = useContext(UserContext); const { selectedElements, - } = useEntityToggle(getLocalStorageKey(entity_id)); + } = useEntityToggle(localStorageKey); useEffect(() => { const newTargetEntities: TargetEntity[] = Object.values(selectedElements).map((item) => ({ @@ -287,43 +247,34 @@ const SelectEntity = ({ setTargetEntities(newTargetEntities); }, [selectedElements]); - const buildColumns = (platformModuleHelpers: ModuleHelper | undefined) => { - const isRuntimeSort = platformModuleHelpers?.isRuntimeFieldEnable(); - return { - entity_type: { - label: 'Type', - percentWidth: 15, - isSortable: true, - }, - value: { - label: 'Value', - percentWidth: 32, - isSortable: false, - }, - createdBy: { - label: 'Author', - percentWidth: 15, - isSortable: isRuntimeSort, - }, - objectLabel: { - label: 'Labels', - percentWidth: 22, - isSortable: false, - }, - objectMarking: { - label: 'Marking', - percentWidth: 15, - isSortable: isRuntimeSort, - }, - }; + const isRuntimeSort = platformModuleHelpers?.isRuntimeFieldEnable(); + const buildColumns = { + entity_type: { + label: 'Type', + percentWidth: 15, + isSortable: true, + }, + value: { + label: 'Value', + percentWidth: 32, + isSortable: false, + }, + createdBy: { + label: 'Author', + percentWidth: 15, + isSortable: isRuntimeSort, + }, + objectLabel: { + label: 'Labels', + percentWidth: 22, + isSortable: false, + }, + objectMarking: { + label: 'Marking', + percentWidth: 15, + isSortable: isRuntimeSort, + }, }; - const contextFilters = useBuildEntityTypeBasedFilterContext(virtualEntityTypes, filters); - const searchPaginationOptions: PaginationOptions = { - search: searchTerm, - filters: contextFilters, - orderBy: sortBy, - orderMode: orderAsc ? 'asc' : 'desc', - } as PaginationOptions; const queryRef = useQueryLoading( stixCoreRelationshipCreationFromEntityStixCoreObjectsLinesQuery, { ...searchPaginationOptions, count: 100 } as StixCoreRelationshipCreationFromEntityStixCoreObjectsLinesQuery$variables, @@ -355,45 +306,39 @@ const SelectEntity = ({ width: '100%', }} > - - {({ platformModuleHelpers }) => ( - <> - {queryRef && ( -
- data.stixCoreObjects?.edges?.map((n) => n?.node)} - storageKey={getLocalStorageKey(entity_id)} - lineFragment={stixCoreRelationshipCreationFromEntityStixCoreObjectsLineFragment} - initialValues={initialValues} - toolbarFilters={contextFilters} - preloadedPaginationProps={preloadedPaginationProps} - entityTypes={virtualEntityTypes} - additionalHeaderButtons={[( - - )]} - /> -
- )} - - )} -
+ {queryRef && ( +
+ data.stixCoreObjects?.edges?.map((n) => n?.node)} + storageKey={localStorageKey} + lineFragment={stixCoreRelationshipCreationFromEntityStixCoreObjectsLineFragment} + initialValues={initialValues} + toolbarFilters={contextFilters} + preloadedPaginationProps={preloadedPaginationProps} + entityTypes={virtualEntityTypes} + additionalHeaderButtons={[( + + )]} + /> +
+ )} = ({ - id, + entityId, allowedRelationshipTypes, isReversable = false, defaultStartTime, @@ -597,6 +542,49 @@ const StixCoreRelationshipCreationFromControlledDial: FunctionComponent(0); const [targetEntities, setTargetEntities] = useState([]); + const { state: { stixCoreObjectTypes } } = useContext(CreateRelationshipContext); + + const typeFilters = (stixCoreObjectTypes ?? []).length > 0 + ? { + mode: 'and', + filterGroups: [], + filters: [{ + id: uuid(), + key: 'entity_type', + values: stixCoreObjectTypes ?? [], + operator: 'eq', + mode: 'or', + }], + } + : emptyFilterGroup; + let virtualEntityTypes = stixCoreObjectTypes; + if (virtualEntityTypes === undefined || virtualEntityTypes.length < 1) { + virtualEntityTypes = ['Stix-Domain-Object', 'Stix-Cyber-Observable']; + } + const localStorageKey = `${entityId}_stixCoreRelationshipCreationFromEntity`; + + const [sortBy, setSortBy] = useState('_score'); + const [orderAsc, setOrderAsc] = useState(false); + + const { viewStorage, helpers } = usePaginationLocalStorage( + localStorageKey, + { filters: typeFilters }, + ); + const { searchTerm = '', orderAsc: storageOrderAsc, sortBy: storageSortBy, filters } = viewStorage; + + useEffect(() => { + if (storageSortBy && (storageSortBy !== sortBy)) setSortBy(storageSortBy); + if (storageOrderAsc !== undefined && (storageOrderAsc !== orderAsc)) setOrderAsc(storageOrderAsc); + }, [storageOrderAsc, storageSortBy]); + + const contextFilters = useBuildEntityTypeBasedFilterContext(virtualEntityTypes, filters); + const searchPaginationOptions: PaginationOptions = { + search: searchTerm, + filters: contextFilters, + orderBy: sortBy, + orderMode: orderAsc ? 'asc' : 'desc', + } as PaginationOptions; + const reset = () => { setStep(0); setTargetEntities([]); @@ -607,7 +595,7 @@ const StixCoreRelationshipCreationFromControlledDial: FunctionComponent} + header={
} containerStyle={{ minHeight: '100vh', }} @@ -615,7 +603,7 @@ const StixCoreRelationshipCreationFromControlledDial: FunctionComponent ( { if (props?.stixCoreObject) { const { name, entity_type, observable_value } = props.stixCoreObject; @@ -628,12 +616,17 @@ const StixCoreRelationshipCreationFromControlledDial: FunctionComponent setStep(1)} + searchPaginationOptions={searchPaginationOptions} + localStorageKey={localStorageKey} + helpers={helpers} + contextFilters={contextFilters} + virtualEntityTypes={virtualEntityTypes} /> )} {step === 1 && ( diff --git a/opencti-platform/opencti-front/src/private/components/observations/stix_cyber_observables/StixCyberObservableEntities.tsx b/opencti-platform/opencti-front/src/private/components/observations/stix_cyber_observables/StixCyberObservableEntities.tsx index 1a6922b9ea01..a8e31deac39c 100644 --- a/opencti-platform/opencti-front/src/private/components/observations/stix_cyber_observables/StixCyberObservableEntities.tsx +++ b/opencti-platform/opencti-front/src/private/components/observations/stix_cyber_observables/StixCyberObservableEntities.tsx @@ -105,7 +105,7 @@ const StixCyberObservableEntities: FunctionComponent {