@topconsultnpm/sdkui-react 6.20.0-dev1.10 → 6.20.0-dev1.101

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.
Files changed (157) hide show
  1. package/lib/assets/Toppy-help-center.png +0 -0
  2. package/lib/components/NewComponents/ContextMenu/TMContextMenu.d.ts +4 -0
  3. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +441 -0
  4. package/lib/components/NewComponents/ContextMenu/hooks.d.ts +18 -0
  5. package/lib/components/NewComponents/ContextMenu/hooks.js +120 -0
  6. package/lib/components/NewComponents/ContextMenu/index.d.ts +5 -0
  7. package/lib/components/NewComponents/ContextMenu/index.js +3 -0
  8. package/lib/components/NewComponents/ContextMenu/styles.d.ts +35 -0
  9. package/lib/components/NewComponents/ContextMenu/styles.js +428 -0
  10. package/lib/components/NewComponents/ContextMenu/types.d.ts +39 -0
  11. package/lib/components/NewComponents/ContextMenu/types.js +1 -0
  12. package/lib/components/NewComponents/ContextMenu/useLongPress.d.ts +21 -0
  13. package/lib/components/NewComponents/ContextMenu/useLongPress.js +112 -0
  14. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.d.ts +4 -0
  15. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +821 -0
  16. package/lib/components/NewComponents/FloatingMenuBar/index.d.ts +2 -0
  17. package/lib/components/NewComponents/FloatingMenuBar/index.js +2 -0
  18. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +54 -0
  19. package/lib/components/NewComponents/FloatingMenuBar/styles.js +419 -0
  20. package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +36 -0
  21. package/lib/components/NewComponents/FloatingMenuBar/types.js +1 -0
  22. package/lib/components/base/TMAccordionNew.js +35 -14
  23. package/lib/components/base/TMCustomButton.js +61 -17
  24. package/lib/components/base/TMDataGrid.d.ts +7 -4
  25. package/lib/components/base/TMDataGrid.js +153 -11
  26. package/lib/components/base/TMDropDownMenu.js +19 -18
  27. package/lib/components/base/TMFileManager.d.ts +4 -3
  28. package/lib/components/base/TMFileManager.js +32 -24
  29. package/lib/components/base/TMFileManagerDataGridView.d.ts +3 -2
  30. package/lib/components/base/TMFileManagerDataGridView.js +1 -11
  31. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +7 -1
  32. package/lib/components/base/TMFileManagerThumbnailItems.js +5 -2
  33. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +17 -4
  34. package/lib/components/base/TMFileManagerThumbnailsView.js +18 -6
  35. package/lib/components/base/TMFileManagerUtils.d.ts +0 -12
  36. package/lib/components/base/TMListView.js +33 -15
  37. package/lib/components/base/TMPanel.d.ts +1 -1
  38. package/lib/components/base/TMPanel.js +1 -1
  39. package/lib/components/choosers/TMDistinctValues.js +1 -1
  40. package/lib/components/choosers/TMInvoiceRetrieveFormats.js +1 -1
  41. package/lib/components/choosers/TMMetadataChooser.js +8 -1
  42. package/lib/components/choosers/TMOrderRetrieveFormats.js +1 -1
  43. package/lib/components/choosers/TMUserChooser.d.ts +0 -5
  44. package/lib/components/choosers/TMUserChooser.js +25 -45
  45. package/lib/components/editors/TMDateBox.js +18 -9
  46. package/lib/components/editors/TMMetadataValues.js +23 -5
  47. package/lib/components/editors/TMTextArea.js +18 -30
  48. package/lib/components/editors/TMTextBox.js +6 -3
  49. package/lib/components/features/archive/TMArchive.js +2 -2
  50. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +15 -0
  51. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +460 -0
  52. package/lib/components/features/assistant/TMToppySpeechBubble.d.ts +11 -0
  53. package/lib/components/features/assistant/TMToppySpeechBubble.js +126 -0
  54. package/lib/components/features/documents/TMDcmtForm.d.ts +14 -2
  55. package/lib/components/features/documents/TMDcmtForm.js +457 -206
  56. package/lib/components/features/documents/TMDcmtPreview.js +45 -108
  57. package/lib/components/features/documents/TMDcmtTasks.js +9 -9
  58. package/lib/components/features/documents/TMMasterDetailDcmts.js +38 -53
  59. package/lib/components/features/documents/TMRelationViewer.d.ts +1 -1
  60. package/lib/components/features/documents/TMRelationViewer.js +2 -2
  61. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +8 -0
  62. package/lib/components/features/search/{TMSearchResultCheckoutInfoForm.js → TMDcmtCheckoutInfoForm.js} +2 -2
  63. package/lib/components/features/search/TMSavedQuerySelector.js +72 -67
  64. package/lib/components/features/search/TMSearch.d.ts +3 -0
  65. package/lib/components/features/search/TMSearch.js +50 -11
  66. package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -0
  67. package/lib/components/features/search/TMSearchQueryPanel.js +29 -21
  68. package/lib/components/features/search/TMSearchResult.d.ts +3 -0
  69. package/lib/components/features/search/TMSearchResult.js +208 -250
  70. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +3 -3
  71. package/lib/components/features/search/TMSearchResultsMenuItems.js +205 -169
  72. package/lib/components/features/search/TMSignSettingsForm.js +1 -1
  73. package/lib/components/features/search/TMSignatureInfoContent.d.ts +6 -0
  74. package/lib/components/features/search/TMSignatureInfoContent.js +140 -0
  75. package/lib/components/features/search/TMViewHistoryDcmt.js +2 -2
  76. package/lib/components/features/tasks/TMTaskForm.js +20 -1
  77. package/lib/components/features/tasks/TMTasksAgenda.d.ts +3 -1
  78. package/lib/components/features/tasks/TMTasksAgenda.js +48 -9
  79. package/lib/components/features/tasks/TMTasksCalendar.d.ts +2 -0
  80. package/lib/components/features/tasks/TMTasksCalendar.js +19 -7
  81. package/lib/components/features/tasks/TMTasksUtils.d.ts +2 -2
  82. package/lib/components/features/tasks/TMTasksUtils.js +43 -36
  83. package/lib/components/features/tasks/TMTasksView.js +28 -19
  84. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +33 -2
  85. package/lib/components/features/workflow/TMWorkflowPopup.js +139 -34
  86. package/lib/components/features/workflow/diagram/DiagramItemComponent.d.ts +2 -0
  87. package/lib/components/features/workflow/diagram/DiagramItemComponent.js +12 -7
  88. package/lib/components/features/workflow/diagram/RecipientList.js +3 -2
  89. package/lib/components/features/workflow/diagram/WFDiagram.d.ts +4 -0
  90. package/lib/components/features/workflow/diagram/WFDiagram.js +164 -13
  91. package/lib/components/forms/Login/LoginValidatorService.d.ts +2 -0
  92. package/lib/components/forms/Login/LoginValidatorService.js +7 -2
  93. package/lib/components/forms/Login/TMLoginForm.js +34 -6
  94. package/lib/components/forms/TMChooserForm.js +1 -1
  95. package/lib/components/grids/TMBlogsPost.js +56 -31
  96. package/lib/components/grids/TMRecentsManager.js +20 -10
  97. package/lib/components/index.d.ts +5 -3
  98. package/lib/components/index.js +5 -3
  99. package/lib/components/query/TMQueryEditor.d.ts +2 -1
  100. package/lib/components/query/TMQueryEditor.js +92 -92
  101. package/lib/components/settings/SettingsAppearance.d.ts +2 -1
  102. package/lib/components/settings/SettingsAppearance.js +99 -30
  103. package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
  104. package/lib/components/viewers/TMDataListItemViewer.js +35 -71
  105. package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +8 -0
  106. package/lib/components/viewers/TMDataUserIdItemViewer.js +39 -0
  107. package/lib/css/tm-sdkui.css +1 -1
  108. package/lib/helper/SDKUI_Globals.d.ts +22 -0
  109. package/lib/helper/SDKUI_Globals.js +10 -1
  110. package/lib/helper/SDKUI_Localizator.d.ts +17 -1
  111. package/lib/helper/SDKUI_Localizator.js +167 -1
  112. package/lib/helper/TMCommandsContextMenu.d.ts +4 -2
  113. package/lib/helper/TMCommandsContextMenu.js +15 -4
  114. package/lib/helper/TMIcons.d.ts +4 -0
  115. package/lib/helper/TMIcons.js +13 -3
  116. package/lib/helper/TMPdfViewer.d.ts +8 -0
  117. package/lib/helper/TMPdfViewer.js +373 -0
  118. package/lib/helper/checkinCheckoutManager.d.ts +31 -1
  119. package/lib/helper/checkinCheckoutManager.js +112 -30
  120. package/lib/helper/devextremeCustomMessages.d.ts +30 -0
  121. package/lib/helper/devextremeCustomMessages.js +30 -0
  122. package/lib/helper/helpers.d.ts +3 -1
  123. package/lib/helper/helpers.js +25 -3
  124. package/lib/helper/index.d.ts +2 -0
  125. package/lib/helper/index.js +2 -0
  126. package/lib/helper/queryHelper.d.ts +1 -1
  127. package/lib/helper/queryHelper.js +33 -3
  128. package/lib/helper/workItemsHelper.d.ts +6 -0
  129. package/lib/helper/workItemsHelper.js +230 -0
  130. package/lib/hooks/useCheckInOutOperations.d.ts +28 -0
  131. package/lib/hooks/useCheckInOutOperations.js +223 -0
  132. package/lib/hooks/useDataListItem.d.ts +12 -0
  133. package/lib/hooks/useDataListItem.js +132 -0
  134. package/lib/hooks/useDataUserIdItem.d.ts +10 -0
  135. package/lib/hooks/useDataUserIdItem.js +96 -0
  136. package/lib/hooks/useSettingsFeedback.d.ts +11 -0
  137. package/lib/hooks/useSettingsFeedback.js +38 -0
  138. package/lib/hooks/useWorkflowApprove.d.ts +4 -0
  139. package/lib/hooks/useWorkflowApprove.js +14 -1
  140. package/lib/index.d.ts +1 -0
  141. package/lib/index.js +3 -2
  142. package/lib/services/platform_services.d.ts +3 -3
  143. package/lib/ts/types.d.ts +61 -1
  144. package/lib/utils/theme.d.ts +1 -1
  145. package/lib/utils/theme.js +1 -1
  146. package/package.json +7 -4
  147. package/lib/components/base/TMContextMenu.d.ts +0 -25
  148. package/lib/components/base/TMContextMenu.js +0 -109
  149. package/lib/components/base/TMContextMenuOLD.d.ts +0 -26
  150. package/lib/components/base/TMContextMenuOLD.js +0 -56
  151. package/lib/components/base/TMFloatingToolbar.d.ts +0 -9
  152. package/lib/components/base/TMFloatingToolbar.js +0 -101
  153. package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +0 -30
  154. package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +0 -482
  155. package/lib/components/features/assistant/ToppySpeechBubble.d.ts +0 -9
  156. package/lib/components/features/assistant/ToppySpeechBubble.js +0 -117
  157. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +0 -8
