@topconsultnpm/sdkui-react 6.22.0-dev4.2 → 6.22.0-dev4.20
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/styles.d.ts +43 -45
- package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +60 -67
- package/lib/components/base/Styled.d.ts +77 -93
- package/lib/components/base/TMAlert.d.ts +2 -1
- package/lib/components/base/TMAlert.js +7 -6
- package/lib/components/base/TMCounterBar.d.ts +2 -2
- package/lib/components/base/TMCounterContainer.d.ts +4 -3
- package/lib/components/base/TMCounterContainer.js +16 -1
- package/lib/components/base/TMCustomButton.d.ts +1 -1
- package/lib/components/base/TMDataGrid.js +24 -4
- package/lib/components/base/TMDataGridExportForm.d.ts +1 -2
- package/lib/components/base/TMFileManager.d.ts +1 -2
- package/lib/components/base/TMFileManagerDataGridView.d.ts +1 -2
- package/lib/components/base/TMFileManagerThumbnailItems.d.ts +1 -1
- package/lib/components/base/TMFileManagerThumbnailsView.d.ts +1 -1
- package/lib/components/base/TMFileManagerUtils.d.ts +6 -4
- package/lib/components/base/TMLayout.d.ts +4 -4
- package/lib/components/base/TMList.d.ts +1 -2
- package/lib/components/base/TMListView.d.ts +1 -1
- package/lib/components/base/TMSpinner.d.ts +2 -3
- package/lib/components/base/TMTab.d.ts +3 -4
- package/lib/components/base/TMTabControl.js +208 -208
- package/lib/components/base/TMTooltip.d.ts +1 -1
- package/lib/components/base/TMTreeView.d.ts +8 -14
- package/lib/components/base/TMUserAvatar.d.ts +1 -2
- package/lib/components/base/TMVilViewer.d.ts +1 -2
- package/lib/components/base/TMWaitPanel.d.ts +2 -3
- package/lib/components/base/waitPanel/TMWaitPanelManager.d.ts +16 -6
- package/lib/components/base/waitPanel/TMWaitPanelManager.js +55 -2
- package/lib/components/base/waitPanel/TMWaitPanelView.d.ts +6 -2
- package/lib/components/base/waitPanel/TMWaitPanelView.js +75 -3
- package/lib/components/choosers/TMDistinctValues.js +3 -3
- package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
- package/lib/components/choosers/TMInvoiceRetrieveFormats.d.ts +1 -2
- package/lib/components/choosers/TMOrderRetrieveFormats.d.ts +1 -2
- package/lib/components/choosers/TMQuickSearchInfo.d.ts +1 -2
- package/lib/components/choosers/TMRelationChooser.d.ts +3 -3
- package/lib/components/choosers/TMUserChooser.d.ts +3 -2
- package/lib/components/choosers/TMUserChooser.js +3 -3
- package/lib/components/editors/TMEditorStyled.d.ts +42 -20
- package/lib/components/editors/TMFormulaEditor.d.ts +1 -1
- package/lib/components/editors/TMHtmlContentDisplay.d.ts +1 -2
- package/lib/components/editors/TMHtmlEditor.d.ts +1 -2
- package/lib/components/editors/TMTreeDropDown.d.ts +1 -1
- package/lib/components/features/assistant/TMHelpOnLineChat.d.ts +0 -1
- package/lib/components/features/assistant/TMHelpOnLineChat.js +8 -161
- package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +1 -1
- package/lib/components/features/blog/TMBlogCommentForm.d.ts +1 -2
- package/lib/components/features/documents/TMDcmtForm.d.ts +6 -1
- package/lib/components/features/documents/TMDcmtForm.js +42 -7
- package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +1 -1
- package/lib/components/features/documents/TMDcmtFormActionButtons.js +5 -2
- package/lib/components/features/documents/TMDcmtIcon.d.ts +1 -2
- package/lib/components/features/documents/TMDcmtPreview.d.ts +8 -8
- package/lib/components/features/documents/TMDcmtPreview.js +16 -7
- package/lib/components/features/documents/TMDcmtTasks.d.ts +1 -2
- package/lib/components/features/documents/TMDragDropOverlay.d.ts +1 -1
- package/lib/components/features/documents/TMFileUploader.js +21 -21
- package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +2 -0
- package/lib/components/features/documents/TMMasterDetailDcmts.js +14 -5
- package/lib/components/features/documents/TMMasterInfoFields.d.ts +1 -2
- package/lib/components/features/documents/TMMergeToPdfForm.d.ts +1 -2
- package/lib/components/features/documents/TMMergeToPdfForm.js +5 -4
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.d.ts +1 -2
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.d.ts +4 -4
- package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +1 -2
- package/lib/components/features/search/TMMetadataOutputForm.d.ts +1 -2
- package/lib/components/features/search/TMMetadataSorterForm.d.ts +1 -2
- package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
- package/lib/components/features/search/TMSearch.d.ts +1 -2
- package/lib/components/features/search/TMSearchQueryPanel.d.ts +3 -9
- package/lib/components/features/search/TMSearchResult.js +121 -91
- package/lib/components/features/search/TMSearchResultFloatingActionButton.d.ts +1 -1
- package/lib/components/features/search/TMSignatureInfoContent.d.ts +1 -2
- package/lib/components/features/search/TMViewHistoryDcmt.d.ts +1 -2
- package/lib/components/features/search/TMViewHistoryDcmt.js +1 -1
- package/lib/components/features/tasks/TMTaskForm.d.ts +1 -1
- package/lib/components/features/tasks/TMTaskFormUtils.d.ts +10 -10
- package/lib/components/features/tasks/TMTasksAgenda.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksCalendar.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksHeader.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksPanelContent.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksUtilsView.d.ts +5 -5
- package/lib/components/features/tasks/TMTasksView.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksView.js +15 -9
- package/lib/components/features/wg/TMWGsCopyMoveForm.d.ts +2 -3
- package/lib/components/features/wg/TMWGsCopyMoveForm.js +8 -4
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +7 -8
- package/lib/components/features/workflow/TMWorkflowPopup.js +1 -1
- package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.d.ts +1 -3
- package/lib/components/forms/Login/ChangePasswordInputs.d.ts +1 -3
- package/lib/components/forms/Login/Chooser.d.ts +2 -2
- package/lib/components/forms/TMChooserForm.d.ts +1 -2
- package/lib/components/forms/TMSaveForm.d.ts +4 -4
- package/lib/components/grids/TMBlogAttachments.d.ts +1 -2
- package/lib/components/grids/TMBlogHeader.d.ts +1 -1
- package/lib/components/grids/TMBlogsPost.d.ts +1 -1
- package/lib/components/grids/TMBlogsPost.js +1 -1
- package/lib/components/grids/TMBlogsPostUtils.d.ts +9 -9
- package/lib/components/grids/TMValidationItemsList.d.ts +1 -2
- package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -2
- package/lib/components/layout/panelManager/TMPanelManagerContainer.js +12 -12
- package/lib/components/layout/panelManager/TMPanelManagerContext.d.ts +2 -2
- package/lib/components/layout/panelManager/TMPanelManagerLoader.d.ts +1 -2
- package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +6 -5
- package/lib/components/layout/panelManager/TMPanelManagerWithPersistenceProvider.d.ts +2 -2
- package/lib/components/layout/panelManager/TMPanelWrapper.d.ts +2 -2
- package/lib/components/pages/TMPage.d.ts +1 -1
- package/lib/components/pages/TMPage.js +13 -5
- package/lib/components/query/TMQueryEditor.d.ts +10 -14
- package/lib/components/settings/SettingsAppearance.d.ts +1 -2
- package/lib/components/sidebar/TMAboutApp.d.ts +1 -2
- package/lib/components/sidebar/TMCommandsPanel.d.ts +4 -4
- package/lib/components/sidebar/TMHeader.d.ts +3 -3
- package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -3
- package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +2 -3
- package/lib/components/viewers/TMMidViewer.d.ts +2 -2
- package/lib/components/viewers/TMTidViewer.d.ts +2 -2
- package/lib/helper/SDKUI_Globals.d.ts +7 -4
- package/lib/helper/SDKUI_Globals.js +7 -4
- package/lib/helper/SDKUI_Localizator.d.ts +13 -6
- package/lib/helper/SDKUI_Localizator.js +121 -51
- package/lib/helper/TMAppUpdatedModal.d.ts +1 -2
- package/lib/helper/TMAppUpdatedModal.js +93 -93
- package/lib/helper/TMCommandsContextMenu.d.ts +1 -1
- package/lib/helper/TMIcons.d.ts +282 -281
- package/lib/helper/TMIcons.js +4 -1
- package/lib/helper/TMPdfViewer.d.ts +1 -2
- package/lib/helper/TMToppyMessage.d.ts +2 -2
- package/lib/helper/TMUtils.d.ts +4 -10
- package/lib/helper/checkinCheckoutManager.js +2 -3
- package/lib/helper/helpers.d.ts +1 -1
- package/lib/helper/queryHelper.d.ts +15 -2
- package/lib/helper/queryHelper.js +52 -1
- package/lib/hooks/useCaseFlowApprove.js +31 -6
- package/lib/hooks/useCheckInOutOperations.js +2 -3
- package/lib/hooks/useDcmtOperations.js +24 -16
- package/lib/hooks/useDocumentOperations.d.ts +2 -0
- package/lib/hooks/useDocumentOperations.js +7 -7
- package/lib/hooks/useInputDialog.d.ts +1 -2
- package/lib/hooks/useMultiMasterDetailDcmts.js +10 -6
- package/lib/services/caseflow/CaseFlowService.d.ts +33 -3
- package/lib/services/caseflow/CaseFlowService.js +71 -44
- package/lib/services/caseflow/caseFlowNameCache.d.ts +5 -0
- package/lib/services/caseflow/caseFlowNameCache.js +19 -0
- package/lib/services/platform_services.d.ts +2 -3
- package/package.json +69 -69
- package/lib/components/features/assistant/dataset/Designer-Suggested-Questions.json +0 -102
- package/lib/components/features/assistant/dataset/Login-Suggested-Questions.json +0 -32
- package/lib/components/features/assistant/dataset/Surfer-Suggested-Questions.json +0 -102
|
@@ -2,14 +2,11 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
3
|
import styled, { keyframes } from 'styled-components';
|
|
4
4
|
import { locale as dxLocale } from 'devextreme/localization';
|
|
5
|
-
import {
|
|
5
|
+
import { CultureIDs, HolAskDescriptor, SDK_Globals, TopMediaServer } from '@topconsultnpm/sdk-ts';
|
|
6
6
|
import TMTooltip from '../../base/TMTooltip';
|
|
7
7
|
import { TMColors } from '../../../utils/theme';
|
|
8
8
|
import { SDKUI_Localizator } from '../../../helper';
|
|
9
9
|
import ToppyImage from '../../../assets/Toppy-help-center.png';
|
|
10
|
-
import LoginSuggestedQuestions from './dataset/Login-Suggested-Questions.json';
|
|
11
|
-
import SurferSuggestedQuestions from './dataset/Surfer-Suggested-Questions.json';
|
|
12
|
-
import DesignerSuggestedQuestions from './dataset/Designer-Suggested-Questions.json';
|
|
13
10
|
const generateGUID = () => {
|
|
14
11
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replaceAll(/[xy]/g, (c) => {
|
|
15
12
|
const r = Math.trunc(Math.random() * 16);
|
|
@@ -20,7 +17,6 @@ const generateGUID = () => {
|
|
|
20
17
|
const PANEL_DEFAULT_WIDTH = 600;
|
|
21
18
|
const PANEL_MIN_WIDTH = 340;
|
|
22
19
|
const PANEL_MAX_WIDTH = 900;
|
|
23
|
-
const SUGGESTIONS_COUNT = 4;
|
|
24
20
|
const FEEDBACK_MAX_LENGTH = 200;
|
|
25
21
|
const NO_ANSWER_TEXT = 'Nessuna risposta ricevuta.';
|
|
26
22
|
const ERROR_TEXT = 'Si è verificato un errore, riprova più tardi.';
|
|
@@ -53,23 +49,6 @@ const copyToClipboard = async (text) => {
|
|
|
53
49
|
return false;
|
|
54
50
|
}
|
|
55
51
|
};
|
|
56
|
-
const getDefaultSuggestedQuestions = (isLogged) => {
|
|
57
|
-
if (!isLogged)
|
|
58
|
-
return LoginSuggestedQuestions;
|
|
59
|
-
switch (SDK_Globals.appModule) {
|
|
60
|
-
case AppModules.SURFER: return SurferSuggestedQuestions;
|
|
61
|
-
case AppModules.DESIGNER: return DesignerSuggestedQuestions;
|
|
62
|
-
default: return [];
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
const pickRandom = (items, count) => {
|
|
66
|
-
const pool = [...items];
|
|
67
|
-
for (let i = pool.length - 1; i > 0; i--) {
|
|
68
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
69
|
-
[pool[i], pool[j]] = [pool[j], pool[i]];
|
|
70
|
-
}
|
|
71
|
-
return pool.slice(0, count);
|
|
72
|
-
};
|
|
73
52
|
const getSafeSession = () => {
|
|
74
53
|
try {
|
|
75
54
|
return SDK_Globals.tmSession;
|
|
@@ -100,15 +79,14 @@ const getPreLoginSession = (endpointUrl) => {
|
|
|
100
79
|
}
|
|
101
80
|
return preLoginSession;
|
|
102
81
|
};
|
|
103
|
-
const TMHelpOnLineChat = ({ isOpen, showChatButton, isLogged, messages, conversationId, isThinking, endpointUrl, onClose, onToggle, onNewConversation, onAddMessage, onSetThinking, onSetConversationId
|
|
82
|
+
const TMHelpOnLineChat = ({ isOpen, showChatButton, isLogged, messages, conversationId, isThinking, endpointUrl, onClose, onToggle, onNewConversation, onAddMessage, onSetThinking, onSetConversationId }) => {
|
|
104
83
|
const [width, setWidth] = useState(PANEL_DEFAULT_WIDTH);
|
|
105
84
|
const showFab = !isLogged && showChatButton && !isOpen;
|
|
106
|
-
const questions = suggestedQuestions ?? getDefaultSuggestedQuestions(isLogged);
|
|
107
85
|
const [submittedRatings, setSubmittedRatings] = useState({});
|
|
108
86
|
const onFeedbackSubmitted = useCallback((messageId, rating) => {
|
|
109
87
|
setSubmittedRatings(prev => ({ ...prev, [messageId]: rating }));
|
|
110
88
|
}, []);
|
|
111
|
-
return (_jsxs(_Fragment, { children: [isOpen && (_jsxs(_Fragment, { children: [_jsx(Overlay, { onClick: onClose }), _jsx(ChatPanel, { width: width, onWidthChange: setWidth, messages: messages, conversationId: conversationId, isThinking: isThinking, endpointUrl: endpointUrl, onClose: onClose, onNewConversation: onNewConversation, onAddMessage: onAddMessage, onSetThinking: onSetThinking, onSetConversationId: onSetConversationId,
|
|
89
|
+
return (_jsxs(_Fragment, { children: [isOpen && (_jsxs(_Fragment, { children: [_jsx(Overlay, { onClick: onClose }), _jsx(ChatPanel, { width: width, onWidthChange: setWidth, messages: messages, conversationId: conversationId, isThinking: isThinking, endpointUrl: endpointUrl, onClose: onClose, onNewConversation: onNewConversation, onAddMessage: onAddMessage, onSetThinking: onSetThinking, onSetConversationId: onSetConversationId, isLogged: isLogged, submittedRatings: submittedRatings, onFeedbackSubmitted: onFeedbackSubmitted })] })), showFab && (_jsx(Fab, { onClick: onToggle, title: "Chiedi a Toppy", "aria-label": "Chiedi a Toppy", children: _jsx(FabAvatar, { src: ToppyImage, alt: "Toppy" }) }))] }));
|
|
112
90
|
};
|
|
113
91
|
export default TMHelpOnLineChat;
|
|
114
92
|
//#region Header button
|
|
@@ -117,11 +95,8 @@ export const TMToppyHeaderButton = ({ showChatButton, onToggle }) => {
|
|
|
117
95
|
return null;
|
|
118
96
|
return (_jsx(TMTooltip, { content: "Chiedi a Toppy", children: _jsxs(ToppyHeaderButton, { onClick: onToggle, title: "Chiedi a Toppy", children: [_jsx(ToppyHeaderAvatar, { src: ToppyImage, alt: "Toppy" }), _jsx(ToppyHeaderText, { children: "Chiedi a Toppy" })] }) }));
|
|
119
97
|
};
|
|
120
|
-
const ChatPanel = ({ width, onWidthChange, messages, conversationId, isThinking, endpointUrl, onClose, onNewConversation, onAddMessage, onSetThinking, onSetConversationId,
|
|
98
|
+
const ChatPanel = ({ width, onWidthChange, messages, conversationId, isThinking, endpointUrl, onClose, onNewConversation, onAddMessage, onSetThinking, onSetConversationId, isLogged, submittedRatings, onFeedbackSubmitted }) => {
|
|
121
99
|
const [chatInput, setChatInput] = useState('');
|
|
122
|
-
const [suggestions, setSuggestions] = useState(() => pickRandom(suggestedQuestions, SUGGESTIONS_COUNT));
|
|
123
|
-
const [hoveredSuggestion, setHoveredSuggestion] = useState(undefined);
|
|
124
|
-
const prevMessagesCountRef = useRef(messages.length);
|
|
125
100
|
const inputRef = useRef(null);
|
|
126
101
|
const messagesEndRef = useRef(null);
|
|
127
102
|
const onCloseRef = useRef(onClose);
|
|
@@ -133,12 +108,6 @@ const ChatPanel = ({ width, onWidthChange, messages, conversationId, isThinking,
|
|
|
133
108
|
useEffect(() => {
|
|
134
109
|
inputRef.current?.focus();
|
|
135
110
|
}, []);
|
|
136
|
-
useEffect(() => {
|
|
137
|
-
if (messages.length === 0 && prevMessagesCountRef.current > 0) {
|
|
138
|
-
setSuggestions(pickRandom(suggestedQuestions, SUGGESTIONS_COUNT));
|
|
139
|
-
}
|
|
140
|
-
prevMessagesCountRef.current = messages.length;
|
|
141
|
-
}, [messages.length, suggestedQuestions]);
|
|
142
111
|
useEffect(() => {
|
|
143
112
|
const onKeyDown = (e) => {
|
|
144
113
|
if (e.key === 'Escape')
|
|
@@ -167,8 +136,8 @@ const ChatPanel = ({ width, onWidthChange, messages, conversationId, isThinking,
|
|
|
167
136
|
globalThis.addEventListener('mousemove', onMove);
|
|
168
137
|
globalThis.addEventListener('mouseup', onUp);
|
|
169
138
|
}, [width, onWidthChange]);
|
|
170
|
-
const
|
|
171
|
-
const question =
|
|
139
|
+
const askHandler = useCallback(async () => {
|
|
140
|
+
const question = chatInput.trim();
|
|
172
141
|
if (question.length < 2 || isThinking) {
|
|
173
142
|
return;
|
|
174
143
|
}
|
|
@@ -210,12 +179,7 @@ const ChatPanel = ({ width, onWidthChange, messages, conversationId, isThinking,
|
|
|
210
179
|
finally {
|
|
211
180
|
onSetThinking(false);
|
|
212
181
|
}
|
|
213
|
-
}, [conversationId, isThinking, endpointUrl, onAddMessage, onSetThinking, onSetConversationId]);
|
|
214
|
-
const askHandler = useCallback(() => ask(chatInput), [ask, chatInput]);
|
|
215
|
-
const onSuggestionClick = (question) => {
|
|
216
|
-
setHoveredSuggestion(undefined);
|
|
217
|
-
ask(question);
|
|
218
|
-
};
|
|
182
|
+
}, [chatInput, conversationId, isThinking, endpointUrl, onAddMessage, onSetThinking, onSetConversationId]);
|
|
219
183
|
const onFeedbackSubmit = (index, rating, tags, feedback) => {
|
|
220
184
|
const answer = messages[index];
|
|
221
185
|
const question = messages.slice(0, index).reverse().find(m => m.isUser)?.text ?? '';
|
|
@@ -234,8 +198,7 @@ const ChatPanel = ({ width, onWidthChange, messages, conversationId, isThinking,
|
|
|
234
198
|
});
|
|
235
199
|
onFeedbackSubmitted(answer.id, rating);
|
|
236
200
|
};
|
|
237
|
-
|
|
238
|
-
return (_jsxs(PanelContainer, { $width: width, children: [_jsx(ResizeHandle, { onMouseDown: onResizeStart }), _jsxs(ChatHeader, { children: [_jsxs(HeaderLeft, { children: [_jsx(ToppyAvatar, { src: ToppyImage, alt: "Toppy" }), _jsxs(HeaderText, { children: [_jsxs(HeaderGreeting, { children: ["Ciao ", userName] }), _jsx(HeaderQuestion, { children: "Come posso aiutarti?" })] })] }), _jsxs(HeaderRight, { children: [_jsx(TMTooltip, { content: "Nuova conversazione", children: _jsx(HeaderButton, { onClick: onNewConversation, disabled: !conversationId && messages.length === 0, title: "Nuova conversazione", children: _jsx(IconNewChat, { color: "white", fontSize: 18 }) }) }), _jsx(TMTooltip, { content: "Chiudi", children: _jsx(HeaderButton, { onClick: onClose, title: "Chiudi", children: _jsx(IconClose, { fontSize: 18 }) }) })] })] }), _jsxs(ChatBody, { children: [messages.length === 0 ? (_jsxs(WelcomeMessage, { children: [_jsx(WelcomeIcon, { children: "\uD83D\uDCA1" }), _jsxs(WelcomeText, { children: ["Ciao! Sono ", _jsx("strong", { children: "Toppy" }), ", il tuo assistente.", _jsx("br", {}), "Fai una domanda e ti aiuter\u00F2 a trovare la risposta."] })] })) : (messages.map((msg, index) => (_jsxs(MessageBubble, { $isUser: msg.isUser, children: [!msg.isUser && _jsx(BotAvatar, { src: ToppyImage, alt: "Toppy" }), msg.isUser ? (_jsxs(_Fragment, { children: [_jsx(QuestionCopy, { children: _jsx(CopyButton, { text: msg.text }) }), _jsx(MessageContent, { $isUser: true, children: msg.text })] })) : (_jsxs(BotMessageColumn, { children: [_jsx(BotMessageContent, { $isUser: false, children: _jsx(MarkdownContent, { children: renderMarkdown(msg.text) }) }), msg.text !== NO_ANSWER_TEXT && msg.text !== ERROR_TEXT && (_jsx(MessageFeedback, { answer: msg.text, submittedRating: submittedRatings[msg.id], onSubmit: (rating, tags, feedback) => onFeedbackSubmit(index, rating, tags, feedback) }))] }))] }, msg.id)))), isThinking && (_jsxs(MessageBubble, { $isUser: false, children: [_jsx(BotAvatar, { src: ToppyImage, alt: "Toppy" }), _jsx(ThinkingStatus, {}, messages.length)] })), _jsx("div", { ref: messagesEndRef })] }), _jsxs(ChatFooter, { children: [showSuggestions && (_jsxs(SuggestionsSection, { children: [_jsxs(SuggestionsTitle, { children: [_jsx(IconSparkle, { fontSize: 14 }), _jsx("span", { children: "Domande suggerite" })] }), _jsx(SuggestionsGrid, { children: suggestions.map((question, index) => (_jsxs(SuggestionCard, { type: "button", $index: index, title: question, onClick: () => onSuggestionClick(question), onMouseEnter: () => setHoveredSuggestion(question), onMouseLeave: () => setHoveredSuggestion(undefined), onFocus: () => setHoveredSuggestion(question), onBlur: () => setHoveredSuggestion(undefined), children: [_jsx(SuggestionIcon, { children: _jsx(IconQuestion, { fontSize: 16 }) }), _jsx(SuggestionText, { children: question }), _jsx(SuggestionArrow, { children: _jsx(IconArrowForward, { fontSize: 16 }) })] }, question))) })] })), _jsx(TMChatInput, { inputRef: inputRef, value: chatInput, onChange: setChatInput, onSend: askHandler, placeholder: hoveredSuggestion ?? 'Scrivi la tua domanda...', tooltip: "Invia", disabled: isThinking }), _jsx(FooterHint, { children: SDKUI_Localizator.HelpOnLineShiftEnterHint })] })] }));
|
|
201
|
+
return (_jsxs(PanelContainer, { $width: width, children: [_jsx(ResizeHandle, { onMouseDown: onResizeStart }), _jsxs(ChatHeader, { children: [_jsxs(HeaderLeft, { children: [_jsx(ToppyAvatar, { src: ToppyImage, alt: "Toppy" }), _jsxs(HeaderText, { children: [_jsxs(HeaderGreeting, { children: ["Ciao ", userName] }), _jsx(HeaderQuestion, { children: "Come posso aiutarti?" })] })] }), _jsxs(HeaderRight, { children: [_jsx(TMTooltip, { content: "Nuova conversazione", children: _jsx(HeaderButton, { onClick: onNewConversation, disabled: !conversationId && messages.length === 0, title: "Nuova conversazione", children: _jsx(IconNewChat, { color: "white", fontSize: 18 }) }) }), _jsx(TMTooltip, { content: "Chiudi", children: _jsx(HeaderButton, { onClick: onClose, title: "Chiudi", children: _jsx(IconClose, { fontSize: 18 }) }) })] })] }), _jsxs(ChatBody, { children: [messages.length === 0 ? (_jsxs(WelcomeMessage, { children: [_jsx(WelcomeIcon, { children: "\uD83D\uDCA1" }), _jsxs(WelcomeText, { children: ["Ciao! Sono ", _jsx("strong", { children: "Toppy" }), ", il tuo assistente.", _jsx("br", {}), "Fai una domanda e ti aiuter\u00F2 a trovare la risposta."] })] })) : (messages.map((msg, index) => (_jsxs(MessageBubble, { $isUser: msg.isUser, children: [!msg.isUser && _jsx(BotAvatar, { src: ToppyImage, alt: "Toppy" }), msg.isUser ? (_jsxs(_Fragment, { children: [_jsx(QuestionCopy, { children: _jsx(CopyButton, { text: msg.text }) }), _jsx(MessageContent, { $isUser: true, children: msg.text })] })) : (_jsxs(BotMessageColumn, { children: [_jsx(BotMessageContent, { $isUser: false, children: _jsx(MarkdownContent, { children: renderMarkdown(msg.text) }) }), msg.text !== NO_ANSWER_TEXT && msg.text !== ERROR_TEXT && (_jsx(MessageFeedback, { answer: msg.text, submittedRating: submittedRatings[msg.id], onSubmit: (rating, tags, feedback) => onFeedbackSubmit(index, rating, tags, feedback) }))] }))] }, msg.id)))), isThinking && (_jsxs(MessageBubble, { $isUser: false, children: [_jsx(BotAvatar, { src: ToppyImage, alt: "Toppy" }), _jsx(ThinkingStatus, {}, messages.length)] })), _jsx("div", { ref: messagesEndRef })] }), _jsxs(ChatFooter, { children: [_jsx(TMChatInput, { inputRef: inputRef, value: chatInput, onChange: setChatInput, onSend: askHandler, placeholder: "Scrivi la tua domanda...", tooltip: "Invia", disabled: isThinking }), _jsx(FooterHint, { children: SDKUI_Localizator.HelpOnLineShiftEnterHint })] })] }));
|
|
239
202
|
};
|
|
240
203
|
const TMChatInput = ({ value, onChange, onSend, placeholder = 'Scrivi la tua domanda...', disabled = false, inputRef, tooltip = 'Ricerca AI' }) => {
|
|
241
204
|
const isDisabled = disabled || value.length < 2;
|
|
@@ -548,15 +511,6 @@ function IconSendFilled(props) {
|
|
|
548
511
|
function IconNewChat(props) {
|
|
549
512
|
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: props.color || "currentColor", ...props, children: _jsx("path", { d: "M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z" }) }));
|
|
550
513
|
}
|
|
551
|
-
function IconSparkle(props) {
|
|
552
|
-
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "currentColor", ...props, children: _jsx("path", { d: "M19 9l1.25-2.75L23 5l-2.75-1.25L19 1l-1.25 2.75L15 5l2.75 1.25L19 9zm-7.5.5L9 4 6.5 9.5 1 12l5.5 2.5L9 20l2.5-5.5L17 12l-5.5-2.5zM19 15l-1.25 2.75L15 19l2.75 1.25L19 23l1.25-2.75L23 19l-2.75-1.25L19 15z" }) }));
|
|
553
|
-
}
|
|
554
|
-
function IconQuestion(props) {
|
|
555
|
-
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "currentColor", ...props, children: _jsx("path", { d: "M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z" }) }));
|
|
556
|
-
}
|
|
557
|
-
function IconArrowForward(props) {
|
|
558
|
-
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "currentColor", ...props, children: _jsx("path", { d: "M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z" }) }));
|
|
559
|
-
}
|
|
560
514
|
function IconThumbUp(props) {
|
|
561
515
|
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "currentColor", ...props, children: _jsx("path", { d: "M9 21h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.58 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2zM9 9l4.34-4.34L12 10h9v2l-3 7H9V9zM1 9h4v12H1z" }) }));
|
|
562
516
|
}
|
|
@@ -580,10 +534,6 @@ const phraseIn = keyframes `
|
|
|
580
534
|
from { opacity: 0; transform: translateY(4px); }
|
|
581
535
|
to { opacity: 1; transform: translateY(0); }
|
|
582
536
|
`;
|
|
583
|
-
const suggestionIn = keyframes `
|
|
584
|
-
from { opacity: 0; transform: translateY(6px); }
|
|
585
|
-
to { opacity: 1; transform: translateY(0); }
|
|
586
|
-
`;
|
|
587
537
|
const feedbackIn = keyframes `
|
|
588
538
|
from { opacity: 0; transform: translateY(-4px); }
|
|
589
539
|
to { opacity: 1; transform: translateY(0); }
|
|
@@ -1196,109 +1146,6 @@ const ChatFooter = styled.div `
|
|
|
1196
1146
|
border-top: 1px solid #e1e5e9;
|
|
1197
1147
|
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05);
|
|
1198
1148
|
`;
|
|
1199
|
-
const SuggestionsSection = styled.div `
|
|
1200
|
-
margin-bottom: 14px;
|
|
1201
|
-
`;
|
|
1202
|
-
const SuggestionsTitle = styled.div `
|
|
1203
|
-
display: flex;
|
|
1204
|
-
align-items: center;
|
|
1205
|
-
gap: 6px;
|
|
1206
|
-
margin: 0 0 8px 2px;
|
|
1207
|
-
font-size: 11px;
|
|
1208
|
-
font-weight: 600;
|
|
1209
|
-
letter-spacing: 0.06em;
|
|
1210
|
-
text-transform: uppercase;
|
|
1211
|
-
color: #6b7280;
|
|
1212
|
-
|
|
1213
|
-
svg { color: ${TMColors.primary}; }
|
|
1214
|
-
`;
|
|
1215
|
-
const SuggestionsGrid = styled.div `
|
|
1216
|
-
display: grid;
|
|
1217
|
-
grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
|
|
1218
|
-
gap: 8px;
|
|
1219
|
-
`;
|
|
1220
|
-
const SuggestionIcon = styled.span `
|
|
1221
|
-
display: flex;
|
|
1222
|
-
align-items: center;
|
|
1223
|
-
justify-content: center;
|
|
1224
|
-
width: 28px;
|
|
1225
|
-
height: 28px;
|
|
1226
|
-
border-radius: 8px;
|
|
1227
|
-
flex-shrink: 0;
|
|
1228
|
-
background: ${TMColors.primary}14;
|
|
1229
|
-
color: ${TMColors.primary};
|
|
1230
|
-
transition: background 0.2s ease, color 0.2s ease;
|
|
1231
|
-
`;
|
|
1232
|
-
const SuggestionText = styled.span `
|
|
1233
|
-
flex: 1;
|
|
1234
|
-
min-width: 0;
|
|
1235
|
-
display: -webkit-box;
|
|
1236
|
-
-webkit-line-clamp: 2;
|
|
1237
|
-
-webkit-box-orient: vertical;
|
|
1238
|
-
overflow: hidden;
|
|
1239
|
-
`;
|
|
1240
|
-
const SuggestionArrow = styled.span `
|
|
1241
|
-
display: flex;
|
|
1242
|
-
flex-shrink: 0;
|
|
1243
|
-
color: ${TMColors.primary};
|
|
1244
|
-
opacity: 0;
|
|
1245
|
-
transform: translateX(-4px);
|
|
1246
|
-
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
1247
|
-
`;
|
|
1248
|
-
const SuggestionCard = styled.button `
|
|
1249
|
-
display: flex;
|
|
1250
|
-
align-items: center;
|
|
1251
|
-
gap: 10px;
|
|
1252
|
-
width: 100%;
|
|
1253
|
-
min-height: 52px;
|
|
1254
|
-
padding: 9px 12px;
|
|
1255
|
-
border: 1px solid ${TMColors.primary}22;
|
|
1256
|
-
border-radius: 12px;
|
|
1257
|
-
background: linear-gradient(135deg, #ffffff 0%, ${TMColors.primary}08 100%);
|
|
1258
|
-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
1259
|
-
color: #242424;
|
|
1260
|
-
font-family: inherit;
|
|
1261
|
-
font-size: 13px;
|
|
1262
|
-
line-height: 1.35;
|
|
1263
|
-
text-align: left;
|
|
1264
|
-
cursor: pointer;
|
|
1265
|
-
opacity: 0;
|
|
1266
|
-
animation: ${suggestionIn} 0.35s ease-out forwards;
|
|
1267
|
-
animation-delay: ${props => props.$index * 70}ms;
|
|
1268
|
-
transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
|
|
1269
|
-
|
|
1270
|
-
&:hover, &:focus-visible {
|
|
1271
|
-
border-color: ${TMColors.primary}66;
|
|
1272
|
-
background: ${TMColors.primary}0d;
|
|
1273
|
-
box-shadow: 0 4px 14px ${TMColors.primary}1f;
|
|
1274
|
-
transform: translateY(-1px);
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
|
-
&:hover ${SuggestionIcon}, &:focus-visible ${SuggestionIcon} {
|
|
1278
|
-
background: ${TMColors.primary};
|
|
1279
|
-
color: white;
|
|
1280
|
-
}
|
|
1281
|
-
|
|
1282
|
-
&:hover ${SuggestionArrow}, &:focus-visible ${SuggestionArrow} {
|
|
1283
|
-
opacity: 1;
|
|
1284
|
-
transform: translateX(0);
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
&:focus-visible {
|
|
1288
|
-
outline: 2px solid ${TMColors.primary}55;
|
|
1289
|
-
outline-offset: 2px;
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
&:active {
|
|
1293
|
-
transform: translateY(0) scale(0.99);
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
@media (prefers-reduced-motion: reduce) {
|
|
1297
|
-
animation: none;
|
|
1298
|
-
opacity: 1;
|
|
1299
|
-
transition: none;
|
|
1300
|
-
}
|
|
1301
|
-
`;
|
|
1302
1149
|
const FooterHint = styled.p `
|
|
1303
1150
|
margin: 6px 0 0 0;
|
|
1304
1151
|
font-size: 11px;
|
|
@@ -11,5 +11,5 @@ interface TMToppyDraggableHelpCenterProps {
|
|
|
11
11
|
/** Callback chiamato quando si clicca sull'immagine di Toppy */
|
|
12
12
|
onToppyImageClick?: () => void;
|
|
13
13
|
}
|
|
14
|
-
declare const TMToppyDraggableHelpCenter: (props: TMToppyDraggableHelpCenterProps) =>
|
|
14
|
+
declare const TMToppyDraggableHelpCenter: (props: TMToppyDraggableHelpCenterProps) => import("react/jsx-runtime").JSX.Element;
|
|
15
15
|
export default TMToppyDraggableHelpCenter;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { BlogPost, UserDescriptor } from "@topconsultnpm/sdk-ts";
|
|
3
2
|
import { FileItem } from '../../base/TMFileManagerUtils';
|
|
4
3
|
import { TMBlogContextDescriptor } from '../../grids/TMBlogsPostUtils';
|
|
@@ -19,5 +18,5 @@ interface TMBlogCommentFormProps {
|
|
|
19
18
|
/** External save handler - when provided, bypasses internal engine logic */
|
|
20
19
|
onCustomSave?: (blogPost: BlogPost) => Promise<void>;
|
|
21
20
|
}
|
|
22
|
-
declare const TMBlogCommentForm: (props: TMBlogCommentFormProps) =>
|
|
21
|
+
declare const TMBlogCommentForm: (props: TMBlogCommentFormProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
22
|
export default TMBlogCommentForm;
|
|
@@ -13,7 +13,12 @@ export declare enum InvocationContext {
|
|
|
13
13
|
/** Invocato dalla pagina Todo/Task */
|
|
14
14
|
Todo = "todo",
|
|
15
15
|
/** Invocato dalla pagina WorkflowCtrl */
|
|
16
|
-
WorkflowCtrl = "workflowCtrl"
|
|
16
|
+
WorkflowCtrl = "workflowCtrl",
|
|
17
|
+
/**
|
|
18
|
+
* Invocato dal dettaglio di una pratica: il Toppy non mostra le attività di
|
|
19
|
+
* pratica, perché la pratica le ha già nella propria barra azioni.
|
|
20
|
+
*/
|
|
21
|
+
CaseFlow = "caseFlow"
|
|
17
22
|
}
|
|
18
23
|
interface ITMDcmtFormProps {
|
|
19
24
|
TID?: number;
|
|
@@ -4,7 +4,7 @@ import TMDcmtPreview from './TMDcmtPreview';
|
|
|
4
4
|
import { AccessLevels, AccessLevelsEx, AppModules, ArchiveConstraints, ArchiveEngineByID, DcmtTypeDescriptor, DcmtTypeListCacheService, DcmtTypePermission, DossierCacheService, LayoutCacheService, LayoutModes, MetadataDataDomains, MetadataDataTypes, MetadataFormats, ObjectClasses, ResultTypes, SDK_Globals, SDK_Localizator, SystemMIDsAsNumber, SystemTIDs, Task_States, TID_DID, UpdateEngineByID, UserListCacheService, ValidationItem, WorkflowCacheService, WorkingGroupCacheService, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
|
|
5
5
|
import { FormModes, SearchResultContext } from '../../../ts';
|
|
6
6
|
import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
|
|
7
|
-
import { getWorkItemSetIDAsync, handleArchiveVisibility, searchResultToMetadataValues } from '../../../helper/queryHelper';
|
|
7
|
+
import { getDcmtMetadataValuesAsync, getTraceShowFileMids, getTraceShowFileNotUpdatedMessage, getWorkItemSetIDAsync, handleArchiveVisibility, searchResultToMetadataValues } from '../../../helper/queryHelper';
|
|
8
8
|
import { genUniqueId, IconShow, SDKUI_Localizator, updateMruTids, IconBoard, IconDcmtTypeSys, calcIsModified, IconMenuVertical, Globalization, getListMaxItems, getSystemMetadata, IconBoxArchiveIn, IconClear, IconUndo, SDKUI_Globals, IconPreview, isTaskMoreInfo, IconWorkflow, IconSearch, deepCompare, IconActivity, getExceptionMessage, isApprovalWorkflowView, getDcmtCicoStatus, buildWorkItemsFromWFCtrl, IconLock, getDcmtFormToolbarVisibility, taskModalSizes, IconArchiveMultipleDetailDocuments, isNotGrantedDraftsDTD } from '../../../helper';
|
|
9
9
|
import { hasDetailRelations, hasMasterRelations } from '../../../helper/dcmtsHelper';
|
|
10
10
|
import { Gutters, TMColors } from '../../../utils/theme';
|
|
@@ -56,6 +56,11 @@ export var InvocationContext;
|
|
|
56
56
|
InvocationContext["Todo"] = "todo";
|
|
57
57
|
/** Invocato dalla pagina WorkflowCtrl */
|
|
58
58
|
InvocationContext["WorkflowCtrl"] = "workflowCtrl";
|
|
59
|
+
/**
|
|
60
|
+
* Invocato dal dettaglio di una pratica: il Toppy non mostra le attività di
|
|
61
|
+
* pratica, perché la pratica le ha già nella propria barra azioni.
|
|
62
|
+
*/
|
|
63
|
+
InvocationContext["CaseFlow"] = "caseFlow";
|
|
59
64
|
// Aggiungi qui altri contesti futuri secondo necessità
|
|
60
65
|
})(InvocationContext || (InvocationContext = {}));
|
|
61
66
|
let abortControllerLocal = new AbortController();
|
|
@@ -385,6 +390,34 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
|
|
|
385
390
|
const triggerPreviewRefresh = useCallback(async () => {
|
|
386
391
|
setRefreshPreviewTrigger(prev => prev + 1);
|
|
387
392
|
}, []);
|
|
393
|
+
// Dopo il recupero del file in anteprima aggiorna solo i metadati "Mostra file"
|
|
394
|
+
const refreshTraceShowFileMetadataAsync = useCallback(async () => {
|
|
395
|
+
const traceMids = getTraceShowFileMids(fromDTDRef.current);
|
|
396
|
+
if (!TID || !DID || traceMids.length === 0)
|
|
397
|
+
return;
|
|
398
|
+
try {
|
|
399
|
+
const res = await getDcmtMetadataValuesAsync(TID, DID, traceMids);
|
|
400
|
+
// Uscito dalla vista: form e riga della griglia restano invariati
|
|
401
|
+
if (res === null) {
|
|
402
|
+
ShowAlert({ mode: 'warning', title: SDKUI_Localizator.DcmtNoLongerAvailable, ...getTraceShowFileNotUpdatedMessage(fromDTDRef.current), duration: 6000 });
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
const row = res?.dtdResult?.rows?.[0];
|
|
406
|
+
const mids = res?.selectMIDs ?? [];
|
|
407
|
+
if (!row)
|
|
408
|
+
return;
|
|
409
|
+
// Anche l'originale, altrimenti il form risulterebbe modificato
|
|
410
|
+
const patchTraceValues = (list) => list.map(md => traceMids.includes(md.mid) && mids.includes(md.mid) ? { ...md, value: row[mids.indexOf(md.mid)] } : md);
|
|
411
|
+
setFormData(patchTraceValues);
|
|
412
|
+
setFormDataOrig(patchTraceValues);
|
|
413
|
+
formDataOrigRef.current = patchTraceValues(formDataOrigRef.current);
|
|
414
|
+
// Aggiorna anche la riga della griglia dei risultati con lo stesso risultato
|
|
415
|
+
await onSavedAsyncCallback?.(TID, DID, res);
|
|
416
|
+
}
|
|
417
|
+
catch (e) {
|
|
418
|
+
console.error('Errore aggiornamento metadati "Mostra file":', e);
|
|
419
|
+
}
|
|
420
|
+
}, [TID, DID, onSavedAsyncCallback]);
|
|
388
421
|
const openTaskFormHandler = (onTaskCreated) => {
|
|
389
422
|
if (!currentDcmt || !fromDTD)
|
|
390
423
|
return;
|
|
@@ -814,8 +847,10 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
|
|
|
814
847
|
return dcmtReferences.some(ref => ref.objClass === ObjectClasses.Dossier || ref.objClass === ObjectClasses.WorkingGroup);
|
|
815
848
|
}, [allowButtonsRefs, layoutMode, dcmtReferences, isOpenDetails, isOpenMaster]);
|
|
816
849
|
// Attività di pratica: stesse condizioni dell'approvazione workflow (documento
|
|
817
|
-
// in consultazione, senza errori, non dentro master/detail).
|
|
818
|
-
|
|
850
|
+
// in consultazione, senza errori, non dentro master/detail). Aperto dal
|
|
851
|
+
// dettaglio di una pratica, il form non le ripete.
|
|
852
|
+
const showToppyForCaseFlow = useMemo(() => layoutMode === LayoutModes.Update && !fetchError && caseFlowWorkItems.length > 0 && !isOpenDetails && !isOpenMaster
|
|
853
|
+
&& invocationContext !== InvocationContext.CaseFlow, [layoutMode, fetchError, caseFlowWorkItems.length, isOpenDetails, isOpenMaster, invocationContext]);
|
|
819
854
|
const isToppyVisible = useMemo(() => Boolean((showToppyForApprove || showToppyForCompleteMoreInfo || showToppyForReferences || showToppyForCaseFlow) && !openS4TViewer && !showTodoDcmtForm && !editPdfForm), [showToppyForApprove, showToppyForCompleteMoreInfo, showToppyForReferences, showToppyForCaseFlow, openS4TViewer, showTodoDcmtForm, editPdfForm]);
|
|
820
855
|
const handleClearForm = useCallback(() => {
|
|
821
856
|
let data = structuredClone(formData);
|
|
@@ -1262,7 +1297,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
|
|
|
1262
1297
|
]);
|
|
1263
1298
|
const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { tid: TID, did: DID, fetchBlogDataTrigger: refreshBlogTrigger, onRefreshBlogDatagrid: onRefreshBlogDatagrid, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), [TID, DID, allTasks, refreshBlogTrigger, handleNavigateToWGs, handleNavigateToDossiers]);
|
|
1264
1299
|
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]);
|
|
1265
|
-
const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { refreshPreviewTrigger: refreshPreviewTrigger, fromDTD: fromDTD, currentDcmt: currentDcmt, dcmtFile: dcmtFile ?? inputFile, deviceType: deviceType, onBack: getOnBackHandler(), layoutMode: layoutMode, onFileUpload: (file) => { setDcmtFile(file); }, openFileUploaderPdfEditor: openFileUploaderPdfEditor, enableDragDropOverlay: enableDragDropOverlay, onScanRequest: onScanRequest }), [currentDcmt, dcmtFile, deviceType, fromDTD, layoutMode, inputFile, enableDragDropOverlay, setDcmtFile, onScanRequest, openFileUploaderPdfEditor, refreshPreviewTrigger]);
|
|
1300
|
+
const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { refreshPreviewTrigger: refreshPreviewTrigger, fromDTD: fromDTD, currentDcmt: currentDcmt, dcmtFile: dcmtFile ?? inputFile, deviceType: deviceType, onBack: getOnBackHandler(), layoutMode: layoutMode, onFileUpload: (file) => { setDcmtFile(file); }, openFileUploaderPdfEditor: openFileUploaderPdfEditor, enableDragDropOverlay: enableDragDropOverlay, onScanRequest: onScanRequest, onFileRetrieved: refreshTraceShowFileMetadataAsync }), [currentDcmt, dcmtFile, deviceType, fromDTD, layoutMode, inputFile, enableDragDropOverlay, setDcmtFile, onScanRequest, openFileUploaderPdfEditor, refreshPreviewTrigger, refreshTraceShowFileMetadataAsync]);
|
|
1266
1301
|
const tmWF = useMemo(() => {
|
|
1267
1302
|
if (isWFDataLoading) {
|
|
1268
1303
|
return (_jsx("div", { style: {
|
|
@@ -1348,7 +1383,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
|
|
|
1348
1383
|
'tmDcmtForm': true,
|
|
1349
1384
|
'tmBlog': false,
|
|
1350
1385
|
'tmSysMetadata': false,
|
|
1351
|
-
'tmDcmtPreview':
|
|
1386
|
+
'tmDcmtPreview': !isPreviewDisabled,
|
|
1352
1387
|
'tmWF': false,
|
|
1353
1388
|
'tmDcmtTasks': false,
|
|
1354
1389
|
};
|
|
@@ -1868,11 +1903,11 @@ const PanelDisabledStateHandler = ({ isWFDisabled, isSysMetadataDisabled, isBoar
|
|
|
1868
1903
|
}, [isPreviewDisabled]);
|
|
1869
1904
|
return null;
|
|
1870
1905
|
};
|
|
1871
|
-
const TMDcmtPreviewWrapper = ({ refreshPreviewTrigger, fromDTD, currentDcmt, layoutMode, dcmtFile, deviceType, isVisible, onFileUpload, openFileUploaderPdfEditor, enableDragDropOverlay = false, onScanRequest, onBack }) => {
|
|
1906
|
+
const TMDcmtPreviewWrapper = ({ refreshPreviewTrigger, fromDTD, currentDcmt, layoutMode, dcmtFile, deviceType, isVisible, onFileUpload, openFileUploaderPdfEditor, enableDragDropOverlay = false, onScanRequest, onBack, onFileRetrieved }) => {
|
|
1872
1907
|
const { setPanelVisibilityById, toggleMaximize, isResizingActive, countVisibleLeafPanels, panelVisibility } = useTMPanelManagerContext();
|
|
1873
1908
|
const isMobile = deviceType === DeviceType.MOBILE;
|
|
1874
1909
|
return (layoutMode === LayoutModes.Update ?
|
|
1875
|
-
_jsx(TMDcmtPreview, { dcmtData: currentDcmt, isVisible: isVisible, onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, onBack: onBack, isResizingActive: isResizingActive }, refreshPreviewTrigger) :
|
|
1910
|
+
_jsx(TMDcmtPreview, { dcmtData: currentDcmt, isVisible: isVisible, onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, onBack: onBack, isResizingActive: isResizingActive, onFileRetrieved: onFileRetrieved }, refreshPreviewTrigger) :
|
|
1876
1911
|
_jsx(TMFileUploader, { fromDTD: fromDTD, onFileUpload: onFileUpload, openFileUploaderPdfEditor: openFileUploaderPdfEditor, onClose: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, isRequired: fromDTD?.archiveConstraint === ArchiveConstraints.ContentCompulsory && dcmtFile === null, defaultBlob: dcmtFile, deviceType: deviceType, isResizingActive: isResizingActive, enableDragDropOverlay: panelVisibility['tmDcmtPreview'] && enableDragDropOverlay, onScanRequest: onScanRequest }));
|
|
1877
1912
|
};
|
|
1878
1913
|
const Ribbon = styled.div `
|
|
@@ -41,5 +41,5 @@ interface TMDcmtFormActionButtonsProps {
|
|
|
41
41
|
setShowMoreInfoTaskPopup: React.Dispatch<React.SetStateAction<boolean>>;
|
|
42
42
|
setShowMoreInfoTaskTask: React.Dispatch<React.SetStateAction<TaskDescriptor | undefined>>;
|
|
43
43
|
}
|
|
44
|
-
declare const TMDcmtFormActionButtons: (props: TMDcmtFormActionButtonsProps) =>
|
|
44
|
+
declare const TMDcmtFormActionButtons: (props: TMDcmtFormActionButtonsProps) => import("react/jsx-runtime").JSX.Element;
|
|
45
45
|
export default TMDcmtFormActionButtons;
|
|
@@ -8,7 +8,7 @@ import TMButton from "../../base/TMButton";
|
|
|
8
8
|
import TMModal from "../../base/TMModal";
|
|
9
9
|
import TMTooltip from "../../base/TMTooltip";
|
|
10
10
|
import { WorkFlowOperationButtons } from "../workflow/TMWorkflowPopup";
|
|
11
|
-
import { getWorkItemActionName, isSignatureWorkItem } from "../../../services/caseflow/caseFlowWorkItemUtils";
|
|
11
|
+
import { getWorkItemActionName, isAcknowledgmentWorkItem, isSignatureWorkItem } from "../../../services/caseflow/caseFlowWorkItemUtils";
|
|
12
12
|
const TMDcmtFormActionButtons = (props) => {
|
|
13
13
|
const { showToppyForApprove, workItems, caseFlowWorkItems, onCompleteCaseFlowWorkItem, onRejectCaseFlowWorkItem, deviceType, isMobile, handleSignApprove, updateShowApprovePopup, updateShowRejectPopup, updateShowReAssignPopup, updateShowMoreInfoPopup, fromDTD, showToppyForCompleteMoreInfo, moreInfoTasks, setShowCommentForm, showToppyForReferences, dcmtReferences, referenceActionMap, handleNavigateToReference, setShowMoreInfoTaskPopup, setShowMoreInfoTaskTask } = props;
|
|
14
14
|
const [showAllMoreInfoModal, setShowAllMoreInfoModal] = useState(false);
|
|
@@ -103,7 +103,10 @@ const TMDcmtFormActionButtons = (props) => {
|
|
|
103
103
|
whiteSpace: 'pre-line',
|
|
104
104
|
}, children: description })), _jsx(WorkFlowOperationButtons, { dtd: fromDTD, deviceType: deviceType, signFlow: requiresSignature, approveDisable: isBusy, signApproveDisable: isBusy, rejectDisable: isBusy, onSignApprove: handleSignApprove, onApprove: onCompleteCaseFlowWorkItem
|
|
105
105
|
? () => void runCaseFlowAction(item, () => onCompleteCaseFlowWorkItem(item))
|
|
106
|
-
: undefined,
|
|
106
|
+
: undefined,
|
|
107
|
+
// La presa visione non si rifiuta, come nella pratica: senza
|
|
108
|
+
// handler il pulsante non viene mostrato.
|
|
109
|
+
onReject: onRejectCaseFlowWorkItem && !isAcknowledgmentWorkItem(workItem)
|
|
107
110
|
? () => { setRejectReason(''); setRejectingItem(item); }
|
|
108
111
|
: undefined })] }, workItem.id));
|
|
109
112
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { DcmtInfo, DownloadModes, DownloadTypes } from '../../../ts';
|
|
3
2
|
import { FileDescriptor } from '@topconsultnpm/sdk-ts';
|
|
4
3
|
interface ITMDcmtIconProps {
|
|
@@ -15,5 +14,5 @@ interface ITMDcmtIconProps {
|
|
|
15
14
|
openInOffice?: (selectedDcmtsOrFocused: Array<DcmtInfo>) => Promise<void>;
|
|
16
15
|
onDownloadDcmtsAsync?: (inputDcmts: DcmtInfo[] | undefined, downloadType: DownloadTypes, downloadMode: DownloadModes, onFileDownloaded?: (dcmtFile: File | undefined) => void, confirmAttachments?: (list: FileDescriptor[]) => Promise<string[] | undefined>) => Promise<void>;
|
|
17
16
|
}
|
|
18
|
-
declare const TMDcmtIcon: ({ fileExtension, fileCount, isLexProt, isSigned, isMail, isShared, tid, did, downloadMode, tooltipContent, openInOffice, onDownloadDcmtsAsync }: ITMDcmtIconProps) =>
|
|
17
|
+
declare const TMDcmtIcon: ({ fileExtension, fileCount, isLexProt, isSigned, isMail, isShared, tid, did, downloadMode, tooltipContent, openInOffice, onDownloadDcmtsAsync }: ITMDcmtIconProps) => import("react/jsx-runtime").JSX.Element;
|
|
19
18
|
export default TMDcmtIcon;
|
|
@@ -12,6 +12,8 @@ interface ITMDcmtPreviewProps {
|
|
|
12
12
|
onBack?: () => void;
|
|
13
13
|
allowMaximize?: boolean;
|
|
14
14
|
onMaximizePanel?: () => void;
|
|
15
|
+
/** File scaricato dal server con tracciatura "Mostra file": i metadati trace sono stati aggiornati */
|
|
16
|
+
onFileRetrieved?: (tid: number | undefined, did: number | undefined) => void;
|
|
15
17
|
}
|
|
16
18
|
declare const TMDcmtPreview: React.FC<ITMDcmtPreviewProps>;
|
|
17
19
|
export default TMDcmtPreview;
|
|
@@ -25,12 +27,10 @@ export declare const TMNothingToShow: ({ text, secondText, fileExt, icon }: {
|
|
|
25
27
|
secondText?: any;
|
|
26
28
|
fileExt?: string;
|
|
27
29
|
icon?: any;
|
|
28
|
-
}) =>
|
|
29
|
-
export declare const StyledHeaderIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components
|
|
30
|
-
style?: React.CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
|
|
31
|
-
}, {
|
|
30
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export declare const StyledHeaderIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$color"> & {
|
|
32
32
|
$color: string;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
}, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$color"> & {
|
|
34
|
+
$color: string;
|
|
35
|
+
}, never>>> & string;
|
|
36
|
+
export declare const StyledPanelStatusContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
|
|
@@ -22,7 +22,7 @@ const ErrorContent = ({ error, isAbortError, onRetry }) => {
|
|
|
22
22
|
}
|
|
23
23
|
return _jsx(TMNothingToShow, { icon: _jsx(IconCloseOutline, { fontSize: 92, color: TMColors.error }), text: error });
|
|
24
24
|
};
|
|
25
|
-
const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev, onClosePanel, onBack, onNext, onPrev, allowMaximize = true, onMaximizePanel }) => {
|
|
25
|
+
const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev, onClosePanel, onBack, onNext, onPrev, allowMaximize = true, onMaximizePanel, onFileRetrieved }) => {
|
|
26
26
|
const [dcmtBlob, setDcmtBlob] = useState(undefined);
|
|
27
27
|
const [showPreview, setShowPreview] = useState(false);
|
|
28
28
|
const [isFromCache, setIsFromCache] = useState(false);
|
|
@@ -40,9 +40,12 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
|
|
|
40
40
|
const cacheKey = getCacheKey();
|
|
41
41
|
const [hasLoadedDataOnce, setHasLoadedDataOnce] = useState(false);
|
|
42
42
|
const [lastLoadedDid, setLastLoadedDid] = useState(undefined);
|
|
43
|
+
// Aggiornato subito, a differenza dello stato: evita il doppio caricamento (es. StrictMode)
|
|
44
|
+
const lastLoadedDidRef = useRef(undefined);
|
|
43
45
|
useEffect(() => {
|
|
44
46
|
if (!dcmtData) {
|
|
45
|
-
|
|
47
|
+
lastLoadedDidRef.current = undefined;
|
|
48
|
+
setLastLoadedDid(undefined); // Reset
|
|
46
49
|
setDcmtBlob(undefined);
|
|
47
50
|
setError('');
|
|
48
51
|
setIsAbortError(false);
|
|
@@ -54,8 +57,9 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
|
|
|
54
57
|
if (!isVisible)
|
|
55
58
|
return;
|
|
56
59
|
// Documento già caricato: ricaricarlo ricreerebbe il visualizzatore senza motivo
|
|
57
|
-
if (hasLoadedDataOnce && currentCacheKey === lastLoadedDid)
|
|
60
|
+
if ((hasLoadedDataOnce && currentCacheKey === lastLoadedDid) || currentCacheKey === lastLoadedDidRef.current)
|
|
58
61
|
return;
|
|
62
|
+
lastLoadedDidRef.current = currentCacheKey;
|
|
59
63
|
if (isDcmtFileInCache(currentCacheKey)) {
|
|
60
64
|
isBasketMode ? loadBasketFile() : loadDocumentWithCache();
|
|
61
65
|
setShowPreview(true);
|
|
@@ -122,20 +126,25 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
|
|
|
122
126
|
}
|
|
123
127
|
}
|
|
124
128
|
};
|
|
125
|
-
|
|
129
|
+
/** @param isShown false se a video resta la richiesta di conferma: il file non è visualizzato */
|
|
130
|
+
const loadDocumentWithCache = async (isShown = true) => {
|
|
126
131
|
const rfo = new RetrieveFileOptions();
|
|
127
|
-
|
|
132
|
+
// Senza impostazione salvata l'anteprima non aggiorna la tracciatura "Mostra file"
|
|
133
|
+
rfo.retrieveReason = isShown && SDKUI_Globals.userSettings?.searchSettings?.previewTracksShowFile === true ? DcmtOpers.ShowFile : DcmtOpers.None;
|
|
128
134
|
rfo.generalRetrieveFormat = GeneralRetrieveFormats.OriginalUnsigned;
|
|
129
135
|
rfo.cvtFormat = extensionHandler(dcmtData?.fileExt) === FileExtensionHandler.CONVERTIBLE ? FileFormats.PDF : FileFormats.None;
|
|
130
136
|
rfo.invoiceRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.invoiceRetrieveFormat;
|
|
131
137
|
rfo.orderRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.orderRetrieveFormat;
|
|
132
138
|
try {
|
|
133
139
|
await sleep(300); //wait for DX-DataGrid selectionChanged
|
|
134
|
-
let dcmtFile = await getDcmtFileAsync({ TID: dcmtData?.tid, DID: dcmtData?.did, FILEEXT: dcmtData?.fileExt }, rfo, 'Anteprima', false);
|
|
140
|
+
let dcmtFile = await getDcmtFileAsync({ TID: dcmtData?.tid, DID: dcmtData?.did, FILEEXT: dcmtData?.fileExt }, rfo, 'Anteprima', false, !isShown);
|
|
135
141
|
setDcmtBlob(dcmtFile?.file);
|
|
136
142
|
setIsFromCache(!!dcmtFile?.isFromCache);
|
|
137
143
|
setError('');
|
|
138
144
|
setIsAbortError(false);
|
|
145
|
+
// Dalla cache l'API non è stata chiamata: la tracciatura non è cambiata
|
|
146
|
+
if (dcmtFile?.file && !dcmtFile.isFromCache && rfo.retrieveReason === DcmtOpers.ShowFile)
|
|
147
|
+
onFileRetrieved?.(dcmtData?.tid, dcmtData?.did);
|
|
139
148
|
}
|
|
140
149
|
catch (ex) {
|
|
141
150
|
const err = ex;
|
|
@@ -179,7 +188,7 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
|
|
|
179
188
|
setIsAbortError(false);
|
|
180
189
|
setDcmtBlob(undefined);
|
|
181
190
|
try {
|
|
182
|
-
isBasketMode ? await loadBasketFile() : await loadDocumentWithCache();
|
|
191
|
+
isBasketMode ? await loadBasketFile() : await loadDocumentWithCache(showPreview);
|
|
183
192
|
}
|
|
184
193
|
catch (error) {
|
|
185
194
|
console.error('Error reopening document:', error);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import { FormModes, TaskContext } from "../../../ts";
|
|
3
2
|
import { HomeBlogPost, TaskDescriptor } from "@topconsultnpm/sdk-ts";
|
|
4
3
|
interface TMDcmtTasksProps {
|
|
@@ -13,5 +12,5 @@ interface TMDcmtTasksProps {
|
|
|
13
12
|
handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
|
|
14
13
|
onBack?: () => void;
|
|
15
14
|
}
|
|
16
|
-
declare const TMDcmtTasks: (props: TMDcmtTasksProps) =>
|
|
15
|
+
declare const TMDcmtTasks: (props: TMDcmtTasksProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
16
|
export default TMDcmtTasks;
|
|
@@ -2,5 +2,5 @@ interface TMDragDropOverlayProps {
|
|
|
2
2
|
handleFile: (file: File) => void;
|
|
3
3
|
refocusAfterFileInput: () => void;
|
|
4
4
|
}
|
|
5
|
-
declare const TMDragDropOverlay: (props: TMDragDropOverlayProps) => import("react").JSX.Element;
|
|
5
|
+
declare const TMDragDropOverlay: (props: TMDragDropOverlayProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
export default TMDragDropOverlay;
|
|
@@ -112,27 +112,27 @@ const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onF
|
|
|
112
112
|
}, [deviceType, fromDTD, onClose]);
|
|
113
113
|
return showTMPanel ? (_jsx(TMPanel, { ref: fileUploaderPanelRef, panelID: 'file-uploader-panel', title: SDKUI_Localizator.FileUpload, onBack: deviceType === DeviceType.MOBILE ? () => onClose?.() : undefined, toolbar: toolbar, children: innerContent })) : (innerContent);
|
|
114
114
|
};
|
|
115
|
-
const UploadContainer = styled.div `
|
|
116
|
-
position: relative;
|
|
117
|
-
display: flex;
|
|
118
|
-
align-items: center;
|
|
119
|
-
justify-content: center;
|
|
120
|
-
flex-direction: column;
|
|
121
|
-
gap: 5px;
|
|
122
|
-
border: 2px dashed ${props => props.$isRequired ? () => TMColors.error : () => TMColors.primaryColor};
|
|
123
|
-
/* max-height: 100px; */
|
|
124
|
-
width: 100%;
|
|
125
|
-
height: 100%;
|
|
126
|
-
border-radius: 8px;
|
|
127
|
-
padding: 30px;
|
|
128
|
-
text-align: center;
|
|
129
|
-
color: ${props => props.$isRequired ? () => TMColors.error : () => TMColors.primaryColor};
|
|
130
|
-
transition: background-color 0.3s;
|
|
131
|
-
&:hover {
|
|
132
|
-
background-color: #658cab;
|
|
133
|
-
}
|
|
115
|
+
const UploadContainer = styled.div `
|
|
116
|
+
position: relative;
|
|
117
|
+
display: flex;
|
|
118
|
+
align-items: center;
|
|
119
|
+
justify-content: center;
|
|
120
|
+
flex-direction: column;
|
|
121
|
+
gap: 5px;
|
|
122
|
+
border: 2px dashed ${props => props.$isRequired ? () => TMColors.error : () => TMColors.primaryColor};
|
|
123
|
+
/* max-height: 100px; */
|
|
124
|
+
width: 100%;
|
|
125
|
+
height: 100%;
|
|
126
|
+
border-radius: 8px;
|
|
127
|
+
padding: 30px;
|
|
128
|
+
text-align: center;
|
|
129
|
+
color: ${props => props.$isRequired ? () => TMColors.error : () => TMColors.primaryColor};
|
|
130
|
+
transition: background-color 0.3s;
|
|
131
|
+
&:hover {
|
|
132
|
+
background-color: #658cab;
|
|
133
|
+
}
|
|
134
134
|
`;
|
|
135
|
-
const HiddenInput = styled.input `
|
|
136
|
-
display: none;
|
|
135
|
+
const HiddenInput = styled.input `
|
|
136
|
+
display: none;
|
|
137
137
|
`;
|
|
138
138
|
export default TMFileUploader;
|