@topconsultnpm/sdkui-react 6.19.0-dev1.5 → 6.19.0-dev1.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/lib/components/base/Styled.d.ts +1 -0
  2. package/lib/components/base/Styled.js +40 -0
  3. package/lib/components/base/TMFileManagerDataGridView.js +4 -1
  4. package/lib/components/base/TMTreeView.js +3 -2
  5. package/lib/components/editors/TMHtmlEditor.d.ts +5 -0
  6. package/lib/components/editors/TMHtmlEditor.js +72 -12
  7. package/lib/components/editors/TMMetadataValues.js +90 -40
  8. package/lib/components/features/archive/TMArchive.d.ts +2 -0
  9. package/lib/components/features/archive/TMArchive.js +56 -25
  10. package/lib/components/features/blog/TMBlogCommentForm.js +57 -41
  11. package/lib/components/features/documents/TMDcmtForm.d.ts +10 -3
  12. package/lib/components/features/documents/TMDcmtForm.js +138 -36
  13. package/lib/components/features/documents/TMDragDropOverlay.js +2 -1
  14. package/lib/components/features/documents/TMMasterDetailDcmts.js +1 -1
  15. package/lib/components/features/documents/TMRelationViewer.d.ts +53 -3
  16. package/lib/components/features/documents/TMRelationViewer.js +232 -85
  17. package/lib/components/features/search/TMSearch.d.ts +3 -1
  18. package/lib/components/features/search/TMSearch.js +13 -4
  19. package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -1
  20. package/lib/components/features/search/TMSearchQueryPanel.js +36 -7
  21. package/lib/components/features/search/TMSearchResult.d.ts +3 -1
  22. package/lib/components/features/search/TMSearchResult.js +102 -328
  23. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -2
  24. package/lib/components/features/search/TMSearchResultsMenuItems.js +32 -15
  25. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +3 -1
  26. package/lib/components/features/workflow/TMWorkflowPopup.js +17 -4
  27. package/lib/components/forms/TMChooserForm.d.ts +1 -1
  28. package/lib/components/forms/TMChooserForm.js +2 -2
  29. package/lib/components/grids/TMBlogsUtils.d.ts +1 -0
  30. package/lib/components/grids/TMBlogsUtils.js +40 -4
  31. package/lib/components/index.d.ts +3 -0
  32. package/lib/components/index.js +3 -0
  33. package/lib/components/viewers/TMTidViewer.js +29 -4
  34. package/lib/css/tm-sdkui.css +1 -1
  35. package/lib/helper/SDKUI_Globals.d.ts +2 -1
  36. package/lib/helper/SDKUI_Globals.js +1 -0
  37. package/lib/helper/SDKUI_Localizator.d.ts +4 -0
  38. package/lib/helper/SDKUI_Localizator.js +46 -0
  39. package/lib/helper/TMIcons.d.ts +2 -0
  40. package/lib/helper/TMIcons.js +6 -0
  41. package/lib/helper/TMToppyMessage.d.ts +7 -0
  42. package/lib/helper/TMToppyMessage.js +42 -0
  43. package/lib/helper/TMUtils.d.ts +7 -0
  44. package/lib/helper/TMUtils.js +16 -0
  45. package/lib/helper/index.d.ts +1 -0
  46. package/lib/helper/index.js +1 -0
  47. package/lib/hooks/useRelatedDocuments.d.ts +72 -0
  48. package/lib/hooks/useRelatedDocuments.js +655 -0
  49. package/lib/index.d.ts +1 -0
  50. package/lib/index.js +1 -0
  51. package/lib/ts/types.d.ts +14 -0
  52. package/lib/ts/types.js +15 -0
  53. package/lib/utils/theme.d.ts +1 -0
  54. package/lib/utils/theme.js +1 -0
  55. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useMemo, useState } from 'react';
2
+ import React, { useEffect, useMemo, useState } from 'react';
3
3
  import Logo from '../../../assets/Toppy-generico.png';
4
4
  import { DcmtTypeListCacheService, LayoutModes, SDK_Localizator } from '@topconsultnpm/sdk-ts';
5
5
  import { IconTree, SDKUI_Globals, SDKUI_Localizator, IconRecentlyViewed, IconPreview, IconShow, IconBoard, IconDcmtTypeSys, removeMruTid } from '../../../helper';
@@ -12,11 +12,14 @@ import TMTreeSelector from '../search/TMTreeSelector';
12
12
  import TMPanel from '../../base/TMPanel';
