@topconsultnpm/sdkui-react 6.19.0-dev1.9 → 6.19.0-dev2.2

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 (116) 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/TMCustomButton.d.ts +11 -0
  4. package/lib/components/base/TMCustomButton.js +63 -0
  5. package/lib/components/base/TMFileManagerDataGridView.js +4 -1
  6. package/lib/components/base/TMLayout.d.ts +2 -1
  7. package/lib/components/base/TMLayout.js +2 -2
  8. package/lib/components/base/TMPopUp.js +5 -18
  9. package/lib/components/base/TMTreeView.js +3 -2
  10. package/lib/components/editors/TMHtmlEditor.d.ts +5 -0
  11. package/lib/components/editors/TMHtmlEditor.js +72 -12
  12. package/lib/components/editors/TMMetadataValues.js +90 -40
  13. package/lib/components/features/archive/TMArchive.d.ts +10 -0
  14. package/lib/components/features/archive/TMArchive.js +56 -25
  15. package/lib/components/features/blog/TMBlogCommentForm.d.ts +4 -4
  16. package/lib/components/features/blog/TMBlogCommentForm.js +76 -51
  17. package/lib/components/features/documents/TMDcmtBlog.d.ts +15 -0
  18. package/lib/components/features/documents/TMDcmtBlog.js +21 -33
  19. package/lib/components/features/documents/TMDcmtForm.d.ts +17 -3
  20. package/lib/components/features/documents/TMDcmtForm.js +205 -46
  21. package/lib/components/features/documents/TMDcmtTasks.d.ts +13 -0
  22. package/lib/components/features/documents/TMDcmtTasks.js +24 -0
  23. package/lib/components/features/documents/TMDragDropOverlay.js +2 -1
  24. package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +8 -1
  25. package/lib/components/features/documents/TMMasterDetailDcmts.js +6 -6
  26. package/lib/components/features/documents/TMRelationViewer.d.ts +53 -3
  27. package/lib/components/features/documents/TMRelationViewer.js +232 -85
  28. package/lib/components/features/search/TMSearch.d.ts +10 -1
  29. package/lib/components/features/search/TMSearch.js +14 -5
  30. package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -1
  31. package/lib/components/features/search/TMSearchQueryPanel.js +36 -7
  32. package/lib/components/features/search/TMSearchResult.d.ts +10 -1
  33. package/lib/components/features/search/TMSearchResult.js +140 -422
  34. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -2
  35. package/lib/components/features/search/TMSearchResultsMenuItems.js +33 -8
  36. package/lib/components/features/tasks/TMTaskForm.d.ts +38 -0
  37. package/lib/components/features/tasks/TMTaskForm.js +386 -0
  38. package/lib/components/features/tasks/TMTasksAgenda.d.ts +17 -0
  39. package/lib/components/features/tasks/TMTasksAgenda.js +107 -0
  40. package/lib/components/features/tasks/TMTasksCalendar.d.ts +21 -0
  41. package/lib/components/features/tasks/TMTasksCalendar.js +240 -0
  42. package/lib/components/features/tasks/TMTasksHeader.d.ts +14 -0
  43. package/lib/components/features/tasks/TMTasksHeader.js +37 -0
  44. package/lib/components/features/tasks/TMTasksPanelContent.d.ts +20 -0
  45. package/lib/components/features/tasks/TMTasksPanelContent.js +65 -0
  46. package/lib/components/features/tasks/TMTasksUtils.d.ts +132 -0
  47. package/lib/components/features/tasks/TMTasksUtils.js +634 -0
  48. package/lib/components/features/tasks/TMTasksUtilsView.d.ts +39 -0
  49. package/lib/components/features/tasks/TMTasksUtilsView.js +118 -0
  50. package/lib/components/features/tasks/TMTasksView.d.ts +40 -0
  51. package/lib/components/features/tasks/TMTasksView.js +560 -0
  52. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +3 -1
  53. package/lib/components/features/workflow/TMWorkflowPopup.js +19 -6
  54. package/lib/components/features/workflow/diagram/RecipientList.js +4 -3
  55. package/lib/components/forms/Login/Chooser.js +1 -1
  56. package/lib/components/forms/TMChooserForm.d.ts +1 -1
  57. package/lib/components/forms/TMChooserForm.js +2 -2
  58. package/lib/components/grids/TMBlogAttachments.d.ts +42 -0
  59. package/lib/components/grids/TMBlogAttachments.js +43 -0
  60. package/lib/components/grids/TMBlogHeader.d.ts +31 -0
  61. package/lib/components/grids/TMBlogHeader.js +41 -0
  62. package/lib/components/grids/{TMBlogs.d.ts → TMBlogsPost.d.ts} +42 -58
  63. package/lib/components/grids/TMBlogsPost.js +628 -0
  64. package/lib/components/grids/{TMBlogsUtils.d.ts → TMBlogsPostUtils.d.ts} +61 -47
  65. package/lib/components/grids/{TMBlogsUtils.js → TMBlogsPostUtils.js} +146 -124
  66. package/lib/components/index.d.ts +14 -1
  67. package/lib/components/index.js +15 -1
  68. package/lib/components/layout/panelManager/TMPanelManagerContext.js +7 -0
  69. package/lib/components/settings/SettingsAppearance.js +8 -0
  70. package/lib/components/viewers/TMTidViewer.js +20 -2
  71. package/lib/css/tm-sdkui.css +1 -1
  72. package/lib/helper/SDKUI_Globals.d.ts +4 -1
  73. package/lib/helper/SDKUI_Globals.js +10 -1
  74. package/lib/helper/SDKUI_Localizator.d.ts +62 -4
  75. package/lib/helper/SDKUI_Localizator.js +618 -25
  76. package/lib/helper/TMCustomSearchBar.d.ts +8 -0
  77. package/lib/helper/TMCustomSearchBar.js +54 -0
  78. package/lib/helper/TMIcons.d.ts +2 -0
  79. package/lib/helper/TMIcons.js +6 -0
  80. package/lib/helper/TMImageLibrary.d.ts +3 -2
  81. package/lib/helper/TMImageLibrary.js +230 -230
  82. package/lib/helper/TMToppyMessage.d.ts +7 -0
  83. package/lib/helper/TMToppyMessage.js +42 -0
  84. package/lib/helper/TMUtils.d.ts +10 -1
  85. package/lib/helper/TMUtils.js +42 -1
  86. package/lib/helper/dcmtsHelper.d.ts +2 -0
  87. package/lib/helper/dcmtsHelper.js +18 -0
  88. package/lib/helper/helpers.js +1 -0
  89. package/lib/helper/index.d.ts +1 -0
  90. package/lib/helper/index.js +1 -0
  91. package/lib/hooks/useRelatedDocuments.d.ts +72 -0
  92. package/lib/hooks/useRelatedDocuments.js +655 -0
  93. package/lib/index.d.ts +1 -0
  94. package/lib/index.js +1 -0
  95. package/lib/ts/types.d.ts +14 -0
  96. package/lib/ts/types.js +15 -0
  97. package/lib/utils/theme.d.ts +1 -0
  98. package/lib/utils/theme.js +1 -0
  99. package/package.json +7 -7
  100. package/lib/components/grids/TMBlogs.js +0 -721
  101. package/lib/stories/TMButton.stories.d.ts +0 -4
  102. package/lib/stories/TMButton.stories.js +0 -29
  103. package/lib/stories/TMDataGrid.stories.d.ts +0 -9
  104. package/lib/stories/TMDataGrid.stories.js +0 -310
  105. package/lib/stories/TMHtmlContentDisplay.stories.d.ts +0 -6
  106. package/lib/stories/TMHtmlContentDisplay.stories.js +0 -45
  107. package/lib/stories/TMHtmlEditor.stories.d.ts +0 -6
  108. package/lib/stories/TMHtmlEditor.stories.js +0 -49
  109. package/lib/stories/TMIcons.stories.d.ts +0 -4
  110. package/lib/stories/TMIcons.stories.js +0 -13
  111. package/lib/stories/TMSDKUI_Localizator.stories.d.ts +0 -4
  112. package/lib/stories/TMSDKUI_Localizator.stories.js +0 -123
  113. package/lib/stories/TMStoriesUtils.d.ts +0 -1
  114. package/lib/stories/TMStoriesUtils.js +0 -10
  115. package/lib/stories/TMUserAvatar.stories.d.ts +0 -6
  116. package/lib/stories/TMUserAvatar.stories.js +0 -20
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
2
3
  interface ITMArchiveProps {
3
4
  inputFile?: File | null;
4
5
  inputMids?: Array<{
@@ -6,6 +7,7 @@ interface ITMArchiveProps {
6
7
  value: string;
7
8
  }>;
8
9
  inputTID?: number;
10
+ inputDID?: number;
9
11
  onDcmtTypeSelect?: (tid: number | undefined) => void;
10
12
  connectorFileSave?: () => Promise<File>;
11
13
  onSavedAsyncCallback?: (tid: number | undefined, did: number | undefined) => Promise<void>;
@@ -14,6 +16,14 @@ interface ITMArchiveProps {
14
16
  mid: number;
15
17
  value: string;
16
18
  }>) => void;
19
+ isSharedArchive?: boolean;
20
+ allTasks?: Array<TaskDescriptor>;
21
+ getAllTasks?: () => Promise<void>;
22
+ deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
23
+ addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
24
+ editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
25
+ handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
26
+ handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
17
27
  }