@@ -0,0 +1,2 @@
1
+ export { default } from './TMFloatingMenuBar';
2
+ export * from './types';
@@ -0,0 +1,2 @@
1
+ export { default } from './TMFloatingMenuBar';
2
+ export * from './types';
@@ -0,0 +1,54 @@
1
+ export declare const Overlay: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
2
+ $visible: boolean;
3
+ }>> & string;
4
+ export declare const FloatingContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("styled-components/dist/types").Substitute<import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
5
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
6
+ }>, {
7
+ $x: number;
8
+ $y: number;
9
+ $orientation: "horizontal" | "vertical";
10
+ $isDragging: boolean;
11
+ $isConfigMode: boolean;
12
+ $isConstrained?: boolean;
13
+ $bgColor?: string;
14
+ }>, {
15
+ $x: number;
16
+ $y: number;
17
+ $orientation: "horizontal" | "vertical";
18
+ $isDragging: boolean;
19
+ $isConfigMode: boolean;
20
+ $isConstrained?: boolean;
21
+ $bgColor?: string;
22
+ }>> & string;
23
+ export declare const GripHandle: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
24
+ $orientation: "horizontal" | "vertical";
25
+ }>> & string;
26
+ export declare const Separator: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
27
+ $orientation: "horizontal" | "vertical";
28
+ }>> & string;
29
+ export declare const ItemSeparator: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
30
+ $orientation: "horizontal" | "vertical";
31
+ $isConfigMode: boolean;
32
+ }>> & string;
33
+ export declare const MenuButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {
34
+ $isActive?: boolean;
35
+ }>> & string;
36
+ export declare const ConfigButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
37
+ export declare const ApplyButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
38
+ export declare const CloseButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
39
+ export declare const ContextMenuButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "$isActive"> & {
40
+ $isActive?: boolean;
41
+ }, "ref"> & {
42
+ ref?: ((instance: HTMLButtonElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLButtonElement> | null | undefined;
43
+ }, never>> & string;
44
+ export declare const AddButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
45
+ export declare const RemoveButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
46
+ export declare const UndoButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
47
+ export declare const DraggableItem: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
48
+ $isDragging: boolean;
49
+ $isDragOver: boolean;
50
+ }>> & string;
51
+ export declare const ContextMenuWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
52
+ export declare const ButtonGroup: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
53
+ $orientation: "horizontal" | "vertical";
54
+ }>> & string;
@@ -0,0 +1,419 @@
1
+ import styled, { keyframes, css } from 'styled-components';
2
+ const fadeIn = keyframes `
3
+ from {
4
+ opacity: 0;
5
+ transform: scale(0.95);
6
+ }
7
+ to {
8
+ opacity: 1;
9
+ transform: scale(1);
10
+ }
11
+ `;
12
+ const shake = keyframes `
13
+ 0%, 100% { transform: translateX(0); }
14
+ 25% { transform: translateX(-2px); }
15
+ 75% { transform: translateX(2px); }
16
+ `;
17
+ export const Overlay = styled.div `
18
+ position: fixed;
19
+ top: 0;
20
+ left: 0;
21
+ right: 0;
22
+ bottom: 0;
23
+ background: rgba(255, 255, 255, 0.8);
24
+ z-index: 9998;
25
+ display: ${props => props.$visible ? 'block' : 'none'};
26
+ animation: ${fadeIn} 0.2s ease-out;
27
+ backdrop-filter: blur(2px);
28
+
29
+ [data-theme='dark'] & {
30
+ background: rgba(0, 0, 0, 0.8);
31
+ }
32
+ `;
33
+ export const FloatingContainer = styled.div.attrs(props => ({
34
+ style: {
35
+ left: `${props.$x}px`,
36
+ top: `${props.$y}px`,
37
+ },
38
+ })) `
39
+ position: ${props => props.$isConstrained ? 'absolute' : 'fixed'};
40
+ z-index: ${props => props.$isConfigMode ? 9999 : 1500};
41
+ display: flex;
42
+ flex-direction: ${props => props.$orientation === 'horizontal' ? 'row' : 'column'};
43
+ align-items: center;
44
+ background: ${props => props.$bgColor || 'linear-gradient(135deg, #0071BC 0%, #1B1464 100%)'};
45
+ border: 1px solid #667eea;
46
+ border-radius: 14px;
47
+ padding: 6px;
48
+ gap: 3px;
49
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3),
50
+ 0 6px 16px rgba(0, 0, 0, 0.2);
51
+ cursor: ${props => props.$isDragging ? 'grabbing' : 'default'};
52
+ user-select: none;
53
+ animation: ${props => props.$isConfigMode && css `${shake} 0.3s ease-in-out`};
54
+ transition: none;
55
+
56
+ &:hover {
57
+ background: ${props => props.$bgColor || 'linear-gradient(135deg, #0071BC 0%, #1B1464 100%)'};
58
+ border: 1px solid #667eea;
59
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3),
60
+ 0 6px 16px rgba(0, 0, 0, 0.2);
61
+ }
62
+
63
+ [data-theme='dark'] & {
64
+ background: ${props => props.$bgColor || 'linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)'};
65
+ border: 1px solid #1a1a2e;
66
+
67
+ &:hover {
68
+ background: ${props => props.$bgColor || 'linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)'};
69
+ border: 1px solid #1a1a2e;
70
+ }
71
+ }
72
+ `;
73
+ export const GripHandle = styled.div `
74
+ display: flex;
75
+ align-items: center;
76
+ justify-content: center;
77
+ padding: ${props => props.$orientation === 'horizontal' ? '6px 4px' : '4px 6px'};
78
+ cursor: grab;
79
+ color: rgba(255, 255, 255, 0.7);
80
+ transition: all 0.2s ease;
81
+ border-radius: 6px;
82
+
83
+ &:hover {
84
+ background: rgba(255, 255, 255, 0.1);
85
+ color: rgba(255, 255, 255, 1);
86
+ }
87
+
88
+ &:active {
89
+ cursor: grabbing;
90
+ background: rgba(255, 255, 255, 0.15);
91
+ }
92
+
93
+ svg {
94
+ width: 14px;
95
+ height: 14px;
96
+ }
97
+ `;
98
+ export const Separator = styled.div `
99
+ background: rgba(255, 255, 255, 0.25);
100
+ width: ${props => props.$orientation === 'horizontal' ? '1px' : '100%'};
101
+ height: ${props => props.$orientation === 'horizontal' ? '20px' : '1px'};
102
+ margin: ${props => props.$orientation === 'horizontal' ? '0 4px' : '4px 0'};
103
+ flex-shrink: 0;
104
+ `;
105
+ export const ItemSeparator = styled.div `
106
+ flex-shrink: 0;
107
+ transition: all 0.2s ease;
108
+
109
+ ${props => props.$isConfigMode ? `
110
+ /* Edit mode: look exactly like MenuButton */
111
+ display: flex;
112
+ align-items: center;
113
+ justify-content: center;
114
+ width: 30px;
115
+ height: 30px;
116
+ background: transparent;
117
+ border-radius: 8px;
118
+ cursor: grab;
119
+ position: relative;
120
+
121
+ &::before {
122
+ content: '';
123
+ background: rgba(255, 255, 255, 0.25);
124
+ width: ${props.$orientation === 'horizontal' ? '2px' : '100%'};
125
+ height: ${props.$orientation === 'horizontal' ? '18px' : '2px'};
126
+ border-radius: 1px;
127
+ }
128
+
129
+ &:hover {
130
+ background: rgba(255, 255, 255, 0.2);
131
+ }
132
+
133
+ &:active {
134
+ opacity: 0.8;
135
+ }
136
+ ` : `
137
+ /* Normal mode: simple line with tight spacing */
138
+ background: rgba(255, 255, 255, 0.25);
139
+ width: ${props.$orientation === 'horizontal' ? '1px' : '100%'};
140
+ height: ${props.$orientation === 'horizontal' ? '20px' : '1px'};
141
+ margin: ${props.$orientation === 'horizontal' ? '0 2px' : '2px 0'};
142
+ `}
143
+ `;
144
+ export const MenuButton = styled.button `
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: center;
148
+ width: 30px;
149
+ height: 30px;
150
+ background: ${props => props.$isActive ? 'rgba(102, 179, 255, 0.3)' : 'transparent'};
151
+ border: none;
152
+ border-radius: 8px;
153
+ color: white;
154
+ font-size: 16px;
155
+ cursor: pointer;
156
+ transition: background 0.2s ease;
157
+ position: relative;
158
+
159
+ &:hover:not(:disabled) {
160
+ background: ${props => props.$isActive ? 'rgba(102, 179, 255, 0.4)' : 'rgba(255, 255, 255, 0.2)'};
161
+ }
162
+
163
+ &:active:not(:disabled) {
164
+ opacity: 0.8;
165
+ }
166
+
167
+ &:disabled {
168
+ opacity: 0.5;
169
+ cursor: default;
170
+ color: rgba(255, 255, 255, 0.6);
171
+ }
172
+
173
+ svg {
174
+ width: 18px;
175
+ height: 18px;
176
+ }
177
+ `;
178
+ export const ConfigButton = styled.button `
179
+ display: flex;
180
+ align-items: center;
181
+ justify-content: center;
182
+ width: 21px;
183
+ height: 21px;
184
+ background: transparent;
185
+ border: none;
186
+ border-radius: 4px;
187
+ color: rgba(255, 255, 255, 0.5);
188
+ font-size: 10px;
189
+ cursor: pointer;
190
+ transition: all 0.2s ease;
191
+ padding: 4px;
192
+
193
+ &:hover:not(:disabled) {
194
+ background: rgba(255, 255, 255, 0.1);
195
+ color: rgba(255, 255, 255, 0.8);
196
+ }
197
+
198
+ &:active:not(:disabled) {
199
+ transform: scale(0.9);
200
+ }
201
+
202
+ &:disabled {
203
+ opacity: 0.3;
204
+ cursor: not-allowed;
205
+ }
206
+
207
+ svg {
208
+ width: 16px;
209
+ height: 16px;
210
+ }
211
+ `;
212
+ export const ApplyButton = styled.button `
213
+ display: flex;
214
+ align-items: center;
215
+ justify-content: center;
216
+ width: 24px;
217
+ height: 24px;
218
+ background: transparent;
219
+ border: none;
220
+ border-radius: 4px;
221
+ color: rgba(34, 197, 94, 1);
222
+ font-size: 10px;
223
+ cursor: pointer;
224
+ transition: all 0.2s ease;
225
+ padding: 3px;
226
+
227
+ &:hover:not(:disabled) {
228
+ background: rgba(255, 255, 255, 0.1);
229
+ color: rgba(34, 197, 94, 1);
230
+ }
231
+
232
+ &:active:not(:disabled) {
233
+ transform: scale(0.9);
234
+ }
235
+
236
+ &:disabled {
237
+ opacity: 0.3;
238
+ cursor: default;
239
+ }
240
+
241
+ svg {
242
+ width: 20px;
243
+ height: 20px;
244
+ }
245
+ `;
246
+ export const CloseButton = styled.button `
247
+ display: flex;
248
+ align-items: center;
249
+ justify-content: center;
250
+ width: 24px;
251
+ height: 24px;
252
+ background: transparent;
253
+ border: none;
254
+ border-radius: 4px;
255
+ color: rgba(239, 68, 68, 1);
256
+ font-size: 10px;
257
+ cursor: pointer;
258
+ transition: all 0.2s ease;
259
+ padding: 3px;
260
+
261
+ &:hover:not(:disabled) {
262
+ background: rgba(255, 255, 255, 0.1);
263
+ color: rgba(239, 68, 68, 1);
264
+ }
265
+
266
+ &:active:not(:disabled) {
267
+ transform: scale(0.9);
268
+ }
269
+
270
+ &:disabled {
271
+ opacity: 0.3;
272
+ cursor: default;
273
+ }
274
+
275
+ svg {
276
+ width: 20px;
277
+ height: 20px;
278
+ }
279
+ `;
280
+ export const ContextMenuButton = styled(MenuButton) `
281
+ svg {
282
+ transform: translateY(0);
283
+ }
284
+ `;
285
+ export const AddButton = styled.button `
286
+ display: flex;
287
+ align-items: center;
288
+ justify-content: center;
289
+ width: 26px;
290
+ height: 26px;
291
+ background: rgba(255, 255, 255, 0.15);
292
+ border: 1px dashed rgba(255, 255, 255, 0.4);
293
+ border-radius: 8px;
294
+ color: white;
295
+ font-size: 18px;
296
+ font-weight: bold;
297
+ line-height: 0;
298
+ cursor: pointer;
299
+ transition: all 0.2s ease;
300
+ position: relative;
301
+ margin-right: 6px;
302
+ margin-left: 8px;
303
+ padding: 0;
304
+
305
+ &:hover {
306
+ background: rgba(255, 255, 255, 0.25);
307
+ border-color: rgba(255, 255, 255, 0.6);
308
+ }
309
+
310
+ &:active {
311
+ transform: scale(0.95);
312
+ }
313
+ `;
314
+ export const RemoveButton = styled.button `
315
+ position: absolute;
316
+ top: -6px;
317
+ right: -6px;
318
+ width: 20px;
319
+ height: 20px;
320
+ background: #ef4444;
321
+ border: none;
322
+ border-radius: 50%;
323
+ color: white;
324
+ font-size: 14px;
325
+ font-weight: bold;
326
+ line-height: 0;
327
+ cursor: pointer;
328
+ display: flex;
329
+ align-items: center;
330
+ justify-content: center;
331
+ padding: 0;
332
+ transition: all 0.2s ease;
333
+ z-index: 1;
334
+
335
+ &:hover {
336
+ background: #dc2626;
337
+ }
338
+
339
+ &:active {
340
+ background: #b91c1c;
341
+ }
342
+ `;
343
+ export const UndoButton = styled.button `
344
+ display: flex;
345
+ align-items: center;
346
+ justify-content: center;
347
+ width: 24px;
348
+ height: 24px;
349
+ background: transparent;
350
+ border: none;
351
+ border-radius: 4px;
352
+ color: rgba(249, 115, 22, 1);
353
+ font-size: 10px;
354
+ cursor: pointer;
355
+ transition: all 0.2s ease;
356
+ padding: 2px;
357
+
358
+ &:hover:not(:disabled) {
359
+ background: rgba(255, 255, 255, 0.1);
360
+ color: rgba(249, 115, 22, 1);
361
+ }
362
+
363
+ &:active:not(:disabled) {
364
+ transform: scale(0.9);
365
+ }
366
+
367
+ &:disabled {
368
+ opacity: 0.3;
369
+ cursor: default;
370
+ }
371
+
372
+ svg {
373
+ width: 16px;
374
+ height: 16px;
375
+ }
376
+ `;
377
+ export const DraggableItem = styled.div `
378
+ position: relative;
379
+ opacity: ${props => props.$isDragging ? 0.3 : 1};
380
+ transform: ${props => {
381
+ if (props.$isDragging)
382
+ return 'scale(1.1) rotate(5deg)';
383
+ if (props.$isDragOver)
384
+ return 'scale(1.05)';
385
+ return 'scale(1)';
386
+ }};
387
+ transition: all 0.2s ease;
388
+ filter: ${props => props.$isDragging ? 'brightness(1.3)' : 'brightness(1)'};
389
+
390
+ ${props => props.$isDragging && css `
391
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
392
+ z-index: 100;
393
+ `}
394
+
395
+ ${props => props.$isDragOver && css `
396
+ &::before {
397
+ content: '';
398
+ position: absolute;
399
+ top: -4px;
400
+ left: 50%;
401
+ transform: translateX(-50%);
402
+ width: 40px;
403
+ height: 3px;
404
+ background: rgba(255, 255, 255, 0.8);
405
+ border-radius: 2px;
406
+ box-shadow: 0 0 8px rgba(255, 255, 255, 0.6);
407
+ }
408
+ `}
409
+ `;
410
+ export const ContextMenuWrapper = styled.div `
411
+ position: static;
412
+ display: contents;
413
+ `;
414
+ export const ButtonGroup = styled.div `
415
+ display: flex;
416
+ flex-direction: ${props => props.$orientation === 'vertical' ? 'column' : 'row'};
417
+ align-items: center;
418
+ gap: 0;
419
+ `;
@@ -0,0 +1,36 @@
1
+ import type { TMContextMenuItemProps } from '../ContextMenu';
2
+ export interface TMFloatingMenuItem {
3
+ id: string;
4
+ name: string;
5
+ icon: React.ReactNode;
6
+ onClick: () => void;
7
+ disabled?: boolean;
8
+ isPinned?: boolean;
9
+ isSeparator?: boolean;
10
+ isToggle?: boolean;
11
+ staticItem?: React.ReactNode;
12
+ }
13
+ export interface TMFloatingMenuBarProps {
14
+ containerRef: React.RefObject<HTMLElement | null>;
15
+ contextMenuItems?: TMContextMenuItemProps[];
16
+ isConstrained?: boolean;
17
+ defaultPosition?: Position;
18
+ maxItems?: number;
19
+ contextMenuDefaultPinnedIds?: string[];
20
+ defaultOrientation?: 'horizontal' | 'vertical';
21
+ defaultItems?: TMFloatingMenuItem[];
22
+ disbaleConfigMode?: boolean;
23
+ bgColor?: string;
24
+ }
25
+ export interface Position {
26
+ x: number;
27
+ y: number;
28
+ }
29
+ export interface TMFloatingMenuBarState {
30
+ position: Position;
31
+ isDragging: boolean;
32
+ isConfigMode: boolean;
33
+ orientation: 'horizontal' | 'vertical';
34
+ items: TMFloatingMenuItem[];
35
+ draggedItemIndex: number | null;
36
+ }
@@ -1,9 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useState, useEffect, useCallback } from 'react';
3
3
  import styled from 'styled-components';