13
13
  import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/panelManager/TMPanelManagerContext';
14
14
  import TMPanelManagerContainer from '../../layout/panelManager/TMPanelManagerContainer';
15
- const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, connectorFileSave = undefined, onSavedAsyncCallback, inputMids = [], enableDragDropOverlay = false, passToSearch }) => {
15
+ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, connectorFileSave = undefined, onSavedAsyncCallback, inputMids = [], enableDragDropOverlay = false, passToSearch, isSharedArchive = false, inputDID = undefined }) => {
16
16
  const [currentTID, setCurrentTID] = useState(inputTID ?? 0);
17
17
  const [mruTIDs, setMruTIDs] = useState([]);
18
18
  const [currentMruTID, setCurrentMruTID] = useState(0);
19
19
  const [fromDTD, setFromDTD] = useState();
20
+ const [currentInputMids, setCurrentInputMids] = useState(inputMids);
21
+ const previousTIDRef = React.useRef(undefined);
22
+ const pendingMidsRef = React.useRef(null);
20
23
  const deviceType = useDeviceType();
21
24
  useEffect(() => { setMruTIDs(SDKUI_Globals.userSettings.archivingSettings.mruTIDs); }, []);
22
25
  useEffect(() => {
@@ -24,9 +27,16 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
24
27
  return;
25
28
  setCurrentTID(inputTID);
26
29
  setCurrentMruTID(mruTIDs.includes(inputTID) ? inputTID : 0);
27
- }, [inputTID]);
30
+ }, [inputTID, mruTIDs]);
31
+ useEffect(() => {
32
+ pendingMidsRef.current = inputMids;
33
+ if (currentTID && currentTID > 0 && inputMids && inputMids.length > 0) {
34
+ setCurrentInputMids(inputMids);
35
+ }
36
+ }, [inputMids, currentTID]);
28
37
  useEffect(() => {
29
38
  if (!currentTID || currentTID <= 0) {
39
+ previousTIDRef.current = currentTID;
30
40
  return;
31
41
  }
32
42
  if (onDcmtTypeSelect)
@@ -34,31 +44,42 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
34
44
  DcmtTypeListCacheService.GetAsync(currentTID).then(async (dtd) => {
35
45
  setFromDTD(dtd);
36
46
  });
37
- }, [currentTID, onDcmtTypeSelect]);
47
+ if (previousTIDRef.current !== undefined && previousTIDRef.current > 0 && previousTIDRef.current !== currentTID) {
48
+ if (!isSharedArchive) {
49
+ setCurrentInputMids([]);
50
+ }
51
+ if (pendingMidsRef.current && pendingMidsRef.current.length > 0) {
52
+ setCurrentInputMids(pendingMidsRef.current);
53
+ pendingMidsRef.current = null;
54
+ }
55
+ }
56
+ previousTIDRef.current = currentTID;
57
+ }, [currentTID, onDcmtTypeSelect, isSharedArchive]);
38
58
  const isMobile = deviceType === DeviceType.MOBILE;