18
28
  declare const TMArchive: React.FunctionComponent<ITMArchiveProps>;
19
29
  export default TMArchive;
@@ -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, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
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, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }, 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, allTasks]);
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);
@@ -1,17 +1,17 @@
1
- import { UserDescriptor } from "@topconsultnpm/sdk-ts";
2
- import { TMBlogContextDescriptor } from '../../grids/TMBlogsUtils';
1
+ import { BlogPost, UserDescriptor } from "@topconsultnpm/sdk-ts";
3
2
  import { FileItem } from '../../base/TMFileManagerUtils';
3
+ import { TMBlogContextDescriptor } from '../../grids/TMBlogsPostUtils';
4
4
  interface TMBlogCommentFormProps {
5
5
  context: TMBlogContextDescriptor;
6
6
  participants: Array<UserDescriptor>;
7
7
  onClose: () => void;
8
- refreshCallback: () => Promise<void>;
9
8
  showAttachmentsSection?: boolean;
10
9
  selectedAttachments?: Array<FileItem>;
11
10
  selectedAttachmentDid?: Array<number>;
12
11
  allFileItems?: FileItem;
13
12
  allArchivedDocumentsFileItems?: Array<FileItem>;
14
- updateShouldSelectLastBlog?: (value: boolean) => void;
13
+ onFilterCreated?: (predicate: (post: BlogPost) => boolean) => void;
14
+ refreshCallback?: () => Promise<void>;
15
15
  }
