@gridsuite/commons-ui 0.197.0 → 0.198.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -256,7 +256,7 @@ import { SelectCell } from "./network-modification-table/renderers/select-cell.j
256
256
  import { SelectHeaderCell } from "./network-modification-table/renderers/select-header-cell.js";
257
257
  import { DragCloneRow } from "./network-modification-table/row/drag-row-clone.js";
258
258
  import { ModificationRow } from "./network-modification-table/row/modification-row.js";
259
- import { fetchSubModificationsForExpandedRows, findAllLoadedCompositeModifications, findModificationInTree, formatToComposedModification, isCompositeModification, mergeSubModificationsIntoTree, moveSubModificationInTree, updateModificationFieldInTree, updateSubModificationsOfACompositeInTree } from "./network-modification-table/utils.js";
259
+ import { MAX_COMPOSITE_NESTING_DEPTH, fetchSubModificationsForExpandedRows, findAllLoadedCompositeModifications, findModificationInTree, formatToComposedModification, isCompositeModification, mergeSubModificationsIntoTree, moveSubModificationInTree, updateModificationFieldInTree, updateSubModificationsOfACompositeInTree } from "./network-modification-table/utils.js";
260
260
  export {
261
261
  ACCURACY,
262
262
  ACTIVE,
@@ -464,6 +464,7 @@ export {
464
464
  MAP_BASE_MAP,
465
465
  MAP_MANUAL_REFRESH,
466
466
  MARGIN_CALCULATION_START_TIME,
467
+ MAX_COMPOSITE_NESTING_DEPTH,
467
468
  MAX_ROWS_NUMBER,
468
469
  MAX_VALUE_ALLOWED_FOR_LIMIT_REDUCTION,
469
470
  MIN_VALUE_ALLOWED_FOR_LIMIT_REDUCTION,
@@ -0,0 +1,2 @@
1
+ export declare const CHIP_ATTR = "data-drag-depth-chip";
2
+ export declare const injectForbiddenChips: (container: HTMLDivElement, rowEl: HTMLElement, isMovingDown: boolean) => void;
@@ -0,0 +1,39 @@
1
+ const CHIP_ATTR = "data-drag-depth-chip";
2
+ const createDragForbiddenChip = ({ side, chipStyle, label, title }) => {
3
+ const chip = document.createElement("span");
4
+ chip.setAttribute(CHIP_ATTR, side);
5
+ chip.setAttribute("style", `${chipStyle}; ${side}: 0px`);
6
+ chip.textContent = label;
7
+ if (title) {
8
+ chip.title = title;
9
+ }
10
+ return chip;
11
+ };
12
+ const injectForbiddenChips = (container, rowEl, isMovingDown) => {
13
+ container.querySelectorAll(`[${CHIP_ATTR}]`).forEach((c) => c.remove());
14
+ const containerRect = container.getBoundingClientRect();
15
+ const rowRect = rowEl.getBoundingClientRect();
16
+ const shadowLineY = isMovingDown ? rowRect.bottom - containerRect.top + container.scrollTop : rowRect.top - containerRect.top + container.scrollTop;
17
+ const chipStyle = [
18
+ "position: absolute",
19
+ `top: ${shadowLineY}px`,
20
+ "transform: translateY(-50%)",
21
+ "display: flex",
22
+ "align-items: center",
23
+ "justify-content: center",
24
+ "height: 20px",
25
+ "min-width: 20px",
26
+ "padding: 0 6px",
27
+ "border-radius: 10px",
28
+ "font-size: 11px",
29
+ "background-color: #d32f2f",
30
+ "color: #ffffff",
31
+ "z-index: 10",
32
+ "box-shadow: 0 1px 3px rgba(0,0,0,0.3)"
33
+ ].join("; ");
34
+ container.appendChild(createDragForbiddenChip({ side: "left", chipStyle, label: "✕" }));
35
+ };
36
+ export {
37
+ CHIP_ATTR,
38
+ injectForbiddenChips
39
+ };
@@ -10,7 +10,7 @@ import { SelectCell } from "./renderers/select-cell.js";
10
10
  import { SelectHeaderCell } from "./renderers/select-header-cell.js";
11
11
  import { DragCloneRow } from "./row/drag-row-clone.js";
12
12
  import { ModificationRow } from "./row/modification-row.js";
13
- import { fetchSubModificationsForExpandedRows, findAllLoadedCompositeModifications, findModificationInTree, formatToComposedModification, isCompositeModification, mergeSubModificationsIntoTree, moveSubModificationInTree, updateModificationFieldInTree, updateSubModificationsOfACompositeInTree } from "./utils.js";
13
+ import { MAX_COMPOSITE_NESTING_DEPTH, fetchSubModificationsForExpandedRows, findAllLoadedCompositeModifications, findModificationInTree, formatToComposedModification, isCompositeModification, mergeSubModificationsIntoTree, moveSubModificationInTree, updateModificationFieldInTree, updateSubModificationsOfACompositeInTree } from "./utils.js";
14
14
  export {
15
15
  AUTO_EXTENSIBLE_COLUMNS,
16
16
  BASE_MODIFICATION_TABLE_COLUMNS,
@@ -23,6 +23,7 @@ export {
23
23
  DepthBox,
24
24
  DragCloneRow,
25
25
  DragHandleCell,
26
+ MAX_COMPOSITE_NESTING_DEPTH,
26
27
  MODIFICATION_ROW_HEIGHT,
27
28
  ModificationRow,
28
29
  NameCell,
@@ -98,7 +98,7 @@ function NetworkModificationsTable({
98
98
  });
99
99
  const virtualItems = virtualizer.getVirtualItems();
100
100
  const { handleDragUpdate, handleDragEnd, renderClone } = useModificationsDragAndDrop({
101
- rows,
101
+ table,
102
102
  containerRef,
103
103
  composedModifications,
104
104
  setComposedModifications,
@@ -1,10 +1,10 @@
1
1
  import { default as React, JSX, RefObject } from 'react';
2
- import { Row } from '@tanstack/react-table';
2
+ import { Table } from '@tanstack/react-table';
3
3
  import { DraggableProvided, DraggableRubric, DraggableStateSnapshot, DragUpdate, DropResult } from '@hello-pangea/dnd';
4
4
  import { UUID } from 'node:crypto';
5
5
  import { ComposedModificationMetadata } from '../../utils';
6
6
  interface UseModificationsDragAndDropParams {
7
- rows: Row<ComposedModificationMetadata>[];
7
+ table: Table<ComposedModificationMetadata>;
8
8
  containerRef: RefObject<HTMLDivElement | null>;
9
9
  composedModifications: ComposedModificationMetadata[];
10
10
  setComposedModifications: React.Dispatch<React.SetStateAction<ComposedModificationMetadata[]>>;
@@ -17,5 +17,5 @@ interface UseModificationsDragAndDropReturn {
17
17
  handleDragEnd: (result: DropResult) => void;
18
18
  renderClone: (provided: DraggableProvided, snapshot: DraggableStateSnapshot, rubric: DraggableRubric) => JSX.Element;
19
19
  }
20
- export declare const useModificationsDragAndDrop: ({ rows, containerRef, composedModifications, setComposedModifications, onDragEnd, studyUuid, currentNodeUuid, }: UseModificationsDragAndDropParams) => UseModificationsDragAndDropReturn;
20
+ export declare const useModificationsDragAndDrop: ({ table, containerRef, composedModifications, setComposedModifications, onDragEnd, studyUuid, currentNodeUuid, }: UseModificationsDragAndDropParams) => UseModificationsDragAndDropReturn;
21
21
  export {};
@@ -7,12 +7,13 @@ import "@hello-pangea/dnd";
7
7
  import "react-intl";
8
8
  import "./columns-definition.js";
9
9
  import { DROP_FORBIDDEN_INDICATOR_BOTTOM, DROP_FORBIDDEN_INDICATOR_TOP, DROP_INDICATOR_BOTTOM, DROP_INDICATOR_TOP } from "./network-modification-table-styles.js";
10
- import { moveSubModificationInTree, isCompositeModification, findModificationInTree } from "./utils.js";
10
+ import { isCompositeModification, MAX_COMPOSITE_NESTING_DEPTH, findModificationInTree, moveSubModificationInTree } from "./utils.js";
11
11
  import "../../utils/conversionUtils.js";
12
12
  import { snackWithFallback } from "../../utils/error.js";
13
13
  import "../../utils/types/equipmentType.js";
14
14
  import "@mui/icons-material";
15
15
  import "../../utils/yupConfig.js";
16
+ import { injectForbiddenChips, CHIP_ATTR } from "./drag-forbidden-chip.js";
16
17
  import { changeCompositeSubModificationOrder, changeNetworkModificationOrder } from "../../services/networkModification.js";
17
18
  import "localized-countries";
18
19
  import "localized-countries/data/fr";
@@ -23,13 +24,7 @@ const clearRowDragIndicators = (container) => {
23
24
  rowElements?.forEach((rowElement) => {
24
25
  rowElement.style.boxShadow = "";
25
26
  });
26
- };
27
- const isDropForbidden = (sourceRow, targetRow) => {
28
- const isDraggingDown = targetRow.index > sourceRow.index;
29
- if (isCompositeModification(sourceRow.original) && (isCompositeModification(targetRow.original) && targetRow.getIsExpanded() && isDraggingDown || isCompositeModification(targetRow.getParentRow()?.original))) {
30
- return true;
31
- }
32
- return !!(isCompositeModification(sourceRow.original) && findModificationInTree(targetRow.original.uuid, [sourceRow.original]));
27
+ container?.querySelectorAll(`[${CHIP_ATTR}]`).forEach((chip) => chip.remove());
33
28
  };
34
29
  function getTargetCompositeUuid(droppingIntoExpandedComposite, targetRow) {
35
30
  if (droppingIntoExpandedComposite) {
@@ -47,7 +42,7 @@ function getContainerShadow(forbidden, isMovingDown) {
47
42
  return isMovingDown ? DROP_INDICATOR_BOTTOM : DROP_INDICATOR_TOP;
48
43
  }
49
44
  const useModificationsDragAndDrop = ({
50
- rows,
45
+ table,
51
46
  containerRef,
52
47
  composedModifications,
53
48
  setComposedModifications,
@@ -56,6 +51,30 @@ const useModificationsDragAndDrop = ({
56
51
  currentNodeUuid = void 0
57
52
  }) => {
58
53
  const { snackError } = useSnackMessage();
54
+ const { rows } = table.getRowModel();
55
+ const computeTargetDepth = useCallback(
56
+ (sourceRow, targetRow) => {
57
+ const sourceRowIndex = table.getRowModel().flatRows.findIndex((row) => {
58
+ return row.id === sourceRow.id;
59
+ });
60
+ const targetRowIndex = table.getRowModel().flatRows.findIndex((row) => {
61
+ return row.id === targetRow.id;
62
+ });
63
+ const isDraggingDown = sourceRowIndex < targetRowIndex;
64
+ return isCompositeModification(targetRow.original) && targetRow.getIsExpanded() && isDraggingDown ? targetRow.depth + 1 : targetRow.depth;
65
+ },
66
+ [table]
67
+ );
68
+ const isDropForbidden = useCallback(
69
+ (sourceRow, targetRow) => {
70
+ if (isCompositeModification(sourceRow.original)) {
71
+ const targetDepth = computeTargetDepth(sourceRow, targetRow);
72
+ return (sourceRow.original.maxDepth ?? 0) + targetDepth > MAX_COMPOSITE_NESTING_DEPTH || !!(isCompositeModification(sourceRow.original) && findModificationInTree(targetRow.original.uuid, [sourceRow.original]));
73
+ }
74
+ return false;
75
+ },
76
+ [computeTargetDepth]
77
+ );
59
78
  const handleDragUpdate = useCallback(
60
79
  (update) => {
61
80
  clearRowDragIndicators(containerRef.current);
@@ -72,8 +91,11 @@ const useModificationsDragAndDrop = ({
72
91
  const forbidden = isDropForbidden(sourceRow, targetRow);
73
92
  const isMovingDown = destination.index > source.index;
74
93
  el.style.boxShadow = getContainerShadow(forbidden, isMovingDown);
94
+ if (forbidden && containerRef.current) {
95
+ injectForbiddenChips(containerRef.current, el, isMovingDown);
96
+ }
75
97
  },
76
- [rows, containerRef]
98
+ [containerRef, isDropForbidden, rows]
77
99
  );
78
100
  const handleDragEndComposite = useCallback(
79
101
  (sourceRow, targetRow, droppingIntoExpandedComposite, isDraggingDown) => {
@@ -151,12 +173,13 @@ const useModificationsDragAndDrop = ({
151
173
  containerRef,
152
174
  onDragEnd,
153
175
  rows,
154
- studyUuid,
155
- currentNodeUuid,
156
- snackError,
176
+ isDropForbidden,
177
+ handleDragEndComposite,
157
178
  composedModifications,
179
+ currentNodeUuid,
158
180
  setComposedModifications,
159
- handleDragEndComposite
181
+ studyUuid,
182
+ snackError
160
183
  ]
161
184
  );
162
185
  const renderClone = useCallback(
@@ -1,6 +1,7 @@
1
1
  import { Dispatch, SetStateAction } from 'react';
2
2
  import { UUID } from 'node:crypto';
3
3
  import { ComposedModificationMetadata, NetworkModificationMetadata } from '../../utils';
4
+ export declare const MAX_COMPOSITE_NESTING_DEPTH = 5;
4
5
  export declare const formatToComposedModification: (modifications: NetworkModificationMetadata[]) => ComposedModificationMetadata[];
5
6
  export declare function isCompositeModification(modification: ComposedModificationMetadata | undefined): boolean;
6
7
  /**
@@ -5,6 +5,7 @@ import "react/jsx-runtime";
5
5
  import "@mui/icons-material";
6
6
  import "../../utils/yupConfig.js";
7
7
  import { getNetworkModificationsFromComposite } from "../../services/networkModification.js";
8
+ const MAX_COMPOSITE_NESTING_DEPTH = 5;
8
9
  const formatToComposedModification = (modifications) => {
9
10
  return modifications.map((modification) => ({ ...modification, subModifications: [] }));
10
11
  };
@@ -152,6 +153,7 @@ function fetchSubModificationsForExpandedRows(expandedIds, mods, setMods, force
152
153
  });
153
154
  }
154
155
  export {
156
+ MAX_COMPOSITE_NESTING_DEPTH,
155
157
  fetchSubModificationsForExpandedRows,
156
158
  findAllLoadedCompositeModifications,
157
159
  findModificationInTree,
package/dist/index.js CHANGED
@@ -309,7 +309,7 @@ import { SelectCell } from "./components/network-modification-table/renderers/se
309
309
  import { SelectHeaderCell } from "./components/network-modification-table/renderers/select-header-cell.js";
310
310
  import { DragCloneRow } from "./components/network-modification-table/row/drag-row-clone.js";
311
311
  import { ModificationRow } from "./components/network-modification-table/row/modification-row.js";
312
- import { fetchSubModificationsForExpandedRows, findAllLoadedCompositeModifications, findModificationInTree, formatToComposedModification, isCompositeModification, mergeSubModificationsIntoTree, moveSubModificationInTree, updateModificationFieldInTree, updateSubModificationsOfACompositeInTree } from "./components/network-modification-table/utils.js";
312
+ import { MAX_COMPOSITE_NESTING_DEPTH, fetchSubModificationsForExpandedRows, findAllLoadedCompositeModifications, findModificationInTree, formatToComposedModification, isCompositeModification, mergeSubModificationsIntoTree, moveSubModificationInTree, updateModificationFieldInTree, updateSubModificationsOfACompositeInTree } from "./components/network-modification-table/utils.js";
313
313
  import { useStateBoolean } from "./hooks/customStates/useStateBoolean.js";
314
314
  import { useStateNumber } from "./hooks/customStates/useStateNumber.js";
315
315
  import { useModificationLabelComputer } from "./hooks/useModificationLabelComputer.js";
@@ -651,6 +651,7 @@ export {
651
651
  MAP_MANUAL_REFRESH,
652
652
  MARGIN_CALCULATION_START_TIME,
653
653
  MAX_CHAR_DESCRIPTION,
654
+ MAX_COMPOSITE_NESTING_DEPTH,
654
655
  MAX_ROWS_NUMBER,
655
656
  MAX_VALUE_ALLOWED_FOR_LIMIT_REDUCTION,
656
657
  MEGA_VAR,
@@ -12,4 +12,5 @@ export interface NetworkModificationMetadata {
12
12
  }
13
13
  export interface ComposedModificationMetadata extends NetworkModificationMetadata {
14
14
  subModifications: ComposedModificationMetadata[];
15
+ maxDepth?: number;
15
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gridsuite/commons-ui",
3
- "version": "0.197.0",
3
+ "version": "0.198.0",
4
4
  "description": "common react components for gridsuite applications",
5
5
  "author": "gridsuite team",
6
6
  "homepage": "https://github.com/gridsuite",