39
- const tmTreeSelectorElement = useMemo(() => _jsx(TMTreeSelectorWrapper, { isMobile: isMobile, onSelectedTIDChanged: (tid) => {
59
+ const tmTreeSelectorElement = useMemo(() => _jsx(TMTreeSelectorWrapper, { isMobile: isMobile, isSharedArchive: isSharedArchive, onSelectedTIDChanged: (tid) => {
40
60
  setCurrentTID(tid);
41
61
  if (tid && mruTIDs.includes(tid))
42
62
  setCurrentMruTID(tid);
43
63
  else
44
64
  setCurrentMruTID(0);
45
- } }), [isMobile, currentTID]);
46
- const tmRecentsManagerElement = useMemo(() => _jsx(TMRecentsManagerWrapper, { mruTIDs: mruTIDs, currentTID: currentTID, currentMruTID: currentMruTID, deviceType: deviceType, onSelectedTID: (tid) => {
65
+ } }), [isMobile, currentTID, isSharedArchive]);
66
+ const tmRecentsManagerElement = useMemo(() => _jsx(TMRecentsManagerWrapper, { mruTIDs: mruTIDs, currentTID: currentTID, currentMruTID: currentMruTID, deviceType: deviceType, isSharedArchive: isSharedArchive, onSelectedTID: (tid) => {
47
67
  setCurrentMruTID(tid);
48
68
  setCurrentTID(tid);
49
69
  }, onDeletedTID: (tid) => {
50
70
  let newMruTIDS = removeMruTid(SDKUI_Globals.userSettings.archivingSettings.mruTIDs, tid);
51
71
  SDKUI_Globals.userSettings.archivingSettings.mruTIDs = newMruTIDS;
52
72
  setMruTIDs(newMruTIDS);
53
- } }), [mruTIDs, currentMruTID, deviceType]);
73
+ } }), [mruTIDs, currentMruTID, deviceType, isSharedArchive]);
54
74
  const tmFormElement = useMemo(() => currentTID ?
55
- _jsx(TMDcmtForm, { TID: currentTID, DID: undefined, groupId: 'tmForm', layoutMode: LayoutModes.Ark, onClose: deviceType === DeviceType.MOBILE ? () => setCurrentTID(undefined) : undefined, onSaveRecents: (TIDs) => setMruTIDs(TIDs), showDcmtFormSidebar: false, inputFile: inputFile, connectorFileSave: connectorFileSave, onSavedAsyncCallback: onSavedAsyncCallback, inputMids: inputMids, enableDragDropOverlay: enableDragDropOverlay, passToSearch: passToSearch ? (outputMids) => {
75
+ _jsx(TMDcmtForm, { TID: currentTID, DID: currentTID === inputTID ? inputDID : undefined, sharedSourceTID: isSharedArchive ? inputTID : undefined, sharedSourceDID: isSharedArchive ? inputDID : undefined, groupId: 'tmForm', layoutMode: LayoutModes.Ark, onClose: deviceType === DeviceType.MOBILE ? () => setCurrentTID(undefined) : undefined, onSaveRecents: (TIDs) => setMruTIDs(TIDs), showDcmtFormSidebar: false, inputFile: inputFile, connectorFileSave: connectorFileSave, onSavedAsyncCallback: onSavedAsyncCallback, inputMids: currentInputMids, enableDragDropOverlay: enableDragDropOverlay, passToSearch: passToSearch ? (outputMids, tid) => {
76
+ const tidToUse = tid ?? currentTID;
56
77
  if (onDcmtTypeSelect)
57
- onDcmtTypeSelect(currentTID);
58
- passToSearch(currentTID, outputMids);
59
- } : undefined })
78
+ onDcmtTypeSelect(tidToUse);
79
+ passToSearch(tidToUse, outputMids);
80
+ } : undefined, isSharedDcmt: isSharedArchive }, currentTID)
60
81
  :
61
- _jsx(TMPanel, { title: 'Archiviazione', allowMaximize: false, children: _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsx(StyledToppyTextContainer, { children: _jsx(StyledToppyText, { children: SDKUI_Localizator.DcmtTypeSelect }) }), _jsx(StyledToppyImage, { src: Logo, alt: 'Toppy' })] }) }), [currentTID, deviceType, mruTIDs, inputFile, inputMids]);
82
+ _jsx(TMPanel, { title: 'Archiviazione', allowMaximize: false, children: _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsx(StyledToppyTextContainer, { children: _jsx(StyledToppyText, { children: SDKUI_Localizator.DcmtTypeSelect }) }), _jsx(StyledToppyImage, { src: Logo, alt: 'Toppy' })] }) }), [currentTID, deviceType, mruTIDs, inputFile, currentInputMids, enableDragDropOverlay, isSharedArchive]);
62
83
  const allInitialPanelVisibility = {
63
84
  'tmTreeSelector': true,
64
85
  'tmRecentsManager': true,
@@ -66,13 +87,13 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
66
87
  'tmDcmtForm': true,
67
88
  'tmBlog': false,
68
89
  'tmSysMetadata': false,
69
- 'tmDcmtPreview': true,
90
+ 'tmDcmtPreview': !isSharedArchive,
70
91
  };