16
16
  declare const TMBlogCommentForm: (props: TMBlogCommentFormProps) => import("react/jsx-runtime").JSX.Element;
17
17
  export default TMBlogCommentForm;
@@ -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,7 +28,8 @@ const getNonDirectoryFiles = (items, exclude) => {
28
28
  });
29
29
  };
30
30
  const TMBlogCommentForm = (props) => {
31
- const { participants, selectedAttachments, selectedAttachmentDid, allFileItems, allArchivedDocumentsFileItems = [], onClose, refreshCallback, context, showAttachmentsSection = true, updateShouldSelectLastBlog } = props;
31
+ const maxLength = 1000;
32
+ const { participants, selectedAttachments, selectedAttachmentDid, allFileItems, allArchivedDocumentsFileItems = [], onClose, context, showAttachmentsSection = true, onFilterCreated, refreshCallback } = props;
32
33
  // Initialize state with combined array
33
34
  const [dataSource, setDataSource] = useState(() => [...getNonDirectoryFiles(allFileItems?.items || [], []), ...allArchivedDocumentsFileItems]);
34
35
  const [isEditorEnabled, setIsEditorEnabled] = useState(true);
@@ -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
@@ -143,23 +136,32 @@ const TMBlogCommentForm = (props) => {
143
136
  // Create an instance of WorkingGroupEngine to interact with the working group
144
137
  const workingGroupEngine = new WorkingGroupEngine(SDK_Globals.tmSession);
145
138
  // Call the BlogPostAddAsync method to add the blog post to the working group
146
- await workingGroupEngine.BlogPostAddAsync(context.object.id, blogPost);
147
- await refreshCallback();
148
- updateShouldSelectLastBlog?.(true);
139
+ const newBlogPostId = await workingGroupEngine.BlogPostAddAsync(context.object.id, blogPost);
140
+ await refreshCallback?.();
141
+ if (newBlogPostId && onFilterCreated) {
142
+ onFilterCreated(post => post.id === newBlogPostId);
143
+ }
144
+ ;
149
145
  }
150
146
  else if (context.engine === 'SearchEngine') {
151
147
  // Create an instance of SearchEngine
152
148
  const searchEngine = SDK_Globals.tmSession?.NewSearchEngine();
153
- await searchEngine.BlogPostAddAsync(context.object.tid, context.object.did, cleanComment);
154
- await refreshCallback();
155
- setTimeout(() => updateShouldSelectLastBlog?.(true), 300);
149
+ const newBlogPostId = await searchEngine.BlogPostAddAsync(context.object.tid, context.object.did, cleanComment);
150
+ await refreshCallback?.();
151
+ if (newBlogPostId && onFilterCreated) {
152
+ onFilterCreated(post => post.id === newBlogPostId);
153
+ }
154
+ ;
156
155
  }
157
156
  else if (context.engine === 'DossierEngine' && context.object && context.object.id) {
158
157
  // Create an instance of DossierEngine
159
158
  const dossierEngine = SDK_Globals.tmSession?.NewDossierEngine();
160
- await dossierEngine.BlogPostAddAsync(context.object.id, blogPost);
161
- await refreshCallback();
162
- setTimeout(() => updateShouldSelectLastBlog?.(true), 300);
159
+ const newBlogPostId = await dossierEngine.BlogPostAddAsync(context.object.id, blogPost);
160
+ await refreshCallback?.();
161
+ if (newBlogPostId && onFilterCreated) {
162
+ onFilterCreated(post => post.id === newBlogPostId);
163
+ }
164
+ ;
163
165
  }
164
166
  }
