@topconsultnpm/sdkui-react 6.20.0-dev1.120 → 6.20.0-dev1.121

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.
@@ -1,14 +1,13 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState, useRef, useEffect, useCallback } from 'react';
3
3
  import { ContextMenu } from '../ContextMenu';
4
4
  import ShowAlert from '../../base/TMAlert';
5
5
  import TMTooltip from '../../base/TMTooltip';
6
6
  import * as S from './styles';
7
- import { IconAdd, IconCloseOutline, IconDelete, IconMenuVertical, IconPin, IconRotate, IconSave, IconSeparator, IconSettings, IconUndo, SDKUI_Globals, SDKUI_Localizator } from '../../../helper';
8
- import { ButtonNames, TMMessageBoxManager } from '../../base/TMPopUp';
7
+ import { IconDelete, IconMenuVertical, IconPin, IconRotate, IconSeparator, SDKUI_Globals } from '../../../helper';
9
8
  const Separator = (props) => (_jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", height: "1em", width: "1em", ...props, children: _jsx("path", { d: "M12 2v20", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round" }) }));
10
9
  const IconDraggableDots = (props) => (_jsx("svg", { fontSize: 18, viewBox: "0 0 24 24", fill: "currentColor", height: "1em", width: "1em", ...props, children: _jsx("path", { d: "M9 3a2 2 0 11-4 0 2 2 0 014 0zm0 9a2 2 0 11-4 0 2 2 0 014 0zm0 9a2 2 0 11-4 0 2 2 0 014 0zm10-18a2 2 0 11-4 0 2 2 0 014 0zm0 9a2 2 0 11-4 0 2 2 0 014 0zm0 9a2 2 0 11-4 0 2 2 0 014 0z" }) }));
11
- const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained = false, defaultPosition = { x: 1, y: 90 }, defaultOrientation = 'horizontal', maxItems = 100, contextMenuDefaultPinnedIds = [], defaultItems = [], disbaleConfigMode = false, bgColor = undefined, hasContextMenu = true, pinnedItemIds: externalPinnedItemIds, onPinChange, }) => {
10
+ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained = false, defaultPosition = { x: 1, y: 90 }, defaultOrientation = 'horizontal', maxItems = 100, contextMenuDefaultPinnedIds = [], defaultItems = [], enableConfigMode = true, bgColor = undefined, hasContextMenu = true, pinnedItemIds: externalPinnedItemIds, onPinChange, }) => {
12
11
  const percentToPixels = (percent, containerSize) => {
13
12
  return (percent / 100) * containerSize;
14
13
  };
@@ -42,7 +41,7 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
42
41
  };