71
92
  const initialPanelDimensions = {
72
93
  'tmTreeSelector': { width: '20%', height: '100%' },
73
94
  'tmRecentsManager': { width: '20%', height: '100%' },
74
95
  'tmForm': { width: '60%', height: '100%' },
75
- 'tmDcmtForm': { width: '25%', height: '100%' },
96
+ 'tmDcmtForm': { width: isSharedArchive ? '50%' : '25%', height: '100%' },
76
97
  'tmBlog': { width: '25%', height: '100%' },
77
98
  'tmSysMetadata': { width: '25%', height: '100%' },
78
99
  'tmDcmtPreview': { width: '25%', height: '100%' },
@@ -114,15 +135,15 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
114
135
  {
115
136
  id: 'tmDcmtPreview',
116
137
  name: SDKUI_Localizator.PreviewDocument,
117
- toolbarOptions: { icon: _jsx(IconShow, { fontSize: 24 }), visible: false, orderNumber: 7, isActive: allInitialPanelVisibility['tmDcmtPreview'] }
138
+ toolbarOptions: { icon: _jsx(IconShow, { fontSize: 24 }), visible: false, disabled: isSharedArchive, orderNumber: 7, isActive: allInitialPanelVisibility['tmDcmtPreview'] }
118
139
  }
119
140
  ]
120
141
  },
121
- ], [tmTreeSelectorElement, tmRecentsManagerElement, tmFormElement, currentTID, mruTIDs]);
142
+ ], [tmTreeSelectorElement, tmRecentsManagerElement, tmFormElement, currentTID, mruTIDs, isSharedArchive]);
122
143
  return (_jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmRecentsManager', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }));
123
144
  };
124
145
  export default TMArchive;