165
167
  catch (e) {
@@ -214,7 +216,7 @@ const TMBlogCommentForm = (props) => {
214
216
  // Update the state with selected draft items
215
217
  setCurrentDraftAttachments(selectedDraftItems);
216
218
  };
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: {
219
+ 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
220
  width: 'calc(100% - 60px)',
219
221
  overflowX: 'auto',
220
222
  whiteSpace: 'nowrap',
@@ -229,14 +231,22 @@ const TMBlogCommentForm = (props) => {
229
231
  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
232
  return _jsxs("div", { style: {
231
233
  display: 'inline-flex',
232
- alignItems: 'center',
233
- padding: '8px 12px',
234
- marginRight: '8px',
234
+ alignItems: 'center', // <-- this centers content vertically
235
+ padding: '4px 8px',
236
+ margin: '4px',
235
237
  border: '1px solid #ddd',
236
238
  borderRadius: '8px',
239
+ boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
240
+ cursor: 'pointer',
241
+ fontSize: '0.9rem',
237
242
  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: {
243
+ }, onMouseEnter: (e) => {
244
+ e.currentTarget.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.15)';
245
+ e.currentTarget.style.backgroundColor = '#cfcfcf';
246
+ }, onMouseLeave: (e) => {
247
+ e.currentTarget.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
248
+ e.currentTarget.style.backgroundColor = '#fff';
249
+ }, 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
250
  display: 'inline-flex',
241
251
  width: '20px',
242
252
  height: '20px',
@@ -248,7 +258,7 @@ const TMBlogCommentForm = (props) => {
248
258
  fontWeight: 'bold',
249
259
  marginRight: '8px',
250
260
  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: {
261
+ }, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Version, children: draft.version }) })), _jsx(TMTooltip, { content: SDKUI_Localizator.RemoveAttachment, children: _jsx("span", { onClick: () => removeAttachment(draft), style: {
252
262
  display: 'inline-flex',
253
263
  width: '20px',
254
264
  height: '20px',
@@ -259,21 +269,36 @@ const TMBlogCommentForm = (props) => {
259
269
  borderRadius: '30px',
260
270
  cursor: 'pointer',
261
271
  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) })] }) });