43
42
  const loadConfig = () => {
44
43
  // If config mode is disabled, use default position and orientation
45
- if (disbaleConfigMode) {
44
+ if (!enableConfigMode) {
46
45
  return {
47
46
  orientation: defaultOrientation,
48
47
  savedItemIds: contextMenuDefaultPinnedIds,
@@ -129,7 +128,6 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
129
128
  const [state, setState] = useState({
130
129
  position: initialConfig.position, // Stored as percentage
131
130
  isDragging: false,
132
- isConfigMode: false,
133
131
  orientation: initialConfig.orientation,
134
132
  verticalDirection: 'down',
135
133
  items: [],
@@ -141,12 +139,10 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
141
139
  const [pixelPosition, setPixelPosition] = useState({ x: 0, y: 0 }); // Calculated pixel position
142
140
  const [isOrientationChanging, setIsOrientationChanging] = useState(false); // Hide bar during orientation transition
143
141
  const containerSizeRef = useRef({ width: 0, height: 0 });
144
- const stateSnapshot = useRef(null);
145
142
  const positionBeforeOrientationChange = useRef(null);
146
143
  const floatingBarItemIds = useRef(new Set());
147
144
  const floatingBarItemNames = useRef(new Set());
148
145
  const isSyncingFromExternal = useRef(false);
149
- const isExitingConfigMode = useRef(false);
150
146
  const isLocalChange = useRef(false);
151
147
  const dragStartPosition = useRef(null);
152
148
  useEffect(() => {
@@ -213,11 +209,11 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
213
209
  if (contextMenuItems.length > 0 || initialConfig.savedItemIds.length > 0 || defaultItems.length > 0) {
214
210
  const flatItems = flattenMenuItems(contextMenuItems);
215
211
  let itemsToSet = [];
216
- // If disbaleConfigMode is true and defaultItems provided, use only defaultItems
217
- if (disbaleConfigMode && defaultItems.length > 0) {
212
+ // If enableConfigMode is false and defaultItems provided, use only defaultItems
213
+ if (!enableConfigMode && defaultItems.length > 0) {
218
214
  itemsToSet = defaultItems;
219
215
  }
220
- else if (!disbaleConfigMode && initialConfig.savedItemIds.length > 0) {
216
+ else if (enableConfigMode && initialConfig.savedItemIds.length > 0) {
221
217
  // Restore items in the saved order from localStorage (only if config mode is enabled)
222
218
  const restoredItems = initialConfig.savedItemIds
223
219
  .map((id) => {
@@ -250,20 +246,15 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
250
246
  setState(s => ({ ...s, items: itemsToSet }));
251
247
  }
252
248
  }
253
- }, disbaleConfigMode ? [defaultItems] : []); // Update when defaultItems change if config mode is disabled
249
+ }, enableConfigMode ? [] : [defaultItems]); // Update when defaultItems change if config mode is disabled
254
250
  // Sync with external pinnedItemIds when they change (from parent component)
255
251
  useEffect(() => {
256
- // Skip sync if exiting config mode - let save effect update external state first
257
- if (isExitingConfigMode.current) {
258
- isExitingConfigMode.current = false;
259
- return;
260
- }
261
252
  // Skip sync if a local change was just made (e.g. right-click remove/add separator)
262
253
  if (isLocalChange.current) {
263
254
  isLocalChange.current = false;
264
255
  return;
265
256
  }
266
- if (externalPinnedItemIds === undefined || disbaleConfigMode || state.isConfigMode)
257
+ if (externalPinnedItemIds === undefined || !enableConfigMode)
267
258
  return;
268
259
  const flatItems = flattenMenuItems(contextMenuItems);
269
260
  // Build items from external pinned IDs
@@ -288,7 +279,7 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
288
279
  isSyncingFromExternal.current = true; // Mark that we're syncing from external
289
280
  setState(s => ({ ...s, items: itemsFromExternal }));
290
281
  }
291
- }, [externalPinnedItemIds, contextMenuItems, disbaleConfigMode, state.isConfigMode, flattenMenuItems]);
282
+ }, [externalPinnedItemIds, contextMenuItems, enableConfigMode, flattenMenuItems]);
292
283
  const togglePin = useCallback((item) => {
293
284
  setState(s => {
294
285
  const isInFloatingBar = s.items.some(i => i.id === item.id);
@@ -368,42 +359,6 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
368
359
  const separator = createSeparator();
369
360
  setState(s => ({ ...s, items: [...s.items, separator] }));
370
361
  }, [state.items.length, maxItems, createSeparator]);
371
- const getPinContextMenuItems = useCallback(() => {
372
- const flatItems = flattenMenuItems(contextMenuItems);
373
- const currentItemIds = new Set(state.items.map(i => i.id));
374
- const createPinItems = (items) => {
375
- return items.map(item => {
376
- const flatItem = flatItems.find(fi => fi.id === item.id);
377
- const itemId = flatItem?.id || item.id || '';
378
- const isAlreadyPinned = currentItemIds.has(itemId);
379
- const pinItem = {
380
- ...item,
381
- // Remove rightIconProps in config mode - clicking the item itself pins it
382
- rightIconProps: undefined,
383
- onClick: item.onClick && !item.submenu ? () => {
384
- if (flatItem && !isAlreadyPinned) {
385
- togglePin(flatItem);
386
- }
387
- } : undefined,
388
- disabled: isAlreadyPinned,
389
- };
390
- if (item.submenu) {
391
- pinItem.submenu = createPinItems(item.submenu);
392
- }
393
- return pinItem;
394
- });
395
- };
396
- const pinItems = createPinItems(contextMenuItems);
397
- // Add separator option at the end
398
- pinItems.push({
399
- id: 'add-separator',
400
- name: SDKUI_Localizator.Add + ' separatore',
401
- icon: _jsx(IconSeparator, {}),
402
- onClick: addSeparator,
403
- beginGroup: true
404
- });
405
- return pinItems;
406
- }, [contextMenuItems, flattenMenuItems, togglePin, state.items, addSeparator]);
407
362
  const getContextMenuItemsWithPinIcons = useCallback(() => {
408
363
  const flatItems = flattenMenuItems(contextMenuItems);
409
364
  const currentItemIds = new Set(state.items.map(i => i.id));
@@ -431,8 +386,6 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
431
386
  return addPinIcons(contextMenuItems);
432
387
  }, [contextMenuItems, flattenMenuItems, togglePin, state.items]);
433
388
  const handleMouseDown = (e) => {
434
- if (state.isConfigMode)
435
- return;
436
389
  const containerRect = containerRef.current?.getBoundingClientRect();
437
390
  if (containerRect) {
438
391
  // Calculate drag offset based on positioning mode
@@ -456,8 +409,6 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
456
409
  setState(s => ({ ...s, isDragging: true }));
457
410
  };
458
411
  const handleGripDoubleClick = () => {
459
- if (state.isConfigMode)
460
- return;
461
412
  toggleOrientation();
462
413
  };
463
414
  const handleMouseMove = useCallback((e) => {
@@ -513,8 +464,6 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
513
464
  }, [state.isDragging, pixelPosition]);
514
465
  // Touch event handlers for tablet support
515
466
  const handleTouchStart = (e) => {
516
- if (state.isConfigMode)
517
- return;
518
467
  const touch = e.touches[0];
519
468
  const containerRect = containerRef.current?.getBoundingClientRect();
520
469
  if (containerRect) {
@@ -596,11 +545,9 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
596
545
  }
597
546
  return undefined;
598
547
  }, [state.isDragging, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
599
- // Save to SDKUI_Globals.userSettings only when NOT in config mode (when applying changes)
548
+ // Save to SDKUI_Globals.userSettings
600
549
  useEffect(() => {
601
- if (state.isConfigMode)
602
- return; // Don't save during edit mode
603
- if (disbaleConfigMode)
550
+ if (!enableConfigMode)
604
551
  return; // Don't save if config mode is disabled
605
552
  const pinnedIds = state.items.map(item => item.id);
606
553
  try {
@@ -621,139 +568,7 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
621
568
  onPinChange?.(pinnedIds);
622
569
  }
623
570
  isSyncingFromExternal.current = false; // Reset the flag
624
- }, [state.orientation, state.items, state.position, state.isConfigMode, disbaleConfigMode, onPinChange]);
625
- const toggleConfigMode = () => {
626
- setState(s => {
627
- if (!s.isConfigMode) {
628
- stateSnapshot.current = {
629
- items: [...s.items],
630
- orientation: s.orientation,
631
- verticalDirection: s.verticalDirection,
632
- position: { ...s.position },
633
- };
634
- return { ...s, isConfigMode: true };
635
- }
636
- else {
637
- // Exiting edit mode (applying changes) - clean up trailing separators and clear snapshot
638
- stateSnapshot.current = null;
639
- isExitingConfigMode.current = true; // Prevent sync effect from overwriting changes
640
- const cleanedItems = removeTrailingSeparators(s.items);
641
- return { ...s, isConfigMode: false, items: cleanedItems };
642
- }
643
- });
644
- };
645
- // Auto-reposition when entering edit mode to ensure Apply/Undo buttons are visible
646
- useEffect(() => {
647
- if (!state.isConfigMode || !floatingRef.current)
648
- return;
649
- // Use double requestAnimationFrame to ensure the DOM has fully updated with new buttons
650
- requestAnimationFrame(() => {
651
- requestAnimationFrame(() => {
652
- if (!floatingRef.current)
653
- return;
654
- const floating = floatingRef.current.getBoundingClientRect();
655
- const containerWidth = isConstrained && containerRef.current
656
- ? containerRef.current.getBoundingClientRect().width
657
- : window.innerWidth;
658
- const containerHeight = isConstrained && containerRef.current
659
- ? containerRef.current.getBoundingClientRect().height
660
- : window.innerHeight;
661
- // Use current pixel position
662
- let newPixelX = pixelPosition.x;
663
- let newPixelY = pixelPosition.y;
664
- let needsUpdate = false;
665
- // Check horizontal overflow
666
- if (newPixelX + floating.width > containerWidth) {
667
- newPixelX = Math.max(0, containerWidth - floating.width);
668
- needsUpdate = true;
669
- }
670
- // Check vertical overflow
671
- if (newPixelY + floating.height > containerHeight) {
672
- newPixelY = Math.max(0, containerHeight - floating.height);
673
- needsUpdate = true;
674
- }
675
- if (needsUpdate) {
676
- // Update pixel position immediately
677
- setPixelPosition({ x: newPixelX, y: newPixelY });
678
- // Convert to percentage for state
679
- const newPercentagePosition = {
680
- x: pixelsToPercent(newPixelX, containerWidth),
681
- y: pixelsToPercent(newPixelY, containerHeight),
682
- };
683
- setState(s => ({
684
- ...s,
685
- position: newPercentagePosition,
686
- }));
687
- // Update snapshot position to the corrected position so Undo restores to visible position
688
- if (stateSnapshot.current) {
689
- stateSnapshot.current.position = newPercentagePosition;
690
- }
691
- }
692
- });
693
- });
694
- }, [state.isConfigMode, state.orientation, isConstrained, state.items, pixelPosition.x, pixelPosition.y]);
695
- const handleUndo = () => {
696
- if (stateSnapshot.current) {
697
- setState(s => ({
698
- ...s,
699
- items: [...stateSnapshot.current.items],
700
- orientation: stateSnapshot.current.orientation,
701
- verticalDirection: stateSnapshot.current.verticalDirection,
702
- position: { ...stateSnapshot.current.position },
703
- isConfigMode: true,
704
- }));
705
- }
706
- };
707
- // Check if current state has changed from snapshot
708
- const hasChanges = () => {
709
- if (!stateSnapshot.current)
710
- return false;
711
- // Check if items have changed (different IDs or different order)
712
- const currentIds = state.items.map(i => i.id).join(',');
713
- const snapshotIds = stateSnapshot.current.items.map(i => i.id).join(',');
714
- return currentIds !== snapshotIds;
715
- };
716
- const handleClose = () => {
717
- // If all items removed, exit without asking and restore last items
718
- if (state.items.length === 0 && stateSnapshot.current) {
719
- setState(s => ({
720
- ...s,
721
- items: [...stateSnapshot.current.items],
722
- orientation: stateSnapshot.current.orientation,
723
- verticalDirection: stateSnapshot.current.verticalDirection,
724
- position: { ...stateSnapshot.current.position },
725
- isConfigMode: false,
726
- }));
727
- stateSnapshot.current = null;
728
- return;
729
- }
730
- // If no changes, simply exit config mode
731
- if (!hasChanges()) {
732
- stateSnapshot.current = null;
733
- const cleanedItems = removeTrailingSeparators(state.items);
734
- setState(s => ({ ...s, isConfigMode: false, items: cleanedItems }));
735
- return;
736
- }
737
- // If there are changes, ask for confirmation
738
- TMMessageBoxManager.show({
739
- message: 'Perderai le tue modifiche, sei sicuro?',
740
- buttons: [ButtonNames.YES, ButtonNames.NO],
741
- onButtonClick: (buttonName) => {
742
- if (buttonName === ButtonNames.YES && stateSnapshot.current) {
743
- // Restore snapshot and exit config mode
744
- setState(s => ({
745
- ...s,
746
- items: [...stateSnapshot.current.items],
747
- orientation: stateSnapshot.current.orientation,
748
- verticalDirection: stateSnapshot.current.verticalDirection,
749
- position: { ...stateSnapshot.current.position },
750
- isConfigMode: false,
751
- }));
752
- stateSnapshot.current = null;
753
- }
754
- },
755
- });
756
- };
571
+ }, [state.orientation, state.items, state.position, enableConfigMode, onPinChange]);
757
572
  const toggleOrientation = () => {
758
573
  const newOrientation = state.orientation === 'horizontal' ? 'vertical' : 'horizontal';
759
574
  // When switching from vertical back to horizontal, restore the original position
@@ -887,50 +702,41 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
887
702
  onClick: () => removeItem(item.id),
888
703
  },
889
704
  {
890
- name: 'Aggiungi separatore a destra',
891
- icon: _jsx(IconSeparator, { style: { transform: 'rotate(-90deg)' }, fontSize: 16 }),
892
- disabled: hasSeparatorOnRight,
705
+ name: 'Aggiungi separatore a sinistra',
706
+ icon: _jsx(IconSeparator, { fontSize: 16 }),
707
+ disabled: hasSeparatorOnLeft,
893
708
  onClick: () => {
894
709
  isLocalChange.current = true;
895
710
  const separator = createSeparator();
896
711
  setState(s => {
897
712
  const newItems = [...s.items];
898
- newItems.splice(index + 1, 0, separator);
713
+ newItems.splice(index, 0, separator);
899
714
  return { ...s, items: newItems };
900
715
  });
901
716
  },
902
717
  },
903
718
  {
904
- name: 'Aggiungi separatore a sinistra',
905
- icon: _jsx(IconSeparator, { fontSize: 16 }),
906
- disabled: hasSeparatorOnLeft,
719
+ name: 'Aggiungi separatore a destra',
720
+ icon: _jsx(IconSeparator, { style: { transform: 'rotate(-90deg)' }, fontSize: 16 }),
721
+ disabled: hasSeparatorOnRight,
907
722
  onClick: () => {
908
723
  isLocalChange.current = true;
909
724
  const separator = createSeparator();
910
725
  setState(s => {
911
726
  const newItems = [...s.items];
912
- newItems.splice(index, 0, separator);
727
+ newItems.splice(index + 1, 0, separator);
913
728
  return { ...s, items: newItems };
914
729
  });
915
730
  },
916
731
  },
917
- ...(!disbaleConfigMode ? [{
918
- beginGroup: true,
919
- name: SDKUI_Localizator.Configure,
920
- icon: _jsx(IconSettings, { fontSize: 16 }),
921
- onClick: () => {
922
- if (!state.isConfigMode) {
923
- toggleConfigMode();
924
- }
925
- },
926
- }] : []),
927
732
  {
733
+ beginGroup: true,
928
734
  name: state.orientation === 'horizontal' ? 'Floating bar verticale' : 'Floating bar orizzontale',
929
735
  icon: _jsx(IconRotate, { fontSize: 16 }),
930
736
  onClick: toggleOrientation,
931
737
  },
932
738
  ];
933
- }, [state.items, state.isConfigMode, state.orientation, removeItem, createSeparator, toggleConfigMode, toggleOrientation, disbaleConfigMode]);
739
+ }, [state.items, state.orientation, removeItem, createSeparator, toggleOrientation]);
934
740
  const getSeparatorRightClickMenuItems = useCallback((index) => {
935
741
  return [
936
742
  {
@@ -939,42 +745,33 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
939
745
  onClick: () => removeItem(state.items[index].id),
940
746
  },
941
747
  {
942
- name: 'Aggiungi separatore a destra',
943
- icon: _jsx(IconSeparator, { style: { transform: 'rotate(-90deg)' }, fontSize: 16 }),
748
+ name: 'Aggiungi separatore a sinistra',
749
+ icon: _jsx(IconSeparator, { fontSize: 16 }),
944
750
  disabled: true,
945
751
  },
946
752
  {
947
- name: 'Aggiungi separatore a sinistra',
948
- icon: _jsx(IconSeparator, { fontSize: 16 }),
753
+ name: 'Aggiungi separatore a destra',
754
+ icon: _jsx(IconSeparator, { style: { transform: 'rotate(-90deg)' }, fontSize: 16 }),
949
755
  disabled: true,
950
756
  },
951
- ...(!disbaleConfigMode ? [{
952
- beginGroup: true,
953
- name: SDKUI_Localizator.Configure,
954
- icon: _jsx(IconSettings, { fontSize: 16 }),
955
- onClick: () => {
956
- if (!state.isConfigMode) {
957
- toggleConfigMode();
958
- }
959
- },
960
- }] : []),
961
757
  {
758
+ beginGroup: true,
962
759
  name: state.orientation === 'horizontal' ? 'Floating bar verticale' : 'Floating bar orizzontale',
963
760
  icon: _jsx(IconRotate, { fontSize: 16 }),
964
761
  onClick: toggleOrientation,
965
762
  },
966
763
  ];
967
- }, [state.items, state.isConfigMode, state.orientation, removeItem, toggleConfigMode, toggleOrientation, disbaleConfigMode]);
764
+ }, [state.items, state.orientation, removeItem, toggleOrientation]);
968
765
  // Drag and drop for reordering