125
- const TMTreeSelectorWrapper = ({ isMobile, onSelectedTIDChanged }) => {
146
+ const TMTreeSelectorWrapper = ({ isMobile, isSharedArchive, onSelectedTIDChanged }) => {
126
147
  const { setPanelVisibilityById, toggleMaximize, setToolbarButtonVisibility, countVisibleLeafPanels } = useTMPanelManagerContext();
127
148
  return (_jsx(TMTreeSelector, { layoutMode: LayoutModes.Ark, onClosePanel: !isMobile && countVisibleLeafPanels() > 1 ? () => setPanelVisibilityById('tmTreeSelector', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: !isMobile && countVisibleLeafPanels() > 1 ? () => toggleMaximize("tmTreeSelector") : undefined, onSelectedTIDChanged: (tid) => {
128
149
  onSelectedTIDChanged?.(tid);
@@ -130,21 +151,27 @@ const TMTreeSelectorWrapper = ({ isMobile, onSelectedTIDChanged }) => {
130
151
  setPanelVisibilityById('tmDcmtForm', true);
131
152
  else {
132
153
  setPanelVisibilityById('tmDcmtForm', true);
133
- setPanelVisibilityById('tmDcmtPreview', true);
154
+ if (!isSharedArchive) {
155
+ setPanelVisibilityById('tmDcmtPreview', true);
156
+ }
157
+ }
158
+ if (!isSharedArchive) {
159
+ setToolbarButtonVisibility('tmDcmtPreview', true);
134
160
  }
135
- setToolbarButtonVisibility('tmDcmtPreview', true);
136
161
  setToolbarButtonVisibility('tmDcmtForm', true);
137
162
  } }));
138
163
  };
139
- const TMRecentsManagerWrapper = ({ mruTIDs, currentTID, currentMruTID, deviceType, onSelectedTID, onDeletedTID }) => {
164
+ const TMRecentsManagerWrapper = ({ mruTIDs, currentTID, currentMruTID, deviceType, isSharedArchive, onSelectedTID, onDeletedTID }) => {
140
165
  const { setPanelVisibilityById, setToolbarButtonVisibility } = useTMPanelManagerContext();
141
166
  useEffect(() => {
142
167
  if (currentTID) {
143
168
  setPanelVisibilityById('tmDcmtForm', true);
144
- setToolbarButtonVisibility('tmDcmtPreview', true);
169
+ if (!isSharedArchive) {
170
+ setToolbarButtonVisibility('tmDcmtPreview', true);
171
+ }
145
172
  setToolbarButtonVisibility('tmDcmtForm', true);
146
173
  }
147
- }, [currentTID]);
174
+ }, [currentTID, isSharedArchive]);
148
175
  return (_jsx(TMRecentsManager, { accessFilter: 'canArchive', mruTIDs: mruTIDs, currentMruTID: currentMruTID, deviceType: deviceType, onSelectedTID: (tid) => {
149
176
  onSelectedTID?.(tid);
150
177
  if (deviceType === DeviceType.MOBILE) {
@@ -152,9 +179,13 @@ const TMRecentsManagerWrapper = ({ mruTIDs, currentTID, currentMruTID, deviceTyp
152
179
  }
153
180
  else {
154
181
  setPanelVisibilityById('tmDcmtForm', true);
155
- setPanelVisibilityById('tmDcmtPreview', true);
182
+ if (!isSharedArchive) {
183
+ setPanelVisibilityById('tmDcmtPreview', true);
184
+ }
185
+ }
186
+ if (!isSharedArchive) {
187
+ setToolbarButtonVisibility('tmDcmtPreview', true);
156
188
  }
157
- setToolbarButtonVisibility('tmDcmtPreview', true);
158
189
  setToolbarButtonVisibility('tmDcmtForm', true);
159
190
  }, onDeletedTID: (tid) => {
160
191
  onDeletedTID?.(tid);
@@ -10,7 +10,7 @@ import { TMExceptionBoxManager, TMMessageBoxManager, ButtonNames } from '../../b
10
10
  import TMSpinner from '../../base/TMSpinner';
11
11
  import TMTooltip from '../../base/TMTooltip';
12
12
  import TMUserAvatar from '../../base/TMUserAvatar';
13
- import TMHtmlEditor from '../../editors/TMHtmlEditor';
13
+ import TMHtmlEditor, { sanitizeAndFormatComment } from '../../editors/TMHtmlEditor';
14
14
  import TMChooserForm from '../../forms/TMChooserForm';
15
15
  import TMSaveForm from '../../forms/TMSaveForm';
16
16
  const getNonDirectoryFiles = (items, exclude) => {
@@ -28,6 +28,7 @@ const getNonDirectoryFiles = (items, exclude) => {
28
28
  });
29
29
  };
30
30
  const TMBlogCommentForm = (props) => {
31
+ const maxLength = 1000;
31
32
  const { participants, selectedAttachments, selectedAttachmentDid, allFileItems, allArchivedDocumentsFileItems = [], onClose, refreshCallback, context, showAttachmentsSection = true, updateShouldSelectLastBlog } = props;
32
33
  // Initialize state with combined array
33
34
  const [dataSource, setDataSource] = useState(() => [...getNonDirectoryFiles(allFileItems?.items || [], []), ...allArchivedDocumentsFileItems]);
@@ -39,14 +40,18 @@ const TMBlogCommentForm = (props) => {
39
40
  const validator = async (params) => {
40
41
  let vil = [];
41
42
  const { comment } = params;
43
+ const cleanedMarkup = sanitizeAndFormatComment(comment);
42
44
  // Check for empty comment
43
- if (!comment || comment.trim() === "") {
45
+ if (!cleanedMarkup || cleanedMarkup.trim() === "") {
44
46
  vil.push(new ValidationItem(ResultTypes.ERROR, SDKUI_Localizator.Comment, `${SDK_Localizator.RequiredField}`));
45
47
  }
46
48
  else {
47
- // Validate description length (max 500)
48
- if (comment.length > 500) {
49
- vil.push(new ValidationItem(ResultTypes.ERROR, SDKUI_Localizator.Comment, `${SDKUI_Localizator.DescriptionTooLongMessage.replaceParams(500)}`));
49
+ // Calcola la lunghezza effettiva del commento inserito
50
+ const commentLength = cleanedMarkup.length;
51
+ const exceededChars = commentLength - maxLength;
52
+ // Validate description length (max 1000)
53
+ if (commentLength > maxLength) {
54
+ vil.push(new ValidationItem(ResultTypes.ERROR, SDKUI_Localizator.Comment, `${SDKUI_Localizator.DescriptionLengthExceededMessage.replaceParams(exceededChars)}`));
50
55
  }
51
56
  // Detect dangerous HTML tags
52
57
  const tagRegex = /<\/?(script|iframe|embed|object|link|style|img|video|audio|svg|form|input|button|textarea|select|pre|function)[^>]*>/gi;
@@ -108,20 +113,8 @@ const TMBlogCommentForm = (props) => {
108
113
  const blogPost = new BlogPost();
109
114
  // Retrieve the comment from formData, or use an empty string if undefined
110
115
  const comment = formData?.comment ?? "";
111
- // Clean the comment by removing <p> tags and replacing </p> with line breaks
112
- let cleanComment = comment
113
- // Replace </p> with '' only if followed by <ol> or <ul>
114
- .replace(/<\/p>(?=\s*<(ol|ul)>)/gi, '')
115
- // Replace all other </p> with '\r\n'
116
- .replace(/<\/p>/gi, '\r\n')
117
- // Remove all <p> tags
118
- .replace(/<p>/gi, '')
119
- // Remove all <br> tags
120
- .replace(/<br>/gi, '')
121
- // Trim whitespace
122
- .trim();
123
- // Validate and remove any potentially dangerous HTML tags (like <script>, <iframe>, etc.)
124
- cleanComment = cleanComment.replace(/<(script|iframe|embed|object|link|style|img|video|audio|svg|form|input|button|textarea|select|pre|function)[^>]*>/gi, '');
116
+ // Clean the comment using the sanitizeAndFormatComment function
117
+ const cleanComment = sanitizeAndFormatComment(comment);
125
118
  // Assign the cleaned comment as the description for the blog post
126
119
  blogPost.description = cleanComment ?? "";
127
120
  // If there are file items (attachments), process them
@@ -214,7 +207,7 @@ const TMBlogCommentForm = (props) => {
214
207
  // Update the state with selected draft items
215
208
  setCurrentDraftAttachments(selectedDraftItems);
216
209
  };
217
- return _jsx(TMSaveForm, { id: 1, title: SDKUI_Localizator.AddNewComment, showTitleFormMode: false, showErrorCount: false, customSaveButton: _jsx("i", { className: 'dx-icon-send' }), customTooltipSaveButton: SDKUI_Localizator.Send, showUndoButton: false, hasNavigation: false, skipIsModifiedCheck: true, isModal: true, width: calcResponsiveSizes(deviceType, '800px', '800px', '95%'), height: '550px', formMode: FormModes.Create, validationItems: validationItems, exception: exception, isModified: calcIsModified(formData, formDataOrig), onSaveAsync: onSaveAsync, onClose: onCloseCallback, customToolbarElements: _jsx("div", { style: { display: 'flex', gap: '2px' }, children: _jsx(TMButton, { btnStyle: "toolbar", icon: isEditorEnabled ? _jsx("i", { className: 'dx-icon-font' }) : _jsx("i", { className: 'dx-icon-background' }), caption: isEditorEnabled ? SDKUI_Localizator.HideFormattingOptions : SDKUI_Localizator.ShowFormattingOptions, onClick: toggleEditorMode }) }), children: _jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx("div", { style: { width: "100%", height: showAttachmentsSection ? "calc(100% - 60px)" : "100%" }, children: _jsx(TMHtmlEditor, { width: '100%', height: '100%', isEditorEnabled: isEditorEnabled, validationItems: validationItems, onValueChanged: onValueChanged, mentionsConfig: mentionsConfig, autoFocus: true }) }), showAttachmentsSection && _jsxs("div", { style: { display: 'flex', alignItems: 'center', height: '60px', marginTop: '10px' }, children: [_jsx("div", { style: {
210
+ return _jsx(TMSaveForm, { id: 1, title: SDKUI_Localizator.AddNewComment, showTitleFormMode: false, showErrorCount: false, customSaveButton: _jsx("i", { className: 'dx-icon-send' }), customTooltipSaveButton: SDKUI_Localizator.Send, showUndoButton: false, hasNavigation: false, skipIsModifiedCheck: true, isModal: true, width: calcResponsiveSizes(deviceType, '800px', '800px', '95%'), height: '550px', formMode: FormModes.Create, validationItems: validationItems, exception: exception, isModified: calcIsModified(formData, formDataOrig), onSaveAsync: onSaveAsync, onClose: onCloseCallback, customToolbarElements: _jsx("div", { style: { display: 'flex', gap: '2px' }, children: _jsx(TMButton, { btnStyle: "toolbar", icon: isEditorEnabled ? _jsx("i", { className: 'dx-icon-font' }) : _jsx("i", { className: 'dx-icon-background' }), caption: isEditorEnabled ? SDKUI_Localizator.HideFormattingOptions : SDKUI_Localizator.ShowFormattingOptions, onClick: toggleEditorMode }) }), children: _jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx("div", { style: { width: "100%", height: showAttachmentsSection ? "calc(100% - 60px)" : "100%" }, children: _jsx(TMHtmlEditor, { width: '100%', height: '100%', isEditorEnabled: isEditorEnabled, validationItems: validationItems, onValueChanged: onValueChanged, mentionsConfig: mentionsConfig, autoFocus: true, maxLength: maxLength }) }), showAttachmentsSection && _jsxs("div", { style: { display: 'flex', alignItems: 'center', height: '60px', marginTop: '10px' }, children: [_jsx("div", { style: {
218
211
  width: 'calc(100% - 60px)',
219
212
  overflowX: 'auto',
220
213
  whiteSpace: 'nowrap',
@@ -229,14 +222,22 @@ const TMBlogCommentForm = (props) => {
229
222
  const tooltipContent = (_jsxs("div", { style: { textAlign: 'left' }, children: [_jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Name, ":"] }), " ", draft.name ?? '-'] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Author, ":"] }), " ", draft.updaterName ?? '-'] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Version, ":"] }), " ", draft.version] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Size, ":"] }), " ", formatBytes(draft.size ?? 0)] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.CreationTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(draft.creationTime)] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.LastUpdateTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(draft.lastUpdateTime)] })] }));
230
223
  return _jsxs("div", { style: {
231
224
  display: 'inline-flex',
232
- alignItems: 'center',
233
- padding: '8px 12px',
234
- marginRight: '8px',
225
+ alignItems: 'center', // <-- this centers content vertically
226
+ padding: '4px 8px',
227
+ margin: '4px',
235
228
  border: '1px solid #ddd',
236
229
  borderRadius: '8px',
230
+ boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
231
+ cursor: 'pointer',
232
+ fontSize: '0.9rem',
237
233
  backgroundColor: '#fff',
238
- boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
239
- }, children: [draft.ext ? (_jsx("span", { style: { marginRight: '10px' }, children: getFileIcon(draft.ext, undefined, tooltipContent) })) : (_jsx(IconAttachment, { style: { marginRight: '5px' } })), _jsx("span", { style: { marginRight: '8px' }, children: draft.name }), draft.version && _jsx("span", { style: {
234
+ }, onMouseEnter: (e) => {
235
+ e.currentTarget.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.15)';
236
+ e.currentTarget.style.backgroundColor = '#cfcfcf';
237
+ }, onMouseLeave: (e) => {
238
+ e.currentTarget.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
239
+ e.currentTarget.style.backgroundColor = '#fff';
240
+ }, children: [draft.ext ? (_jsx("span", { style: { marginRight: '10px', display: 'flex', alignItems: 'center' }, children: getFileIcon(draft.ext, undefined, tooltipContent) })) : (_jsx(IconAttachment, { style: { marginRight: '5px' } })), _jsx("span", { style: { marginRight: '8px', display: 'flex', alignItems: 'center' }, children: draft.name }), draft.version && (_jsx("span", { style: {
240
241
  display: 'inline-flex',
241
242
  width: '20px',
242
243
  height: '20px',
@@ -248,7 +249,7 @@ const TMBlogCommentForm = (props) => {
248
249
  fontWeight: 'bold',
249
250
  marginRight: '8px',
250
251
  boxShadow: '1px 1px 2px #00000020',
251
- }, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Version, children: draft.version }) }), _jsx(TMTooltip, { content: SDKUI_Localizator.RemoveAttachment, children: _jsx("span", { onClick: () => removeAttachment(draft), style: {
252
+ }, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Version, children: draft.version }) })), _jsx(TMTooltip, { content: SDKUI_Localizator.RemoveAttachment, children: _jsx("span", { onClick: () => removeAttachment(draft), style: {
252
253
  display: 'inline-flex',
253
254
  width: '20px',
254
255
  height: '20px',
@@ -259,21 +260,36 @@ const TMBlogCommentForm = (props) => {
259
260
  borderRadius: '30px',
260
261
  cursor: 'pointer',
261
262
  boxShadow: '1px 1px 2px #00000020',
262
- }, children: _jsx("span", { style: { fontSize: "15px" }, children: "\u00D7" }) }) })] }, draft.did);
263
- })) : (_jsx("div", { style: { color: '#999', width: '100%', textAlign: 'center' }, children: SDKUI_Localizator.NoAttachments })) }), _jsx(TMTooltip, { content: SDKUI_Localizator.Attachments, children: _jsx("i", { className: "dx-icon-attach", style: {
264
- width: '50px',
265
- height: '50px',
266
- marginLeft: '10px',
267
- fontSize: '20px',
268
- cursor: 'pointer',
269
- border: '1px solid #ccc',
270
- borderRadius: '8px',
271
- backgroundColor: '#f9f9f9',
272
- display: 'flex',
273
- alignItems: 'center',
274
- justifyContent: 'center',
275
- transition: 'all 0.2s ease-in-out',
276
- }, onMouseOver: (e) => (e.currentTarget.style.backgroundColor = '#e6f7ff'), onMouseOut: (e) => (e.currentTarget.style.backgroundColor = '#f9f9f9'), onClick: () => setShowAttachmentsForm(true) }) })] })] }), showAttachmentsForm && _jsx(TMAttachmentsView, { dataSource: dataSource, selectedIDs: currentDraftAttachments.map(draft => draft.id), onChoose: onChoose, onClose: () => setShowAttachmentsForm(false) })] }) });
263
+ }, children: _jsx("span", { style: { fontSize: '15px' }, children: "\u00D7" }) }) })] }, draft.did);
264
+ })) : (_jsx("div", { style: { color: '#999', width: '100%', textAlign: 'center' }, children: SDKUI_Localizator.NoAttachments })) }), _jsx(TMTooltip, { content: SDKUI_Localizator.Attachments + ": " + currentDraftAttachments.length, children: _jsxs("div", { style: { position: 'relative', display: 'inline-block' }, children: [_jsx("i", { className: "dx-icon-attach", style: {
265
+ width: '50px',
266
+ height: '50px',
267
+ marginLeft: '10px',
268
+ fontSize: '20px',
269
+ cursor: 'pointer',
270
+ border: '1px solid #ccc',
271
+ borderRadius: '8px',
272
+ backgroundColor: '#f9f9f9',
273
+ display: 'flex',
274
+ alignItems: 'center',
275
+ justifyContent: 'center',
276
+ transition: 'all 0.2s ease-in-out',
277
+ }, onMouseOver: (e) => (e.currentTarget.style.backgroundColor = '#e6f7ff'), onMouseOut: (e) => (e.currentTarget.style.backgroundColor = '#f9f9f9'), onClick: () => setShowAttachmentsForm(true) }), currentDraftAttachments.length > 0 && (_jsx("span", { style: {
278
+ position: 'absolute',
279
+ top: '-5px',
280
+ right: '-5px',
281
+ backgroundColor: '#203E5A',
282
+ color: 'white',
283
+ borderRadius: '50%',
284
+ minWidth: '20px',
285
+ height: '20px',
286
+ display: 'flex',
287
+ alignItems: 'center',
288
+ justifyContent: 'center',
289
+ padding: '0 6px',
290
+ fontSize: '12px',
291
+ fontWeight: 'bold',
292
+ }, children: currentDraftAttachments.length > 99 ? '99+' : currentDraftAttachments.length }))] }) })] })] }), showAttachmentsForm && _jsx(TMAttachmentsView, { dataSource: dataSource, selectedIDs: currentDraftAttachments.map(draft => draft.id), onChoose: onChoose, onClose: () => setShowAttachmentsForm(false) })] }) });
277
293
  };
