From 02fc2219c3e9ea5f0fd4aa70de2e62b58de185f0 Mon Sep 17 00:00:00 2001 From: Verbose Cat <166016581+VerboseCat@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:58:14 -0400 Subject: [PATCH] Convert Sectors closer to original component --- .../private/components/entities/Sectors.jsx | 87 +++++++++++ .../private/components/entities/Sectors.tsx | 124 ---------------- .../entities/sectors/SectorsLines.jsx | 140 ++++++++++++++++++ .../entities/sectors/SectorsLines.tsx | 111 -------------- 4 files changed, 227 insertions(+), 235 deletions(-) create mode 100644 opencti-platform/opencti-front/src/private/components/entities/Sectors.jsx delete mode 100644 opencti-platform/opencti-front/src/private/components/entities/Sectors.tsx create mode 100644 opencti-platform/opencti-front/src/private/components/entities/sectors/SectorsLines.jsx delete mode 100644 opencti-platform/opencti-front/src/private/components/entities/sectors/SectorsLines.tsx diff --git a/opencti-platform/opencti-front/src/private/components/entities/Sectors.jsx b/opencti-platform/opencti-front/src/private/components/entities/Sectors.jsx new file mode 100644 index 0000000000000..696b359d47675 --- /dev/null +++ b/opencti-platform/opencti-front/src/private/components/entities/Sectors.jsx @@ -0,0 +1,87 @@ +import React, { useState, useEffect } from 'react'; +import * as PropTypes from 'prop-types'; +import { useNavigate, useLocation } from 'react-router-dom'; +import { QueryRenderer } from '../../../relay/environment'; +import { buildViewParamsFromUrlAndStorage, saveViewParameters } from '../../../utils/ListParameters'; +import { useFormatter } from '../../../components/i18n'; +import SectorsLines, { sectorsLinesQuery } from './sectors/SectorsLines'; +import SectorCreation from './sectors/SectorCreation'; +import SearchInput from '../../../components/SearchInput'; +import Security from '../../../utils/Security'; +import { KNOWLEDGE_KNUPDATE } from '../../../utils/hooks/useGranted'; +import Breadcrumbs from '../../../components/Breadcrumbs'; +import useConnectedDocumentModifier from '../../../utils/hooks/useConnectedDocumentModifier'; + +const LOCAL_STORAGE_KEY = 'sectors'; + +const Sectors = () => { + const { t_i18n } = useFormatter(); + const { setTitle } = useConnectedDocumentModifier(); + setTitle(t_i18n('Sectors | Entities')); + const navigate = useNavigate(); + const location = useLocation(); + const params = buildViewParamsFromUrlAndStorage( + navigate, + location, + LOCAL_STORAGE_KEY, + ); + + const [sectorsState, setSectorsState] = useState({ + searchTerm: params.searchTerm ?? '', + openExports: false, + }); + + const saveView = () => { + saveViewParameters( + navigate, + location, + LOCAL_STORAGE_KEY, + sectorsState, + ); + }; + + const handleSearch = (value) => { + setSectorsState({ ...sectorsState, + searchTerm: value, + }); + }; + + useEffect(() => { + saveView(); + }, [sectorsState]); + + return ( + <> + +
+ +
+ + + +
+
+
+ ( + + )} + /> + + ); +}; + +Sectors.propTypes = { + t: PropTypes.func, + navigate: PropTypes.func, + location: PropTypes.object, +}; + +export default Sectors; diff --git a/opencti-platform/opencti-front/src/private/components/entities/Sectors.tsx b/opencti-platform/opencti-front/src/private/components/entities/Sectors.tsx deleted file mode 100644 index 9027e3b6ed495..0000000000000 --- a/opencti-platform/opencti-front/src/private/components/entities/Sectors.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import React from 'react'; -import { SectorLineDummy } from '@components/entities/sectors/SectorLine'; -import { SectorsLinesPaginationQuery, SectorsLinesPaginationQuery$variables } from './sectors/__generated__/SectorsLinesPaginationQuery.graphql'; -import useHelper from '../../../utils/hooks/useHelper'; -import ListLines from '../../../components/list_lines/ListLines'; -import SectorsLines, { sectorsLinesQuery } from './sectors/SectorsLines'; -import SectorCreation from './sectors/SectorCreation'; -import Security from '../../../utils/Security'; -import { KNOWLEDGE_KNUPDATE } from '../../../utils/hooks/useGranted'; -import { usePaginationLocalStorage } from '../../../utils/hooks/useLocalStorage'; -import useQueryLoading from '../../../utils/hooks/useQueryLoading'; -import { emptyFilterGroup } from '../../../utils/filters/filtersUtils'; -import { useFormatter } from '../../../components/i18n'; -import Breadcrumbs from '../../../components/Breadcrumbs'; -import useConnectedDocumentModifier from '../../../utils/hooks/useConnectedDocumentModifier'; - -const LOCAL_STORAGE_KEY = 'sectors'; - -const Sectors = () => { - const { t_i18n } = useFormatter(); - const { setTitle } = useConnectedDocumentModifier(); - setTitle(t_i18n('Sectors | Entities')); - const { isFeatureEnable } = useHelper(); - const isFABReplaced = isFeatureEnable('FAB_REPLACEMENT'); - const { viewStorage, helpers, paginationOptions } = usePaginationLocalStorage( - LOCAL_STORAGE_KEY, - { - searchTerm: '', - sortBy: 'name', - orderAsc: true, - openExports: false, - filters: emptyFilterGroup, - }, - ); - const renderLines = () => { - const { - searchTerm, - sortBy, - orderAsc, - filters, - openExports, - numberOfElements, - } = viewStorage; - const dataColumns = { - name: { - label: 'Name', - width: '23%', - isSortable: true, - }, - description: { - label: 'Description', - width: '23%', - isSortable: true, - }, - }; - const queryRef = useQueryLoading( - sectorsLinesQuery, - paginationOptions, - ); - return ( - - - } - > - {queryRef && ( - - {Array(20) - .fill(0) - .map((_, idx) => ( - - ))} - - } - > - - - )} - - ); - }; - - return ( - <> - - {renderLines()} - {!isFABReplaced - && - - - } - - ); -}; - -export default Sectors; diff --git a/opencti-platform/opencti-front/src/private/components/entities/sectors/SectorsLines.jsx b/opencti-platform/opencti-front/src/private/components/entities/sectors/SectorsLines.jsx new file mode 100644 index 0000000000000..979f6a9ce8a6d --- /dev/null +++ b/opencti-platform/opencti-front/src/private/components/entities/sectors/SectorsLines.jsx @@ -0,0 +1,140 @@ +import React, { Component } from 'react'; +import * as PropTypes from 'prop-types'; +import { compose, pipe, map, pathOr, sortBy, toLower, prop, filter, join, assoc } from 'ramda'; +import { graphql, createPaginationContainer } from 'react-relay'; +import withStyles from '@mui/styles/withStyles'; +import List from '@mui/material/List'; +import { SectorLine, SectorLineDummy } from './SectorLine'; +import inject18n from '../../../../components/i18n'; + +const styles = () => ({ + root: { + margin: 0, + }, +}); + +class SectorsLinesComponent extends Component { + render() { + const { data, keyword, classes } = this.props; + const sortByNameCaseInsensitive = sortBy(compose(toLower, prop('name'))); + const filterSubsector = (n) => n.isSubSector === false; + const filterByKeyword = (n) => keyword === '' + || n.name.toLowerCase().indexOf(keyword.toLowerCase()) !== -1 + || (n.description ?? '').toLowerCase().indexOf(keyword.toLowerCase()) + !== -1 + || (n.subsectors_text ?? '').toLowerCase().indexOf(keyword.toLowerCase()) + !== -1; + const sectors = pipe( + pathOr([], ['sectors', 'edges']), + map((n) => n.node), + map((n) => assoc( + 'subsectors_text', + pipe( + map((o) => `${o.node.name} ${o.node.description}`), + join(' | '), + )(pathOr([], ['subSectors', 'edges'], n)), + n, + )), + filter(filterSubsector), + filter(filterByKeyword), + sortByNameCaseInsensitive, + )(data); + return ( + + {data + ? map((sector) => { + const subSectors = pipe( + pathOr([], ['subSectors', 'edges']), + map((n) => n.node), + filter(filterByKeyword), + sortByNameCaseInsensitive, + )(sector); + return ( + + ); + }, sectors) + : Array.from(Array(20), (e, i) => )} + + ); + } +} + +SectorsLinesComponent.propTypes = { + classes: PropTypes.object, + keyword: PropTypes.string, + data: PropTypes.object, +}; + +export const sectorsLinesQuery = graphql` + query SectorsLinesPaginationQuery($count: Int!, $cursor: ID) { + ...SectorsLines_data @arguments(count: $count, cursor: $cursor) + } +`; + +const SectorsLinesFragment = createPaginationContainer( + SectorsLinesComponent, + { + data: graphql` + fragment SectorsLines_data on Query + @argumentDefinitions( + count: { type: "Int", defaultValue: 25 } + cursor: { type: "ID" } + ) { + sectors(first: $count, after: $cursor) + @connection(key: "Pagination_sectors") { + edges { + node { + id + name + description + isSubSector + subSectors { + edges { + node { + id + name + description + } + } + } + } + } + pageInfo { + endCursor + hasNextPage + globalCount + } + } + } + `, + }, + { + direction: 'forward', + getConnectionFromProps(props) { + return props.data && props.data.sectors; + }, + getFragmentVariables(prevVars, totalCount) { + return { + ...prevVars, + count: totalCount, + }; + }, + getVariables(props, { count, cursor }) { + return { + count, + cursor, + }; + }, + query: sectorsLinesQuery, + }, +); + +export default compose(inject18n, withStyles(styles))(SectorsLinesFragment); diff --git a/opencti-platform/opencti-front/src/private/components/entities/sectors/SectorsLines.tsx b/opencti-platform/opencti-front/src/private/components/entities/sectors/SectorsLines.tsx deleted file mode 100644 index 0f0b78543fa52..0000000000000 --- a/opencti-platform/opencti-front/src/private/components/entities/sectors/SectorsLines.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import React, { FunctionComponent } from 'react'; -import { graphql, PreloadedQuery } from 'react-relay'; -import { SectorsLinesPaginationQuery, SectorsLinesPaginationQuery$variables } from '@components/entities/sectors/__generated__/SectorsLinesPaginationQuery.graphql'; -import { SectorsLines_data$key } from './__generated__/SectorsLines_data.graphql'; -import ListLinesContent from '../../../../components/list_lines/ListLinesContent'; -import { SectorLine, SectorLineDummy } from './SectorLine'; -import { DataColumns } from '../../../../components/list_lines'; -import { HandleAddFilter, UseLocalStorageHelpers } from '../../../../utils/hooks/useLocalStorage'; -import usePreloadedPaginationFragment from '../../../../utils/hooks/usePreloadedPaginationFragment'; - -const nbOfRowsToLoad = 50; - -interface SectorsLinesProps { - queryRef: PreloadedQuery; - dataColumns: DataColumns; - paginationOptions?: SectorsLinesPaginationQuery$variables; - setNumberOfElements: UseLocalStorageHelpers['handleSetNumberOfElements']; - onLabelClick: HandleAddFilter; -} - -export const sectorsLinesQuery = graphql` - query SectorsLinesPaginationQuery( - $search: String - $count: Int! - $cursor: ID - $orderBy: SectorsOrdering - $filters: FilterGroup - ) { - ...SectorsLines_data - @arguments( - search: $search - count: $count - cursor: $cursor - orderBy: $orderBy - filters: $filters - ) - } -`; - -export const sectorsLinesFragment = graphql` - fragment SectorsLines_data on Query - @argumentDefinitions( - search: { type: "String" } - count: { type: "Int", defaultValue: 25 } - cursor: { type: "ID" } - orderBy: { type: "SectorsOrdering", defaultValue: name } - filters: { type: "FilterGroup" } - ) - @refetchable(queryName: "SectorsLinesRefetchQuery") { - sectors( - search: $search - first: $count - after: $cursor - orderBy: $orderBy - filters: $filters - ) @connection(key: "Pagination_sectors") { - edges { - node { - id - name - description - } - } - pageInfo { - endCursor - hasNextPage - globalCount - } - } - } -`; - -const SectorsLines: FunctionComponent = ({ - setNumberOfElements, - queryRef, - dataColumns, - paginationOptions, - onLabelClick, -}) => { - const { data, hasMore, loadMore, isLoadingMore } = usePreloadedPaginationFragment< - SectorsLinesPaginationQuery, - SectorsLines_data$key - >({ - linesQuery: sectorsLinesQuery, - linesFragment: sectorsLinesFragment, - queryRef, - nodePath: ['sectors', 'pageInfo', 'globalCount'], - setNumberOfElements, - }); - - return ( - - ); -}; - -export default SectorsLines;