969
766
  const handleDragStart = (e, index) => {
970
- if (!state.isConfigMode)
767
+ if (!enableConfigMode)
971
768
  return;
972
769
  e.dataTransfer.effectAllowed = 'move';
973
770
  e.dataTransfer.setData('text/plain', index.toString());
974
771
  setState(s => ({ ...s, draggedItemIndex: index }));
975
772
  };
976
773
  const handleDragEnter = (e, index) => {
977
- if (!state.isConfigMode)
774
+ if (!enableConfigMode)
978
775
  return;
979
776
  e.preventDefault();
980
777
  if (state.draggedItemIndex !== index) {
@@ -982,13 +779,13 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
982
779
  }
983
780
  };
984
781
  const handleDragOver = (e) => {
985
- if (!state.isConfigMode)
782
+ if (!enableConfigMode)
986
783
  return;
987
784
  e.preventDefault();
988
785
  e.dataTransfer.dropEffect = 'move';
989
786
  };
990
787
  const handleDragLeave = (_e, index) => {
991
- if (!state.isConfigMode)
788
+ if (!enableConfigMode)
992
789
  return;
993
790
  // Only clear if we're actually leaving this specific item
994
791
  if (dragOverIndex === index) {
@@ -996,7 +793,7 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
996
793
  }
997
794
  };
