@topconsultnpm/sdkui-react 6.20.0-dev1.59 → 6.20.0-dev1.60
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.
- package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +12 -0
- package/lib/components/NewComponents/ContextMenu/index.d.ts +3 -0
- package/lib/components/NewComponents/ContextMenu/index.js +2 -0
- package/lib/components/NewComponents/ContextMenu/useLongPress.d.ts +21 -0
- package/lib/components/NewComponents/ContextMenu/useLongPress.js +112 -0
- package/lib/components/base/TMAccordionNew.js +35 -14
- package/lib/components/base/TMDataGrid.js +30 -0
- package/lib/components/editors/TMTextBox.js +6 -3
- package/lib/components/features/documents/TMMasterDetailDcmts.js +36 -51
- package/lib/components/features/tasks/TMTasksUtils.d.ts +2 -2
- package/lib/components/features/tasks/TMTasksUtils.js +62 -52
- package/lib/components/features/tasks/TMTasksView.js +4 -4
- package/lib/components/grids/TMBlogsPost.js +35 -29
- package/package.json +1 -1
|
@@ -187,10 +187,22 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
|
|
|
187
187
|
});
|
|
188
188
|
}
|
|
189
189
|
}, [items, menuState.visible, externalControl, keepOpenOnClick]);
|
|
190
|
+
// Track when the menu was opened to prevent immediate close on iOS
|
|
191
|
+
const menuOpenedAtRef = useRef(0);
|
|
192
|
+
useEffect(() => {
|
|
193
|
+
if (menuState.visible) {
|
|
194
|
+
menuOpenedAtRef.current = Date.now();
|
|
195
|
+
}
|
|
196
|
+
}, [menuState.visible]);
|
|
190
197
|
useEffect(() => {
|
|
191
198
|
if (!menuState.visible)
|
|
192
199
|
return;
|
|
193
200
|
const handleClickOutside = (event) => {
|
|
201
|
+
// On iOS, prevent closing immediately after opening (within 300ms)
|
|
202
|
+
// This handles the case where touchend from long-press triggers touchstart listener
|
|
203
|
+
if (Date.now() - menuOpenedAtRef.current < 300) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
194
206
|
const target = event.target;
|
|
195
207
|
// Check if click is inside main menu
|
|
196
208
|
if (menuRef.current?.contains(target)) {
|
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
export { default as ContextMenu } from './TMContextMenu';
|
|
2
2
|
export type { TMContextMenuItemProps, TMContextMenuProps } from './types';
|
|
3
|
+
export { useLongPress, triggerContextMenuEvent } from './useLongPress';
|
|
4
|
+
export type { UseLongPressOptions } from './useLongPress';
|
|
5
|
+
export { useIsIOS } from './hooks';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface UseLongPressOptions {
|
|
2
|
+
containerRef: React.RefObject<HTMLElement>;
|
|
3
|
+
targetSelector: string | string[];
|
|
4
|
+
onLongPress: (event: {
|
|
5
|
+
clientX: number;
|
|
6
|
+
clientY: number;
|
|
7
|
+
target: HTMLElement;
|
|
8
|
+
}) => void;
|
|
9
|
+
onTouchStart?: (event: {
|
|
10
|
+
clientX: number;
|
|
11
|
+
clientY: number;
|
|
12
|
+
target: HTMLElement;
|
|
13
|
+
rowElement: HTMLElement;
|
|
14
|
+
}) => void;
|
|
15
|
+
duration?: number;
|
|
16
|
+
moveThreshold?: number;
|
|
17
|
+
hapticFeedback?: boolean;
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function useLongPress({ containerRef, targetSelector, onLongPress, onTouchStart, duration, moveThreshold, hapticFeedback, enabled, }: UseLongPressOptions): void;
|
|
21
|
+
export declare function triggerContextMenuEvent(target: HTMLElement, clientX: number, clientY: number): void;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { useIsIOS } from './hooks';
|
|
3
|
+
export function useLongPress({ containerRef, targetSelector, onLongPress, onTouchStart, duration = 500, moveThreshold = 10, hapticFeedback = true, enabled = true, }) {
|
|
4
|
+
const isIOS = useIsIOS();
|
|
5
|
+
const longPressTriggeredRef = useRef(false);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!isIOS || !enabled || !containerRef.current)
|
|
8
|
+
return;
|
|
9
|
+
const container = containerRef.current;
|
|
10
|
+
let longPressTimeout = null;
|
|
11
|
+
let touchStartPos = null;
|
|
12
|
+
let longPressTarget = null;
|
|
13
|
+
const matchesSelector = (element) => {
|
|
14
|
+
const selectors = Array.isArray(targetSelector) ? targetSelector : [targetSelector];
|
|
15
|
+
for (const selector of selectors) {
|
|
16
|
+
const match = element.closest(selector);
|
|
17
|
+
if (match)
|
|
18
|
+
return match;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
};
|
|
22
|
+
const handleTouchStart = (e) => {
|
|
23
|
+
const touch = e.touches[0];
|
|
24
|
+
const target = touch.target;
|
|
25
|
+
// Check if target matches any of the specified selectors
|
|
26
|
+
const matchedElement = matchesSelector(target);
|
|
27
|
+
if (!matchedElement)
|
|
28
|
+
return;
|
|
29
|
+
touchStartPos = { x: touch.clientX, y: touch.clientY };
|
|
30
|
+
longPressTriggeredRef.current = false;
|
|
31
|
+
longPressTarget = target;
|
|
32
|
+
// Call optional onTouchStart callback
|
|
33
|
+
if (onTouchStart) {
|
|
34
|
+
onTouchStart({
|
|
35
|
+
clientX: touch.clientX,
|
|
36
|
+
clientY: touch.clientY,
|
|
37
|
+
target,
|
|
38
|
+
rowElement: matchedElement,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (longPressTimeout)
|
|
42
|
+
clearTimeout(longPressTimeout);
|
|
43
|
+
longPressTimeout = setTimeout(() => {
|
|
44
|
+
longPressTriggeredRef.current = true;
|
|
45
|
+
// Haptic feedback
|
|
46
|
+
if (hapticFeedback && 'vibrate' in navigator) {
|
|
47
|
+
navigator.vibrate(50);
|
|
48
|
+
}
|
|
49
|
+
// Call onLongPress callback
|
|
50
|
+
onLongPress({
|
|
51
|
+
clientX: touch.clientX,
|
|
52
|
+
clientY: touch.clientY,
|
|
53
|
+
target: longPressTarget,
|
|
54
|
+
});
|
|
55
|
+
longPressTimeout = null;
|
|
56
|
+
}, duration);
|
|
57
|
+
};
|
|
58
|
+
const handleTouchMove = (e) => {
|
|
59
|
+
if (!touchStartPos || !longPressTimeout)
|
|
60
|
+
return;
|
|
61
|
+
const touch = e.touches[0];
|
|
62
|
+
const dx = Math.abs(touch.clientX - touchStartPos.x);
|
|
63
|
+
const dy = Math.abs(touch.clientY - touchStartPos.y);
|
|
64
|
+
// Cancel long-press if finger moved too much
|
|
65
|
+
if (dx > moveThreshold || dy > moveThreshold) {
|
|
66
|
+
clearTimeout(longPressTimeout);
|
|
67
|
+
longPressTimeout = null;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const handleTouchEnd = () => {
|
|
71
|
+
if (longPressTimeout) {
|
|
72
|
+
clearTimeout(longPressTimeout);
|
|
73
|
+
longPressTimeout = null;
|
|
74
|
+
}
|
|
75
|
+
touchStartPos = null;
|
|
76
|
+
longPressTarget = null;
|
|
77
|
+
};
|
|
78
|
+
// Prevent click after long-press to avoid unintended actions
|
|
79
|
+
const handleClick = (e) => {
|
|
80
|
+
if (longPressTriggeredRef.current) {
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
e.stopPropagation();
|
|
83
|
+
e.stopImmediatePropagation();
|
|
84
|
+
longPressTriggeredRef.current = false;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
container.addEventListener('touchstart', handleTouchStart, { passive: true });
|
|
88
|
+
container.addEventListener('touchmove', handleTouchMove, { passive: true });
|
|
89
|
+
container.addEventListener('touchend', handleTouchEnd);
|
|
90
|
+
container.addEventListener('touchcancel', handleTouchEnd);
|
|
91
|
+
container.addEventListener('click', handleClick, { capture: true });
|
|
92
|
+
return () => {
|
|
93
|
+
if (longPressTimeout)
|
|
94
|
+
clearTimeout(longPressTimeout);
|
|
95
|
+
container.removeEventListener('touchstart', handleTouchStart);
|
|
96
|
+
container.removeEventListener('touchmove', handleTouchMove);
|
|
97
|
+
container.removeEventListener('touchend', handleTouchEnd);
|
|
98
|
+
container.removeEventListener('touchcancel', handleTouchEnd);
|
|
99
|
+
container.removeEventListener('click', handleClick, { capture: true });
|
|
100
|
+
};
|
|
101
|
+
}, [isIOS, enabled, containerRef, targetSelector, onLongPress, onTouchStart, duration, moveThreshold, hapticFeedback]);
|
|
102
|
+
}
|
|
103
|
+
export function triggerContextMenuEvent(target, clientX, clientY) {
|
|
104
|
+
const contextMenuEvent = new MouseEvent('contextmenu', {
|
|
105
|
+
bubbles: true,
|
|
106
|
+
cancelable: true,
|
|
107
|
+
clientX,
|
|
108
|
+
clientY,
|
|
109
|
+
button: 2,
|
|
110
|
+
});
|
|
111
|
+
target.dispatchEvent(contextMenuEvent);
|
|
112
|
+
}
|
|
@@ -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 {
|
|
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(
|
|
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
|
-
|
|
244
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)) }),
|
|
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;
|
|
@@ -5,6 +5,7 @@ import DataSource from 'devextreme/data/data_source';
|
|
|
5
5
|
import { IconAll, IconSelected, IconVisible, SDKUI_Globals, SDKUI_Localizator } from '../../helper';
|
|
6
6
|
import TMCounterContainer, { CounterItemKey } from './TMCounterContainer';
|
|
7
7
|
import TMContextMenu from '../NewComponents/ContextMenu/TMContextMenu';
|
|
8
|
+
import { useLongPress } from '../NewComponents/ContextMenu/useLongPress';
|
|
8
9
|
;
|
|
9
10
|
export var TMDataGridPageSize;
|
|
10
11
|
(function (TMDataGridPageSize) {
|
|
@@ -77,6 +78,35 @@ const TMDataGrid = React.forwardRef((props, ref) => {
|
|
|
77
78
|
gridContainer.removeEventListener('contextmenu', handleContextMenu);
|
|
78
79
|
};
|
|
79
80
|
}, [customContextMenuItems]);
|
|
81
|
+
// iOS-specific: Handle touch for focused row change and long-press for context menu
|
|
82
|
+
useLongPress({
|
|
83
|
+
containerRef: gridContainerRef,
|
|
84
|
+
targetSelector: '.dx-data-row',
|
|
85
|
+
enabled: !!customContextMenuItems,
|
|
86
|
+
onTouchStart: ({ rowElement }) => {
|
|
87
|
+
// Change focused row immediately on touch (fixes focus issue)
|
|
88
|
+
if (!internalRef.current)
|
|
89
|
+
return;
|
|
90
|
+
const rowIndex = Array.from(rowElement.parentElement?.children || []).indexOf(rowElement);
|
|
91
|
+
const rowKey = internalRef.current.instance().getKeyByRowIndex(rowIndex);
|
|
92
|
+
if (rowKey !== undefined && rowKey !== focusedRowKey) {
|
|
93
|
+
internalRef.current.instance().option('focusedRowKey', rowKey);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
onLongPress: ({ clientX, clientY, target }) => {
|
|
97
|
+
if (!internalRef.current)
|
|
98
|
+
return;
|
|
99
|
+
const rowElement = target.closest('.dx-data-row');
|
|
100
|
+
if (!rowElement)
|
|
101
|
+
return;
|
|
102
|
+
const rowIndex = Array.from(rowElement.parentElement?.children || []).indexOf(rowElement);
|
|
103
|
+
const rowKey = internalRef.current.instance().getKeyByRowIndex(rowIndex);
|
|
104
|
+
// Show context menu
|
|
105
|
+
setCustomContextMenuVisible(true);
|
|
106
|
+
setCustomContextMenuPosition({ x: clientX, y: clientY });
|
|
107
|
+
setCustomContextMenuRowKey(rowKey);
|
|
108
|
+
},
|
|
109
|
+
});
|
|
80
110
|
// Creating a ref to store the timestamp of the last selection change
|
|
81
111
|
const lastSelectionChangeTime = useRef(Date.now());
|
|
82
112
|
useEffect(() => {
|
|
@@ -9,7 +9,7 @@ import { TMExceptionBoxManager } from '../base/TMPopUp';
|
|
|
9
9
|
import TMLayoutContainer, { TMLayoutItem } from '../base/TMLayout';
|
|
10
10
|
import TMVilViewer from '../base/TMVilViewer';
|
|
11
11
|
import TMTooltip from '../base/TMTooltip';
|
|
12
|
-
import
|
|
12
|
+
import TMContextMenu from '../NewComponents/ContextMenu/TMContextMenu';
|
|
13
13
|
import { DeviceType, useDeviceType } from '../base/TMDeviceProvider';
|
|
14
14
|
import TMChooserForm from '../forms/TMChooserForm';
|
|
15
15
|
import { FormulaItemHelper } from './TMTextExpression';
|
|
@@ -94,7 +94,10 @@ const TMTextBox = ({ autoFocus, maxLength, labelColor, precision, fromModal = fa
|
|
|
94
94
|
if (formulaItems && formulaItems.length > 0) {
|
|
95
95
|
let menuItems = [];
|
|
96
96
|
for (const formula of formulaItems) {
|
|
97
|
-
menuItems.push({
|
|
97
|
+
menuItems.push({
|
|
98
|
+
name: formula,
|
|
99
|
+
onClick: () => insertText(formula)
|
|
100
|
+
});
|
|
98
101
|
}
|
|
99
102
|
setFormulaMenuItems(menuItems);
|
|
100
103
|
}
|
|
@@ -269,7 +272,7 @@ const TMTextBox = ({ autoFocus, maxLength, labelColor, precision, fromModal = fa
|
|
|
269
272
|
onBlur?.(undefined);
|
|
270
273
|
}, children: _jsx(IconClearButton, {}) }), buttons.map((buttonItem, index) => {
|
|
271
274
|
return (_jsx(StyledTextBoxEditorButton, { onClick: buttonItem.onClick, children: _jsx(TMTooltip, { content: buttonItem.text, children: buttonItem.icon }) }, buttonItem.text));
|
|
272
|
-
})] }), openFormulaItemsChooser(), formulaItems.length > 0 && (_jsx(
|
|
275
|
+
})] }), openFormulaItemsChooser(), formulaItems.length > 0 && (_jsx(TMContextMenu, { items: formulaMenuItems, target: `#text-${id}` })), _jsx(TMVilViewer, { vil: validationItems })] }));
|
|
273
276
|
};
|
|
274
277
|
const renderedLeftLabelTextBox = () => {
|
|
275
278
|
return (_jsxs(TMLayoutContainer, { direction: 'horizontal', children: [icon && _jsx(TMLayoutItem, { width: '20px', children: _jsx(StyledEditorIcon, { "$disabled": disabled, "$vil": validationItems, "$isModified": isModifiedWhen, children: icon }) }), _jsx(TMLayoutItem, { children: _jsxs(StyledEditorContainer, { "$width": width, children: [label && _jsx(StyledEditorLabel, { "$color": labelColor, "$isFocused": isFocused, "$labelPosition": labelPosition, "$disabled": disabled, children: label }), renderInputField()] }) })] }));
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import { DcmtTypeListCacheService, SDK_Localizator } from '@topconsultnpm/sdk-ts';
|
|
4
|
-
import { ContextMenu } from 'devextreme-react';
|
|
5
4
|
import TMRelationViewer from './TMRelationViewer';
|
|
6
|
-
import
|
|
5
|
+
import TMContextMenu from '../../NewComponents/ContextMenu/TMContextMenu';
|
|
6
|
+
import { genUniqueId, IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, IconMail, IconDcmtTypeOnlyMetadata, IconCopy, IconMenuVertical, IconDataList, IconPreview, IconSearchCheck, IconBoard, IconDcmtTypeSys, IconShow } from '../../../helper';
|
|
7
7
|
import { FormModes, SearchResultContext } from '../../../ts';
|
|
8
8
|
import { TMColors } from '../../../utils/theme';
|
|
9
9
|
import ShowAlert from '../../base/TMAlert';
|
|
@@ -46,120 +46,105 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
46
46
|
}, []);
|
|
47
47
|
const commandsMenuItems = [
|
|
48
48
|
{
|
|
49
|
-
icon:
|
|
50
|
-
|
|
51
|
-
operationType: 'singleRow',
|
|
49
|
+
icon: _jsx(IconMultipleSelection, { color: allowMultipleSelection ? TMColors.tertiary : TMColors.text_normal }),
|
|
50
|
+
name: "Selezione multipla",
|
|
52
51
|
onClick: () => {
|
|
53
52
|
setAllowMultipleSelection(prev => !prev);
|
|
54
53
|
}
|
|
55
54
|
},
|
|
56
55
|
{
|
|
57
|
-
icon:
|
|
58
|
-
|
|
59
|
-
operationType: 'singleRow',
|
|
56
|
+
icon: _jsx(IconCheckFile, {}),
|
|
57
|
+
name: "Consenti dettagli con 0 documenti",
|
|
60
58
|
onClick: () => {
|
|
61
59
|
setShowZeroDcmts(prev => !prev);
|
|
62
60
|
}
|
|
63
61
|
},
|
|
64
62
|
{
|
|
65
|
-
icon:
|
|
66
|
-
|
|
67
|
-
operationType: 'singleRow',
|
|
63
|
+
icon: _jsx(IconDetailDcmts, { transform: 'scale(-1, 1)' }),
|
|
64
|
+
name: SDKUI_Localizator.DcmtsMaster,
|
|
68
65
|
disabled: !focusedItem?.isDcmt || !isForMaster,
|
|
69
66
|
onClick: () => {
|
|
70
67
|
appendMasterDcmts?.(focusedItem?.tid, focusedItem?.did);
|
|
71
68
|
}
|
|
72
69
|
},
|
|
73
70
|
{
|
|
74
|
-
icon:
|
|
75
|
-
|
|
76
|
-
operationType: 'multiRow',
|
|
71
|
+
icon: _jsx(IconMail, {}),
|
|
72
|
+
name: "Invia per posta",
|
|
77
73
|
disabled: false,
|
|
78
74
|
beginGroup: true,
|
|
79
|
-
|
|
75
|
+
submenu: [
|
|
80
76
|
{
|
|
81
|
-
icon:
|
|
82
|
-
|
|
83
|
-
operationType: 'multiRow',
|
|
77
|
+
icon: _jsx(IconMail, {}),
|
|
78
|
+
name: "I documenti selezionati",
|
|
84
79
|
disabled: false,
|
|
85
80
|
onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
|
|
86
81
|
},
|
|
87
82
|
{
|
|
88
|
-
icon:
|
|
89
|
-
|
|
90
|
-
operationType: 'multiRow',
|
|
83
|
+
icon: _jsx(IconMail, {}),
|
|
84
|
+
name: "I documenti di primo livello e tutti i documenti correlati",
|
|
91
85
|
disabled: false,
|
|
92
86
|
onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
|
|
93
87
|
},
|
|
94
88
|
{
|
|
95
|
-
icon:
|
|
96
|
-
|
|
97
|
-
operationType: 'multiRow',
|
|
89
|
+
icon: _jsx(IconMail, {}),
|
|
90
|
+
name: "I documenti di primo livello e i documenti correlati personalizzando l'operazione",
|
|
98
91
|
disabled: false,
|
|
99
92
|
onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
|
|
100
93
|
},
|
|
101
94
|
]
|
|
102
95
|
},
|
|
103
96
|
{
|
|
104
|
-
icon:
|
|
105
|
-
|
|
106
|
-
operationType: 'multiRow',
|
|
97
|
+
icon: _jsx(IconDcmtTypeOnlyMetadata, {}),
|
|
98
|
+
name: "Unisci in un file PDF",
|
|
107
99
|
disabled: false,
|
|
108
|
-
|
|
100
|
+
submenu: [
|
|
109
101
|
{
|
|
110
|
-
icon:
|
|
111
|
-
|
|
112
|
-
operationType: 'multiRow',
|
|
102
|
+
icon: _jsx(IconDcmtTypeOnlyMetadata, {}),
|
|
103
|
+
name: "I documenti selezionati",
|
|
113
104
|
disabled: false,
|
|
114
105
|
onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
|
|
115
106
|
},
|
|
116
107
|
{
|
|
117
|
-
icon:
|
|
118
|
-
|
|
119
|
-
operationType: 'multiRow',
|
|
108
|
+
icon: _jsx(IconDcmtTypeOnlyMetadata, {}),
|
|
109
|
+
name: "I documenti di primo livello e tutti i documenti correlati",
|
|
120
110
|
disabled: false,
|
|
121
111
|
onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
|
|
122
112
|
},
|
|
123
113
|
{
|
|
124
|
-
icon:
|
|
125
|
-
|
|
126
|
-
operationType: 'multiRow',
|
|
114
|
+
icon: _jsx(IconDcmtTypeOnlyMetadata, {}),
|
|
115
|
+
name: "I documenti di primo livello e i documenti correlati personalizzando l'operazione",
|
|
127
116
|
disabled: false,
|
|
128
117
|
onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
|
|
129
118
|
},
|
|
130
119
|
]
|
|
131
120
|
},
|
|
132
121
|
{
|
|
133
|
-
icon:
|
|
134
|
-
|
|
135
|
-
operationType: 'multiRow',
|
|
122
|
+
icon: _jsx(IconCopy, {}),
|
|
123
|
+
name: "Copia in una cartella",
|
|
136
124
|
disabled: false,
|
|
137
|
-
|
|
125
|
+
submenu: [
|
|
138
126
|
{
|
|
139
|
-
icon:
|
|
140
|
-
|
|
141
|
-
operationType: 'multiRow',
|
|
127
|
+
icon: _jsx(IconCopy, {}),
|
|
128
|
+
name: "I documenti selezionati",
|
|
142
129
|
disabled: false,
|
|
143
130
|
onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
|
|
144
131
|
},
|
|
145
132
|
{
|
|
146
|
-
icon:
|
|
147
|
-
|
|
148
|
-
operationType: 'multiRow',
|
|
133
|
+
icon: _jsx(IconCopy, {}),
|
|
134
|
+
name: "I documenti di primo livello e tutti i documenti correlati",
|
|
149
135
|
disabled: false,
|
|
150
136
|
onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
|
|
151
137
|
},
|
|
152
138
|
{
|
|
153
|
-
icon:
|
|
154
|
-
|
|
155
|
-
operationType: 'multiRow',
|
|
139
|
+
icon: _jsx(IconCopy, {}),
|
|
140
|
+
name: "I documenti di primo livello e i documenti correlati personalizzando l'operazione",
|
|
156
141
|
disabled: false,
|
|
157
142
|
onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
|
|
158
143
|
},
|
|
159
144
|
]
|
|
160
145
|
}
|
|
161
146
|
];
|
|
162
|
-
const toolbar = _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [allowMultipleSelection && _jsx("p", { style: { color: TMColors.colorHeader, textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${selectedItems.length} selezionati` }), allowNavigation && canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), allowNavigation && canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(
|
|
147
|
+
const toolbar = _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [allowMultipleSelection && _jsx("p", { style: { color: TMColors.colorHeader, textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${selectedItems.length} selezionati` }), allowNavigation && canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), allowNavigation && canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(TMContextMenu, { items: commandsMenuItems, trigger: 'left', children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) })] });
|
|
163
148
|
const getTitle = () => isForMaster ? `${SDKUI_Localizator.DcmtsMaster} - ${dtdMaster?.nameLoc}` : SDKUI_Localizator.DcmtsDetail;
|
|
164
149
|
const isMobile = deviceType === DeviceType.MOBILE;
|
|
165
150
|
const tmTreeView = useMemo(() => _jsx(_Fragment, { children: !inputDcmts || inputDcmts.length === 0
|
|
@@ -2,7 +2,7 @@ import { Appointment } from 'devextreme/ui/scheduler';
|
|
|
2
2
|
import { ContextMenuTypes } from 'devextreme-react/context-menu';
|
|
3
3
|
import { TaskDescriptor, Task_States, PdGs, Priorities, ValidationItem } from '@topconsultnpm/sdk-ts';
|
|
4
4
|
import { FormModes, TaskContext } from '../../../ts';
|
|
5
|
-
import {
|
|
5
|
+
import { TMContextMenuItemProps } from '../../NewComponents/ContextMenu';
|
|
6
6
|
export declare const TEXT_SELECTED_COLOR = "#ff5e1a";
|
|
7
7
|
export declare const BG_COLOR_INACTIVE_WIDGET = "#fff";
|
|
8
8
|
export declare const BG_COLOR_ACTIVE_WIDGET = "#fff0b7";
|
|
@@ -100,7 +100,7 @@ export declare const gotoPDGExtendedLabel: (gotoVisible: boolean, pdg: PdGs, iD1
|
|
|
100
100
|
export declare const convertToSchedulerAppointments: (tasks: Array<TaskDescriptor>) => Array<Appointment>;
|
|
101
101
|
export declare const formatDate: (date: Date) => string;
|
|
102
102
|
export declare const areDifferentIDs: (fromID: number | undefined, userID: number | undefined) => boolean;
|
|
103
|
-
export declare const createTasksMenuItems: (taskDescriptor: TaskDescriptor | undefined, showId: boolean, setShowId: React.Dispatch<React.SetStateAction<boolean>>, showSearch: boolean, setShowSearch: React.Dispatch<React.SetStateAction<boolean>>, openTaskForm: (formMode: FormModes, task?: TaskDescriptor, isContextual?: boolean) => void, openEditTaskForm: (rowId: number | undefined) => void, openDuplicateTaskForm: (rowId: number | undefined) => void, onDeleteCallback: (rowIds: Array<number>) => void, markAsStatus: (rowIds: Array<number>, status: Task_States) => void, getAllTasks: () => Promise<void>, fromWG: boolean, showContextualWG: boolean, setShowContextualWG: React.Dispatch<React.SetStateAction<boolean>>, fromDossier: boolean, showContextualDossier: boolean, setShowContextualDossier: React.Dispatch<React.SetStateAction<boolean>>, fromDocument: boolean, showContextualDocument: boolean, setShowContextualDocument: React.Dispatch<React.SetStateAction<boolean>>, showGoToToday: boolean, handleGoToToday?: () => void, fromDatagrid?: boolean) =>
|
|
103
|
+
export declare const createTasksMenuItems: (taskDescriptor: TaskDescriptor | undefined, showId: boolean, setShowId: React.Dispatch<React.SetStateAction<boolean>>, showSearch: boolean, setShowSearch: React.Dispatch<React.SetStateAction<boolean>>, openTaskForm: (formMode: FormModes, task?: TaskDescriptor, isContextual?: boolean) => void, openEditTaskForm: (rowId: number | undefined) => void, openDuplicateTaskForm: (rowId: number | undefined) => void, onDeleteCallback: (rowIds: Array<number>) => void, markAsStatus: (rowIds: Array<number>, status: Task_States) => void, getAllTasks: () => Promise<void>, fromWG: boolean, showContextualWG: boolean, setShowContextualWG: React.Dispatch<React.SetStateAction<boolean>>, fromDossier: boolean, showContextualDossier: boolean, setShowContextualDossier: React.Dispatch<React.SetStateAction<boolean>>, fromDocument: boolean, showContextualDocument: boolean, setShowContextualDocument: React.Dispatch<React.SetStateAction<boolean>>, showGoToToday: boolean, handleGoToToday?: () => void, fromDatagrid?: boolean) => TMContextMenuItemProps[];
|
|
104
104
|
export declare const checkIfNew: (fromId: number | undefined, isNew: number | undefined) => boolean;
|
|
105
105
|
export declare const getNewTaskCount: (tasks: Array<TaskDescriptor>) => number;
|
|
106
106
|
export declare const isTaskAssignedToAnotherUser: (task: TaskDescriptor) => boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
2
|
import { Task_States, PdGs, Priorities, ValidationItem, SDK_Localizator, ResultTypes, SDK_Globals } from '@topconsultnpm/sdk-ts';
|
|
2
3
|
import { TMColors } from '../../../utils/theme';
|
|
3
4
|
import { SDKUI_Localizator } from '../../../helper';
|
|
@@ -401,107 +402,116 @@ export const createTasksMenuItems = (taskDescriptor, showId, setShowId, showSear
|
|
|
401
402
|
const isTaskFromAnotherUser = isTaskDescriptorDefined && areDifferentIDs(taskDescriptor.fromID, SDK_Globals.tmSession?.SessionDescr?.userID);
|
|
402
403
|
const menuItems = [
|
|
403
404
|
{
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
icon: 'plus',
|
|
405
|
+
name: SDKUI_Localizator.CreateContextualTask,
|
|
406
|
+
icon: _jsx("span", { className: "dx-icon-plus" }),
|
|
407
407
|
onClick: () => { openTaskForm(FormModes.Create, undefined, true); },
|
|
408
|
-
disabled: false
|
|
408
|
+
disabled: false,
|
|
409
|
+
id: 'createContextualTask',
|
|
410
|
+
operationType: 'singleRow'
|
|
409
411
|
},
|
|
410
412
|
{
|
|
411
|
-
|
|
412
|
-
icon:
|
|
413
|
+
name: SDKUI_Localizator.Create,
|
|
414
|
+
icon: _jsx("span", { className: "dx-icon-plus" }),
|
|
413
415
|
onClick: () => { openTaskForm(FormModes.Create, undefined, false); },
|
|
414
|
-
disabled: false
|
|
416
|
+
disabled: false,
|
|
417
|
+
operationType: 'singleRow'
|
|
415
418
|
},
|
|
416
419
|
{
|
|
417
|
-
|
|
418
|
-
icon:
|
|
420
|
+
name: SDKUI_Localizator.Update,
|
|
421
|
+
icon: _jsx("span", { className: "dx-icon-edit" }),
|
|
419
422
|
onClick: openEditTaskForm,
|
|
420
|
-
|
|
421
|
-
|
|
423
|
+
disabled: fromDatagrid ? false : !isTaskDescriptorDefined,
|
|
424
|
+
operationType: 'singleRow'
|
|
422
425
|
},
|
|
423
426
|
{
|
|
424
|
-
|
|
425
|
-
icon:
|
|
427
|
+
name: SDKUI_Localizator.Duplicate,
|
|
428
|
+
icon: _jsx("span", { className: "dx-icon-copy" }),
|
|
426
429
|
onClick: openDuplicateTaskForm,
|
|
427
|
-
|
|
428
|
-
|
|
430
|
+
disabled: fromDatagrid ? isTaskFromAnotherUser : !isTaskDescriptorDefined || isTaskFromAnotherUser,
|
|
431
|
+
operationType: 'singleRow'
|
|
429
432
|
},
|
|
430
433
|
{
|
|
431
|
-
|
|
432
|
-
icon:
|
|
434
|
+
name: SDKUI_Localizator.Delete,
|
|
435
|
+
icon: _jsx("span", { className: "dx-icon-trash" }),
|
|
433
436
|
onClick: onDeleteCallback,
|
|
434
|
-
|
|
435
|
-
|
|
437
|
+
disabled: fromDatagrid ? isTaskFromAnotherUser : !isTaskDescriptorDefined || isTaskFromAnotherUser,
|
|
438
|
+
operationType: 'multiRow'
|
|
436
439
|
},
|
|
437
440
|
{
|
|
438
|
-
|
|
439
|
-
|
|
441
|
+
name: SDKUI_Localizator.MarkAs,
|
|
442
|
+
icon: _jsx("span", { className: "dx-icon-optionsgear" }),
|
|
443
|
+
disabled: fromDatagrid ? false : !isTaskDescriptorDefined,
|
|
440
444
|
id: "markAs",
|
|
441
445
|
operationType: 'multiRow',
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
{
|
|
445
|
-
{
|
|
446
|
-
{
|
|
447
|
-
{
|
|
448
|
-
{ icon: 'clock', text: SDKUI_Localizator.Postponed, operationType: 'multiRow', onClick: (rowIds) => markAsStatus(rowIds, Task_States.Deferred) }
|
|
446
|
+
submenu: [
|
|
447
|
+
{ name: SDKUI_Localizator.NewFemale, icon: _jsx("span", { className: "dx-icon-product" }), onClick: ((rowIds) => markAsStatus(rowIds, Task_States.NotStarted)), operationType: 'multiRow' },
|
|
448
|
+
{ name: SDKUI_Localizator.InProgress, icon: _jsx("span", { className: "dx-icon-refresh" }), onClick: ((rowIds) => markAsStatus(rowIds, Task_States.InProgress)), operationType: 'multiRow' },
|
|
449
|
+
{ name: SDKUI_Localizator.Completed, icon: _jsx("span", { className: "dx-icon-check" }), onClick: ((rowIds) => markAsStatus(rowIds, Task_States.Completed)), operationType: 'multiRow' },
|
|
450
|
+
{ name: SDKUI_Localizator.Pending, icon: _jsx("span", { className: "dx-icon-taskstop" }), onClick: ((rowIds) => markAsStatus(rowIds, Task_States.Waiting)), operationType: 'multiRow' },
|
|
451
|
+
{ name: SDKUI_Localizator.Postponed, icon: _jsx("span", { className: "dx-icon-clock" }), onClick: ((rowIds) => markAsStatus(rowIds, Task_States.Deferred)), operationType: 'multiRow' }
|
|
449
452
|
]
|
|
450
453
|
},
|
|
451
454
|
{
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
icon: 'filter',
|
|
455
|
+
name: showContextualWG ? SDKUI_Localizator.RemoveContextualFilter : SDKUI_Localizator.ApplyContextualFilter,
|
|
456
|
+
icon: _jsx("span", { className: "dx-icon-filter" }),
|
|
455
457
|
onClick: () => { setShowContextualWG(prev => !prev); },
|
|
456
458
|
disabled: false,
|
|
457
459
|
beginGroup: true,
|
|
458
|
-
visible: fromWG
|
|
460
|
+
visible: fromWG,
|
|
461
|
+
id: 'wgContextFilter',
|
|
462
|
+
operationType: 'singleRow'
|
|
459
463
|
},
|
|
460
464
|
{
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
icon: 'filter',
|
|
465
|
+
name: showContextualDossier ? SDKUI_Localizator.RemoveContextualFilter : SDKUI_Localizator.ApplyContextualFilter,
|
|
466
|
+
icon: _jsx("span", { className: "dx-icon-filter" }),
|
|
464
467
|
onClick: () => { setShowContextualDossier(prev => !prev); },
|
|
465
468
|
disabled: false,
|
|
466
469
|
beginGroup: !fromWG && !fromDocument,
|
|
467
|
-
visible: fromDossier
|
|
470
|
+
visible: fromDossier,
|
|
471
|
+
id: 'dossierContextFilter',
|
|
472
|
+
operationType: 'singleRow'
|
|
468
473
|
},
|
|
469
474
|
{
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
icon: 'filter',
|
|
475
|
+
name: showContextualDocument ? SDKUI_Localizator.RemoveContextualFilter : SDKUI_Localizator.ApplyContextualFilter,
|
|
476
|
+
icon: _jsx("span", { className: "dx-icon-filter" }),
|
|
473
477
|
onClick: () => { setShowContextualDocument(prev => !prev); },
|
|
474
478
|
disabled: false,
|
|
475
479
|
beginGroup: !fromDossier && !fromWG,
|
|
476
|
-
visible: fromDocument
|
|
480
|
+
visible: fromDocument,
|
|
481
|
+
id: 'documentContextFilter',
|
|
482
|
+
operationType: 'singleRow'
|
|
477
483
|
},
|
|
478
484
|
{
|
|
479
|
-
|
|
485
|
+
name: SDKUI_Localizator.GoToToday,
|
|
486
|
+
icon: _jsx("span", { className: "dx-icon-event" }),
|
|
480
487
|
onClick: () => { if (handleGoToToday) {
|
|
481
488
|
handleGoToToday();
|
|
482
489
|
} },
|
|
483
|
-
text: SDKUI_Localizator.GoToToday,
|
|
484
490
|
disabled: false,
|
|
485
491
|
beginGroup: true,
|
|
492
|
+
operationType: 'singleRow'
|
|
486
493
|
},
|
|
487
494
|
{
|
|
488
|
-
|
|
489
|
-
icon: showSearch ? "eyeclose" : "eyeopen",
|
|
495
|
+
name: showSearch ? SDKUI_Localizator.HideSearch : SDKUI_Localizator.ShowSearch,
|
|
496
|
+
icon: _jsx("span", { className: showSearch ? "dx-icon-eyeclose" : "dx-icon-eyeopen" }),
|
|
490
497
|
onClick: () => setShowSearch(prevShowSearch => !prevShowSearch),
|
|
491
|
-
|
|
492
|
-
|
|
498
|
+
disabled: false,
|
|
499
|
+
beginGroup: true,
|
|
500
|
+
operationType: 'singleRow'
|
|
493
501
|
},
|
|
494
502
|
{
|
|
495
|
-
|
|
503
|
+
name: showId ? SDKUI_Localizator.ID_Hide : SDKUI_Localizator.ID_Show,
|
|
504
|
+
icon: _jsx("span", { className: showId ? "dx-icon-eyeclose" : "dx-icon-eyeopen" }),
|
|
496
505
|
onClick: () => setShowId(prevShowId => !prevShowId),
|
|
497
|
-
|
|
498
|
-
|
|
506
|
+
disabled: false,
|
|
507
|
+
operationType: 'singleRow'
|
|
499
508
|
},
|
|
500
509
|
{
|
|
501
|
-
|
|
502
|
-
icon:
|
|
510
|
+
name: SDKUI_Localizator.Refresh,
|
|
511
|
+
icon: _jsx("span", { className: "dx-icon-refresh" }),
|
|
503
512
|
onClick: () => getAllTasks(),
|
|
504
513
|
disabled: false,
|
|
514
|
+
operationType: 'singleRow'
|
|
505
515
|
},
|
|
506
516
|
];
|
|
507
517
|
// Apply filters
|
|
@@ -529,7 +539,7 @@ export const createTasksMenuItems = (taskDescriptor, showId, setShowId, showSear
|
|
|
529
539
|
item.visible === undefined);
|
|
530
540
|
}
|
|
531
541
|
if (showGoToToday === false) {
|
|
532
|
-
filteredMenuItems = filteredMenuItems.filter(item => item.
|
|
542
|
+
filteredMenuItems = filteredMenuItems.filter(item => item.name !== SDKUI_Localizator.GoToToday);
|
|
533
543
|
}
|
|
534
544
|
return filteredMenuItems;
|
|
535
545
|
};
|
|
@@ -5,7 +5,6 @@ import { TabPanel, Item } from 'devextreme-react/tab-panel';
|
|
|
5
5
|
import { Priorities, ResultTypes, SDK_Globals, Task_States } from "@topconsultnpm/sdk-ts";
|
|
6
6
|
import { calculateNumberOfDays, renderTaskIcons } from "./TMTasksUtilsView";
|
|
7
7
|
import { getPriorityLocalizatorValue } from "../tasks/TMTasksUtils";
|
|
8
|
-
import ContextMenu from 'devextreme-react/context-menu';
|
|
9
8
|
import { calcResponsiveSizes, getExceptionMessage, SDKUI_Localizator, StyledTabItem, TMCountBadge } from "../../../helper";
|
|
10
9
|
import { useDeviceType } from "../../base/TMDeviceProvider";
|
|
11
10
|
import { FormModes } from "../../../ts";
|
|
@@ -17,6 +16,7 @@ import { TMResultManager } from "../../forms/TMResultDialog";
|
|
|
17
16
|
import TMTasksCalendar from "./TMTasksCalendar";
|
|
18
17
|
import TMTasksAgenda from "./TMTasksAgenda";
|
|
19
18
|
import TMTaskForm from "./TMTaskForm";
|
|
19
|
+
import { ContextMenu as TMContextMenu } from "../../NewComponents/ContextMenu";
|
|
20
20
|
let abortController = new AbortController();
|
|
21
21
|
const TMTasksView = (props) => {
|
|
22
22
|
const { id, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, visualizedTasks, activeComponent, activeTabIndex, setActiveTabIndex, currentTask, setCurrentTask, assignedToMeCount, assignedByMeCount, allTasksFilteredCount, showId, setShowId, showSearch, setShowSearch, showContextualWG, setShowContextualWG, showContextualDossier, setShowContextualDossier, showContextualDocument, setShowContextualDocument, handleNavigateToWGs, handleNavigateToDossiers, taskContext, usersList, onOpenS4TViewerRequest, s4TViewerDialogComponent, afterTaskSaved, } = props;
|
|
@@ -519,13 +519,13 @@ const TMTasksView = (props) => {
|
|
|
519
519
|
];
|
|
520
520
|
}, [showId]);
|
|
521
521
|
const getFromOrToDatagridElement = (fromOrToDataSource, fromCell = false, toCell = false) => {
|
|
522
|
-
return _jsx(TMDataGrid, { dataSource: fromOrToDataSource, dataColumns: getDataColumns(fromCell, toCell), selection: { mode: 'multiple', showCheckBoxesMode: "always" }, focusedRowKey: focusedRowKey, selectedRowKeys: [...selectedRowKeys], onFocusedRowChanged: onFocusedRowChanged, onSelectionChanged: onSelectionChanged, onRowDblClick: onRowDblClick,
|
|
522
|
+
return _jsx(TMDataGrid, { dataSource: fromOrToDataSource, dataColumns: getDataColumns(fromCell, toCell), selection: { mode: 'multiple', showCheckBoxesMode: "always" }, focusedRowKey: focusedRowKey, selectedRowKeys: [...selectedRowKeys], onFocusedRowChanged: onFocusedRowChanged, onSelectionChanged: onSelectionChanged, onRowDblClick: onRowDblClick, customContextMenuItems: menuItems, showSearchPanel: showSearch, noDataText: SDKUI_Localizator.TasksEmpty, counterConfig: { show: true }, onHasFiltersChange: (active) => setHasFilters(active) });
|
|
523
523
|
};
|
|
524
524
|
const getFromOrToAgendaElement = (fromOrToDataSource, fromCell = false, toCell = false) => {
|
|
525
|
-
return
|
|
525
|
+
return _jsx("div", { style: { width: '100%', height: '100%', display: 'flex', flexDirection: 'column', overflow: "auto" }, children: _jsxs("div", { style: { width: "100%", height: "100%" }, id: `agenda-container-${id}`, children: [_jsx(TMTasksAgenda, { id: id, showId: showId, showSearch: showSearch, visualizedTasks: fromOrToDataSource, fromCell: fromCell, toCell: toCell, currentAgendaDate: currentAgendaDate, setCurrentAgendaDate: setCurrentAgendaDate, openTaskForm: openTaskFormCallback, handleFocusedRowChange: handleFocusedRowChange }), _jsx(TMContextMenu, { items: menuItems, target: `#agenda-container-${id}` })] }) });
|
|
526
526
|
};
|
|
527
527
|
const getFromOrToCalendarElement = (fromOrToDataSource, fromCell = false, toCell = false) => {
|
|
528
|
-
return
|
|
528
|
+
return _jsx("div", { style: { width: '100%', height: '100%', display: 'flex', flexDirection: 'column', overflow: "auto" }, children: _jsx("div", { style: { width: "100%", height: "100%" }, children: _jsx(TMTasksCalendar, { id: id, visualizedTasks: fromOrToDataSource, showId: showId, fromCell: fromCell, toCell: toCell, showSearch: showSearch, currentCalendarDate: currentCalendarDate, setCurrentCalendarDate: setCurrentCalendarDate, openTaskForm: openTaskFormCallback, onDeleteCallback: onDeleteCallback, setCalendarStartDate: setCalendarStartDate, setCalendarEndDate: setCalendarEndDate, focusedRowKey: focusedRowKey, handleFocusedRowChange: handleFocusedRowChange }) }) });
|
|
529
529
|
};
|
|
530
530
|
return _jsxs("div", { style: { width: '100%', height: '100%' }, onContextMenu: (e) => e.preventDefault(), children: [_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, isCancelable: true, abortController: abortController, children: _jsxs(TabPanel, { width: "100%", height: "100%", animationEnabled: false, swipeEnabled: false, loop: false, showNavButtons: true, repaintChangesOnly: true, stylingMode: "primary", iconPosition: 'start', tabsPosition: 'top', selectedIndex: activeTabIndex, onSelectedIndexChange: onSelectedIndexChange, id: "task-centered-tab-title", children: [_jsx(Item, { title: SDKUI_Localizator.AssignedToMe, icon: "user", tabRender: (params) => {
|
|
531
531
|
return _jsxs(StyledTabItem, { "$isSelected": activeTabIndex === AssignedTab.AssignedToMe, children: [_jsxs(TMTooltip, { content: SDKUI_Localizator.AssignedToMe, children: [_jsx("i", { className: `dx-icon-${params.icon}` }), "\u00A0", params.title, " ", (assignedToMeCount > 0) ? `(${assignedToMeCount})` : ''] }), newTaskCount > 0 && (_jsx(TMTooltip, { content: SDKUI_Localizator.NewAssignedActivitiesNumber + ": " + newTaskCount, children: _jsx(TMCountBadge, { children: newTaskCount }) }))] });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { DossierEngine, LayoutModes, ObjectClasses, ResultTypes, SDK_Globals, TaskDescriptor, WorkingGroupEngine } from "@topconsultnpm/sdk-ts";
|
|
4
|
-
import { ContextMenu } from "
|
|
4
|
+
import { ContextMenu as TMContextMenu } from "../NewComponents/ContextMenu";
|
|
5
5
|
import { SDKUI_Localizator, Globalization, getExceptionMessage, TMConditionalWrapper, calcResponsiveSizes } from "../../helper";
|
|
6
6
|
import TMToppyMessage from "../../helper/TMToppyMessage";
|
|
7
7
|
import { useDcmtOperations } from "../../hooks/useDcmtOperations";
|
|
@@ -68,7 +68,8 @@ const TMBlogsPost = (props) => {
|
|
|
68
68
|
const [showTaskForm, setShowTaskForm] = useState(false);
|
|
69
69
|
// State to manage show selected file
|
|
70
70
|
const [dcmtForm, setDcmtForm] = useState({ show: false, dcmt: undefined });
|
|
71
|
-
const [
|
|
71
|
+
const [menuVisible, setMenuVisible] = useState(false);
|
|
72
|
+
const [menuPosition, setMenuPosition] = useState({ x: 0, y: 0 });
|
|
72
73
|
const [menuItems, setMenuItems] = useState([]);
|
|
73
74
|
const [localShowWaitPanel, setLocalShowWaitPanel] = useState(false);
|
|
74
75
|
const [localWaitPanelTitle, setLocalWaitPanelTitle] = useState('');
|
|
@@ -500,8 +501,8 @@ const TMBlogsPost = (props) => {
|
|
|
500
501
|
const classId = targetItem ? targetItem.classID : undefined;
|
|
501
502
|
if (contextMenuParams.isDownloadAttachmentEnabled && focusedAttachment !== undefined) {
|
|
502
503
|
menuItems.push({
|
|
503
|
-
icon: "download",
|
|
504
|
-
|
|
504
|
+
icon: _jsx("span", { className: "dx-icon-download" }),
|
|
505
|
+
name: 'Download',
|
|
505
506
|
onClick: async () => {
|
|
506
507
|
await downloadDcmtsAsync([
|
|
507
508
|
{ TID: focusedAttachment.TID, DID: focusedAttachment.DID, fileName: focusedAttachment.fileName }
|
|
@@ -511,26 +512,26 @@ const TMBlogsPost = (props) => {
|
|
|
511
512
|
}
|
|
512
513
|
if (contextMenuParams.isViewEditMetadata && focusedAttachment !== undefined) {
|
|
513
514
|
menuItems.push({
|
|
514
|
-
icon:
|
|
515
|
-
|
|
515
|
+
icon: _jsx("span", { className: "dx-icon-eyeopen" }),
|
|
516
|
+
name: SDKUI_Localizator.OpenForm,
|
|
516
517
|
onClick: () => openDcmtForm(focusedAttachment),
|
|
517
518
|
});
|
|
518
519
|
}
|
|
519
520
|
if (contextMenuParams.isCommentEnabled && showCommentFormCallback !== undefined) {
|
|
520
521
|
menuItems.push({
|
|
521
|
-
icon:
|
|
522
|
-
|
|
522
|
+
icon: _jsx("span", { className: "dx-icon-chat" }),
|
|
523
|
+
name: SDKUI_Localizator.Comment,
|
|
523
524
|
disabled: isGroupArchived ? true : false,
|
|
524
525
|
onClick: () => {
|
|
525
526
|
showCommentFormCallback(focusedAttachment);
|
|
526
527
|
},
|
|
527
|
-
beginGroup:
|
|
528
|
+
beginGroup: menuItems.length > 0
|
|
528
529
|
});
|
|
529
530
|
}
|
|
530
531
|
if (targetItem && contextMenuParams.isDeleteEnabled) {
|
|
531
532
|
menuItems.push({
|
|
532
|
-
icon: "trash",
|
|
533
|
-
|
|
533
|
+
icon: _jsx("span", { className: "dx-icon-trash" }),
|
|
534
|
+
name: SDKUI_Localizator.Delete,
|
|
534
535
|
visible: contextMenuParams.isDeleteEnabled,
|
|
535
536
|
onClick: () => deleteOrUndeleteCommentCallback(targetItem, true),
|
|
536
537
|
disabled: isNotOwner || isDeleted || isGroupArchived,
|
|
@@ -538,24 +539,24 @@ const TMBlogsPost = (props) => {
|
|
|
538
539
|
}
|
|
539
540
|
if (targetItem && contextMenuParams.isRestoreEnabled) {
|
|
540
541
|
menuItems.push({
|
|
541
|
-
icon: "undo",
|
|
542
|
-
|
|
542
|
+
icon: _jsx("span", { className: "dx-icon-undo" }),
|
|
543
|
+
name: SDKUI_Localizator.Restore,
|
|
543
544
|
onClick: () => deleteOrUndeleteCommentCallback(targetItem, false),
|
|
544
545
|
disabled: isNotOwner || (targetItem && (targetItem.isDel === undefined || targetItem.isDel === 0)),
|
|
545
546
|
});
|
|
546
547
|
}
|
|
547
548
|
if (targetItem && contextMenuParams.isCopyToClipboardEnabled) {
|
|
548
549
|
menuItems.push({
|
|
549
|
-
|
|
550
|
-
icon:
|
|
550
|
+
name: SDKUI_Localizator.CopyToClipboard,
|
|
551
|
+
icon: _jsx("span", { className: "dx-icon-copy" }),
|
|
551
552
|
disabled: false,
|
|
552
553
|
onClick: () => { copyInClipboard(targetItem); }
|
|
553
554
|
});
|
|
554
555
|
}
|
|
555
556
|
if (contextMenuParams.isCreateContextualTask) {
|
|
556
557
|
menuItems.push({
|
|
557
|
-
|
|
558
|
-
icon:
|
|
558
|
+
name: SDKUI_Localizator.CreateContextualTask,
|
|
559
|
+
icon: _jsx("span", { className: "dx-icon-plus" }),
|
|
559
560
|
onClick: () => openTaskFormCallback(targetItem),
|
|
560
561
|
disabled: isGroupArchived ? true : false,
|
|
561
562
|
beginGroup: true
|
|
@@ -563,15 +564,15 @@ const TMBlogsPost = (props) => {
|
|
|
563
564
|
}
|
|
564
565
|
if (targetItem && Boolean(classId && (classId === 'WG' || classId === 'DS'))) {
|
|
565
566
|
menuItems.push({
|
|
566
|
-
icon: "eyeclose",
|
|
567
|
-
|
|
567
|
+
icon: _jsx("span", { className: "dx-icon-eyeclose" }),
|
|
568
|
+
name: SDKUI_Localizator.Unfollow,
|
|
568
569
|
onClick: () => (targetItem && classId) && unFollowCallback(targetItem, classId),
|
|
569
570
|
});
|
|
570
571
|
}
|
|
571
572
|
if (contextMenuParams.isShowHideFilterEnabled) {
|
|
572
573
|
menuItems.push({
|
|
573
|
-
icon: isHeaderHidden ?
|
|
574
|
-
|
|
574
|
+
icon: _jsx("span", { className: isHeaderHidden ? "dx-icon-eyeopen" : "dx-icon-eyeclose" }),
|
|
575
|
+
name: isHeaderHidden ? SDKUI_Localizator.ShowFilters : SDKUI_Localizator.HideFilters,
|
|
575
576
|
onClick: toggleHeaderClick,
|
|
576
577
|
disabled: false,
|
|
577
578
|
beginGroup: true
|
|
@@ -579,23 +580,24 @@ const TMBlogsPost = (props) => {
|
|
|
579
580
|
}
|
|
580
581
|
if (contextMenuParams.isShowHideIDEnaled) {
|
|
581
582
|
menuItems.push({
|
|
582
|
-
icon: localShowId ?
|
|
583
|
+
icon: _jsx("span", { className: localShowId ? "dx-icon-eyeclose" : "dx-icon-eyeopen" }),
|
|
583
584
|
onClick: () => setLocalShowId(prevShowId => !prevShowId),
|
|
584
|
-
|
|
585
|
+
name: localShowId ? SDKUI_Localizator.ID_Hide : SDKUI_Localizator.ID_Show,
|
|
585
586
|
disabled: false,
|
|
586
587
|
});
|
|
587
588
|
}
|
|
588
589
|
if (contextMenuParams.isRefreshEnabled && refreshCallback !== undefined) {
|
|
589
590
|
menuItems.push({
|
|
590
|
-
icon: "refresh",
|
|
591
|
-
|
|
591
|
+
icon: _jsx("span", { className: "dx-icon-refresh" }),
|
|
592
|
+
name: SDKUI_Localizator.Refresh,
|
|
592
593
|
onClick: refresh,
|
|
593
594
|
disabled: false,
|
|
594
595
|
});
|
|
595
596
|
}
|
|
596
597
|
if (menuItems.length > 0) {
|
|
597
|
-
|
|
598
|
+
setMenuPosition({ x: event.clientX, y: event.clientY });
|
|
598
599
|
setMenuItems(menuItems);
|
|
600
|
+
setMenuVisible(true);
|
|
599
601
|
}
|
|
600
602
|
};
|
|
601
603
|
const handlePostsToShowChange = (value) => {
|
|
@@ -606,7 +608,7 @@ const TMBlogsPost = (props) => {
|
|
|
606
608
|
setSearchText(value);
|
|
607
609
|
};
|
|
608
610
|
const closeContextMenu = useCallback(() => {
|
|
609
|
-
|
|
611
|
+
setMenuVisible(false);
|
|
610
612
|
}, []);
|
|
611
613
|
const handleNavigateToReference = (ref) => {
|
|
612
614
|
switch (ref.objClass) {
|
|
@@ -630,7 +632,7 @@ const TMBlogsPost = (props) => {
|
|
|
630
632
|
return _jsx("div", { ref: containerRef, style: { height: height, width: width }, children: _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: localShowWaitPanel, showWaitPanelPrimary: localShowPrimary, waitPanelTitle: localWaitPanelTitle, waitPanelTextPrimary: localWaitPanelTextPrimary, waitPanelValuePrimary: localWaitPanelValuePrimary, waitPanelMaxValuePrimary: localWaitPanelMaxValuePrimary, isCancelable: true, abortController: localAbortController, children: [_jsx(TMBlogHeader, { isVisible: currentHeader !== undefined && !isHeaderHidden, layoutMode: layoutMode, height: layoutMode === 'extended' ? "40px" : "70px", width: "100%", allPosts: posts, postsToShow: postsToShow, onPostsToShowChange: handlePostsToShowChange, categoryIdDataSource: categoryIdDataSource, appliedCategoryIdFilters: appliedCategoryIdFilters, setAppliedCategoryIdFilters: setAppliedCategoryIdFilters, searchText: searchText, onSearchChange: handleSearchChange }), _jsxs("div", { style: {
|
|
631
633
|
width: "100%",
|
|
632
634
|
height: currentHeader !== undefined && !isHeaderHidden ? `calc(100% - ${layoutMode === 'extended' ? "40px" : "70px"})` : "100%",
|
|
633
|
-
}, children: [blogPosts.length === 0 && _jsx(TMToppyMessage, { message: searchText.length > 0 ? SDKUI_Localizator.NoMessagesFound : SDKUI_Localizator.NoMessages }), blogPosts.length > 0 && _jsxs("div", { tabIndex: 0, onKeyDown: handleKeyDown, onContextMenu: onContextMenu, style: {
|
|
635
|
+
}, children: [blogPosts.length === 0 && _jsx(TMToppyMessage, { message: searchText.length > 0 ? SDKUI_Localizator.NoMessagesFound : SDKUI_Localizator.NoMessages }), blogPosts.length > 0 && _jsxs("div", { id: `${id}-blogs-container`, tabIndex: 0, onKeyDown: handleKeyDown, onContextMenu: onContextMenu, style: {
|
|
634
636
|
height: '100%',
|
|
635
637
|
width: '100%',
|
|
636
638
|
outline: "none",
|
|
@@ -678,7 +680,11 @@ const TMBlogsPost = (props) => {
|
|
|
678
680
|
boxShadow: isFocused ? "0 4px 12px rgba(19, 85, 150, 0.6)" : "none",
|
|
679
681
|
cursor: 'pointer',
|
|
680
682
|
}, children: [_jsx(BlogPostTitle, { displayMode: displayMode, layoutMode: layoutMode, blogPost: blogPost, isSelected: isSelected, isOwnComment: isOwnComment, searchText: searchText, isSys: isSys, isHomeBlogPost: isHomeBlogPost, showId: localShowId, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), isNew && _jsx(NewBadge, { layoutMode: layoutMode }), _jsx("div", { style: { fontSize: '1rem', color: "#000", marginTop: "10px", overflow: "hidden" }, children: _jsx(TMHtmlContentDisplay, { markup: blogPost.description ?? '-', searchText: searchText, isSelected: isSelected }) }), showExtendedAttachments && blogPost.attachments && blogPost.attachments.length > 0 && (_jsx(TMBlogAttachments, { attachments: blogPost.attachments, layoutMode: layoutMode, isSelected: isSelected, searchText: searchText, dcmtTypeDescriptors: dcmtTypeDescriptors, treeFs: treeFs, draftLatestInfoMap: draftLatestInfoMap, archivedDocumentMap: archivedDocumentMap, handleAttachmentFocus: handleFocusedAttachment, openDcmtForm: openDcmtForm }))] }, `${id}-blogpost-${blogPost.id}`) })] }, "blog-post-wrapper-" + id + "-" + blogPost.id);
|
|
681
|
-
}), _jsx("div", { ref: bottomRef }),
|
|
683
|
+
}), _jsx("div", { ref: bottomRef }), _jsx(TMContextMenu, { items: menuItems, target: `#${id}-blogs-container`, externalControl: {
|
|
684
|
+
visible: menuVisible,
|
|
685
|
+
position: menuPosition,
|
|
686
|
+
onClose: closeContextMenu,
|
|
687
|
+
} })] }), (showTaskForm && handleNavigateToWGs && handleNavigateToDossiers && getAllTasks && deleteTaskByIdsCallback && addTaskCallback && editTaskCallback) && _jsx("div", { style: { height: "100%", width: "100%" }, children: _jsx(TMTaskForm, { id: -1, title: SDKUI_Localizator.ContextualTask, isModal: true, width: calcResponsiveSizes(deviceType, '700px', '700px', '95%'), height: calcResponsiveSizes(deviceType, '670px', '80%', '95%'), formMode: FormModes.Create, visualizedTasks: [], currentTask: currentTask, setCurrentTask: () => { }, selectedRowKeys: [], handleFocusedRowKeyChange: () => { }, onStatusChanged: () => { }, onSaved: onSavedTaskFormCallback, onClose: () => closeTaskFormCallback(), onCancel: () => closeTaskFormCallback(), usersList: participants, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, isContextualCreate: true, taskContext: taskContext, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback }) }), (dcmtForm.dcmt && dcmtForm.dcmt.TID && dcmtForm.dcmt.DID) && _jsx(TMDcmtForm, { TID: Number(dcmtForm.dcmt.TID), DID: Number(dcmtForm.dcmt.DID), layoutMode: LayoutModes.Update, onClose: closeDcmtForm, isClosable: true, titleModal: SDKUI_Localizator.Attachment + ": " + dcmtForm.dcmt.fileName, isModal: true, widthModal: "95%", heightModal: "95%", allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, onReferenceClick: handleNavigateToReference }), (showFloatingCommentButton && showCommentFormCallback && !(context?.engine === 'WorkingGroupEngine' && context?.object?.customData1 === 1)) && _jsx("button", { style: {
|
|
682
688
|
position: 'absolute',
|
|
683
689
|
bottom: '18px',
|
|
684
690
|
right: '20px',
|