@topconsultnpm/sdkui-react 6.19.0 → 6.20.0-dev1.11
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.d.ts +4 -0
- package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +187 -0
- package/lib/components/NewComponents/ContextMenu/hooks.d.ts +11 -0
- package/lib/components/NewComponents/ContextMenu/hooks.js +48 -0
- package/lib/components/NewComponents/ContextMenu/index.d.ts +2 -0
- package/lib/components/NewComponents/ContextMenu/index.js +1 -0
- package/lib/components/NewComponents/ContextMenu/styles.d.ts +27 -0
- package/lib/components/NewComponents/ContextMenu/styles.js +308 -0
- package/lib/components/NewComponents/ContextMenu/types.d.ts +26 -0
- package/lib/components/NewComponents/ContextMenu/types.js +1 -0
- package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.d.ts +4 -0
- package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +370 -0
- package/lib/components/NewComponents/FloatingMenuBar/index.d.ts +2 -0
- package/lib/components/NewComponents/FloatingMenuBar/index.js +2 -0
- package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +38 -0
- package/lib/components/NewComponents/FloatingMenuBar/styles.js +267 -0
- package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +30 -0
- package/lib/components/NewComponents/FloatingMenuBar/types.js +1 -0
- package/lib/components/NewComponents/Notification/Notification.d.ts +4 -0
- package/lib/components/NewComponents/Notification/Notification.js +60 -0
- package/lib/components/NewComponents/Notification/NotificationContainer.d.ts +8 -0
- package/lib/components/NewComponents/Notification/NotificationContainer.js +33 -0
- package/lib/components/NewComponents/Notification/index.d.ts +2 -0
- package/lib/components/NewComponents/Notification/index.js +2 -0
- package/lib/components/NewComponents/Notification/styles.d.ts +21 -0
- package/lib/components/NewComponents/Notification/styles.js +180 -0
- package/lib/components/NewComponents/Notification/types.d.ts +18 -0
- package/lib/components/NewComponents/Notification/types.js +1 -0
- package/lib/components/base/TMAccordion.js +2 -2
- package/lib/components/editors/TMHtmlEditor.js +1 -1
- package/lib/components/editors/TMMetadataValues.js +16 -2
- package/lib/components/features/documents/TMDcmtBlog.d.ts +1 -7
- package/lib/components/features/documents/TMDcmtBlog.js +29 -2
- package/lib/components/features/documents/TMDcmtForm.js +12 -29
- package/lib/components/features/documents/TMDcmtPreview.js +69 -37
- package/lib/components/features/search/TMSearchResult.js +158 -47
- package/lib/components/features/search/TMSearchResultCheckoutInfoForm.js +4 -9
- package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +1 -1
- package/lib/components/features/search/TMSearchResultsMenuItems.js +16 -16
- package/lib/components/features/search/{TMViewHistoryDcmtForm.d.ts → TMViewHistoryDcmt.d.ts} +3 -3
- package/lib/components/features/search/{TMViewHistoryDcmtForm.js → TMViewHistoryDcmt.js} +83 -13
- package/lib/helper/SDKUI_Globals.d.ts +3 -14
- package/lib/helper/SDKUI_Localizator.d.ts +7 -0
- package/lib/helper/SDKUI_Localizator.js +88 -0
- package/lib/helper/TMUtils.d.ts +3 -1
- package/lib/helper/TMUtils.js +51 -0
- package/lib/helper/checkinCheckoutManager.d.ts +55 -0
- package/lib/helper/checkinCheckoutManager.js +266 -0
- package/lib/helper/helpers.js +6 -1
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/helper/queryHelper.js +13 -1
- package/lib/services/platform_services.d.ts +1 -1
- package/package.json +52 -52
- package/lib/helper/cicoHelper.d.ts +0 -31
- package/lib/helper/cicoHelper.js +0 -155
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
originalMenuItem?: TMContextMenuItemProps;
|
|
10
|
+
}
|
|
11
|
+
export interface TMFloatingMenuBarProps {
|
|
12
|
+
containerRef: React.RefObject<HTMLElement | null>;
|
|
13
|
+
contextMenuItems?: TMContextMenuItemProps[];
|
|
14
|
+
storageKey?: string;
|
|
15
|
+
isConstrained?: boolean;
|
|
16
|
+
defaultPosition?: Position;
|
|
17
|
+
maxItems?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface Position {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
}
|
|
23
|
+
export interface TMFloatingMenuBarState {
|
|
24
|
+
position: Position;
|
|
25
|
+
isDragging: boolean;
|
|
26
|
+
isConfigMode: boolean;
|
|
27
|
+
orientation: 'horizontal' | 'vertical';
|
|
28
|
+
items: TMFloatingMenuItem[];
|
|
29
|
+
draggedItemIndex: number | null;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, useRef } from 'react';
|
|
3
|
+
import * as S from './styles';
|
|
4
|
+
const Notification = ({ title, message, mode = 'info', position = 'top-right', duration = 3000, closable = false, stopOnMouseEnter = true, hasProgress = true, onClose, }) => {
|
|
5
|
+
const [state, setState] = useState({
|
|
6
|
+
visible: true,
|
|
7
|
+
isPaused: false,
|
|
8
|
+
progress: 100,
|
|
9
|
+
});
|
|
10
|
+
const timeoutRef = useRef(undefined);
|
|
11
|
+
const remainingTimeRef = useRef(duration);
|
|
12
|
+
const pauseTimeRef = useRef(0);
|
|
13
|
+
const closeNotification = () => {
|
|
14
|
+
setState(prev => ({ ...prev, visible: false }));
|
|
15
|
+
setTimeout(() => {
|
|
16
|
+
onClose?.();
|
|
17
|
+
}, 300);
|
|
18
|
+
};
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
// Set up auto-close timer
|
|
21
|
+
timeoutRef.current = setTimeout(() => {
|
|
22
|
+
closeNotification();
|
|
23
|
+
}, duration);
|
|
24
|
+
return () => {
|
|
25
|
+
if (timeoutRef.current) {
|
|
26
|
+
clearTimeout(timeoutRef.current);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}, [duration]);
|
|
30
|
+
const handleMouseEnter = () => {
|
|
31
|
+
if (!stopOnMouseEnter)
|
|
32
|
+
return;
|
|
33
|
+
// Pause the timer
|
|
34
|
+
if (timeoutRef.current) {
|
|
35
|
+
clearTimeout(timeoutRef.current);
|
|
36
|
+
pauseTimeRef.current = Date.now();
|
|
37
|
+
}
|
|
38
|
+
setState(prev => ({ ...prev, isPaused: true }));
|
|
39
|
+
};
|
|
40
|
+
const handleMouseLeave = () => {
|
|
41
|
+
if (!stopOnMouseEnter)
|
|
42
|
+
return;
|
|
43
|
+
// Resume the timer with remaining time
|
|
44
|
+
const pauseDuration = Date.now() - pauseTimeRef.current;
|
|
45
|
+
remainingTimeRef.current = Math.max(0, remainingTimeRef.current - pauseDuration);
|
|
46
|
+
timeoutRef.current = setTimeout(() => {
|
|
47
|
+
closeNotification();
|
|
48
|
+
}, remainingTimeRef.current);
|
|
49
|
+
setState(prev => ({ ...prev, isPaused: false }));
|
|
50
|
+
};
|
|
51
|
+
const handleClose = (e) => {
|
|
52
|
+
e.stopPropagation();
|
|
53
|
+
if (timeoutRef.current) {
|
|
54
|
+
clearTimeout(timeoutRef.current);
|
|
55
|
+
}
|
|
56
|
+
closeNotification();
|
|
57
|
+
};
|
|
58
|
+
return (_jsxs(S.NotificationContainer, { "$position": position, "$mode": mode, "$visible": state.visible, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, role: "alert", "aria-live": "assertive", children: [_jsxs(S.NotificationContent, { children: [_jsx(S.NotificationTitle, { children: title }), _jsx(S.NotificationMessage, { children: message })] }), closable && (_jsx(S.CloseButton, { onClick: handleClose, "aria-label": "Close notification", children: "\u00D7" })), hasProgress && (_jsx(S.ProgressBar, { "$duration": duration, "$mode": mode, "$isPaused": state.isPaused }))] }));
|
|
59
|
+
};
|
|
60
|
+
export default Notification;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { NotificationPosition } from './types';
|
|
3
|
+
interface NotificationContainerProps {
|
|
4
|
+
position: NotificationPosition;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
declare const NotificationContainer: React.FC<NotificationContainerProps>;
|
|
8
|
+
export default NotificationContainer;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
const Container = styled.div `
|
|
4
|
+
position: fixed;
|
|
5
|
+
z-index: 10002;
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
gap: 12px;
|
|
9
|
+
pointer-events: none;
|
|
10
|
+
|
|
11
|
+
${props => {
|
|
12
|
+
const isTop = props.$position.startsWith('top');
|
|
13
|
+
const isBottom = props.$position.startsWith('bottom');
|
|
14
|
+
const isLeft = props.$position.endsWith('left');
|
|
15
|
+
const isRight = props.$position.endsWith('right');
|
|
16
|
+
const isCenter = props.$position.endsWith('center');
|
|
17
|
+
return `
|
|
18
|
+
${isTop ? 'top: 24px;' : ''}
|
|
19
|
+
${isBottom ? 'bottom: 24px;' : ''}
|
|
20
|
+
${isLeft ? 'left: 24px;' : ''}
|
|
21
|
+
${isRight ? 'right: 24px;' : ''}
|
|
22
|
+
${isCenter ? 'left: 50%; transform: translateX(-50%);' : ''}
|
|
23
|
+
`;
|
|
24
|
+
}}
|
|
25
|
+
|
|
26
|
+
& > * {
|
|
27
|
+
pointer-events: auto;
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
const NotificationContainer = ({ position, children }) => {
|
|
31
|
+
return _jsx(Container, { "$position": position, children: children });
|
|
32
|
+
};
|
|
33
|
+
export default NotificationContainer;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { NotificationMode, NotificationPosition } from './types';
|
|
2
|
+
export declare const NotificationContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
3
|
+
$position: NotificationPosition;
|
|
4
|
+
$mode: NotificationMode;
|
|
5
|
+
$visible: boolean;
|
|
6
|
+
}>> & string;
|
|
7
|
+
export declare const NotificationContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
8
|
+
export declare const NotificationTitle: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
9
|
+
export declare const NotificationMessage: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
10
|
+
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;
|
|
11
|
+
export declare const ProgressBar: 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"> & {
|
|
12
|
+
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;
|
|
13
|
+
}>, {
|
|
14
|
+
$duration: number;
|
|
15
|
+
$mode: NotificationMode;
|
|
16
|
+
$isPaused: boolean;
|
|
17
|
+
}>, {
|
|
18
|
+
$duration: number;
|
|
19
|
+
$mode: NotificationMode;
|
|
20
|
+
$isPaused: boolean;
|
|
21
|
+
}>> & string;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import styled, { keyframes } from 'styled-components';
|
|
2
|
+
const slideInFromTop = keyframes `
|
|
3
|
+
from {
|
|
4
|
+
opacity: 0;
|
|
5
|
+
transform: translateY(-100%);
|
|
6
|
+
}
|
|
7
|
+
to {
|
|
8
|
+
opacity: 1;
|
|
9
|
+
transform: translateY(0);
|
|
10
|
+
}
|
|
11
|
+
`;
|
|
12
|
+
const slideInFromBottom = keyframes `
|
|
13
|
+
from {
|
|
14
|
+
opacity: 0;
|
|
15
|
+
transform: translateY(100%);
|
|
16
|
+
}
|
|
17
|
+
to {
|
|
18
|
+
opacity: 1;
|
|
19
|
+
transform: translateY(0);
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
22
|
+
const slideOut = keyframes `
|
|
23
|
+
from {
|
|
24
|
+
opacity: 1;
|
|
25
|
+
transform: scale(1);
|
|
26
|
+
}
|
|
27
|
+
to {
|
|
28
|
+
opacity: 0;
|
|
29
|
+
transform: scale(0.9);
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
const getModeColors = (mode) => {
|
|
33
|
+
const colors = {
|
|
34
|
+
success: {
|
|
35
|
+
bg: '#10b981',
|
|
36
|
+
bgDark: '#059669',
|
|
37
|
+
border: '#34d399',
|
|
38
|
+
text: '#ffffff',
|
|
39
|
+
},
|
|
40
|
+
error: {
|
|
41
|
+
bg: '#ef4444',
|
|
42
|
+
bgDark: '#dc2626',
|
|
43
|
+
border: '#f87171',
|
|
44
|
+
text: '#ffffff',
|
|
45
|
+
},
|
|
46
|
+
warning: {
|
|
47
|
+
bg: '#f59e0b',
|
|
48
|
+
bgDark: '#d97706',
|
|
49
|
+
border: '#fbbf24',
|
|
50
|
+
text: '#ffffff',
|
|
51
|
+
},
|
|
52
|
+
info: {
|
|
53
|
+
bg: '#3b82f6',
|
|
54
|
+
bgDark: '#2563eb',
|
|
55
|
+
border: '#60a5fa',
|
|
56
|
+
text: '#ffffff',
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
return colors[mode];
|
|
60
|
+
};
|
|
61
|
+
export const NotificationContainer = styled.div `
|
|
62
|
+
position: relative;
|
|
63
|
+
z-index: 1;
|
|
64
|
+
min-width: 320px;
|
|
65
|
+
max-width: 420px;
|
|
66
|
+
background: ${props => getModeColors(props.$mode).bg};
|
|
67
|
+
border-radius: 12px;
|
|
68
|
+
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.2),
|
|
69
|
+
0 4px 12px rgba(0, 0, 0, 0.15);
|
|
70
|
+
padding: 16px 20px;
|
|
71
|
+
animation: ${props => {
|
|
72
|
+
if (!props.$visible)
|
|
73
|
+
return slideOut;
|
|
74
|
+
return props.$position.startsWith('top') ? slideInFromTop : slideInFromBottom;
|
|
75
|
+
}} 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;
|
|
76
|
+
backdrop-filter: blur(10px);
|
|
77
|
+
border: 2px solid ${props => getModeColors(props.$mode).border};
|
|
78
|
+
color: ${props => getModeColors(props.$mode).text};
|
|
79
|
+
overflow: hidden;
|
|
80
|
+
|
|
81
|
+
[data-theme='dark'] & {
|
|
82
|
+
background: ${props => getModeColors(props.$mode).bgDark};
|
|
83
|
+
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4),
|
|
84
|
+
0 4px 12px rgba(0, 0, 0, 0.3);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@media (max-width: 768px) {
|
|
88
|
+
min-width: 280px;
|
|
89
|
+
max-width: calc(100vw - 48px);
|
|
90
|
+
}
|
|
91
|
+
`;
|
|
92
|
+
export const NotificationContent = styled.div `
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
gap: 6px;
|
|
96
|
+
padding-right: 24px;
|
|
97
|
+
`;
|
|
98
|
+
export const NotificationTitle = styled.div `
|
|
99
|
+
font-size: 16px;
|
|
100
|
+
font-weight: 600;
|
|
101
|
+
line-height: 1.4;
|
|
102
|
+
letter-spacing: -0.01em;
|
|
103
|
+
`;
|
|
104
|
+
export const NotificationMessage = styled.div `
|
|
105
|
+
font-size: 14px;
|
|
106
|
+
font-weight: 400;
|
|
107
|
+
line-height: 1.5;
|
|
108
|
+
opacity: 0.95;
|
|
109
|
+
`;
|
|
110
|
+
export const CloseButton = styled.button `
|
|
111
|
+
position: absolute;
|
|
112
|
+
top: 12px;
|
|
113
|
+
right: 12px;
|
|
114
|
+
background: transparent;
|
|
115
|
+
border: none;
|
|
116
|
+
color: inherit;
|
|
117
|
+
cursor: pointer;
|
|
118
|
+
width: 24px;
|
|
119
|
+
height: 24px;
|
|
120
|
+
display: flex;
|
|
121
|
+
align-items: center;
|
|
122
|
+
justify-content: center;
|
|
123
|
+
border-radius: 6px;
|
|
124
|
+
transition: all 0.15s ease;
|
|
125
|
+
font-size: 18px;
|
|
126
|
+
line-height: 1;
|
|
127
|
+
padding: 0;
|
|
128
|
+
opacity: 0.8;
|
|
129
|
+
|
|
130
|
+
&:hover {
|
|
131
|
+
opacity: 1;
|
|
132
|
+
background: rgba(255, 255, 255, 0.2);
|
|
133
|
+
transform: scale(1.1);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
&:active {
|
|
137
|
+
transform: scale(0.95);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
&:focus {
|
|
141
|
+
outline: 2px solid rgba(255, 255, 255, 0.5);
|
|
142
|
+
outline-offset: 2px;
|
|
143
|
+
}
|
|
144
|
+
`;
|
|
145
|
+
export const ProgressBar = styled.div.attrs(props => ({
|
|
146
|
+
style: {
|
|
147
|
+
animationDuration: `${props.$duration}ms`,
|
|
148
|
+
},
|
|
149
|
+
})) `
|
|
150
|
+
position: absolute;
|
|
151
|
+
bottom: 0;
|
|
152
|
+
left: 0;
|
|
153
|
+
height: 4px;
|
|
154
|
+
width: 100%;
|
|
155
|
+
background: ${props => getModeColors(props.$mode).border};
|
|
156
|
+
border-radius: 0 0 0 10px;
|
|
157
|
+
box-shadow: 0 0 8px ${props => getModeColors(props.$mode).border};
|
|
158
|
+
transform-origin: left;
|
|
159
|
+
animation: progress-shrink linear forwards;
|
|
160
|
+
animation-play-state: ${props => props.$isPaused ? 'paused' : 'running'};
|
|
161
|
+
|
|
162
|
+
@keyframes progress-shrink {
|
|
163
|
+
from {
|
|
164
|
+
transform: scaleX(1);
|
|
165
|
+
}
|
|
166
|
+
to {
|
|
167
|
+
transform: scaleX(0);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
&::after {
|
|
172
|
+
content: '';
|
|
173
|
+
position: absolute;
|
|
174
|
+
top: 0;
|
|
175
|
+
right: 0;
|
|
176
|
+
width: 20px;
|
|
177
|
+
height: 100%;
|
|
178
|
+
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4));
|
|
179
|
+
}
|
|
180
|
+
`;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type NotificationMode = 'warning' | 'info' | 'error' | 'success';
|
|
2
|
+
export type NotificationPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
|
|
3
|
+
export interface NotificationProps {
|
|
4
|
+
title: string;
|
|
5
|
+
message: string;
|
|
6
|
+
mode?: NotificationMode;
|
|
7
|
+
position?: NotificationPosition;
|
|
8
|
+
duration?: number;
|
|
9
|
+
closable?: boolean;
|
|
10
|
+
stopOnMouseEnter?: boolean;
|
|
11
|
+
hasProgress?: boolean;
|
|
12
|
+
onClose?: () => void;
|
|
13
|
+
}
|
|
14
|
+
export interface NotificationState {
|
|
15
|
+
visible: boolean;
|
|
16
|
+
isPaused: boolean;
|
|
17
|
+
progress: number;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -47,12 +47,12 @@ const StyledGroupTemplate = styled.div `
|
|
|
47
47
|
&::after {
|
|
48
48
|
content: '';
|
|
49
49
|
display: block;
|
|
50
|
-
width:
|
|
50
|
+
width: calc(100% - 35px);
|
|
51
51
|
margin: 0 auto;
|
|
52
52
|
border-bottom: 1px solid #00A99D;
|
|
53
53
|
margin-top: 8px;
|
|
54
54
|
position: absolute;
|
|
55
|
-
left:
|
|
55
|
+
left: 35px;
|
|
56
56
|
bottom: 0;
|
|
57
57
|
}
|
|
58
58
|
`;
|
|
@@ -170,7 +170,7 @@ const TMHtmlEditor = (props) => {
|
|
|
170
170
|
justifyContent: 'flex-end',
|
|
171
171
|
fontSize: 12,
|
|
172
172
|
color: '#6c757d',
|
|
173
|
-
marginTop: 4,
|
|
173
|
+
marginTop: showInfoIcon ? 0 : 4,
|
|
174
174
|
gap: 4,
|
|
175
175
|
}, children: [`${Math.max(charactersRemaining, 0)} ${SDKUI_Localizator.CharactersRemaining}`, showInfoIcon && (_jsx(TMTooltip, { content: 'Markup HTML', children: _jsx("span", { className: "dx-icon-codeblock", style: { fontSize: 22, cursor: 'pointer' }, onClick: () => {
|
|
176
176
|
TMMessageBoxManager.show({
|
|
@@ -10,7 +10,7 @@ import TMTooltip from "../base/TMTooltip";
|
|
|
10
10
|
import TMCheckBox from "./TMCheckBox";
|
|
11
11
|
import TMMetadataEditor, { useMetadataEditableList } from "./TMMetadataEditor";
|
|
12
12
|
import { FormulaHelper } from "./TMFormulaEditor";
|
|
13
|
-
import { DraftsMIDs, DSAttachsMIDs } from "../../ts";
|
|
13
|
+
import { ChronologyMIDs, DraftsMIDs, DSAttachsMIDs } from "../../ts";
|
|
14
14
|
import { TMNothingToShow } from "../features/documents/TMDcmtPreview";
|
|
15
15
|
import TMAccordion from "../base/TMAccordion";
|
|
16
16
|
import TabPanel, { Item } from 'devextreme-react/tab-panel';
|
|
@@ -388,6 +388,20 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
388
388
|
});
|
|
389
389
|
return (_jsxs("div", { style: { width: '100%' }, children: [draftData.length > 0 && _jsx(TMAccordion, { title: SDKUI_Localizator.Draft, children: draftData.map(item => renderMetadataItem(item, isReadOnly)) }), checkOutData.length > 0 && _jsx(TMAccordion, { title: `${SDKUI_Localizator.CheckIn}/${SDKUI_Localizator.CheckOut}`, children: checkOutData.map(item => renderMetadataItem(item, true)) })] }));
|
|
390
390
|
}, [metadataValues, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
|
|
391
|
+
const layoutChronology = useMemo(() => {
|
|
392
|
+
const chronologyData = [];
|
|
393
|
+
metadataValues.forEach(item => {
|
|
394
|
+
switch (item.md?.id) {
|
|
395
|
+
case ChronologyMIDs.Ver:
|
|
396
|
+
case ChronologyMIDs.AuthorID:
|
|
397
|
+
chronologyData.push(item);
|
|
398
|
+
break;
|
|
399
|
+
default:
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
return (_jsx("div", { style: { width: '100%' }, children: chronologyData.length > 0 && chronologyData.map(item => renderMetadataItem(item, isReadOnly)) }));
|
|
404
|
+
}, [metadataValues, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
|
|
391
405
|
const layoutDsAttachs = useMemo(() => {
|
|
392
406
|
const dsAttachsData = [];
|
|
393
407
|
metadataValues.forEach(item => {
|
|
@@ -541,7 +555,7 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
541
555
|
}
|
|
542
556
|
switch (currentDTD?.id) {
|
|
543
557
|
case SystemTIDs.Drafts: return layoutDraft;
|
|
544
|
-
|
|
558
|
+
case SystemTIDs.Chronology: return layoutChronology;
|
|
545
559
|
case SystemTIDs.DSAttachs: return layoutDsAttachs;
|
|
546
560
|
default:
|
|
547
561
|
// Se è presente un layout personalizzato, usalo, altrimenti usa il rendering standard
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
|
|
3
3
|
interface ITMDcmtBlogProps {
|
|
4
|
-
blogsDatasource: HomeBlogPost[];
|
|
5
|
-
setBlogsDatasource: (posts: HomeBlogPost[]) => void;
|
|
6
|
-
hasLoadedDataOnce: boolean;
|
|
7
|
-
setHasLoadedDataOnce: (loaded: boolean) => void;
|
|
8
|
-
lastLoadedDid: number | undefined;
|
|
9
|
-
setLastLoadedDid: (did: number | undefined) => void;
|
|
10
4
|
tid: number | undefined;
|
|
11
5
|
did: number | undefined;
|
|
12
|
-
fetchBlogDataAsync: (tid: number | undefined, did: number | undefined) => Promise<void>;
|
|
13
6
|
isVisible?: boolean;
|
|
7
|
+
fetchBlogDataTrigger?: number;
|
|
14
8
|
allTasks?: Array<TaskDescriptor>;
|
|
15
9
|
getAllTasks?: () => Promise<void>;
|
|
16
10
|
deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
|
|
@@ -6,13 +6,40 @@ import { TMNothingToShow } from './TMDcmtPreview';
|
|
|
6
6
|
import { IconBoard, SDKUI_Localizator } from '../../../helper';
|
|
7
7
|
import TMBlogCommentForm from '../blog/TMBlogCommentForm';
|
|
8
8
|
import TMBlogsPost from '../../grids/TMBlogsPost';
|
|
9
|
-
|
|
9
|
+
import TMSpinner from '../../base/TMSpinner';
|
|
10
|
+
import { TMExceptionBoxManager } from '../../base/TMPopUp';
|
|
11
|
+
const TMDcmtBlog = ({ tid, did, isVisible, fetchBlogDataTrigger, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
|
|
12
|
+
const [blogsDatasource, setBlogsDatasource] = useState([]);
|
|
13
|
+
const [hasLoadedDataOnce, setHasLoadedDataOnce] = useState(false); //traccia se *qualsiasi* dato è stato caricato per la prima volta
|
|
14
|
+
const [lastLoadedDid, setLastLoadedDid] = useState(undefined); // `lastLoadedDid` tiene traccia dell'ultimo `did` per cui abbiamo caricato i dati
|
|
10
15
|
// State to manage show comment form selected file
|
|
11
16
|
const [showCommentForm, setShowCommentForm] = useState(false);
|
|
12
17
|
const [externalBlogPost, setExternalBlogPost] = useState(undefined);
|
|
18
|
+
const fetchBlogDataAsync = useCallback(async (tid, did) => {
|
|
19
|
+
try {
|
|
20
|
+
TMSpinner.show({ description: 'Caricamento - Bacheca...' });
|
|
21
|
+
const res = await SDK_Globals.tmSession?.NewSearchEngine().BlogRetrieveAsync(tid, did);
|
|
22
|
+
setBlogsDatasource(res ?? []);
|
|
23
|
+
setHasLoadedDataOnce(true);
|
|
24
|
+
setLastLoadedDid(did);
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
let err = e;
|
|
28
|
+
TMExceptionBoxManager.show({ exception: err });
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
TMSpinner.hide();
|
|
32
|
+
}
|
|
33
|
+
}, []);
|
|
13
34
|
const showCommentFormCallback = useCallback(() => {
|
|
14
35
|
setShowCommentForm(true);
|
|
15
36
|
}, []);
|
|
37
|
+
// useEffect per triggerare il fetch dall'esterno tramite props
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (fetchBlogDataTrigger !== undefined && fetchBlogDataTrigger > 0) {
|
|
40
|
+
fetchBlogDataAsync(tid, did);
|
|
41
|
+
}
|
|
42
|
+
}, [fetchBlogDataTrigger, fetchBlogDataAsync, tid, did]);
|
|
16
43
|
useEffect(() => {
|
|
17
44
|
if (!tid || !did) {
|
|
18
45
|
setBlogsDatasource([]);
|
|
@@ -21,7 +48,7 @@ const TMDcmtBlog = ({ blogsDatasource, setBlogsDatasource, hasLoadedDataOnce, se
|
|
|
21
48
|
}
|
|
22
49
|
// Condizione per eseguire il fetch:
|
|
23
50
|
// 1. Il pannello è visibile
|
|
24
|
-
// 2. E (non abbiamo ancora caricato dati
|
|
51
|
+
// 2. E (non abbiamo ancora caricato dati o il `did` è cambiato rispetto all'ultima volta)
|
|
25
52
|
const shouldFetch = isVisible && (!hasLoadedDataOnce || did !== lastLoadedDid);
|
|
26
53
|
// Esegui la chiamata API solo se il pannello è visibile E i dati non sono già stati caricati
|
|
27
54
|
// O, se vuoi ricaricare ogni volta che diventa visibile (ma è meno efficiente per "pesante")
|
|
@@ -96,10 +96,11 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
96
96
|
const [isInitialLoading, setIsInitialLoading] = useState(true);
|
|
97
97
|
const [isNavigating, setIsNavigating] = useState(false);
|
|
98
98
|
const [dcmtReferences, setDcmtReferences] = useState(undefined);
|
|
99
|
-
//
|
|
100
|
-
const [
|
|
101
|
-
const
|
|
102
|
-
|
|
99
|
+
// Stato per triggerare il refresh del blog dall'esterno
|
|
100
|
+
const [refreshBlogTrigger, setRefreshBlogTrigger] = useState(0);
|
|
101
|
+
const triggerBlogRefresh = useCallback(async () => {
|
|
102
|
+
setRefreshBlogTrigger(prev => prev + 1);
|
|
103
|
+
}, []);
|
|
103
104
|
useEffect(() => {
|
|
104
105
|
if (!allowButtonsRefs)
|
|
105
106
|
setDcmtReferences(undefined);
|
|
@@ -237,11 +238,11 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
237
238
|
// Imposta il layout e customButtonsLayout immediatamente
|
|
238
239
|
setLayout(resLayout);
|
|
239
240
|
if (layoutMode === LayoutModes.Update && customButtonsLayoutResult) {
|
|
240
|
-
|
|
241
|
-
//setCustomButtonsLayout(customButtonsLayoutResult);
|
|
241
|
+
setCustomButtonsLayout(customButtonsLayoutResult);
|
|
242
242
|
}
|
|
243
243
|
// Carica DTD e metadata
|
|
244
244
|
let dtd = await DcmtTypeListCacheService.GetWithNotGrantedAsync(TID, DID, getMetadataResult);
|
|
245
|
+
console.log('GetWithNotGrantedAsync DTD:', dtd);
|
|
245
246
|
setFromDTD(dtd);
|
|
246
247
|
if (layoutMode === LayoutModes.Update || (layoutMode === LayoutModes.Ark && DID)) {
|
|
247
248
|
await setMetadataList(dtd?.metadata ?? [], getMetadataResult);
|
|
@@ -680,13 +681,11 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
680
681
|
text: customButton.title || 'Bottone personalizzato',
|
|
681
682
|
onClick: () => setCustomButton(customButton)
|
|
682
683
|
}));
|
|
683
|
-
//disabilitato per ora
|
|
684
|
-
/*
|
|
685
684
|
items.push({
|
|
686
|
-
icon: svgToString(
|
|
685
|
+
icon: svgToString(_jsx(IconCheck, {})),
|
|
687
686
|
text: SDKUI_Localizator.CustomButtons,
|
|
688
687
|
items: customButtonsItems
|
|
689
|
-
}
|
|
688
|
+
});
|
|
690
689
|
}
|
|
691
690
|
return items;
|
|
692
691
|
}, [
|
|
@@ -1007,28 +1006,12 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
1007
1006
|
setShowAll(true);
|
|
1008
1007
|
}
|
|
1009
1008
|
}, [shouldShowAll, showAll]);
|
|
1010
|
-
const fetchBlogDataAsync = useCallback(async (tid, did) => {
|
|
1011
|
-
try {
|
|
1012
|
-
TMSpinner.show({ description: 'Caricamento - Bacheca...' });
|
|
1013
|
-
const res = await SDK_Globals.tmSession?.NewSearchEngine().BlogRetrieveAsync(tid, did);
|
|
1014
|
-
setBlogsDatasource(res ?? []);
|
|
1015
|
-
setHasLoadedDataOnce(true);
|
|
1016
|
-
setLastLoadedDid(did);
|
|
1017
|
-
}
|
|
1018
|
-
catch (e) {
|
|
1019
|
-
let err = e;
|
|
1020
|
-
TMExceptionBoxManager.show({ exception: err });
|
|
1021
|
-
}
|
|
1022
|
-
finally {
|
|
1023
|
-
TMSpinner.hide();
|
|
1024
|
-
}
|
|
1025
|
-
}, []);
|
|
1026
1009
|
const afterTaskSaved = useCallback(async (task, formMode, forceRefresh = false) => {
|
|
1027
1010
|
const shouldRefresh = forceRefresh || (task && task.state === Task_States.Completed) || formMode === FormModes.Create || formMode === FormModes.Duplicate;
|
|
1028
1011
|
if (TID && DID && shouldRefresh) {
|
|
1029
|
-
await
|
|
1012
|
+
await triggerBlogRefresh();
|
|
1030
1013
|
}
|
|
1031
|
-
}, [TID, DID]);
|
|
1014
|
+
}, [TID, DID, triggerBlogRefresh]);
|
|
1032
1015
|
const tmDcmtForm = useMemo(() => {
|
|
1033
1016
|
return _jsx(_Fragment, { children: metadataValuesSource.length > 0 &&
|
|
1034
1017
|
_jsxs(StyledToolbarCardContainer, { children: [_jsx(TMMetadataValues, { TID: TID, metadataValues: metadataValuesSource, metadataValuesOrig: metadataValuesSourceOrig, isExpertMode: isExpertMode, isOpenDistinctValues: isOpenDistinctValues, openChooserBySingleClick: !isOpenDistinctValues, selectedMID: focusedMetadataValue?.mid, isReadOnly: formMode === FormModes.ReadOnly, layoutMode: layoutMode, deviceType: deviceType, validationItems: validationItems, inputMids: inputMids, layout: layout, onFocusedItemChanged: (item) => { (item?.mid !== focusedMetadataValue?.mid) && setFocusedMetadataValue(item); }, onValueChanged: (newItems) => {
|
|
@@ -1078,7 +1061,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
1078
1061
|
handleUndo,
|
|
1079
1062
|
handleClearForm
|
|
1080
1063
|
]);
|
|
1081
|
-
const tmBlog = useMemo(() => _jsx(TMDcmtBlog, {
|
|
1064
|
+
const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { tid: TID, did: DID, allTasks: allTasks, fetchBlogDataTrigger: refreshBlogTrigger, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), [TID, DID, allTasks, refreshBlogTrigger]);
|
|
1082
1065
|
const tmSysMetadata = useMemo(() => _jsx(TMMetadataValues, { layoutMode: layoutMode, openChooserBySingleClick: !isOpenDistinctValues, TID: TID, isReadOnly: true, deviceType: deviceType, metadataValues: formData.filter(o => (o.mid != undefined && o.mid <= 100)), metadataValuesOrig: formData.filter(o => (o.mid != undefined && o.mid <= 100)), validationItems: [], inputMids: inputMids }), [TID, layoutMode, formData, deviceType, inputMids]);
|
|
1083
1066
|
const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { currentDcmt: currentDcmt, dcmtFile: dcmtFile ?? inputFile, deviceType: deviceType, fromDTD: fromDTD, layoutMode: layoutMode, onFileUpload: (file) => {
|
|
1084
1067
|
setDcmtFile(file);
|