998
795
  const handleDrop = (e, dropIndex) => {
999
- if (!state.isConfigMode || state.draggedItemIndex === null)
796
+ if (!enableConfigMode || state.draggedItemIndex === null)
1000
797
  return;
1001
798
  e.preventDefault();
1002
799
  e.stopPropagation();
@@ -1005,6 +802,7 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
1005
802
  setDragOverIndex(null);
1006
803
  return;
1007
804
  }
805
+ isLocalChange.current = true;
1008
806
  const newItems = [...state.items];
1009
807
  const [draggedItem] = newItems.splice(dragIndex, 1);
1010
808
  newItems.splice(dropIndex, 0, draggedItem);
@@ -1019,46 +817,37 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
1019
817
  setState(s => ({ ...s, draggedItemIndex: null }));
1020
818
  setDragOverIndex(null);
1021
819
  };
1022
- return (_jsxs(_Fragment, { children: [_jsx(S.Overlay, { "$visible": state.isConfigMode }), _jsxs(S.FloatingContainer, { ref: floatingRef, "$x": pixelPosition.x, "$y": pixelPosition.y, "$orientation": state.orientation, "$verticalDirection": state.verticalDirection, "$isDragging": state.isDragging, "$isConfigMode": state.isConfigMode, "$isConstrained": isConstrained, "$isHidden": isOrientationChanging, "$bgColor": bgColor, onContextMenu: state.isConfigMode ? (e) => e.preventDefault() : undefined, children: [!state.isConfigMode ? (_jsx(ContextMenu, { items: [
1023
- ...(!disbaleConfigMode ? [{
1024
- name: SDKUI_Localizator.Configure,
1025
- icon: _jsx(IconSettings, { fontSize: 16 }),
1026
- onClick: () => {
1027
- if (!state.isConfigMode) {
1028
- toggleConfigMode();
1029
- }
1030
- },
1031
- }] : []),
1032
- {
1033
- name: state.orientation === 'horizontal' ? 'Floating bar verticale' : 'Floating bar orizzontale',
1034
- icon: _jsx(IconRotate, { fontSize: 16, style: { transform: state.orientation === 'horizontal' ? 'rotate(90deg)' : 'rotate(0deg)' } }),
1035
- onClick: toggleOrientation,
1036
- },
1037
- ], trigger: "right", children: _jsx(S.GripHandle, { "$orientation": state.orientation, onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, onDoubleClick: handleGripDoubleClick, children: _jsx(IconDraggableDots, {}) }) })) : (_jsx(S.GripHandle, { "$orientation": state.orientation, onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, onDoubleClick: handleGripDoubleClick, children: _jsx(IconDraggableDots, {}) })), _jsx(S.Separator, { "$orientation": state.orientation }), state.items.map((item, index) => {
1038
- // Handle separator items
1039
- if (item.isSeparator) {
1040
- return (_jsx(S.DraggableItem, { "$isDragging": state.draggedItemIndex === index, "$isDragOver": dragOverIndex === index && state.draggedItemIndex !== index, draggable: state.isConfigMode, onDragStart: (e) => handleDragStart(e, index), onDragEnter: (e) => handleDragEnter(e, index), onDragOver: handleDragOver, onDragLeave: (e) => handleDragLeave(e, index), onDrop: (e) => handleDrop(e, index), onDragEnd: handleDragEnd, children: state.isConfigMode ? (_jsxs(_Fragment, { children: [_jsx(S.ItemSeparator, { "$orientation": state.orientation, "$isConfigMode": state.isConfigMode }), _jsx(S.RemoveButton, { onClick: () => removeItem(item.id), children: "\u00D7" })] })) : (_jsx(ContextMenu, { items: getSeparatorRightClickMenuItems(index), trigger: "right", children: _jsx(S.ItemSeparator, { "$orientation": state.orientation, "$isConfigMode": state.isConfigMode }) })) }, item.id));
1041
- }
1042
- // Get current state (disabled and onClick) from contextMenuItems
1043
- const currentState = getCurrentItemState(item.id);
1044
- // Prefer currentState.disabled if contextMenuItems has items, otherwise use item.disabled
1045
- const isDisabled = (contextMenuItems.length > 0 && currentState.disabled !== undefined)
1046
- ? currentState.disabled === true
1047
- : item.disabled === true;
1048
- const currentOnClick = currentState.onClick || item.onClick; // Fallback to stored onClick if not found
1049
- return (_jsx(S.DraggableItem, { "$isDragging": state.draggedItemIndex === index, "$isDragOver": dragOverIndex === index && state.draggedItemIndex !== index, draggable: state.isConfigMode, onDragStart: (e) => handleDragStart(e, index), onDragEnter: (e) => handleDragEnter(e, index), onDragOver: handleDragOver, onDragLeave: (e) => handleDragLeave(e, index), onDrop: (e) => handleDrop(e, index), onDragEnd: handleDragEnd, children: state.isConfigMode ? (
1050
- // Config mode: show remove button, no right-click menu
1051
- _jsxs(_Fragment, { children: [item.staticItem ? (item.staticItem) : (_jsx(TMTooltip, { content: item.name, position: "bottom", children: _jsx(S.MenuButton, { onClick: () => { }, disabled: isDisabled, "$isActive": item.isToggle, children: item.icon }) })), _jsx(S.RemoveButton, { onClick: () => removeItem(item.id), children: "\u00D7" })] })) : (
1052
- // Normal mode: wrap in right-click context menu
1053
- _jsx(ContextMenu, { items: getItemRightClickMenuItems(item, index), trigger: "right", children: item.staticItem ? (_jsx("div", { children: item.staticItem })) : (_jsx(TMTooltip, { content: item.name, position: "bottom", children: _jsx(S.MenuButton, { onClick: () => {
1054
- if (isDisabled)
1055
- return;
1056
- if (currentOnClick) {
1057
- currentOnClick();
1058
- }
1059
- }, disabled: isDisabled, "$isActive": item.isToggle, children: item.icon }) })) })) }, item.id));
1060
- }), !state.isConfigMode && !disbaleConfigMode && hasContextMenu && contextMenuItems.length > 0 && (_jsx(ContextMenu, { items: getContextMenuItemsWithPinIcons(), trigger: "left", keepOpenOnClick: false, children: _jsx(S.ContextMenuButton, { children: _jsx(IconMenuVertical, {}) }) })), state.isConfigMode && state.items.length < maxItems && contextMenuItems.length > 0 && (_jsx(ContextMenu, { items: getPinContextMenuItems(), trigger: "left", keepOpenOnClick: true, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Add, children: _jsx(S.AddButton, { children: _jsx(IconAdd, {}) }) }) })), state.isConfigMode && (_jsxs(_Fragment, { children: [_jsx(S.Separator, { "$orientation": state.orientation }), _jsxs(S.ButtonGroup, { "$orientation": state.orientation, children: [_jsx(TMTooltip, { content: SDKUI_Localizator.Undo, position: state.orientation === 'horizontal' ? 'right' : 'top', children: _jsx(S.UndoButton, { onClick: handleUndo, disabled: !hasChanges(), children: _jsx(IconUndo, { fontSize: 18 }) }) }), _jsx(TMTooltip, { content: state.items.length === 0
1061
- ? 'Devi aggiungere almeno un item'
1062
- : SDKUI_Localizator.Save, position: state.orientation === 'horizontal' ? 'right' : 'top', children: _jsx(S.ApplyButton, { onClick: toggleConfigMode, disabled: state.items.length === 0 || !hasChanges(), children: _jsx(IconSave, { fontSize: 20 }) }) }), _jsx(TMTooltip, { content: SDKUI_Localizator.Close, position: state.orientation === 'horizontal' ? 'right' : 'top', children: _jsx(S.CloseButton, { onClick: handleClose, children: _jsx(IconCloseOutline, { fontSize: 20 }) }) })] })] }))] })] }));
820
+ return (_jsxs(S.FloatingContainer, { ref: floatingRef, "$x": pixelPosition.x, "$y": pixelPosition.y, "$orientation": state.orientation, "$verticalDirection": state.verticalDirection, "$isDragging": state.isDragging, "$isConfigMode": false, "$isConstrained": isConstrained, "$isHidden": isOrientationChanging, "$bgColor": bgColor, onContextMenu: undefined, children: [_jsx(ContextMenu, { items: [
821
+ {
822
+ name: state.orientation === 'horizontal' ? 'Floating bar verticale' : 'Floating bar orizzontale',
823
+ icon: _jsx(IconRotate, { fontSize: 16, style: { transform: state.orientation === 'horizontal' ? 'rotate(90deg)' : 'rotate(0deg)' } }),
824
+ onClick: toggleOrientation,
825
+ },
826
+ ], trigger: "right", children: _jsx(S.GripHandle, { "$orientation": state.orientation, onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, onDoubleClick: handleGripDoubleClick, children: _jsx(IconDraggableDots, {}) }) }), _jsx(S.Separator, { "$orientation": state.orientation }), state.items.map((item, index) => {
827
+ // Handle separator items
828
+ if (item.isSeparator) {
829
+ return (_jsx(S.DraggableItem, { "$isDragging": state.draggedItemIndex === index, "$isDragOver": dragOverIndex === index && state.draggedItemIndex !== index, draggable: enableConfigMode, onDragStart: (e) => handleDragStart(e, index), onDragEnter: (e) => handleDragEnter(e, index), onDragOver: handleDragOver, onDragLeave: (e) => handleDragLeave(e, index), onDrop: (e) => handleDrop(e, index), onDragEnd: handleDragEnd, children: enableConfigMode ? (_jsx(ContextMenu, { items: getSeparatorRightClickMenuItems(index), trigger: "right", children: _jsx(S.ItemSeparator, { "$orientation": state.orientation, "$isConfigMode": false }) })) : (_jsx(S.ItemSeparator, { "$orientation": state.orientation, "$isConfigMode": false })) }, item.id));
830
+ }
831
+ // Get current state (disabled and onClick) from contextMenuItems
832
+ const currentState = getCurrentItemState(item.id);
833
+ // Prefer currentState.disabled if contextMenuItems has items, otherwise use item.disabled
834
+ const isDisabled = (contextMenuItems.length > 0 && currentState.disabled !== undefined)
835
+ ? currentState.disabled === true
836
+ : item.disabled === true;
837
+ const currentOnClick = currentState.onClick || item.onClick; // Fallback to stored onClick if not found
838
+ return (_jsx(S.DraggableItem, { "$isDragging": state.draggedItemIndex === index, "$isDragOver": dragOverIndex === index && state.draggedItemIndex !== index, draggable: enableConfigMode, onDragStart: (e) => handleDragStart(e, index), onDragEnter: (e) => handleDragEnter(e, index), onDragOver: handleDragOver, onDragLeave: (e) => handleDragLeave(e, index), onDrop: (e) => handleDrop(e, index), onDragEnd: handleDragEnd, children: enableConfigMode ? (_jsx(ContextMenu, { items: getItemRightClickMenuItems(item, index), trigger: "right", children: item.staticItem ? (_jsx("div", { children: item.staticItem })) : (_jsx(TMTooltip, { content: item.name, position: "bottom", children: _jsx(S.MenuButton, { onClick: () => {
839
+ if (isDisabled)
840
+ return;
841
+ if (currentOnClick) {
842
+ currentOnClick();
843
+ }
844
+ }, disabled: isDisabled, "$isActive": item.isToggle, children: item.icon }) })) })) : (item.staticItem ? (_jsx("div", { children: item.staticItem })) : (_jsx(TMTooltip, { content: item.name, position: "bottom", children: _jsx(S.MenuButton, { onClick: () => {
845
+ if (isDisabled)
846
+ return;
847
+ if (currentOnClick) {
848
+ currentOnClick();
849
+ }
850
+ }, disabled: isDisabled, "$isActive": item.isToggle, children: item.icon }) }))) }, item.id));
851
+ }), enableConfigMode && hasContextMenu && contextMenuItems.length > 0 && (_jsx(ContextMenu, { items: getContextMenuItemsWithPinIcons(), trigger: "left", keepOpenOnClick: false, children: _jsx(S.ContextMenuButton, { children: _jsx(IconMenuVertical, {}) }) }))] }));
1063
852
  };
