diff --git a/opencti-platform/opencti-front/src/components/FilterIconButton.tsx b/opencti-platform/opencti-front/src/components/FilterIconButton.tsx index 4b2db19bc5298..de406163f02f5 100644 --- a/opencti-platform/opencti-front/src/components/FilterIconButton.tsx +++ b/opencti-platform/opencti-front/src/components/FilterIconButton.tsx @@ -2,7 +2,6 @@ import React, { FunctionComponent } from 'react'; import makeStyles from '@mui/styles/makeStyles'; import { DataColumns } from './list_lines'; import { Filter, FilterGroup } from '../utils/filters/filtersUtils'; -import { TriggerLine_node$data } from '../private/components/profile/triggers/__generated__/TriggerLine_node.graphql'; import { filterIconButtonContentQuery } from './FilterIconButtonContent'; import useQueryLoading from '../utils/hooks/useQueryLoading'; import Loader from './Loader'; @@ -50,7 +49,6 @@ interface FilterIconButtonProps { dataColumns?: DataColumns; disabledPossible?: boolean; redirection?: boolean; - resolvedInstanceFilters?: TriggerLine_node$data['resolved_instance_filters']; } const FilterIconButton: FunctionComponent = ({ @@ -64,7 +62,6 @@ const FilterIconButton: FunctionComponent = ({ dataColumns, disabledPossible, redirection, - resolvedInstanceFilters, }) => { const classes = useStyles(); @@ -97,17 +94,17 @@ const FilterIconButton: FunctionComponent = ({ > {filtersRepresentativesQueryRef && ( }> - + ) } diff --git a/opencti-platform/opencti-front/src/components/FilterIconButtonContainer.tsx b/opencti-platform/opencti-front/src/components/FilterIconButtonContainer.tsx index 02ea879b024f0..670e770a0f782 100644 --- a/opencti-platform/opencti-front/src/components/FilterIconButtonContainer.tsx +++ b/opencti-platform/opencti-front/src/components/FilterIconButtonContainer.tsx @@ -8,7 +8,7 @@ import { truncate } from '../utils/String'; import { DataColumns } from './list_lines'; import { useFormatter } from './i18n'; import { Theme } from './Theme'; -import { Filter, filterValue } from '../utils/filters/filtersUtils'; +import { Filter } from '../utils/filters/filtersUtils'; import FilterIconButtonContent, { filterIconButtonContentQuery } from './FilterIconButtonContent'; import { FilterIconButtonContentQuery } from './__generated__/FilterIconButtonContentQuery.graphql'; @@ -122,23 +122,22 @@ const FilterIconButtonContainer: FunctionComponent {filterValues.map((n) => { - const value = filterValue(n); return ( - - - {last(filterValues) !== n && ( - handleSwitchLocalMode?.(currentFilter)} - /> - )}{' '} - + + + {last(filterValues) !== n && ( + handleSwitchLocalMode?.(currentFilter)} + /> + )}{' '} + ); })} diff --git a/opencti-platform/opencti-front/src/components/FilterIconButtonContent.tsx b/opencti-platform/opencti-front/src/components/FilterIconButtonContent.tsx index 591534fe25d80..5076c39f34fb0 100644 --- a/opencti-platform/opencti-front/src/components/FilterIconButtonContent.tsx +++ b/opencti-platform/opencti-front/src/components/FilterIconButtonContent.tsx @@ -1,17 +1,10 @@ -import React, { FunctionComponent, useState } from 'react'; +import React, { FunctionComponent } from 'react'; import { graphql } from 'react-relay'; import { Link } from 'react-router-dom'; -import { - dateFilters, - entityFilters, entityTypesFilters, - filtersWithRepresentative, - vocabularyFiltersWithTranslation, -} from '../utils/filters/filtersUtils'; +import { entityFilters, filterValue } from '../utils/filters/filtersUtils'; import { truncate } from '../utils/String'; import { useFormatter } from './i18n'; -import { - FilterIconButtonContentQuery$data, -} from './__generated__/FilterIconButtonContentQuery.graphql'; +import { FilterIconButtonContentQuery$data } from './__generated__/FilterIconButtonContentQuery.graphql'; export const filterIconButtonContentQuery = graphql` query FilterIconButtonContentQuery( @@ -36,59 +29,26 @@ const FilterIconButtonContent: FunctionComponent = id, filtersRepresentatives, }) => { - const { t, nsdt } = useFormatter(); - const [isDeleted, setDeleted] = useState(false); - const filterValue = () => { - if (filtersWithRepresentative.includes(filterKey)) { - const value = filtersRepresentatives?.filter((n) => n?.id === id)?.[0]?.value; - if (!value) { - setDeleted(true); - return 'deleted'; - } - return value; - } - if (vocabularyFiltersWithTranslation.includes(filterKey)) { - return t(id); - } - if (filterKey === 'basedOn') { - return id === 'EXISTS' ? t('Yes') : t('No'); - } - if (filterKey === 'x_opencti_negative') { - return t(id ? 'False positive' : 'Malicious'); - } - if (entityTypesFilters.includes(filterKey)) { - return id === 'all' - ? t('entity_All') - : t( - id.toString()[0] === id.toString()[0].toUpperCase() - ? `entity_${id.toString()}` - : `relationship_${id.toString()}`, - ); - } - if (dateFilters.includes(filterKey)) { - return nsdt(id); - } - return id; - }; - const displayedValue = truncate(filterValue(), 15); - const renderWithRedirection = () => { + const { t } = useFormatter(); + + const displayedValue = truncate(filterValue(filterKey, id, filtersRepresentatives), 15); + + if (displayedValue === null) { return ( <> - {!isDeleted - ? ( - {displayedValue} - ) - : ({displayedValue})} + {t('deleted')} ); - }; + } if (redirection && entityFilters.includes(filterKey)) { - return renderWithRedirection(); + return ( + + {displayedValue} + + ); } return ( - - {displayedValue}{' '} - + {displayedValue} ); }; diff --git a/opencti-platform/opencti-front/src/components/FilterIconButtonContentWithRedirection.tsx b/opencti-platform/opencti-front/src/components/FilterIconButtonContentWithRedirection.tsx deleted file mode 100644 index 79d6e30a80c46..0000000000000 --- a/opencti-platform/opencti-front/src/components/FilterIconButtonContentWithRedirection.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { FunctionComponent } from 'react'; -import { Link } from 'react-router-dom'; -import { graphql, PreloadedQuery, usePreloadedQuery } from 'react-relay'; -import { FilterIconButtonContentWithRedirectionQuery } from './__generated__/FilterIconButtonContentWithRedirectionQuery.graphql'; -import useQueryLoading from '../utils/hooks/useQueryLoading'; - -export const filterIconButtonContentWithRedirectionQuery = graphql` - query FilterIconButtonContentWithRedirectionQuery($id: String!) { - stixObjectOrStixRelationship(id: $id) { - ... on BasicObject { - id - } - ... on BasicRelationship { - id - } - } - } -`; - -interface FilterIconButtonContentWithRedirectionComponentProps { - queryRef: PreloadedQuery; - displayedValue: string; -} - -interface FilterIconButtonContentWithRedirectionProps { - filterId: string; - displayedValue: string; -} - -const FilterIconButtonContentWithRedirectionComponent: FunctionComponent< -FilterIconButtonContentWithRedirectionComponentProps -> = ({ queryRef, displayedValue }) => { - const data = usePreloadedQuery( - filterIconButtonContentWithRedirectionQuery, - queryRef, - ); - return ( - <> - {data.stixObjectOrStixRelationship?.id ? ( - - {displayedValue} - - ) : ( - {displayedValue} - )} - - ); -}; - -const FilterIconButtonContentWithRedirection: FunctionComponent< -FilterIconButtonContentWithRedirectionProps -> = ({ filterId, displayedValue }) => { - const queryRef = useQueryLoading( - filterIconButtonContentWithRedirectionQuery, - { id: filterId }, - ); - return ( - <> - {queryRef && ( - {displayedValue}} - > - - - )} - - ); -}; - -export default FilterIconButtonContentWithRedirection; diff --git a/opencti-platform/opencti-front/src/components/FilterIconButtonContentWithRedirectionContainer.tsx b/opencti-platform/opencti-front/src/components/FilterIconButtonContentWithRedirectionContainer.tsx deleted file mode 100644 index b642465e79eaf..0000000000000 --- a/opencti-platform/opencti-front/src/components/FilterIconButtonContentWithRedirectionContainer.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React, { FunctionComponent } from 'react'; -import { Link } from 'react-router-dom'; -import { Tooltip } from '@mui/material'; -import FilterIconButtonContentWithRedirection from './FilterIconButtonContentWithRedirection'; -import { truncate } from '../utils/String'; -import { useFormatter } from './i18n'; -import { TriggerLine_node$data } from '../private/components/profile/triggers/__generated__/TriggerLine_node.graphql'; - -interface FilterIconButtonContentWithRedirectionContainerProps { - id: string, - displayedValue: string, - resolvedInstanceFilters?: TriggerLine_node$data['resolved_instance_filters']; -} - -const FilterIconButtonContentWithRedirectionContainer: FunctionComponent< -FilterIconButtonContentWithRedirectionContainerProps -> = ({ id, displayedValue, resolvedInstanceFilters }) => { - const { t } = useFormatter(); - const redirectionWithResolvedInstances = () => { - const resolvedInstanceFiltersMap = new Map( - resolvedInstanceFilters?.map((n) => [n.id, n]), - ); - const invalidInstanceIds = resolvedInstanceFilters - ?.filter((n) => !n.valid) - .map((n) => n.id); - return ( - - {invalidInstanceIds?.includes(id) ? ( - - {displayedValue} - - ) : ( - - - {resolvedInstanceFiltersMap.has(id) - ? resolvedInstanceFiltersMap.get(id)?.value - : t('No label')} - - - )} - - ); - }; - const classicalRedirection = () => { - return ( - - ); - }; - if (resolvedInstanceFilters) { - return redirectionWithResolvedInstances(); - } - return classicalRedirection(); -}; - -export default FilterIconButtonContentWithRedirectionContainer; diff --git a/opencti-platform/opencti-front/src/private/components/common/stix_core_objects/StixCoreObjectQuickSubscriptionContent.tsx b/opencti-platform/opencti-front/src/private/components/common/stix_core_objects/StixCoreObjectQuickSubscriptionContent.tsx index 3d0c97cda8b10..4fee164ba9926 100644 --- a/opencti-platform/opencti-front/src/private/components/common/stix_core_objects/StixCoreObjectQuickSubscriptionContent.tsx +++ b/opencti-platform/opencti-front/src/private/components/common/stix_core_objects/StixCoreObjectQuickSubscriptionContent.tsx @@ -65,11 +65,6 @@ export const stixCoreObjectQuickSubscriptionContentQuery = graphql` id name } - resolved_instance_filters { - id - valid - value - } } } } @@ -83,7 +78,6 @@ interface InstanceTriggerEditionFormValues { event_types: readonly Option[]; notifiers: readonly Option[]; filters: string | null, - resolved_instance_filters?: TriggerLine_node$data['resolved_instance_filters'], } const useStyles = makeStyles((theme) => ({ @@ -361,7 +355,6 @@ const StixCoreObjectQuickSubscriptionContent: FunctionComponent } @@ -399,7 +392,7 @@ const StixCoreObjectQuickSubscriptionContent: FunctionComponent l) .map((n) => ({ - ...pick(['id', 'name', 'description', 'filters', 'resolved_instance_filters'], n?.node), + ...pick(['id', 'name', 'description', 'filters'], n?.node), notifiers: convertNotifiers(n?.node), event_types: convertEventTypes(n?.node), })) as InstanceTriggerEditionFormValues[]; diff --git a/opencti-platform/opencti-front/src/private/components/data/ToolBar.jsx b/opencti-platform/opencti-front/src/private/components/data/ToolBar.jsx index df040147e241c..13a3bf97991da 100644 --- a/opencti-platform/opencti-front/src/private/components/data/ToolBar.jsx +++ b/opencti-platform/opencti-front/src/private/components/data/ToolBar.jsx @@ -57,6 +57,7 @@ import Alert from '@mui/material/Alert'; import TextField from '@mui/material/TextField'; import Grid from '@mui/material/Grid'; import Avatar from '@mui/material/Avatar'; +import ToolBarFilterValueContainer from './ToolBarFilterValueContainer'; import inject18n from '../../../components/i18n'; import { truncate } from '../../../utils/String'; import { commitMutation, fetchQuery, MESSAGING$ } from '../../../relay/environment'; @@ -73,8 +74,10 @@ import { hexToRGB } from '../../../utils/Colors'; import { externalReferencesQueriesSearchQuery } from '../analyses/external_references/ExternalReferencesQueries'; import StixDomainObjectCreation from '../common/stix_domain_objects/StixDomainObjectCreation'; import ItemMarkings from '../../../components/ItemMarkings'; -import { filterValue, findFilterFromKey } from '../../../utils/filters/filtersUtils'; +import { findFilterFromKey } from '../../../utils/filters/filtersUtils'; import { stixCyberObservableTypes } from '../../../utils/hooks/useAttributes'; +import useQueryLoading from '../../../utils/hooks/useQueryLoading'; +import { filterIconButtonContentQuery } from '../../../components/FilterIconButtonContent'; const styles = (theme) => ({ bottomNav: { @@ -1599,60 +1602,9 @@ class ToolBar extends Component { )} )} - {filters.filters.map((currentFilter) => { - const label = `${truncate( - currentFilter.key.startsWith('rel_') - ? t( - `relationship_${currentFilter.key - .replace('rel_', '') - .replace('.*', '')}`, - ) - : t(`filter_${currentFilter.key}`), - 20, - )}`; - const localFilterMode = currentFilter.operator === 'or' - ? t('AND') - : t('OR'); - const values = ( - - {currentFilter.values.map( - (o) => ( - - {/* eslint-disable-next-line no-nested-ternary */} - {filterValue(o) && filterValue(o).length > 0 - ? truncate(o, 15) - : t('No label')}{' '} - {R.last(currentFilter.values) - !== o && ( - {localFilterMode} - )}{' '} - - ), - )} - - ); - return ( - - - {label}: {values} - - } - /> - {R.last(filters.filters).key - !== currentFilter.key && ( - - )} - - ); - })} + ) : ( diff --git a/opencti-platform/opencti-front/src/private/components/data/ToolBarFilterValue.tsx b/opencti-platform/opencti-front/src/private/components/data/ToolBarFilterValue.tsx new file mode 100644 index 0000000000000..f5541c5184da5 --- /dev/null +++ b/opencti-platform/opencti-front/src/private/components/data/ToolBarFilterValue.tsx @@ -0,0 +1,86 @@ +import * as R from 'ramda'; +import React from 'react'; +import { PreloadedQuery, usePreloadedQuery } from 'react-relay'; +import Chip from '@mui/material/Chip'; +import makeStyles from '@mui/styles/makeStyles'; +import FilterIconButtonContent, { filterIconButtonContentQuery } from '../../../components/FilterIconButtonContent'; +import { FilterIconButtonContentQuery } from '../../../components/__generated__/FilterIconButtonContentQuery.graphql'; +import { useFormatter } from '../../../components/i18n'; +import { Filter } from '../../../utils/filters/filtersUtils'; +import { truncate } from '../../../utils/String'; +import { Theme } from '../../../components/Theme'; + +const useStyles = makeStyles((theme) => ({ + filter: { + margin: '5px 10px 5px 0', + }, + operator: { + fontFamily: 'Consolas, monaco, monospace', + backgroundColor: theme.palette.background.accent, + margin: '5px 10px 5px 0', + }, +})); + +const ToolBarFilterValue = ({ filtersList, queryRef }: +{ + filtersList: Filter[], + queryRef: PreloadedQuery, +}) => { + const { t } = useFormatter(); + const classes = useStyles(); + const { filtersRepresentatives } = usePreloadedQuery(filterIconButtonContentQuery, queryRef); + + return ( + <> + {filtersList.map((currentFilter) => { + const label = `${truncate( + currentFilter.key.startsWith('rel_') + ? t( + `relationship_${currentFilter.key + .replace('rel_', '') + .replace('.*', '')}`, + ) + : t(`filter_${currentFilter.key}`), + 20, + )}`; + return ( + + + {label}: {currentFilter.values.map( + (o) => { + const localFilterMode = t(currentFilter.operator.toUpperCase()); + return ( + + + {R.last(currentFilter.values) !== o + && ({localFilterMode}) + }{' '} + + ); + }, + )} + + } + /> + {R.last(filtersList)?.key + !== currentFilter.key && ( + + )} + + ); + })} + + ); +}; + +export default ToolBarFilterValue; diff --git a/opencti-platform/opencti-front/src/private/components/data/ToolBarFilterValueContainer.tsx b/opencti-platform/opencti-front/src/private/components/data/ToolBarFilterValueContainer.tsx new file mode 100644 index 0000000000000..2ed7a485ea297 --- /dev/null +++ b/opencti-platform/opencti-front/src/private/components/data/ToolBarFilterValueContainer.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { Filter } from '../../../utils/filters/filtersUtils'; +import { filterIconButtonContentQuery } from '../../../components/FilterIconButtonContent'; +import useQueryLoading from '../../../utils/hooks/useQueryLoading'; +import ToolBarFilterValue from './ToolBarFilterValue'; +import Loader from '../../../components/Loader'; +import { FilterIconButtonContentQuery } from '../../../components/__generated__/FilterIconButtonContentQuery.graphql'; + +const ToolBarFilterValueContainer = ({ filtersList }: { + filtersList: Filter[], +}) => { + const queryRef = useQueryLoading( + filterIconButtonContentQuery, + { filters: filtersList }, + ); + + return ( + <> + {queryRef && ( + }> + + + )} + + ); +}; + +export default ToolBarFilterValueContainer; diff --git a/opencti-platform/opencti-front/src/private/components/data/entities/EntitiesStixDomainObjectsLines.tsx b/opencti-platform/opencti-front/src/private/components/data/entities/EntitiesStixDomainObjectsLines.tsx index 15af4ced9e538..0dfcc00b35a92 100644 --- a/opencti-platform/opencti-front/src/private/components/data/entities/EntitiesStixDomainObjectsLines.tsx +++ b/opencti-platform/opencti-front/src/private/components/data/entities/EntitiesStixDomainObjectsLines.tsx @@ -42,7 +42,7 @@ export const entitiesStixDomainObjectsLinesQuery = graphql` $cursor: ID $orderBy: StixDomainObjectsOrdering $orderMode: OrderingMode - $filters: [StixDomainObjectsFiltering] + $filters: StixDomainObjectsGroupFiltering ) { ...EntitiesStixDomainObjectsLines_data @arguments( @@ -66,7 +66,7 @@ export const entitiesStixDomainObjectsLinesFragment = graphql` cursor: { type: "ID" } orderBy: { type: "StixDomainObjectsOrdering", defaultValue: name } orderMode: { type: "OrderingMode", defaultValue: asc } - filters: { type: "[StixDomainObjectsFiltering]" } + filters: { type: "StixDomainObjectsGroupFiltering" } ) @refetchable(queryName: "EntitiesStixDomainObjectsLinesRefetchQuery") { stixDomainObjects( diff --git a/opencti-platform/opencti-front/src/private/components/profile/triggers/TriggerEditionOverview.tsx b/opencti-platform/opencti-front/src/private/components/profile/triggers/TriggerEditionOverview.tsx index 477bcae3fb2a2..98d37ed4c4073 100644 --- a/opencti-platform/opencti-front/src/private/components/profile/triggers/TriggerEditionOverview.tsx +++ b/opencti-platform/opencti-front/src/private/components/profile/triggers/TriggerEditionOverview.tsx @@ -59,11 +59,6 @@ const triggerEditionOverviewFragment = graphql` id name } - resolved_instance_filters { - id - valid - value - } } `; @@ -475,7 +470,6 @@ TriggerEditionOverviewProps handleRemoveFilter={handleRemoveFilter} classNameNumber={2} redirection - resolvedInstanceFilters={trigger.resolved_instance_filters ?? []} /> } diff --git a/opencti-platform/opencti-front/src/private/components/profile/triggers/TriggerLine.tsx b/opencti-platform/opencti-front/src/private/components/profile/triggers/TriggerLine.tsx index 7e6d91bab2a17..f5e889527b8dd 100644 --- a/opencti-platform/opencti-front/src/private/components/profile/triggers/TriggerLine.tsx +++ b/opencti-platform/opencti-front/src/private/components/profile/triggers/TriggerLine.tsx @@ -104,11 +104,6 @@ const triggerLineFragment = graphql` isDirectAdministrator currentUserAccessRight instance_trigger - resolved_instance_filters { - id - valid - value - } } `; @@ -207,7 +202,6 @@ export const TriggerLineComponent: FunctionComponent = ({ classNameNumber={3} styleNumber={3} redirection - resolvedInstanceFilters={data.resolved_instance_filters ?? []} /> )} {data.trigger_type === 'digest' && ( diff --git a/opencti-platform/opencti-front/src/schema/relay.schema.graphql b/opencti-platform/opencti-front/src/schema/relay.schema.graphql index effbe22921885..7b8db156b7ea5 100644 --- a/opencti-platform/opencti-front/src/schema/relay.schema.graphql +++ b/opencti-platform/opencti-front/src/schema/relay.schema.graphql @@ -8105,7 +8105,8 @@ type Query { stixCoreObjectsMultiNumber(startDate: DateTime, endDate: DateTime, onlyInferred: Boolean, numberParameters: [StixCoreObjectsNumberParameters]): [Number] stixCoreObjectsDistribution(objectId: [String], relationship_type: [String], toTypes: [String], elementWithTargetTypes: [String], field: String!, startDate: DateTime, endDate: DateTime, dateAttribute: String, operation: StatsOperation!, limit: Int, order: String, types: [String], filters: [StixCoreObjectsFiltering], filterMode: FilterMode, search: String): [Distribution] stixCoreObjectsMultiDistribution(field: String!, startDate: DateTime, endDate: DateTime, dateAttribute: String, operation: StatsOperation!, limit: Int, order: String, distributionParameters: StixCoreObjectsDistributionParameters): [MultiDistribution] - filtersRepresentatives(filters: [Filter]): [FilterRepresentative] + filterRepresentative(filter: Filter!): FilterRepresentative + filtersRepresentatives(filters: [Filter]!): [FilterRepresentative] stixDomainObject(id: String!): StixDomainObject stixDomainObjects(first: Int, after: ID, types: [String], orderBy: StixDomainObjectsOrdering, orderMode: OrderingMode, filters: StixDomainObjectsGroupFiltering, filterMode: FilterMode, search: String, relationship_type: [String], elementId: String): StixDomainObjectConnection bookmarks(first: Int, after: ID, types: [String]): StixDomainObjectConnection @@ -9721,7 +9722,6 @@ type Trigger implements InternalObject & BasicObject { isDirectAdministrator: Boolean currentUserAccessRight: String instance_trigger: Boolean - resolved_instance_filters: [ResolvedInstanceFilter!] } type TriggerConnection { diff --git a/opencti-platform/opencti-front/src/utils/filters/filtersUtils.tsx b/opencti-platform/opencti-front/src/utils/filters/filtersUtils.tsx index 871ff4cc74ba4..79fe4383e171f 100644 --- a/opencti-platform/opencti-front/src/utils/filters/filtersUtils.tsx +++ b/opencti-platform/opencti-front/src/utils/filters/filtersUtils.tsx @@ -1,4 +1,5 @@ -import { truncate } from '../String'; +import { useFormatter } from '../../components/i18n'; +import { FilterIconButtonContentQuery$data } from '../../components/__generated__/FilterIconButtonContentQuery.graphql'; export const FiltersVariant = { list: 'list', @@ -204,10 +205,35 @@ export const filtersWithEntityType = (filters: FilterGroup | undefined, type: st : undefined); }; -export const filterValue = (id: string) => { - return truncate(id, 5); // TODO implement correctly -}; - export const isFilterGroupNotEmpty = (filterGroup: FilterGroup) => { return filterGroup.filters.length > 0 || filterGroup.filterGroups.length > 0; }; + +export const filterValue = (filterKey: string, id: string, filtersRepresentatives: FilterIconButtonContentQuery$data['filtersRepresentatives']) => { + const { t, nsdt } = useFormatter(); + if (filtersWithRepresentative.includes(filterKey)) { + return filtersRepresentatives?.filter((n) => n?.id === id)?.[0]?.value; + } + if (vocabularyFiltersWithTranslation.includes(filterKey)) { + return t(id); + } + if (filterKey === 'basedOn') { + return id === 'EXISTS' ? t('Yes') : t('No'); + } + if (filterKey === 'x_opencti_negative') { + return t(id ? 'False positive' : 'Malicious'); + } + if (entityTypesFilters.includes(filterKey)) { + return id === 'all' + ? t('entity_All') + : t( + id.toString()[0] === id.toString()[0].toUpperCase() + ? `entity_${id.toString()}` + : `relationship_${id.toString()}`, + ); + } + if (dateFilters.includes(filterKey)) { + return nsdt(id); + } + return id; +}; diff --git a/opencti-platform/opencti-front/src/utils/hooks/useLocalStorage.ts b/opencti-platform/opencti-front/src/utils/hooks/useLocalStorage.ts index 574660435dba8..93c69fc215078 100644 --- a/opencti-platform/opencti-front/src/utils/hooks/useLocalStorage.ts +++ b/opencti-platform/opencti-front/src/utils/hooks/useLocalStorage.ts @@ -92,7 +92,7 @@ const localStorageToPaginationOptions = ( basePagination.orderMode = orderAsc ? OrderMode.asc : OrderMode.desc; basePagination.orderBy = sortBy; } - let convertedFilters = filters.filters as Filter[]; + let convertedFilters = filters?.filters as Filter[]; const fromId = R.head(convertedFilters.filter((n) => n.key === 'fromId'))?.values || undefined; const toId = R.head(convertedFilters.filter((n) => n.key === 'toId'))?.values || undefined; const fromTypes = R.head(convertedFilters.filter((n) => n.key === 'fromTypes'))?.values || undefined; @@ -102,7 +102,7 @@ const localStorageToPaginationOptions = ( ); const paginationFilters = { - mode: filters.mode ?? 'and', + mode: filters?.mode ?? 'and', filters: convertedFilters ?? [] as Filter[], filterGroups: [] as FilterGroup[], }; diff --git a/opencti-platform/opencti-graphql/config/schema/opencti.graphql b/opencti-platform/opencti-graphql/config/schema/opencti.graphql index 48df46d249d7f..b78bfab7d1243 100644 --- a/opencti-platform/opencti-graphql/config/schema/opencti.graphql +++ b/opencti-platform/opencti-graphql/config/schema/opencti.graphql @@ -12172,7 +12172,8 @@ type Query { order: String distributionParameters: StixCoreObjectsDistributionParameters ): [MultiDistribution] @auth(for: [KNOWLEDGE, EXPLORE]) - filtersRepresentatives(filters: [Filter]): [FilterRepresentative] @auth(for: [KNOWLEDGE]) + filterRepresentative(filter: Filter!): FilterRepresentative @auth(for: [KNOWLEDGE]) + filtersRepresentatives(filters: [Filter]!): [FilterRepresentative] @auth(for: [KNOWLEDGE]) ######## STIX DOMAIN OBJECT ENTITIES diff --git a/opencti-platform/opencti-graphql/src/domain/stixCoreObject.js b/opencti-platform/opencti-graphql/src/domain/stixCoreObject.js index a1e5c28b73fa1..a076539bc67f9 100644 --- a/opencti-platform/opencti-graphql/src/domain/stixCoreObject.js +++ b/opencti-platform/opencti-graphql/src/domain/stixCoreObject.js @@ -461,7 +461,7 @@ export const stixCoreObjectEditContext = async (context, user, stixCoreObjectId, // endregion // filters representatives -const findFilterRepresentative = async (context, user, filter) => { +export const findFilterRepresentative = async (context, user, filter) => { const { key, values } = filter; let data; switch (key) { diff --git a/opencti-platform/opencti-graphql/src/generated/graphql.ts b/opencti-platform/opencti-graphql/src/generated/graphql.ts index d0820840a17cf..f568907f74b56 100644 --- a/opencti-platform/opencti-graphql/src/generated/graphql.ts +++ b/opencti-platform/opencti-graphql/src/generated/graphql.ts @@ -17539,6 +17539,7 @@ export type Query = { feedbacks?: Maybe; feeds?: Maybe; file?: Maybe; + filterRepresentative?: Maybe; filtersRepresentatives?: Maybe>>; globalSearch?: Maybe; group?: Maybe; @@ -18237,8 +18238,13 @@ export type QueryFileArgs = { }; +export type QueryFilterRepresentativeArgs = { + filter: Filter; +}; + + export type QueryFiltersRepresentativesArgs = { - filters?: InputMaybe>>; + filters: Array>; }; @@ -26170,7 +26176,6 @@ export type Trigger = BasicObject & InternalObject & { parent_types: Array>; period?: Maybe; recipients?: Maybe>>; - resolved_instance_filters?: Maybe>; standard_id: Scalars['String']['output']; trigger_ids?: Maybe>>; trigger_time?: Maybe; @@ -34860,7 +34865,8 @@ export type QueryResolvers, ParentType, ContextType, Partial>; feeds?: Resolver, ParentType, ContextType, Partial>; file?: Resolver, ParentType, ContextType, RequireFields>; - filtersRepresentatives?: Resolver>>, ParentType, ContextType, Partial>; + filterRepresentative?: Resolver, ParentType, ContextType, RequireFields>; + filtersRepresentatives?: Resolver>>, ParentType, ContextType, RequireFields>; globalSearch?: Resolver, ParentType, ContextType, Partial>; group?: Resolver, ParentType, ContextType, RequireFields>; grouping?: Resolver, ParentType, ContextType, RequireFields>; @@ -37026,7 +37032,6 @@ export type TriggerResolvers>, ParentType, ContextType>; period?: Resolver, ParentType, ContextType>; recipients?: Resolver>>, ParentType, ContextType>; - resolved_instance_filters?: Resolver>, ParentType, ContextType>; standard_id?: Resolver; trigger_ids?: Resolver>>, ParentType, ContextType>; trigger_time?: Resolver, ParentType, ContextType>; diff --git a/opencti-platform/opencti-graphql/src/modules/notification/notification-domain.ts b/opencti-platform/opencti-graphql/src/modules/notification/notification-domain.ts index ce9b9909ffeab..04d341910f382 100644 --- a/opencti-platform/opencti-graphql/src/modules/notification/notification-domain.ts +++ b/opencti-platform/opencti-graphql/src/modules/notification/notification-domain.ts @@ -57,24 +57,6 @@ import { ForbiddenAccess, UnsupportedError } from '../../config/errors'; import { ENTITY_TYPE_GROUP, ENTITY_TYPE_USER } from '../../schema/internalObject'; import { ENTITY_TYPE_IDENTITY_ORGANIZATION } from '../organization/organization-types'; -// Outcomes - -export const batchResolvedInstanceFilters = async (context: AuthContext, user: AuthUser, instanceFiltersIds: string[]) => { - const instanceIds = instanceFiltersIds.map((u) => (Array.isArray(u) ? u : [u])); - const allInstanceIds = instanceIds.flat(); - const instanceToFinds = R.uniq(allInstanceIds.filter((u) => isNotEmptyField(u))); - const instances = await elFindByIds(context, user, instanceToFinds, { toMap: true }) as BasicStoreObject[]; - return instanceIds - .map((ids) => ids - .map((id) => [ - id, - Object.keys(instances).includes(id), - instances[id] ? extractEntityRepresentativeName(instances[id]) : '', - ])); -}; - -const resolvedInstanceFiltersLoader = batchLoader(batchResolvedInstanceFilters); - // Triggers // Due to engine limitation we restrict the recipient to only one user for now const extractUniqRecipient = async ( @@ -242,21 +224,6 @@ export const triggerDelete = async (context: AuthContext, user: AuthUser, trigge }); return triggerId; }; - -export const resolvedInstanceFiltersGet = async (context: AuthContext, user: AuthUser, trigger: BasicStoreEntityLiveTrigger | BasicStoreEntityTrigger) => { - if (trigger.trigger_type === 'live') { - const filters = trigger.trigger_type === 'live' ? JSON.parse((trigger as BasicStoreEntityLiveTrigger).filters) : {}; - const instanceFilters = ENTITY_FILTERS.map((n) => filters[n]).filter((el) => el); - const instanceFiltersIds = instanceFilters.flat().map((instanceFilter) => instanceFilter.id); - const resolvedInstanceFilters = await resolvedInstanceFiltersLoader.load(instanceFiltersIds, context, user) as [string, boolean, string | undefined][]; - return resolvedInstanceFilters.map((n) => { - const [id, valid, value] = n; - return { id, valid, value }; - }); - } - return []; -}; - export const triggersKnowledgeFind = (context: AuthContext, user: AuthUser, opts: QueryTriggersKnowledgeArgs) => { // key is a string[] because of the resolver, we have updated the keys const finalFilter = []; diff --git a/opencti-platform/opencti-graphql/src/modules/notification/notification-resolver.ts b/opencti-platform/opencti-graphql/src/modules/notification/notification-resolver.ts index 671bcf7a64703..ff33b0bb01e5a 100644 --- a/opencti-platform/opencti-graphql/src/modules/notification/notification-resolver.ts +++ b/opencti-platform/opencti-graphql/src/modules/notification/notification-resolver.ts @@ -15,7 +15,6 @@ import { notificationEditRead, notificationGet, notificationsFind, - resolvedInstanceFiltersGet, triggerActivityEdit, triggerDelete, triggerEdit, @@ -51,9 +50,6 @@ const notificationResolvers: Resolvers = { isDirectAdministrator: (trigger, _, context) => isDirectAdministrator(context.user, trigger), currentUserAccessRight: (trigger, _, context) => getUserAccessRight(context.user, trigger), notifiers: (trigger, _, context) => getNotifiers(context, context.user, trigger.notifiers), - resolved_instance_filters: (trigger: BasicStoreEntityLiveTrigger | BasicStoreEntityTrigger, _, context) => { - return resolvedInstanceFiltersGet(context, context.user, trigger); - }, }, TriggerFilter: { user_ids: 'authorized_members.id', diff --git a/opencti-platform/opencti-graphql/src/modules/notification/notification.graphql b/opencti-platform/opencti-graphql/src/modules/notification/notification.graphql index 32eea219efa67..4fce40ede8f1e 100644 --- a/opencti-platform/opencti-graphql/src/modules/notification/notification.graphql +++ b/opencti-platform/opencti-graphql/src/modules/notification/notification.graphql @@ -86,7 +86,6 @@ type Trigger implements InternalObject & BasicObject { isDirectAdministrator: Boolean currentUserAccessRight: String instance_trigger: Boolean - resolved_instance_filters: [ResolvedInstanceFilter!] } type TriggerConnection { pageInfo: PageInfo! diff --git a/opencti-platform/opencti-graphql/src/resolvers/stixCoreObject.js b/opencti-platform/opencti-graphql/src/resolvers/stixCoreObject.js index 4021f394ad4be..d08a86afc0f3f 100644 --- a/opencti-platform/opencti-graphql/src/resolvers/stixCoreObject.js +++ b/opencti-platform/opencti-graphql/src/resolvers/stixCoreObject.js @@ -12,7 +12,7 @@ import { batchOpinions, batchReports, findAll, - findById, findFiltersRepresentatives, + findById, findFilterRepresentative, findFiltersRepresentatives, stixCoreObjectAddRelation, stixCoreObjectAddRelations, stixCoreObjectCleanContext, @@ -81,6 +81,7 @@ const stixCoreObjectResolvers = { }, stixCoreObjectsMultiDistribution: (_, args, context) => stixCoreObjectsMultiDistribution(context, context.user, args), stixCoreObjectsExportFiles: (_, { type, first }, context) => filesListing(context, context.user, first, `export/${type}/`), + filterRepresentative: (_, { filter }, context) => findFilterRepresentative(context, context.user, filter), filtersRepresentatives: (_, { filters }, context) => findFiltersRepresentatives(context, context.user, filters), }, StixCoreObjectsFilter: stixCoreObjectOptions.StixCoreObjectsFilter,