278
294
  export default TMBlogCommentForm;
279
295
  const TMAttachmentsView = (props) => {
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { LayoutModes, SearchResultDescriptor, TaskDescriptor } from '@topconsultnpm/sdk-ts';
3
- import { DcmtInfo, FormModes, TaskContext } from '../../../ts';
2
+ import { LayoutModes, ObjectRef, SearchResultDescriptor, TaskDescriptor, ValidationItem } from '@topconsultnpm/sdk-ts';
3
+ import { DcmtInfo, FormModes, MetadataValueDescriptorEx, TaskContext } from '../../../ts';
4
4
  interface ITMDcmtFormProps {
5
5
  TID?: number;
6
6
  DID?: number;
@@ -20,6 +20,7 @@ interface ITMDcmtFormProps {
20
20
  invokedByTodo?: boolean;
21
21
  taskFormDialogComponent?: React.ReactNode;
22
22
  taskMoreInfo?: TaskDescriptor;
23
+ showBackButton?: boolean;
23
24
  onNext?: () => void;
24
25
  onPrev?: () => void;
25
26
  onClose?: () => void;
@@ -44,7 +45,13 @@ interface ITMDcmtFormProps {
44
45
  passToSearch?: (outputMids: Array<{
45
46
  mid: number;
46
47
  value: string;
47
- }>) => void;
48
+ }>, tid?: number) => void;
49
+ isSharedDcmt?: boolean;
50
+ sharedSourceTID?: number;
51
+ sharedSourceDID?: number;
52
+ allowButtonsRefs?: boolean;
53
+ onReferenceClick?: (ref: ObjectRef) => void;
48
54
  }
49
55
  declare const TMDcmtForm: React.FC<ITMDcmtFormProps>;
50
56
  export default TMDcmtForm;
57
+ export declare const validateMetadataList: (mvdList?: MetadataValueDescriptorEx[]) => ValidationItem[];