272
+ }, children: _jsx("span", { style: { fontSize: '15px' }, children: "\u00D7" }) }) })] }, draft.did);
273
+ })) : (_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: {
274
+ width: '50px',
275
+ height: '50px',
276
+ marginLeft: '10px',
277
+ fontSize: '20px',
278
+ cursor: 'pointer',
279
+ border: '1px solid #ccc',
280
+ borderRadius: '8px',
281
+ backgroundColor: '#f9f9f9',
282
+ display: 'flex',
283
+ alignItems: 'center',
284
+ justifyContent: 'center',
285
+ transition: 'all 0.2s ease-in-out',
286
+ }, onMouseOver: (e) => (e.currentTarget.style.backgroundColor = '#e6f7ff'), onMouseOut: (e) => (e.currentTarget.style.backgroundColor = '#f9f9f9'), onClick: () => setShowAttachmentsForm(true) }), currentDraftAttachments.length > 0 && (_jsx("span", { style: {
287
+ position: 'absolute',
288
+ top: '-5px',
289
+ right: '-5px',
290
+ backgroundColor: '#203E5A',
291
+ color: 'white',
292
+ borderRadius: '50%',
293
+ minWidth: '20px',
294
+ height: '20px',
295
+ display: 'flex',
296
+ alignItems: 'center',
297
+ justifyContent: 'center',
298
+ padding: '0 6px',
299
+ fontSize: '12px',
300
+ fontWeight: 'bold',
301
+ }, children: currentDraftAttachments.length > 99 ? '99+' : currentDraftAttachments.length }))] }) })] })] }), showAttachmentsForm && _jsx(TMAttachmentsView, { dataSource: dataSource, selectedIDs: currentDraftAttachments.map(draft => draft.id), onChoose: onChoose, onClose: () => setShowAttachmentsForm(false) })] }) });
277
302
  };
278
303
  export default TMBlogCommentForm;
279
304
  const TMAttachmentsView = (props) => {
@@ -1,8 +1,23 @@
1
1
  import React from 'react';
2
+ import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
2
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;
3
10
  tid: number | undefined;
4
11
  did: number | undefined;
12
+ fetchBlogDataAsync: (tid: number | undefined, did: number | undefined) => Promise<void>;
5
13
  isVisible?: boolean;
14
+ allTasks?: Array<TaskDescriptor>;
15
+ getAllTasks?: () => Promise<void>;
16
+ deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
17
+ addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
18
+ editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
19
+ handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
20
+ handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
6
21
  }
7
22
  declare const TMDcmtBlog: React.FC<ITMDcmtBlogProps>;
8
23
  export default TMDcmtBlog;
@@ -2,39 +2,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useState } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import { SDK_Globals } from '@topconsultnpm/sdk-ts';
5
- import { TMExceptionBoxManager } from '../../base/TMPopUp';
6
- import TMSpinner from '../../base/TMSpinner';
7
- import TMBlogs from '../../grids/TMBlogs';
8
5
  import { TMNothingToShow } from './TMDcmtPreview';
9
6
  import { IconBoard, SDKUI_Localizator } from '../../../helper';
10
7
  import TMBlogCommentForm from '../blog/TMBlogCommentForm';