4
- import { ContextMenu, LoadIndicator } from 'devextreme-react';
4
+ import { LoadIndicator } from 'devextreme-react';
5
5
  import { LocalStorageService } from '@topconsultnpm/sdk-ts';
6
6
  import TMTooltip from './TMTooltip';
7
+ import TMContextMenu from '../NewComponents/ContextMenu/TMContextMenu';
7
8
  const Container = styled.div `
8
9
  width: 100%;
9
10
  height: 100%;
@@ -154,12 +155,15 @@ const DEFAULT_COLORS = ['#339af0', '#fa5252', '#40c057', '#f59f00', '#e64980', '
154
155
  const TMAccordion = ({ groups, localStorageKey, selectedItem, onSelectedItemChange }) => {
155
156
  const [openAccordions, setOpenAccordions] = useState({});
156
157
  const [isInitialized, setIsInitialized] = useState(false);
157
- const [anchorEl, setAnchorEl] = useState(null);
158
- const [contextMenuItems, setContextMenuItems] = useState([]);
159
158
  const [focusedItem, setFocusedItem] = useState(undefined);
159
+ // Item context menu state
160
+ const [itemContextMenuVisible, setItemContextMenuVisible] = useState(false);
161
+ const [itemContextMenuPosition, setItemContextMenuPosition] = useState({ x: 0, y: 0 });
162
+ const [itemContextMenuItems, setItemContextMenuItems] = useState([]);
163
+ // Header context menu state
160
164
  const [headerContextGroupId, setHeaderContextGroupId] = useState(null);
161
165
  const [headerContextVisible, setHeaderContextVisible] = useState(false);
162
- const [headerContextPosition, setHeaderContextPosition] = useState(null);
166
+ const [headerContextPosition, setHeaderContextPosition] = useState({ x: 0, y: 0 });
163
167
  useEffect(() => {
164
168
  const initialState = {};
165
169
  if (!groups || groups.length === 0) {
@@ -240,11 +244,21 @@ const TMAccordion = ({ groups, localStorageKey, selectedItem, onSelectedItemChan
240
244
  if (menuItems.length === 0) {
241
245
  return;
242
246
  }
243
- setAnchorEl(event.currentTarget);
244
- setContextMenuItems(menuItems);
247
+ // Convert to TMContextMenuItemProps format
248
+ const convertedItems = menuItems.map((mi) => ({
249
+ name: mi.text || mi.name || '',
250
+ // Only pass icon if it's a React element, not a string (DevExtreme used string icons)
251
+ icon: typeof mi.icon === 'string' ? undefined : mi.icon,
252
+ disabled: mi.disabled,
253
+ onClick: mi.onClick,
254
+ submenu: mi.items || mi.submenu,
255
+ }));
256
+ setItemContextMenuPosition({ x: event.clientX, y: event.clientY });
257
+ setItemContextMenuItems(convertedItems);
258
+ setItemContextMenuVisible(true);
245
259
  };
246
260
  const closeContextMenu = useCallback(() => {
247
- setAnchorEl(null);
261
+ setItemContextMenuVisible(false);
248
262
  }, []);
249
263
  const handleHeaderContextMenu = (event, groupId) => {
250
264
  event.preventDefault();
@@ -260,12 +274,11 @@ const TMAccordion = ({ groups, localStorageKey, selectedItem, onSelectedItemChan
260
274
  };
261
275
  const closeHeaderContextMenu = useCallback(() => {
262
276
  setHeaderContextVisible(false);
263
- setHeaderContextPosition(null);
264
277
  setHeaderContextGroupId(null);
265
278
  }, []);
266
279
  const headerContextMenuItems = headerContextGroupId ? [
267
280
  {
268
- text: openAccordions[headerContextGroupId] ? 'Collassa' : 'Espandi',
281
+ name: openAccordions[headerContextGroupId] ? 'Collassa' : 'Espandi',
269
282
  onClick: () => {
270
283
  toggleAccordion(headerContextGroupId);
271
284
  closeHeaderContextMenu();
@@ -295,19 +308,19 @@ const TMAccordion = ({ groups, localStorageKey, selectedItem, onSelectedItemChan
295
308
  const color = getGroupColor(group, index);
296
309
  const isOpen = openAccordions[group.id] ?? true;
297
310
  if (group.customComponent) {
298
- return (_jsxs(AccordionItem, { children: [_jsxs(AccordionHeader, { "$color": color, "$isOpen": isOpen, onClick: (e) => handleHeaderClick(e, group.id), onContextMenu: (e) => handleHeaderContextMenu(e, group.id), children: [_jsxs(AccordionTitle, { children: [group.icon, _jsx(TitleText, { children: group.title })] }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [renderBadges(group, color), _jsx(ToggleIcon, { "$isOpen": isOpen, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: _jsx("path", { d: "M4 6L8 10L12 6", stroke: "#495057", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }), isOpen && (_jsx(CustomComponentContainer, { children: group.customComponent }))] }, group.id));
311
+ return (_jsxs(AccordionItem, { children: [_jsxs(AccordionHeader, { id: `accordion-header-${group.id}`, "$color": color, "$isOpen": isOpen, onClick: (e) => handleHeaderClick(e, group.id), onContextMenu: (e) => handleHeaderContextMenu(e, group.id), children: [_jsxs(AccordionTitle, { children: [group.icon, _jsx(TitleText, { children: group.title })] }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [renderBadges(group, color), _jsx(ToggleIcon, { "$isOpen": isOpen, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: _jsx("path", { d: "M4 6L8 10L12 6", stroke: "#495057", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }), isOpen && (_jsx(CustomComponentContainer, { children: group.customComponent }))] }, group.id));
299
312
  }
300
313
  if (!group.dataSource || group.dataSource.length === 0)
301
314
  return null;
302
315
  if (!group.renderItem) {
303
- return (_jsxs(AccordionItem, { children: [_jsxs(AccordionHeader, { "$color": color, "$isOpen": isOpen, onClick: (e) => handleHeaderClick(e, group.id), onContextMenu: (e) => handleHeaderContextMenu(e, group.id), children: [_jsxs(AccordionTitle, { children: [group.icon, _jsx(TitleText, { children: group.title })] }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [renderBadges(group, color), _jsx(ToggleIcon, { "$isOpen": isOpen, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: _jsx("path", { d: "M4 6L8 10L12 6", stroke: "#495057", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }), _jsx(AccordionContent, { "$isOpen": isOpen, "$maxHeight": 100, children: _jsxs(ErrorMessage, { children: ["\u26A0\uFE0F renderItem function is required for \"", group.title, "\" group"] }) })] }, group.id));
316
+ return (_jsxs(AccordionItem, { children: [_jsxs(AccordionHeader, { id: `accordion-header-${group.id}`, "$color": color, "$isOpen": isOpen, onClick: (e) => handleHeaderClick(e, group.id), onContextMenu: (e) => handleHeaderContextMenu(e, group.id), children: [_jsxs(AccordionTitle, { children: [group.icon, _jsx(TitleText, { children: group.title })] }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [renderBadges(group, color), _jsx(ToggleIcon, { "$isOpen": isOpen, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: _jsx("path", { d: "M4 6L8 10L12 6", stroke: "#495057", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }), _jsx(AccordionContent, { "$isOpen": isOpen, "$maxHeight": 100, children: _jsxs(ErrorMessage, { children: ["\u26A0\uFE0F renderItem function is required for \"", group.title, "\" group"] }) })] }, group.id));
304
317
  }
305
318
  const itemHeight = group.itemHeight || 80;
306
319
  const maxHeight = group.dataSource.length * itemHeight + 20;
307
- return (_jsxs(AccordionItem, { children: [_jsxs(AccordionHeader, { "$color": color, "$isOpen": isOpen, onClick: (e) => handleHeaderClick(e, group.id), onContextMenu: (e) => handleHeaderContextMenu(e, group.id), children: [_jsxs(AccordionTitle, { children: [group.icon, _jsx(TitleText, { children: group.title })] }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [renderBadges(group, color), _jsx(ToggleIcon, { "$isOpen": isOpen, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: _jsx("path", { d: "M4 6L8 10L12 6", stroke: "#495057", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }), _jsx(AccordionContent, { "$isOpen": isOpen, "$maxHeight": maxHeight, children: _jsx(ItemsList, { children: group.dataSource.map((item, itemIndex) => {
320
+ return (_jsxs(AccordionItem, { children: [_jsxs(AccordionHeader, { id: `accordion-header-${group.id}`, "$color": color, "$isOpen": isOpen, onClick: (e) => handleHeaderClick(e, group.id), onContextMenu: (e) => handleHeaderContextMenu(e, group.id), children: [_jsxs(AccordionTitle, { children: [group.icon, _jsx(TitleText, { children: group.title })] }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [renderBadges(group, color), _jsx(ToggleIcon, { "$isOpen": isOpen, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: _jsx("path", { d: "M4 6L8 10L12 6", stroke: "#495057", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }), _jsx(AccordionContent, { "$isOpen": isOpen, "$maxHeight": maxHeight, children: _jsx(ItemsList, { children: group.dataSource.map((item, itemIndex) => {
308
321
  const isSelected = selectedItem === item;
309
322
  const isFocused = focusedItem === item;
310
- return (_jsx(ListItem, { "$isSelected": isSelected, "$color": color, onClick: () => handleItemClick(item, group), onDoubleClick: () => handleItemDoubleClick(item, group), onMouseEnter: () => setFocusedItem(item), onMouseLeave: () => setFocusedItem(undefined), onContextMenu: (e) => handleContextMenu(e, item, group), children: group.renderItem(item, isSelected, isFocused, color) }, itemIndex * 2));
323
+ return (_jsx(ListItem, { id: `accordion-item-${group.id}-${itemIndex}`, className: "tm-accordion-list-item", "$isSelected": isSelected, "$color": color, onClick: () => handleItemClick(item, group), onDoubleClick: () => handleItemDoubleClick(item, group), onMouseEnter: () => setFocusedItem(item), onMouseLeave: () => setFocusedItem(undefined), onContextMenu: (e) => handleContextMenu(e, item, group), children: group.renderItem(item, isSelected, isFocused, color) }, itemIndex * 2));
311
324
  }) }) })] }, group.id));
312
325
  };
313
326
  if (!isInitialized) {
@@ -321,6 +334,14 @@ const TMAccordion = ({ groups, localStorageKey, selectedItem, onSelectedItemChan
321
334
  event.preventDefault();
322
335
  }
323
336
  };
324
- return (_jsxs(_Fragment, { children: [_jsx(Container, { onContextMenu: handleContainerContextMenu, children: groups.map((group, index) => renderAccordion(group, index)) }), anchorEl && contextMenuItems.length > 0 && (_jsx(ContextMenu, { dataSource: contextMenuItems, target: anchorEl, onHiding: closeContextMenu })), headerContextPosition && headerContextMenuItems.length > 0 && (_jsx(ContextMenu, { dataSource: headerContextMenuItems, visible: headerContextVisible, position: { my: 'left top', at: 'left top', offset: `${headerContextPosition.x} ${headerContextPosition.y}` }, onHiding: closeHeaderContextMenu }))] }));
337
+ return (_jsxs(_Fragment, { children: [_jsx(Container, { onContextMenu: handleContainerContextMenu, children: groups.map((group, index) => renderAccordion(group, index)) }), _jsx(TMContextMenu, { items: itemContextMenuItems, target: ".tm-accordion-list-item", externalControl: {
338
+ visible: itemContextMenuVisible,
339
+ position: itemContextMenuPosition,
340
+ onClose: closeContextMenu
341
+ } }), _jsx(TMContextMenu, { items: headerContextMenuItems, target: "[id^='accordion-header-']", externalControl: {
342
+ visible: headerContextVisible,
343
+ position: headerContextPosition,
344
+ onClose: closeHeaderContextMenu
345
+ } })] }));
325
346
  };
326
347
  export default TMAccordion;