From 3ee8bebbe96eef07f5827103dbbfacc196ced32d Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Tue, 24 Mar 2026 10:59:52 +0100 Subject: [PATCH] use commons-ui to display netmods through tanstack Signed-off-by: Mathieu DEHARBE --- .../network-modification-menu.type.ts | 5 - .../network-modification-node-editor.tsx | 2 +- ...lumns-definition.tsx => createColumns.tsx} | 82 ++------ .../network-modifications-table.tsx | 31 +-- .../renderers/description-cell.tsx | 8 +- .../renderers/drag-handle-cell.tsx | 21 -- .../renderers/name-cell.tsx | 40 ---- ...k-modification-node-editor-name-header.tsx | 76 ------- .../renderers/root-network-chip-cell.tsx | 12 +- .../renderers/select-cell.tsx | 80 ------- .../renderers/select-header-cell.tsx | 40 ---- .../row/drag-row-clone.tsx | 31 --- .../row/modification-row.tsx | 69 ------ .../network-modification-table/styles.ts | 199 ------------------ .../use-modifications-drag-and-drop.tsx | 81 ------- src/services/study/network-modifications.ts | 2 +- 16 files changed, 58 insertions(+), 721 deletions(-) rename src/components/graph/menus/network-modifications/network-modification-table/{columns-definition.tsx => createColumns.tsx} (69%) delete mode 100644 src/components/graph/menus/network-modifications/network-modification-table/renderers/drag-handle-cell.tsx delete mode 100644 src/components/graph/menus/network-modifications/network-modification-table/renderers/name-cell.tsx delete mode 100644 src/components/graph/menus/network-modifications/network-modification-table/renderers/network-modification-node-editor-name-header.tsx delete mode 100644 src/components/graph/menus/network-modifications/network-modification-table/renderers/select-cell.tsx delete mode 100644 src/components/graph/menus/network-modifications/network-modification-table/renderers/select-header-cell.tsx delete mode 100644 src/components/graph/menus/network-modifications/network-modification-table/row/drag-row-clone.tsx delete mode 100644 src/components/graph/menus/network-modifications/network-modification-table/row/modification-row.tsx delete mode 100644 src/components/graph/menus/network-modifications/network-modification-table/styles.ts delete mode 100644 src/components/graph/menus/network-modifications/network-modification-table/use-modifications-drag-and-drop.tsx diff --git a/src/components/graph/menus/network-modifications/network-modification-menu.type.ts b/src/components/graph/menus/network-modifications/network-modification-menu.type.ts index e7c1d3e216..96dd732473 100644 --- a/src/components/graph/menus/network-modifications/network-modification-menu.type.ts +++ b/src/components/graph/menus/network-modifications/network-modification-menu.type.ts @@ -33,11 +33,6 @@ export interface CaseInfos { caseFormat: string | null; } -export interface ExcludedNetworkModifications { - rootNetworkUuid: UUID; - modificationUuidsToExclude: UUID[]; -} - export enum NetworkModificationCopyType { COPY = 'COPY', MOVE = 'MOVE', diff --git a/src/components/graph/menus/network-modifications/network-modification-node-editor.tsx b/src/components/graph/menus/network-modifications/network-modification-node-editor.tsx index a1fea8ff9f..d8daf666bd 100644 --- a/src/components/graph/menus/network-modifications/network-modification-node-editor.tsx +++ b/src/components/graph/menus/network-modifications/network-modification-node-editor.tsx @@ -9,6 +9,7 @@ import { ElementSaveDialog, ElementType, EquipmentType, + ExcludedNetworkModifications, fetchNetworkModification, IElementCreationDialog, IElementUpdateDialog, @@ -82,7 +83,6 @@ import { stashModifications, } from '../../../../services/study/network-modifications'; import { - ExcludedNetworkModifications, MenuDefinitionSubItem, MenuDefinitionWithoutSubItem, MenuSection, diff --git a/src/components/graph/menus/network-modifications/network-modification-table/columns-definition.tsx b/src/components/graph/menus/network-modifications/network-modification-table/createColumns.tsx similarity index 69% rename from src/components/graph/menus/network-modifications/network-modification-table/columns-definition.tsx rename to src/components/graph/menus/network-modifications/network-modification-table/createColumns.tsx index a8a28e6d71..9a01de4c7c 100644 --- a/src/components/graph/menus/network-modifications/network-modification-table/columns-definition.tsx +++ b/src/components/graph/menus/network-modifications/network-modification-table/createColumns.tsx @@ -1,67 +1,31 @@ -/* +/** * Copyright (c) 2026, RTE (http://www.rte-france.com) * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -import React, { SetStateAction } from 'react'; -import { Badge, Box } from '@mui/material'; -import { NetworkModificationMetadata } from '@gridsuite/commons-ui'; -import { ColumnDef } from '@tanstack/react-table'; -import DragHandleCell from './renderers/drag-handle-cell'; import { + BASE_MODIFICATION_TABLE_COLUMNS, + computeTagMinSize, + createRootNetworkChipCellSx, + DragHandleCell, + ExcludedNetworkModifications, + NameCell, + NameHeaderProps, NetworkModificationEditorNameHeader, - NetworkModificationEditorNameHeaderProps, -} from './renderers/network-modification-node-editor-name-header'; -import NameCell from './renderers/name-cell'; + NetworkModificationMetadata, + networkTableStyles, + SelectCell, + SelectHeaderCell, +} from '@gridsuite/commons-ui'; +import React, { SetStateAction } from 'react'; +import { ColumnDef } from '@tanstack/react-table'; import DescriptionCell from './renderers/description-cell'; import SwitchCell from './renderers/switch-cell'; -import { ExcludedNetworkModifications, RootNetworkMetadata } from '../network-modification-menu.type'; -import RootNetworkChipCell from './renderers/root-network-chip-cell'; +import { RootNetworkMetadata } from '../network-modification-menu.type'; +import { Badge, Box } from '@mui/material'; import { RemoveRedEye as RemoveRedEyeIcon } from '@mui/icons-material'; -import SelectCell from './renderers/select-cell'; -import SelectHeaderCell from './renderers/select-header-cell'; -import { createRootNetworkChipCellSx, styles } from './styles'; - -const CHIP_PADDING_PX = 24; -const CHAR_WIDTH_PX = 8; -const COLUMN_PADDING_PX = 12; -const MIN_COLUMN_SIZE = 40; - -const computeTagMinSize = (tag: string): number => { - const chipContentWidth = tag.length * CHAR_WIDTH_PX + CHIP_PADDING_PX; - return Math.max(chipContentWidth + COLUMN_PADDING_PX, MIN_COLUMN_SIZE); -}; - -export const BASE_MODIFICATION_TABLE_COLUMNS = { - DRAG_HANDLE: { - id: 'dragHandle', - autoExtensible: false, - }, - SELECT: { - id: 'select', - autoExtensible: false, - }, - NAME: { - id: 'modificationName', - autoExtensible: true, - }, - DESCRIPTION: { - id: 'modificationDescription', - autoExtensible: false, - }, - SWITCH: { - id: 'switch', - autoExtensible: false, - }, -}; - -export const AUTO_EXTENSIBLE_COLUMNS = Object.values(BASE_MODIFICATION_TABLE_COLUMNS) - .filter((column) => column.autoExtensible) - .map((column) => column.id); - -type NameHeaderProps = Omit; +import RootNetworkChipCell from './renderers/root-network-chip-cell'; /** * Column definition is broken up in 2 parts : base columns which are always on display and root networks columns. @@ -77,7 +41,7 @@ export const createBaseColumns = ( ): ColumnDef[] => [ { id: BASE_MODIFICATION_TABLE_COLUMNS.DRAG_HANDLE.id, - cell: () => , + cell: () => , size: 24, minSize: 24, meta: { @@ -93,7 +57,7 @@ export const createBaseColumns = ( size: 32, minSize: 32, meta: { - cellStyle: styles.columnCell.select, + cellStyle: networkTableStyles.columnCell.select, }, }, { @@ -103,7 +67,7 @@ export const createBaseColumns = ( ), cell: ({ row }) => , meta: { - cellStyle: styles.columnCell.modificationName, + cellStyle: networkTableStyles.columnCell.modificationName, }, minSize: 160, }, @@ -145,7 +109,7 @@ export const createRootNetworksColumns = ( id: rootNetworkUuid, header: () => isCurrentRootNetwork && modificationsCount >= 1 ? ( - + @@ -164,7 +128,7 @@ export const createRootNetworksColumns = ( size: sharedSize, minSize: tagMinSize, meta: { - cellStyle: styles.columnCell.rootNetworkChip, + cellStyle: networkTableStyles.columnCell.rootNetworkChip, }, }; }); diff --git a/src/components/graph/menus/network-modifications/network-modification-table/network-modifications-table.tsx b/src/components/graph/menus/network-modifications/network-modification-table/network-modifications-table.tsx index ddc64cba06..af8eae0cff 100644 --- a/src/components/graph/menus/network-modifications/network-modification-table/network-modifications-table.tsx +++ b/src/components/graph/menus/network-modifications/network-modification-table/network-modifications-table.tsx @@ -6,20 +6,25 @@ */ import React, { Dispatch, FunctionComponent, SetStateAction, useEffect, useMemo, useRef } from 'react'; -import { NetworkModificationMetadata } from '@gridsuite/commons-ui'; +import { + AUTO_EXTENSIBLE_COLUMNS, + createHeaderCellStyle, + ExcludedNetworkModifications, + MODIFICATION_ROW_HEIGHT, + ModificationRow, + NetworkModificationEditorNameHeaderProps, + NetworkModificationMetadata, + networkTableStyles, + useModificationsDragAndDrop, +} from '@gridsuite/commons-ui'; import { Box, Table, TableBody, TableCell, TableHead, TableRow } from '@mui/material'; import { useSelector } from 'react-redux'; import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'; import { DragDropContext, DragStart, Droppable, DroppableProvided, DropResult } from '@hello-pangea/dnd'; import { useVirtualizer } from '@tanstack/react-virtual'; -import { NetworkModificationEditorNameHeaderProps } from './renderers/network-modification-node-editor-name-header'; -import { ExcludedNetworkModifications } from '../network-modification-menu.type'; -import { createHeaderCellStyle, MODIFICATION_ROW_HEIGHT, styles } from './styles'; -import { AUTO_EXTENSIBLE_COLUMNS, createBaseColumns, createRootNetworksColumns } from './columns-definition'; -import ModificationRow from './row/modification-row'; import { useTheme } from '@mui/material/styles'; -import { useModificationsDragAndDrop } from './use-modifications-drag-and-drop'; import { AppState } from '../../../../../redux/reducer.type'; +import { createBaseColumns, createRootNetworksColumns } from './createColumns'; interface NetworkModificationsTableProps extends Omit { modifications: NetworkModificationMetadata[]; @@ -126,14 +131,14 @@ const NetworkModificationsTable: FunctionComponent - + {(provided: DroppableProvided) => ( - - - + +
+ {table.getHeaderGroups().map((headerGroup) => ( - + {headerGroup.headers.map((header) => ( {virtualItems.map((virtualRow) => { const row = rows[virtualRow.index]; diff --git a/src/components/graph/menus/network-modifications/network-modification-table/renderers/description-cell.tsx b/src/components/graph/menus/network-modifications/network-modification-table/renderers/description-cell.tsx index 4e39b3401e..7ddb7e860c 100644 --- a/src/components/graph/menus/network-modifications/network-modification-table/renderers/description-cell.tsx +++ b/src/components/graph/menus/network-modifications/network-modification-table/renderers/description-cell.tsx @@ -4,13 +4,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { DescriptionModificationDialog, EditNoteIcon, NetworkModificationMetadata } from '@gridsuite/commons-ui'; +import { + createEditDescriptionStyle, + DescriptionModificationDialog, + EditNoteIcon, + NetworkModificationMetadata, +} from '@gridsuite/commons-ui'; import { FunctionComponent, useCallback, useState } from 'react'; import { Tooltip } from '@mui/material'; import { useSelector } from 'react-redux'; import IconButton from '@mui/material/IconButton'; import { useIsAnyNodeBuilding } from '../../../../../utils/is-any-node-building-hook'; -import { createEditDescriptionStyle } from '../styles'; import { setModificationMetadata } from '../../../../../../services/study/network-modifications'; import { AppState } from '../../../../../../redux/reducer.type'; diff --git a/src/components/graph/menus/network-modifications/network-modification-table/renderers/drag-handle-cell.tsx b/src/components/graph/menus/network-modifications/network-modification-table/renderers/drag-handle-cell.tsx deleted file mode 100644 index e7f32e1206..0000000000 --- a/src/components/graph/menus/network-modifications/network-modification-table/renderers/drag-handle-cell.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import DragIndicatorIcon from '@mui/icons-material/DragIndicator'; -import { Box } from '@mui/material'; -import { styles } from '../styles'; -import { FunctionComponent } from 'react'; - -const DragHandleCell: FunctionComponent<{ isRowDragDisabled: boolean }> = ({ isRowDragDisabled }) => { - return ( - - {!isRowDragDisabled && } - - ); -}; - -export default DragHandleCell; diff --git a/src/components/graph/menus/network-modifications/network-modification-table/renderers/name-cell.tsx b/src/components/graph/menus/network-modifications/network-modification-table/renderers/name-cell.tsx deleted file mode 100644 index f58f83a568..0000000000 --- a/src/components/graph/menus/network-modifications/network-modification-table/renderers/name-cell.tsx +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import React, { FunctionComponent, useCallback, useMemo } from 'react'; -import { Row } from '@tanstack/react-table'; -import { mergeSx, NetworkModificationMetadata, useModificationLabelComputer } from '@gridsuite/commons-ui'; -import { useIntl } from 'react-intl'; -import { Box, Tooltip } from '@mui/material'; -import { createModificationNameCellStyle, styles } from '../styles'; - -const NameCell: FunctionComponent<{ row: Row }> = ({ row }) => { - const intl = useIntl(); - const { computeLabel } = useModificationLabelComputer(); - - const getModificationLabel = useCallback( - (modification: NetworkModificationMetadata, formatBold: boolean = true) => { - return intl.formatMessage( - { id: `network_modifications.${modification.messageType}` }, - { ...modification, ...computeLabel(modification, formatBold) } - ); - }, - [computeLabel, intl] - ); - - const label = useMemo(() => getModificationLabel(row.original), [getModificationLabel, row.original]); - - return ( - - - {label} - - - ); -}; - -export default NameCell; diff --git a/src/components/graph/menus/network-modifications/network-modification-table/renderers/network-modification-node-editor-name-header.tsx b/src/components/graph/menus/network-modifications/network-modification-table/renderers/network-modification-node-editor-name-header.tsx deleted file mode 100644 index a6f2822515..0000000000 --- a/src/components/graph/menus/network-modifications/network-modification-table/renderers/network-modification-node-editor-name-header.tsx +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright (c) 2025, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { Box, CircularProgress, Typography } from '@mui/material'; -import { FormattedMessage } from 'react-intl'; -import { styles } from '../../network-modification-node-editor-utils'; -import { FunctionComponent } from 'react'; - -export interface NetworkModificationEditorNameHeaderProps { - modificationCount?: number; - notificationMessageId?: string; - isFetchingModifications: boolean; - isImpactedByNotification: () => boolean; - pendingState: boolean; -} - -export const NetworkModificationEditorNameHeader: FunctionComponent = ( - props -) => { - const { - modificationCount, - isFetchingModifications, - isImpactedByNotification, - notificationMessageId, - pendingState, - } = props; - - if (isImpactedByNotification() && notificationMessageId) { - return ( - - - - - - - - - ); - } - - if (isFetchingModifications) { - return ( - - - - - - - - - ); - } - - return ( - - {pendingState && ( - - - - )} - - - - - ); -}; diff --git a/src/components/graph/menus/network-modifications/network-modification-table/renderers/root-network-chip-cell.tsx b/src/components/graph/menus/network-modifications/network-modification-table/renderers/root-network-chip-cell.tsx index 876c57d236..19272e6164 100644 --- a/src/components/graph/menus/network-modifications/network-modification-table/renderers/root-network-chip-cell.tsx +++ b/src/components/graph/menus/network-modifications/network-modification-table/renderers/root-network-chip-cell.tsx @@ -5,11 +5,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { useState, useCallback, useMemo, SetStateAction, FunctionComponent } from 'react'; -import { ActivableChip, NetworkModificationMetadata, snackWithFallback, useSnackMessage } from '@gridsuite/commons-ui'; +import React, { useState, useCallback, useMemo, SetStateAction, FunctionComponent } from 'react'; +import { + ActivableChip, + ExcludedNetworkModifications, + NetworkModificationMetadata, + snackWithFallback, + useSnackMessage, +} from '@gridsuite/commons-ui'; import { updateModificationStatusByRootNetwork } from 'services/study/network-modifications'; import { useSelector } from 'react-redux'; -import { ExcludedNetworkModifications, RootNetworkMetadata } from '../../network-modification-menu.type'; +import { RootNetworkMetadata } from '../../network-modification-menu.type'; import { useIsAnyNodeBuilding } from 'components/utils/is-any-node-building-hook'; import type { UUID } from 'node:crypto'; import { AppState } from '../../../../../../redux/reducer.type'; diff --git a/src/components/graph/menus/network-modifications/network-modification-table/renderers/select-cell.tsx b/src/components/graph/menus/network-modifications/network-modification-table/renderers/select-cell.tsx deleted file mode 100644 index a9f92c88ff..0000000000 --- a/src/components/graph/menus/network-modifications/network-modification-table/renderers/select-cell.tsx +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import React, { FunctionComponent, useCallback } from 'react'; -import { Checkbox } from '@mui/material'; -import { Row, Table } from '@tanstack/react-table'; -import { NetworkModificationMetadata } from '@gridsuite/commons-ui'; -import { styles } from '../styles'; - -interface SelectCellRendererProps { - row: Row; - table: Table; -} - -const SelectCell: FunctionComponent = ({ row, table }) => { - const meta = table.options.meta; - - const handleChange = useCallback( - (event: React.MouseEvent) => { - const rows = table.getRowModel().rows; - const currentIndex = row.index; - const nextSelection = { ...table.getState().rowSelection }; - - // When shift is held and a previous click exists, select or deselect the contiguous range between - // the two clicks instead of toggling a single row. - if ( - event.shiftKey && - meta?.lastClickedIndex.current !== null && - meta?.lastClickedIndex.current !== undefined - ) { - const lastIndex = meta.lastClickedIndex.current; - const [from, to] = lastIndex < currentIndex ? [lastIndex, currentIndex] : [currentIndex, lastIndex]; - const isRowSelected = row.getIsSelected(); - - rows.slice(from, to + 1).forEach((r) => { - if (r.getCanSelect()) { - r.toggleSelected(!isRowSelected); - if (isRowSelected) { - delete nextSelection[r.id]; - } else { - nextSelection[r.id] = true; - } - } - }); - } else { - row.toggleSelected(); - if (row.getIsSelected()) { - // was selected, now toggled off - delete nextSelection[row.id]; - } else { - // was unselected, now toggled on - nextSelection[row.id] = true; - } - } - - if (meta) { - meta.lastClickedIndex.current = currentIndex; - const selectedRows = rows.filter((r) => nextSelection[r.id]).map((r) => r.original); - meta.onRowSelected?.(selectedRows); - } - }, - [table, row, meta] - ); - - return ( - - ); -}; - -export default SelectCell; diff --git a/src/components/graph/menus/network-modifications/network-modification-table/renderers/select-header-cell.tsx b/src/components/graph/menus/network-modifications/network-modification-table/renderers/select-header-cell.tsx deleted file mode 100644 index 62fd86a809..0000000000 --- a/src/components/graph/menus/network-modifications/network-modification-table/renderers/select-header-cell.tsx +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import React, { FunctionComponent, useCallback } from 'react'; -import { Checkbox } from '@mui/material'; -import { Table } from '@tanstack/react-table'; -import { NetworkModificationMetadata } from '@gridsuite/commons-ui'; - -interface SelectHeaderCellProps { - table: Table; -} - -const SelectHeaderCell: FunctionComponent = ({ table }) => { - const handleClick = useCallback(() => { - const meta = table.options.meta; - if (meta) { - const nextSelectedRows = table.getIsAllRowsSelected() - ? [] - : table.getCoreRowModel().rows.map((r) => r.original); - meta.onRowSelected?.(nextSelectedRows); - meta.lastClickedIndex.current = null; - } - table.toggleAllRowsSelected(); - }, [table]); - - return ( - - ); -}; - -export default SelectHeaderCell; diff --git a/src/components/graph/menus/network-modifications/network-modification-table/row/drag-row-clone.tsx b/src/components/graph/menus/network-modifications/network-modification-table/row/drag-row-clone.tsx deleted file mode 100644 index c58dba04ec..0000000000 --- a/src/components/graph/menus/network-modifications/network-modification-table/row/drag-row-clone.tsx +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { Box } from '@mui/material'; -import { NetworkModificationMetadata } from '@gridsuite/commons-ui'; -import { createCellStyle, styles } from '../styles'; -import { flexRender, Row } from '@tanstack/react-table'; -import { AUTO_EXTENSIBLE_COLUMNS, BASE_MODIFICATION_TABLE_COLUMNS } from '../columns-definition'; - -const DragCloneRow = ({ row }: { row: Row }) => ( - - {row - .getVisibleCells() - .filter((cell) => - [BASE_MODIFICATION_TABLE_COLUMNS.DRAG_HANDLE.id, BASE_MODIFICATION_TABLE_COLUMNS.NAME.id].includes( - cell.column.columnDef.id! - ) - ) - .map((cell) => ( - - {flexRender(cell.column.columnDef.cell, cell.getContext())} - - ))} - -); - -export default DragCloneRow; diff --git a/src/components/graph/menus/network-modifications/network-modification-table/row/modification-row.tsx b/src/components/graph/menus/network-modifications/network-modification-table/row/modification-row.tsx deleted file mode 100644 index a248501e70..0000000000 --- a/src/components/graph/menus/network-modifications/network-modification-table/row/modification-row.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import React, { memo, useCallback } from 'react'; -import { flexRender, Row } from '@tanstack/react-table'; -import { mergeSx, NetworkModificationMetadata } from '@gridsuite/commons-ui'; -import { TableCell, TableRow } from '@mui/material'; -import { createCellStyle, createRowSx, styles } from '../styles'; -import { Draggable, DraggableProvided, DraggableStateSnapshot } from '@hello-pangea/dnd'; -import { VirtualItem } from '@tanstack/react-virtual'; -import { AUTO_EXTENSIBLE_COLUMNS, BASE_MODIFICATION_TABLE_COLUMNS } from '../columns-definition'; - -interface ModificationRowProps { - virtualRow: VirtualItem; - row: Row; - handleCellClick?: (modification: NetworkModificationMetadata) => void; - isRowDragDisabled: boolean; - highlightedModificationUuid: string | null; -} - -const ModificationRow = memo( - ({ virtualRow, row, handleCellClick, isRowDragDisabled, highlightedModificationUuid }) => { - const isHighlighted = row.original.uuid === highlightedModificationUuid; - - const handleCellClickCallback = useCallback( - (columnId: string) => { - if (columnId === BASE_MODIFICATION_TABLE_COLUMNS.NAME.id) { - handleCellClick?.(row.original); - } - }, - [handleCellClick, row.original] - ); - - return ( - - {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => { - const { style, ...draggablePropsWithoutStyle } = provided.draggableProps; - return ( - - {row.getVisibleCells().map((cell) => ( - handleCellClickCallback(cell.column.id)} - {...(cell.column.id === BASE_MODIFICATION_TABLE_COLUMNS.DRAG_HANDLE.id - ? provided.dragHandleProps - : undefined)} - > - {flexRender(cell.column.columnDef.cell, cell.getContext())} - - ))} - - ); - }} - - ); - } -); - -export default ModificationRow; diff --git a/src/components/graph/menus/network-modifications/network-modification-table/styles.ts b/src/components/graph/menus/network-modifications/network-modification-table/styles.ts deleted file mode 100644 index d397c4cc63..0000000000 --- a/src/components/graph/menus/network-modifications/network-modification-table/styles.ts +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { MuiStyles } from '@gridsuite/commons-ui'; -import { VirtualItem } from '@tanstack/react-virtual'; -import { SxProps, Theme } from '@mui/material'; -import { alpha } from '@mui/material/styles'; -import { CSSProperties } from 'react'; - -const HIGHLIGHT_COLOR_BASE = 'rgba(144, 202, 249, 0.16)'; -const HIGHLIGHT_COLOR_HOVER = 'rgba(144, 202, 249, 0.24)'; -const ROW_HOVER_COLOR = 'rgba(144, 202, 249, 0.08)'; -const DRAG_OPACITY = 0.5; -const DEACTIVATED_OPACITY = 0.4; - -export const MODIFICATION_ROW_HEIGHT = 41; - -// Static styles - -export const styles = { - tableWrapper: (theme) => ({ - display: 'flex', - flexDirection: 'column', - flexGrow: 1, - margin: theme.spacing(1), - border: `1px solid ${theme.palette.divider}`, - overflow: 'hidden', - minHeight: 0, - }), - container: { - position: 'relative', - flexGrow: 1, - overflow: 'auto', - height: '100%', - }, - table: (theme) => ({ - width: '100%', - tableLayout: 'fixed', - borderCollapse: 'collapse', - backgroundColor: theme.palette.background.paper, - }), - thead: (theme) => ({ - backgroundColor: theme.palette.background.paper, - position: 'sticky', - top: 0, - zIndex: 1, - width: '100%', - '& tr:hover': { - backgroundColor: 'transparent', - }, - }), - tableRow: { - display: 'flex', - alignItems: 'center', - transition: 'none', - opacity: 1, - }, - tableBody: { - position: 'relative', - }, - tableCell: { - fontSize: 'small', - minWidth: 0, - display: 'flex', - }, - dragRowClone: (theme) => ({ - backgroundColor: 'background.paper', - boxShadow: 4, - opacity: 1, - border: '1px solid #f5f5f5', - display: 'flex', - width: 'fit-content', - paddingRight: theme.spacing(1), - }), - overflow: { - whiteSpace: 'pre', - textOverflow: 'ellipsis', - overflow: 'hidden', - }, - selectCheckBox: (theme) => ({ - padding: theme.spacing(0.8), - }), - dragHandle: (theme) => ({ - display: 'flex', - alignItems: 'center', - cursor: 'grab', - opacity: 0, - padding: theme.spacing(0.5), - 'tr:hover &': { opacity: 1 }, - }), - dragIndicatorIcon: { - width: '16px', - height: '16px', - }, - modificationLabel: { - textOverflow: 'ellipsis', - overflow: 'hidden', - whiteSpace: 'nowrap', - }, - rootNetworkHeader: { - width: '100%', - display: 'flex', - justifyContent: 'center', - }, - columnCell: { - select: { padding: 2, justifyContent: 'center' }, - modificationName: { cursor: 'pointer', minWidth: 0, overflow: 'hidden', flex: 1 }, - rootNetworkChip: { textAlign: 'center' }, - }, -} as const satisfies MuiStyles; - -// Dynamic styles - -export const DROP_INDICATOR_TOP = 'inset 0 2px 0 #90caf9'; -export const DROP_INDICATOR_BOTTOM = 'inset 0 -2px 0 #90caf9'; - -export const createRowSx = (isHighlighted: boolean, isDragging: boolean, virtualRow: VirtualItem): SxProps => ({ - position: 'absolute', - top: 0, - left: 0, - right: 0, - width: '100%', - height: `${virtualRow.size}px`, - transform: `translateY(${virtualRow.start}px)`, - backgroundColor: isHighlighted ? HIGHLIGHT_COLOR_BASE : 'transparent', - opacity: isDragging ? DRAG_OPACITY : 1, - '&:hover': { - backgroundColor: isHighlighted ? HIGHLIGHT_COLOR_HOVER : ROW_HOVER_COLOR, - }, - ...(isDragging && { zIndex: 1, transform: 'none' }), -}); - -export const createModificationNameCellStyle = (activated: boolean): CSSProperties => ({ - opacity: activated ? 1 : DEACTIVATED_OPACITY, - paddingLeft: '0.8vw', -}); - -export const createRootNetworkChipCellSx = (activated: boolean): SxProps => ({ - width: '100%', - display: 'flex', - justifyContent: 'center', - opacity: activated ? 1 : DEACTIVATED_OPACITY, -}); - -export const createEditDescriptionStyle = (description: string | undefined): SxProps => ({ - opacity: description ? 1 : 0, - cursor: description ? 'pointer' : 'default', - 'tr:hover &': { opacity: 1 }, -}); - -export const createCellStyle = (cell: any, isAutoExtensible: boolean) => { - const size = cell.column.getSize(); - const minSize = cell.column.columnDef.minSize; - - return { - ...cell.column.columnDef.meta?.cellStyle, - padding: 0, - flex: isAutoExtensible ? `1 1 ${size}px` : `0 1 ${size}px`, - minWidth: minSize ? `${minSize}px` : undefined, - height: `${MODIFICATION_ROW_HEIGHT}px`, - display: 'flex', - alignItems: 'center', - }; -}; - -export const createHeaderCellStyle = ( - header: any, - theme: Theme, - isFirst: boolean, - isLast: boolean, - isAutoExtensible: boolean -) => { - const darkBorder = `1px solid ${alpha(theme.palette.text.secondary, 0.4)}`; - const size = header.column.getSize(); - const minSize = header.column.columnDef.minSize; - - return { - ...header.column.columnDef.meta?.cellStyle, - flex: isAutoExtensible ? `1 1 ${size}px` : `0 1 ${size}px`, - minWidth: minSize ? `${minSize}px` : undefined, - height: `${MODIFICATION_ROW_HEIGHT}px`, - padding: '2px', - textAlign: 'left', - fontWeight: 600, - display: 'flex', - alignItems: 'center', - paddingTop: '1.5vh', - paddingBottom: '1.5vh', - backgroundColor: theme.palette.background.paper, - borderBottom: darkBorder, - borderTop: darkBorder, - ...(isFirst && { borderLeft: darkBorder }), - ...(isLast && { borderRight: darkBorder }), - }; -}; diff --git a/src/components/graph/menus/network-modifications/network-modification-table/use-modifications-drag-and-drop.tsx b/src/components/graph/menus/network-modifications/network-modification-table/use-modifications-drag-and-drop.tsx deleted file mode 100644 index 8b35ef8e3b..0000000000 --- a/src/components/graph/menus/network-modifications/network-modification-table/use-modifications-drag-and-drop.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { JSX, RefObject, useCallback } from 'react'; -import { Row } from '@tanstack/react-table'; -import { NetworkModificationMetadata } from '@gridsuite/commons-ui'; -import { DraggableProvided, DraggableRubric, DraggableStateSnapshot, DragUpdate, DropResult } from '@hello-pangea/dnd'; -import DragCloneRow from './row/drag-row-clone'; -import { DROP_INDICATOR_BOTTOM, DROP_INDICATOR_TOP } from './styles'; - -interface UseModificationsDragAndDropParams { - rows: Row[]; - containerRef: RefObject; - onRowDragEnd?: (result: DropResult) => void; -} - -interface UseModificationsDragAndDropReturn { - handleDragUpdate: (update: DragUpdate) => void; - handleDragEnd: (result: DropResult) => void; - renderClone: ( - provided: DraggableProvided, - snapshot: DraggableStateSnapshot, - rubric: DraggableRubric - ) => JSX.Element; -} - -const clearRowDragIndicators = (container: HTMLDivElement | null): void => { - container?.querySelectorAll('[data-row-id]').forEach((el) => { - el.style.boxShadow = ''; - }); -}; - -export const useModificationsDragAndDrop = ({ - rows, - containerRef, - onRowDragEnd, -}: UseModificationsDragAndDropParams): UseModificationsDragAndDropReturn => { - const handleDragUpdate = useCallback( - (update: DragUpdate) => { - clearRowDragIndicators(containerRef.current); - - const { source, destination } = update; - if (!destination || source.index === destination.index) { - return; - } - - const targetUuid = rows[destination.index]?.original.uuid; - const el = containerRef.current?.querySelector(`[data-row-id="${targetUuid}"]`); - if (el) { - el.style.boxShadow = destination.index > source.index ? DROP_INDICATOR_BOTTOM : DROP_INDICATOR_TOP; - } - }, - [rows, containerRef] - ); - - const handleDragEnd = useCallback( - (result: DropResult) => { - clearRowDragIndicators(containerRef.current); - - if (result.destination && result.source.index !== result.destination.index) { - onRowDragEnd?.(result); - } - }, - [containerRef, onRowDragEnd] - ); - - const renderClone = useCallback( - (provided: DraggableProvided, _snapshot: DraggableStateSnapshot, rubric: DraggableRubric) => ( -
- -
- ), - [rows] - ); - - return { handleDragUpdate, handleDragEnd, renderClone }; -}; diff --git a/src/services/study/network-modifications.ts b/src/services/study/network-modifications.ts index c4aca43476..89f23ed5ab 100644 --- a/src/services/study/network-modifications.ts +++ b/src/services/study/network-modifications.ts @@ -20,6 +20,7 @@ import { toModificationOperation, SubstationCreationDto, SubstationModificationDto, + ExcludedNetworkModifications, } from '@gridsuite/commons-ui'; import { getStudyUrlWithNodeUuid, getStudyUrlWithNodeUuidAndRootNetworkUuid } from './index'; import { EQUIPMENT_TYPES } from '../../components/utils/equipment-types'; @@ -61,7 +62,6 @@ import { VSCModificationInfo, } from '../network-modification-types'; import { Filter } from '../../components/dialogs/network-modifications/by-filter/commons/by-filter.type'; -import { ExcludedNetworkModifications } from 'components/graph/menus/network-modifications/network-modification-menu.type'; import { Modification } from '../../components/dialogs/network-modifications/tabular/tabular-common'; import { ENABLE_OLG_MODIFICATION,