11
- const TMDcmtBlog = ({ tid, did, isVisible }) => {
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
8
+ import TMBlogsPost from '../../grids/TMBlogsPost';
9
+ const TMDcmtBlog = ({ blogsDatasource, setBlogsDatasource, hasLoadedDataOnce, setHasLoadedDataOnce, lastLoadedDid, setLastLoadedDid, tid, did, fetchBlogDataAsync, isVisible, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
15
10
  // State to manage show comment form selected file
16
11
  const [showCommentForm, setShowCommentForm] = useState(false);
17
- // Flag to determine if the last blog should be automatically selected (after a new blog is added)
18
- const [shouldSelectLastBlog, setShouldSelectLastBlog] = useState(false);
12
+ const [externalBlogPost, setExternalBlogPost] = useState(undefined);
19
13
  const showCommentFormCallback = useCallback(() => {
20
14
  setShowCommentForm(true);
21
15
  }, []);
22
- const fetchDataAsync = async (tid, did) => {
23
- try {
24
- TMSpinner.show({ description: 'Caricamento - Bacheca...' });
25
- const res = await SDK_Globals.tmSession?.NewSearchEngine().BlogRetrieveAsync(tid, did);
26
- setBlogsDatasource(res ?? []);
27
- setHasLoadedDataOnce(true);
28
- setLastLoadedDid(did);
29
- }
30
- catch (e) {
31
- let err = e;
32
- TMExceptionBoxManager.show({ exception: err });
33
- }
34
- finally {
35
- TMSpinner.hide();
36
- }
37
- };
38
16
  useEffect(() => {
39
17
  if (!tid || !did) {
40
18
  setBlogsDatasource([]);
@@ -48,17 +26,27 @@ const TMDcmtBlog = ({ tid, did, isVisible }) => {
48
26
  // Esegui la chiamata API solo se il pannello è visibile E i dati non sono già stati caricati
49
27
  // O, se vuoi ricaricare ogni volta che diventa visibile (ma è meno efficiente per "pesante")
50
28
  if (shouldFetch) {
51
- fetchDataAsync(tid, did);
29
+ fetchBlogDataAsync(tid, did);
52
30
  }
53
31
  }, [tid, did, isVisible, hasLoadedDataOnce, lastLoadedDid]);
54
- const updateShouldSelectLastBlog = (value) => {
55
- setShouldSelectLastBlog(value);
56
- };
57
32
  const refreshCallback = async () => {
58
- await fetchDataAsync(tid, did);
33
+ await fetchBlogDataAsync(tid, did);
34
+ };
35
+ const resetExternalBlogPost = useCallback(() => {
36
+ setExternalBlogPost(undefined);
37
+ }, []);
38
+ const handleFilterCreated = async (predicate) => {
39
+ await refreshCallback();
40
+ const res = await SDK_Globals.tmSession?.NewSearchEngine().BlogRetrieveAsync(tid, did);
41
+ if (res && res.length > 0) {
42
+ setBlogsDatasource(res ?? []);
43
+ const firstMatchingPost = res.find(predicate);
44
+ if (firstMatchingPost)
45
+ setExternalBlogPost(firstMatchingPost);
46
+ }
59
47
  };
60
48
  return (_jsxs("div", { style: { width: '100%', height: '100%' }, children: [_jsx(StyledContainer, { children: _jsx(StyledSectionContainer, { style: { position: 'relative' }, children: _jsx(StyledBoardContainer, { children: !did ? _jsx(TMNothingToShow, { text: `${SDKUI_Localizator.NoDcmtSelected}.`, secondText: `${SDKUI_Localizator.BlogCase} - ${SDKUI_Localizator.NotAvailable}`, icon: _jsx(IconBoard, { fontSize: 96 }) }) :
61
- _jsx(TMBlogs, { context: { engine: 'SearchEngine', object: { tid, did } }, id: "dcmt-blog", allData: blogsDatasource, showExtendedAttachments: false, showFloatingCommentButton: true, showCommentFormCallback: showCommentFormCallback, refreshCallback: refreshCallback, contextMenuParams: {
49
+ _jsx(TMBlogsPost, { context: { engine: 'SearchEngine', object: { tid, did } }, id: "dcmt-blog", displayMode: 'chat', scrollToSelected: true, posts: blogsDatasource, showExtendedAttachments: false, showFloatingCommentButton: true, showCommentFormCallback: showCommentFormCallback, refreshCallback: refreshCallback, contextMenuParams: {
62
50
  isShowHideFilterEnabled: true,
63
51
  isShowHideIDEnaled: true,
64
52
  isCommentEnabled: true,
@@ -69,9 +57,9 @@ const TMDcmtBlog = ({ tid, did, isVisible }) => {
69
57
  isRefreshEnabled: true,
70
58
  isRestoreEnabled: true,
71
59
  isCreateContextualTask: false
72
- }, layoutMode: 'chat', shouldSelectLastBlog: shouldSelectLastBlog, updateShouldSelectLastBlog: updateShouldSelectLastBlog }) }) }) }), (showCommentForm && tid && did) && _jsx(TMBlogCommentForm, { context: { engine: 'SearchEngine', object: { tid, did } }, onClose: () => setShowCommentForm(false), refreshCallback: refreshCallback, participants: [], showAttachmentsSection: false, updateShouldSelectLastBlog: updateShouldSelectLastBlog, allArchivedDocumentsFileItems: [] })] }));
60
+ }, externalBlogPost: externalBlogPost, resetExternalBlogPost: resetExternalBlogPost, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }) }) }), (showCommentForm && tid && did) && _jsx(TMBlogCommentForm, { context: { engine: 'SearchEngine', object: { tid, did } }, onClose: () => setShowCommentForm(false), refreshCallback: refreshCallback, participants: [], showAttachmentsSection: false, allArchivedDocumentsFileItems: [], onFilterCreated: handleFilterCreated })] }));
73
61
  };