1064
853
  export default TMFloatingMenuBar;
@@ -19,7 +19,7 @@ export interface TMFloatingMenuBarProps {
19
19
  contextMenuDefaultPinnedIds?: string[];
20
20
  defaultOrientation?: 'horizontal' | 'vertical';
21
21
  defaultItems?: TMFloatingMenuItem[];
22
- disbaleConfigMode?: boolean;
22
+ enableConfigMode?: boolean;
23
23
  bgColor?: string;
24
24
  hasContextMenu?: boolean;
25
25
  pinnedItemIds?: string[];
@@ -32,7 +32,6 @@ export interface Position {
32
32
  export interface TMFloatingMenuBarState {
33
33
  position: Position;
34
34
  isDragging: boolean;
35
- isConfigMode: boolean;
36
35
  orientation: 'horizontal' | 'vertical';
37
36
  verticalDirection: 'down' | 'up';
38
37
  items: TMFloatingMenuItem[];
@@ -1822,7 +1822,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
1822
1822
  }, [isFullScreen]);
1823
1823
  const diagramContent = (_jsxs(CanvasContainer, { onDoubleClick: handleCanvasDoubleClick, children: [_jsx("input", { ref: fileInputRef, type: "file", accept: ".xml" // Filtra per file XML
1824
1824
  , onChange: handleFileChange, style: { display: 'none' } }), SDK_Globals.tmSession?.SessionDescr?.appModuleID === AppModules.SURFER ?
1825
- _jsx(TMFloatingMenuBar, { containerRef: diagramRef, defaultPosition: { x: 45, y: 85 }, disbaleConfigMode: true, defaultItems: [
1825
+ _jsx(TMFloatingMenuBar, { containerRef: diagramRef, defaultPosition: { x: 45, y: 85 }, enableConfigMode: false, defaultItems: [
1826
1826
  { icon: _jsx(IconZoomIn, {}), name: SDKUI_Localizator.ZoomIn, disabled: isAutoZoomEnabled, onClick: () => { handleZoomIn(); }, id: 'zoom-in', isPinned: true },
1827
1827
  { icon: _jsx(IconZoomOut, {}), name: SDKUI_Localizator.ZoomOut, disabled: isAutoZoomEnabled, onClick: () => { handleZoomOut(); }, id: 'zoom-out', isPinned: true },
1828
1828
  { icon: _jsx(IconZoomAuto, {}), name: 'AutoZoom', onClick: () => { handleToggleAutoZoom(); }, id: 'zoom-auto', isPinned: true, isToggle: isAutoZoomEnabled },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.20.0-dev1.120",
3
+ "version": "6.20.0-dev1.121",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",