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;