74
62
  export default TMDcmtBlog;
75
63
  const StyledContainer = styled.div ` user-select: none; overflow: hidden; background-color: #ffffff; width: calc(100%); height: calc(100%); display: flex; gap: 10px; `;
76
64
  const StyledSectionContainer = styled.div ` width: 100%; height: 100%; display:flex; flex-direction: column; `;
77
- const StyledBoardContainer = styled.div `width: 100%; height: 100%; padding: 10px;`;
65
+ const StyledBoardContainer = styled.div `width: 100%; height: 100%;`;
@@ -1,7 +1,14 @@
1
1
  import React from 'react';
2
- import { LayoutModes, SearchResultDescriptor, TaskDescriptor } from '@topconsultnpm/sdk-ts';
3
- import { DcmtInfo, FormModes, TaskContext } from '../../../ts';
2
+ import { HomeBlogPost, LayoutModes, ObjectRef, SearchResultDescriptor, TaskDescriptor, ValidationItem } from '@topconsultnpm/sdk-ts';
3
+ import { DcmtInfo, FormModes, MetadataValueDescriptorEx, TaskContext } from '../../../ts';
4
4
  interface ITMDcmtFormProps {
5
+ allTasks?: Array<TaskDescriptor>;
6
+ getAllTasks?: () => Promise<void>;
7
+ deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
8
+ addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
9
+ editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
10
+ handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
11
+ handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
5
12
  TID?: number;
6
13
  DID?: number;
7
14
  layoutMode?: LayoutModes;
@@ -20,6 +27,7 @@ interface ITMDcmtFormProps {
20
27
  invokedByTodo?: boolean;
21
28
  taskFormDialogComponent?: React.ReactNode;
22
29
  taskMoreInfo?: TaskDescriptor;
30
+ showBackButton?: boolean;
23
31
  onNext?: () => void;
24
32
  onPrev?: () => void;
25
33
  onClose?: () => void;
@@ -44,7 +52,13 @@ interface ITMDcmtFormProps {
44
52
  passToSearch?: (outputMids: Array<{
45
53
  mid: number;
46
54
  value: string;
47
- }>) => void;
55
+ }>, tid?: number) => void;
56
+ isSharedDcmt?: boolean;
57
+ sharedSourceTID?: number;
58
+ sharedSourceDID?: number;
59
+ allowButtonsRefs?: boolean;
60
+ onReferenceClick?: (ref: ObjectRef) => void;
48
61
  }
49
62
  declare const TMDcmtForm: React.FC<ITMDcmtFormProps>;
50
63
  export default TMDcmtForm;
64
+ export declare const validateMetadataList: (mvdList?: MetadataValueDescriptorEx[]) => ValidationItem[];