@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,721 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
- import { DcmtTypeListCacheService, LayoutModes, ResultTypes, SDK_Globals, WorkingGroupEngine } from "@topconsultnpm/sdk-ts";
4
- import { ContextMenu, ScrollView } from 'devextreme-react';
5
- import { SDKUI_Localizator, IconAttachment, getExceptionMessage, Globalization, IconBoard, genUniqueId } from '../../helper';
6
- import { useDeviceType, DeviceType } from '../base/TMDeviceProvider';
7
- import { TMMessageBoxManager, ButtonNames } from '../base/TMPopUp';
8
- import TMTooltip from '../base/TMTooltip';
9
- import { TMLayoutWaitingContainer } from '../base/TMWaitPanel';
10
- import TMDropDown from '../editors/TMDropDown';
11
- import TMHtmlContentDisplay from '../editors/TMHtmlContentDisplay';
12
- import TMTreeDropDown from '../editors/TMTreeDropDown';
13
- import { TMResultManager } from '../forms/TMResultDialog';
14
- import { TMSearchBar } from '../sidebar/TMHeader';
15
- import { AttachmentElement, BlogPostContainer, colors, findFileItemByDraftID, highlightText, IconAndHeaderElement, isHeaderFullyHidden, OwnerInitialsBadge, TMBlogsFilterCategoryId } from './TMBlogsUtils';
16
- import { useDcmtOperations } from '../../hooks/useDcmtOperations';
17
- import { DownloadTypes } from '../../ts';
18
- import TMDcmtForm from '../features/documents/TMDcmtForm';
19
- import { TMColors } from '../../utils/theme';
20
- import ShowAlert from '../base/TMAlert';
21
- let localAbortController = new AbortController();
22
- const TMBlogs = (props) => {
23
- const { id, allData, showExtendedAttachments = true, treeFs, draftLatestInfoMap, archivedDocumentMap, updateVisualizedBlogCallback, height, width, scrollToBottom = true, header, showIconHeader = true, color = colors.PRIMARY_BLUE, handleNavigateToWGs, showId, setShowId, contextMenuParams = {
24
- isShowHideFilterEnabled: true,
25
- isShowHideIDEnaled: true,
26
- isCommentEnabled: false,
27
- isDownloadAttachmentEnabled: false,
28
- isViewEditMetadata: false,
29
- isDeleteEnabled: false,
30
- isCopyToClipboardEnabled: false,
31
- isRestoreEnabled: false,
32
- isRefreshEnabled: false,
33
- isCreateContextualTask: false,
34
- }, refreshCallback, showCommentFormCallback, showTaskFormCallback, handleAttachmentFocus, showFloatingCommentButton = false, context, layoutMode = 'stacked', markBlogAsRead, shouldSelectLastBlog = false, updateShouldSelectLastBlog, refreshHomePageNews } = props;
35
- const [uiId, setUiId] = useState('');
36
- // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
37
- const deviceType = useDeviceType();
38
- const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
39
- // This avoids unnecessary re-renders by only recalculating when deviceType changes.
40
- let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
41
- // State to store an array of blog posts, which can be either BlogPost or HomeBlogPost type
42
- const [blogPosts, setBlogPosts] = useState([]);
43
- // State to store the first newly fetched blog post, used for highlighting or special display
44
- const [firstNewPost, setFirstNewPost] = useState(undefined);
45
- // State to manage the data source for a tree component
46
- const [treeDataSource, setTreeDataSource] = useState([]);
47
- // State to store the user's search input for filtering or searching posts/messages
48
- const [searchText, setSearchText] = useState('');
49
- // State to manage the number of posts to display, with a default value of 30
50
- const [postsToShow, setPostsToShow] = useState(30);
51
- // State that holds an array of filter category IDs
52
- const [appliedGlobalFilters, setAppliedGlobalFilters] = useState([TMBlogsFilterCategoryId.PublishedBlogs]);
53
- // State to manage the focused file
54
- const [focusedBlog, setFocusedBlog] = useState(undefined);
55
- // State to manage the focused file
56
- const [focusedAttachment, setFocusedAttachment] = useState(undefined);
57
- // State to manage the focused file
58
- const [dcmtTypeDescriptors, setDcmtTypeDescriptors] = useState(new Map());
59
- // State to manage the anchor element for context menu positioning
60
- const [anchorEl, setAnchorEl] = useState(null);
61
- const contextMenuRef = useRef(null);
62
- // State to store the current header value. Initialized with the provided 'header' prop.
63
- const [currentHeader, setCurrentHeader] = useState(header);
64
- // State to track whether the header is fully hidden based on the current header value
65
- const [isHeaderHidden, setIsHeaderHidden] = useState(isHeaderFullyHidden(currentHeader));
66
- // showId is a state variable that determines whether an ID-related component or feature should be displayed
67
- const [localShowId, setLocalShowId] = useState(false);
68
- // Ref to the container
69
- const containerRef = useRef(null);
70
- // State variable to control the visibility of the wait panel.
71
- const [localShowWaitPanel, setLocalShowWaitPanel] = useState(false);
72
- // State variable to store the title of the wait panel.
73
- const [localWaitPanelTitle, setLocalWaitPanelTitle] = useState('');
74
- // State variable to control the visibility of the primary section of the wait panel.
75
- const [localShowPrimary, setLocalShowPrimary] = useState(false);
76
- // State variable to store the primary text of the wait panel.
77
- const [localWaitPanelTextPrimary, setLocalWaitPanelTextPrimary] = useState('');
78
- // State variable to track the current value of the primary progress indicator in the wait panel.
79
- const [localWaitPanelValuePrimary, setLocalWaitPanelValuePrimary] = useState(0);
80
- // State variable to define the maximum value for the primary progress indicator in the wait panel.
81
- const [localWaitPanelMaxValuePrimary, setLocalWaitPanelMaxValuePrimary] = useState(0);
82
- // Tracks whether the user has right-clicked on the background area.
83
- const [rightClickedOnBackground, setRightClickedOnBackground] = React.useState(false);
84
- // State to manage show selected file
85
- const [showDcmtForm, setShowDcmtForm] = useState(false);
86
- // Data source for the number of posts to display in the UI
87
- const postsToShowDataSource = [
88
- { value: 30, display: SDKUI_Localizator.Latest + ' 30' },
89
- { value: 50, display: SDKUI_Localizator.Latest + ' 50' },
90
- { value: 100, display: SDKUI_Localizator.Latest + ' 100' },
91
- { value: allData.length, display: SDKUI_Localizator.All },
92
- ];
93
- const toggleHeaderClick = () => {
94
- setCurrentHeader(prevState => {
95
- if (prevState === undefined) {
96
- return {
97
- showViewMode: true,
98
- showFilters: true,
99
- showSearchBar: true,
100
- showPostsDropDown: true,
101
- };
102
- }
103
- else {
104
- return {
105
- showViewMode: !prevState.showViewMode,
106
- showFilters: !prevState.showFilters,
107
- showSearchBar: !prevState.showSearchBar,
108
- showPostsDropDown: !prevState.showPostsDropDown,
109
- };
110
- }
111
- });
112
- };
113
- const deleteOrUndeleteCommentCallback = async (del) => {
114
- if (focusedBlog === undefined || focusedBlog.id === undefined)
115
- return Promise.resolve();
116
- const msg = del ? SDKUI_Localizator.DeleteComment : SDKUI_Localizator.RestoreComment;
117
- TMMessageBoxManager.show({
118
- title: del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore, message: msg, buttons: [ButtonNames.YES, ButtonNames.NO],
119
- onButtonClick: async (e) => {
120
- if (e !== ButtonNames.YES)
121
- return;
122
- if (focusedBlog === undefined || focusedBlog.id === undefined || context === undefined || context.object === undefined
123
- || (context.engine === 'WorkingGroupEngine' && !context.object.id)
124
- || (context.engine === 'SearchEngine' && (!context.object.tid || !context.object.did))
125
- || (context.engine === 'DossierEngine' && !context.object.id)) {
126
- return Promise.resolve();
127
- }
128
- setLocalWaitPanelTitle(del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore);
129
- setLocalShowWaitPanel(true);
130
- setLocalShowPrimary(true);
131
- localAbortController = new AbortController();
132
- let result = [];
133
- let i = 0;
134
- setLocalWaitPanelMaxValuePrimary(1);
135
- if (abortController.signal.aborted) {
136
- result.push({ rowIndex: i, id1: focusedBlog.id, id2: focusedBlog.id, resultType: ResultTypes.WARNING, description: `Operazione interrotta. Elaborate ${i}` });
137
- }
138
- else {
139
- setLocalWaitPanelTextPrimary(del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore);
140
- if (context.engine === 'WorkingGroupEngine' && context.object.id) {
141
- const workingGroupEngine = new WorkingGroupEngine(SDK_Globals.tmSession);
142
- await workingGroupEngine.BlogPostDeleteOrUndeleteAsync(context.object.id, focusedBlog.id, del)
143
- .then(() => {
144
- handleFocusedBlog(undefined);
145
- refresh();
146
- })
147
- .catch((err) => {
148
- result.push({ rowIndex: 1, id1: context.object?.id, id2: context.object?.id, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
149
- TMResultManager.show(result, del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore, "ID", undefined);
150
- });
151
- }
152
- else if (context.engine === 'SearchEngine' && context.object.tid && context.object.did) {
153
- const searchEngine = SDK_Globals.tmSession?.NewSearchEngine();
154
- await searchEngine.BlogPostDeleteOrUndeleteAsync(context.object.tid, context.object.did, focusedBlog.id, del)
155
- .then(() => {
156
- handleFocusedBlog(undefined);
157
- refresh();
158
- })
159
- .catch((err) => {
160
- result.push({ rowIndex: 1, id1: context.object?.tid, id2: context.object?.did, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
161
- TMResultManager.show(result, del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore, "ID", undefined);
162
- });
163
- }
164
- else if (context.engine === 'DossierEngine' && context.object.id) {
165
- const dossierEngine = SDK_Globals.tmSession?.NewDossierEngine();
166
- await dossierEngine.BlogPostDeleteOrUndeleteAsync(context.object.id, focusedBlog.id, del)
167
- .then(() => {
168
- handleFocusedBlog(undefined);
169
- refresh();
170
- })
171
- .catch((err) => {
172
- result.push({ rowIndex: 1, id1: context.object?.id, id2: context.object?.id, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
173
- TMResultManager.show(result, del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore, "ID", undefined);
174
- });
175
- }
176
- }
177
- setLocalWaitPanelTextPrimary('');
178
- setLocalWaitPanelMaxValuePrimary(0);
179
- setLocalWaitPanelValuePrimary(0);
180
- setLocalShowWaitPanel(false);
181
- }
182
- });
183
- };
184
- const handleFocusedAttachment = (attachment) => {
185
- setFocusedAttachment(attachment);
186
- if (handleAttachmentFocus)
187
- handleAttachmentFocus(attachment);
188
- };
189
- const handleFocusedBlog = (blog) => {
190
- setFocusedBlog(blog);
191
- setFocusedAttachment(undefined);
192
- if (handleAttachmentFocus)
193
- handleAttachmentFocus(undefined);
194
- if (markBlogAsRead)
195
- markBlogAsRead(blog);
196
- };
197
- const refresh = async () => {
198
- if (refreshCallback)
199
- await refreshCallback();
200
- };
201
- const downloadAttachment = () => {
202
- if (focusedAttachment === undefined)
203
- return;
204
- if (downloadDcmtsAsync)
205
- downloadDcmtsAsync([{ TID: focusedAttachment.TID, DID: focusedAttachment.DID, fileName: focusedAttachment.fileName }], DownloadTypes.Dcmt, "download");
206
- };
207
- const copyInClipboard = (blog) => {
208
- if (blog === undefined)
209
- return;
210
- const { id, ownerName, creationTime, description } = blog;
211
- const formattedText = `${ownerName} (${Globalization.getDateTimeDisplayValue(creationTime)}):\n${description}`;
212
- let result = [];
213
- window.navigator.clipboard.writeText(formattedText)
214
- .then(() => {
215
- result = [{ rowIndex: id ?? 1, id1: id ?? 1, id2: id ?? 1, description: SDKUI_Localizator.UpdateCompletedSuccessfully, resultType: ResultTypes.SUCCESS }];
216
- })
217
- .catch(err => {
218
- result = [{ rowIndex: id ?? 1, id1: id ?? 1, id2: id ?? 1, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) }];
219
- })
220
- .finally(() => {
221
- TMResultManager.show(result, SDKUI_Localizator.CopyToClipboard, "ID", undefined);
222
- });
223
- };
224
- const unFollowCallback = async (blog, classId) => {
225
- const title = SDKUI_Localizator.Unfollow;
226
- const header = blog.header ?? undefined;
227
- const message = header ? SDKUI_Localizator.UnfollowSelectedItem.replaceParams(header) : SDKUI_Localizator.Unfollow + "?";
228
- TMMessageBoxManager.show({
229
- title, message, buttons: [ButtonNames.YES, ButtonNames.NO],
230
- confirmOnEnter: true,
231
- onButtonClick: async (e) => {
232
- if (e !== ButtonNames.YES)
233
- return;
234
- let result = [];
235
- switch (classId) {
236
- case 'WG':
237
- const workingGroupEngine = new WorkingGroupEngine(SDK_Globals.tmSession);
238
- await workingGroupEngine.FollowAddOrRemoveAsync(blog.id, true).then(async () => {
239
- result.push({ rowIndex: blog.id, id1: blog.id, id2: blog.id, description: SDKUI_Localizator.OperationSuccess, resultType: ResultTypes.SUCCESS });
240
- refreshHomePageNews?.();
241
- })
242
- .catch((err) => {
243
- result.push({ rowIndex: blog.id, id1: blog.id, id2: blog.id, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
244
- });
245
- break;
246
- default:
247
- ShowAlert({ message: 'TODO', mode: 'warning', title: SDKUI_Localizator.Unfollow, duration: 3000 });
248
- break;
249
- }
250
- TMResultManager.show(result, SDKUI_Localizator.Unfollow, "ID", undefined);
251
- }
252
- });
253
- };
254
- // ContexMenuItems array contains a list of context menu items for a blog
255
- const contextMenuItems = useMemo(() => {
256
- // customData1 === 1 means the group is archived (historical)
257
- const isGroupArchived = Boolean(context && context.engine === 'WorkingGroupEngine' && context.object && context.object.customData1 === 1);
258
- const userId = SDK_Globals.tmSession?.SessionDescr?.userID;
259
- const isNotOwner = focusedBlog && focusedBlog.ownerID !== userId;
260
- const isDeleted = focusedBlog && (focusedBlog.isDel !== undefined && focusedBlog.isDel !== 0);
261
- const isInvalid = focusedBlog === undefined;
262
- const classId = focusedBlog ? focusedBlog.classID : undefined;
263
- let menuItemsElements = [
264
- {
265
- icon: "download",
266
- text: 'Download',
267
- visible: contextMenuParams.isDownloadAttachmentEnabled && focusedAttachment !== undefined,
268
- disabled: focusedAttachment === undefined,
269
- onClick: downloadAttachment,
270
- },
271
- {
272
- icon: 'eyeopen',
273
- text: SDKUI_Localizator.OpenForm,
274
- visible: contextMenuParams.isViewEditMetadata && focusedAttachment !== undefined,
275
- disabled: focusedAttachment === undefined,
276
- onClick: () => setShowDcmtForm(true),
277
- },
278
- {
279
- icon: "chat",
280
- text: SDKUI_Localizator.Comment,
281
- visible: contextMenuParams.isCommentEnabled,
282
- disabled: isGroupArchived ? true : false,
283
- onClick: () => { if (showCommentFormCallback)
284
- showCommentFormCallback(); },
285
- beginGroup: true
286
- },
287
- {
288
- icon: "trash",
289
- text: SDKUI_Localizator.Delete,
290
- visible: contextMenuParams.isDeleteEnabled,
291
- onClick: () => deleteOrUndeleteCommentCallback(true),
292
- disabled: isNotOwner || isInvalid || isDeleted || isGroupArchived,
293
- },
294
- {
295
- icon: "undo",
296
- text: SDKUI_Localizator.Restore,
297
- visible: contextMenuParams.isRestoreEnabled,
298
- onClick: () => deleteOrUndeleteCommentCallback(false),
299
- disabled: isNotOwner || isInvalid || (focusedBlog && (focusedBlog.isDel === undefined || focusedBlog.isDel === 0)),
300
- },
301
- {
302
- text: SDKUI_Localizator.CopyToClipboard,
303
- visible: contextMenuParams.isCopyToClipboardEnabled,
304
- icon: 'copy',
305
- disabled: isInvalid,
306
- onClick: () => { copyInClipboard(focusedBlog); }
307
- },
308
- {
309
- text: SDKUI_Localizator.CreateContextualTask,
310
- icon: 'plus',
311
- onClick: () => { if (showTaskFormCallback)
312
- showTaskFormCallback(); },
313
- visible: contextMenuParams.isCreateContextualTask,
314
- disabled: isGroupArchived ? true : false,
315
- beginGroup: true
316
- },
317
- {
318
- icon: "eyeclose",
319
- text: SDKUI_Localizator.Unfollow,
320
- visible: Boolean(classId && classId === 'WG'),
321
- onClick: () => focusedBlog && classId && unFollowCallback(focusedBlog, classId),
322
- },
323
- {
324
- icon: isHeaderHidden ? 'eyeopen' : 'eyeclose',
325
- text: isHeaderHidden ? SDKUI_Localizator.ShowFilters : SDKUI_Localizator.HideFilters,
326
- visible: contextMenuParams.isShowHideFilterEnabled,
327
- onClick: toggleHeaderClick,
328
- disabled: false,
329
- beginGroup: true
330
- },
331
- {
332
- icon: localShowId ? 'eyeclose' : 'eyeopen',
333
- onClick: () => setLocalShowId(prevShowId => !prevShowId),
334
- text: localShowId ? SDKUI_Localizator.ID_Hide : SDKUI_Localizator.ID_Show,
335
- visible: contextMenuParams.isShowHideIDEnaled,
336
- disabled: false,
337
- },
338
- {
339
- icon: "refresh",
340
- text: SDKUI_Localizator.Refresh,
341
- visible: contextMenuParams.isRefreshEnabled,
342
- onClick: refresh,
343
- disabled: false,
344
- },
345
- ];
346
- return menuItemsElements.filter(item => item.visible);
347
- }, [isHeaderHidden, localShowId, setLocalShowId, focusedBlog, focusedAttachment, showDcmtForm]);
348
- useEffect(() => {
349
- setUiId(genUniqueId());
350
- }, []);
351
- useEffect(() => {
352
- if (showId !== undefined)
353
- setLocalShowId(showId);
354
- }, [showId]);
355
- useEffect(() => {
356
- if (setShowId)
357
- setShowId(localShowId);
358
- }, [localShowId]);
359
- useEffect(() => {
360
- setIsHeaderHidden(isHeaderFullyHidden(currentHeader));
361
- }, [currentHeader]);
362
- const getDcmtTypeDescriptor = async (blogPosts) => {
363
- // Create a Map to store tid as key and DcmtTypeDescriptor as value
364
- const dcmtTypeMap = new Map();
365
- for (const blogPost of blogPosts) {
366
- if (blogPost.attachments) {
367
- for (const attachment of blogPost.attachments) {
368
- const dcmtTypeDescriptor = await DcmtTypeListCacheService.GetAsync(attachment.tid, true);
369
- if (dcmtTypeDescriptor && attachment.tid) {
370
- dcmtTypeMap.set(attachment.tid, dcmtTypeDescriptor);
371
- }
372
- }
373
- }
374
- }
375
- return dcmtTypeMap;
376
- };
377
- useEffect(() => {
378
- const fetchDcmtTypeDescriptor = async () => {
379
- const descriptors = await getDcmtTypeDescriptor(blogPosts);
380
- setDcmtTypeDescriptors(descriptors);
381
- };
382
- showExtendedAttachments && fetchDcmtTypeDescriptor();
383
- if (updateVisualizedBlogCallback)
384
- updateVisualizedBlogCallback(blogPosts);
385
- }, [blogPosts]);
386
- useEffect(() => {
387
- const publishedBlogssLength = allData.filter(newsFeed => newsFeed.isSys !== 1 && newsFeed.isDel !== 1).length;
388
- const systemBlogsLength = allData.filter(newsFeed => newsFeed.isSys === 1).length;
389
- const deletedBlogsLength = allData.filter(newsFeed => newsFeed.isDel === 1).length;
390
- setTreeDataSource([
391
- {
392
- id: TMBlogsFilterCategoryId.PublishedBlogs,
393
- label: SDKUI_Localizator.Active + " (" + publishedBlogssLength + ")",
394
- value: SDKUI_Localizator.Active,
395
- },
396
- {
397
- id: TMBlogsFilterCategoryId.SystemBlogs,
398
- label: SDKUI_Localizator.OfSystem + " (" + systemBlogsLength + ")",
399
- value: SDKUI_Localizator.OfSystem,
400
- },
401
- {
402
- id: TMBlogsFilterCategoryId.DeletedBlogs,
403
- label: SDKUI_Localizator.Deleted + " (" + deletedBlogsLength + ")",
404
- value: SDKUI_Localizator.Deleted,
405
- },
406
- ]);
407
- }, [allData]);
408
- useEffect(() => {
409
- // Helper function to check if a blog post is a system blog
410
- const isActiveBlog = (blog) => blog.isSys !== 1 && blog.isDel !== 1;
411
- // Helper function to check if a blog post is a system blog
412
- const isSystemBlog = (blog) => blog.isSys === 1;
413
- // Helper function to check if a blog post is marked as deleted
414
- const isDeletedBlog = (blog) => blog.isDel === 1;
415
- // Create a mapping of filter category IDs to their corresponding filter functions
416
- const filters = {
417
- [TMBlogsFilterCategoryId.PublishedBlogs]: isActiveBlog, // Map PublishedBlogs filter to the isActiveBlog function
418
- [TMBlogsFilterCategoryId.SystemBlogs]: isSystemBlog, // Map SystemBlogs filter to the isSystemBlog function
419
- [TMBlogsFilterCategoryId.DeletedBlogs]: isDeletedBlog, // Map DeletedBlogs filter to the isDeletedBlog function
420
- };
421
- // Function to apply filters to a single blog post
422
- const applyFilters = (newsFeed) => {
423
- // Check if the blog post matches the search text (case insensitive)
424
- if (searchText && !(newsFeed.ownerName?.toLowerCase().includes(searchText.toLowerCase().trim())
425
- || newsFeed.description?.toLowerCase().includes(searchText.toLowerCase().trim())
426
- || newsFeed.id?.toString()?.toLowerCase().includes(searchText.toLowerCase().trim())
427
- || Globalization.getDateTimeDisplayValue(newsFeed.creationTime)?.toString()?.toLowerCase().includes(searchText.toLowerCase().trim())
428
- || newsFeed.header?.toString()?.toLowerCase().includes(searchText.toLowerCase().trim())
429
- || (newsFeed.attachments && newsFeed.attachments?.length > 0 && newsFeed.attachments.some((attachment) => findFileItemByDraftID(treeFs, attachment.draftID)?.name?.toLowerCase().includes(searchText.toLowerCase().trim())))
430
- || (newsFeed.attachments && newsFeed.attachments?.length > 0 && newsFeed.attachments.some((attachment) => attachment.tid && dcmtTypeDescriptors.get(attachment.tid)?.name?.toLowerCase().includes(searchText.toLowerCase().trim()))))) {
431
- return false; // If the blog post doesn't match the search text, filter it out
432
- }
433
- // If no global filters are applied, exclude system and deleted blogs by default
434
- if (appliedGlobalFilters.length === 0) {
435
- return !isActiveBlog(newsFeed) && !isSystemBlog(newsFeed) && !isDeletedBlog(newsFeed);
436
- }
437
- // Check if the blog post matches any of the applied global filters
438
- const matchesFilter = appliedGlobalFilters.some((filter) => filters[filter](newsFeed));
439
- // Return true if it matches any applied filter or if it's neither a system nor a deleted blog
440
- return matchesFilter || (!isActiveBlog(newsFeed) && !isSystemBlog(newsFeed) && !isDeletedBlog(newsFeed));
441
- };
442
- // Apply the filter logic to the complete list of blogs
443
- let filteredBlogs = allData.filter(applyFilters);
444
- if (currentHeader && currentHeader.showPostsDropDown) {
445
- // Limit the results to the most recent postsToShow number of posts if the condition is true
446
- filteredBlogs = filteredBlogs.slice(-postsToShow);
447
- }
448
- // Update the state with the filtered and limited list of blogs
449
- setBlogPosts(filteredBlogs);
450
- setFirstNewPost(filteredBlogs.find(blog => blog.customData1 === 1));
451
- if (focusedBlog && focusedBlog.id && filteredBlogs.find(filteredBlog => focusedBlog.id === filteredBlog.id) === undefined)
452
- handleFocusedBlog(undefined);
453
- }, [allData, appliedGlobalFilters, searchText, postsToShow, currentHeader]);
454
- useEffect(() => {
455
- // Check if we should auto-select the last blog post
456
- if (shouldSelectLastBlog && updateShouldSelectLastBlog && blogPosts.length > 0) {
457
- // Reset the flag to prevent re-selecting in future renders
458
- updateShouldSelectLastBlog(false);
459
- // Set the focus to the last blog post in the array
460
- handleFocusedBlog(blogPosts[blogPosts.length - 1]);
461
- }
462
- }, [shouldSelectLastBlog, blogPosts]);
463
- const ThumbnailView = () => {
464
- const scrollRef = useRef(null);
465
- useEffect(() => {
466
- // Check if there's a focused blog post, its ID is valid, and the scroll container exists
467
- if (focusedBlog && focusedBlog.id && scrollRef.current) {
468
- const container = scrollRef.current;
469
- // Find the DOM element for the focused blog using its composed ID
470
- const focusedElement = document.getElementById(id + "-" + uiId + "-" + focusedBlog.id.toString());
471
- if (focusedElement) {
472
- // Get the position of the container and the focused element
473
- const containerRect = container.getBoundingClientRect();
474
- const elRect = focusedElement.getBoundingClientRect();
475
- // Calculate the offset needed to center the focused element in the container
476
- const offset = elRect.top - containerRect.top - container.clientHeight / 2 + focusedElement.clientHeight / 2;
477
- // Scroll the container to center the focused element smoothly
478
- container.scrollTo({ top: container.scrollTop + offset, behavior: 'smooth', });
479
- }
480
- }
481
- else {
482
- // If there's no focused blog and the user didn't right-click on the background, and the scroll flag is set, scroll to the bottom of the container
483
- if (!rightClickedOnBackground && scrollToBottom && scrollRef.current) {
484
- scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
485
- }
486
- }
487
- }, [blogPosts, focusedBlog, rightClickedOnBackground]);
488
- const attachmentDetails = (attachments, isSelected) => {
489
- return _jsx("div", { style: { marginTop: "5px", overflow: "hidden" }, children: attachments.map(attachment => {
490
- return AttachmentElement(attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText, color, setShowDcmtForm, handleFocusedAttachment, setAnchorEl, contextMenuRef);
491
- }) });
492
- };
493
- const renderBlogPostContent = (blogPost, index, isOwnComment) => {
494
- const isSelected = focusedBlog?.id === blogPost.id;
495
- const isNew = Boolean((blogPost.newPosts ?? 0) || blogPost.customData1);
496
- const backgroundColors = {
497
- default: layoutMode === 'stacked' ? colors.LIGHT_GRAY : isOwnComment ? '#D9EFE0' : '#F3E6E6',
498
- selectedItems: isSelected ? color ?? colors.PRIMARY_BLUE : colors.PRIMARY_BLUE,
499
- };
500
- let bgColor = isSelected ? backgroundColors.selectedItems : backgroundColors.default;
501
- let textColor = blogPost.isSys ? colors.RED : isSelected ? colors.WHITE : colors.BLACK;
502
- let iconColor = textColor;
503
- const classID = blogPost.classID;
504
- if (classID) {
505
- if (classID === 'DS')
506
- iconColor = isSelected ? colors.WHITE : colors.PRIMARY_ORANGE;
507
- if (classID === 'WG')
508
- iconColor = isSelected ? colors.WHITE : colors.PRIMARY_GREEN;
509
- }
510
- const canNavigate = () => {
511
- return Boolean(handleNavigateToWGs && id && classID === 'WG');
512
- };
513
- const headerClickCallback = () => {
514
- const id = blogPost.id;
515
- if (handleNavigateToWGs && id && classID === 'WG')
516
- handleNavigateToWGs(id);
517
- };
518
- const onClickCallback = () => {
519
- handleFocusedBlog(blogPost);
520
- };
521
- const handleKeyDown = (event) => {
522
- event.preventDefault();
523
- if (!focusedBlog)
524
- return;
525
- const currentIndex = blogPosts.findIndex(post => post.id === focusedBlog.id);
526
- if (currentIndex === -1)
527
- return;
528
- switch (event.key) {
529
- case 'ArrowDown':
530
- const nextItem = blogPosts[currentIndex + 1];
531
- if (nextItem)
532
- handleFocusedBlog(nextItem);
533
- break;
534
- case 'Enter':
535
- const item = blogPosts[currentIndex];
536
- const classItemID = item.classID;
537
- if (handleNavigateToWGs && item.id && classItemID === 'WG')
538
- handleNavigateToWGs(item.id);
539
- break;
540
- default:
541
- break;
542
- }
543
- };
544
- const handleKeyUp = (event) => {
545
- event.preventDefault();
546
- if (event.key === 'ArrowUp' && focusedBlog) {
547
- const currentIndex = blogPosts.findIndex(post => post.id === focusedBlog.id);
548
- if (blogPosts[currentIndex - 1]) {
549
- handleFocusedBlog(blogPosts[currentIndex - 1]);
550
- }
551
- ;
552
- }
553
- };
554
- const onContextMenu = (e) => {
555
- e.preventDefault();
556
- setAnchorEl(e.currentTarget);
557
- handleFocusedBlog(blogPost);
558
- handleFocusedAttachment(undefined);
559
- };
560
- return (_jsxs(BlogPostContainer, { className: "blog-post-container", id: id + "-" + uiId + "-" + blogPost.id.toString(), ref: containerRef, "$color": textColor, "$textDecoration": blogPost.isDel ? 'line-through' : 'none', "$backgroundColor": bgColor, "$paddingRight": layoutMode === 'chat' ? isOwnComment ? '50px' : '10px' : '10px', "$canNavigate": canNavigate(), onClick: onClickCallback, onDoubleClick: headerClickCallback, tabIndex: 0, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onContextMenu: onContextMenu, children: [_jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [(layoutMode !== 'chat' || !isOwnComment) && OwnerInitialsBadge(blogPost), _jsx("div", { style: { flex: "1 1 auto", minWidth: "0" }, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: "wrap", /* overflow: "hidden" */ }, children: [_jsxs("div", { style: { flex: "1 1 auto", minWidth: "0" }, children: [_jsxs("div", { style: {
561
- fontWeight: "bold",
562
- fontSize: '1rem',
563
- display: "flex",
564
- alignItems: "center",
565
- justifyContent: "space-between",
566
- gap: "8px",
567
- flexWrap: "wrap"
568
- }, children: [_jsxs("div", { style: { display: "flex", alignItems: "center", flex: "1 1 auto", minWidth: 0 }, children: [showIconHeader && blogPost.header && blogPost.classID
569
- ? IconAndHeaderElement(blogPost, iconColor, isSelected, () => {
570
- if (handleNavigateToWGs && blogPost.id && blogPost.classID === 'WG') {
571
- handleNavigateToWGs(blogPost.id);
572
- }
573
- }, searchText)
574
- : !isOwnComment && (_jsx("span", { style: {
575
- marginLeft: showIconHeader ? "5px" : "0",
576
- color: isSelected ? "#fff" : !blogPost.isSys ? TMColors.primary : colors.RED
577
- }, children: highlightText(blogPost.ownerName ?? '', searchText, isSelected) })), (blogPost?.newPosts ?? 0) > 0 && (_jsx("div", { style: {
578
- marginLeft: "5px",
579
- minWidth: "20px",
580
- height: "20px",
581
- padding: "0 6px",
582
- display: "flex",
583
- alignItems: "center",
584
- justifyContent: "center",
585
- backgroundColor: isSelected ? '#fff' : color,
586
- color: isSelected ? color : "#fff",
587
- boxShadow: "1px 1px 2px #00000020",
588
- borderRadius: "30px",
589
- fontWeight: "bold",
590
- fontSize: "12px",
591
- whiteSpace: "nowrap",
592
- }, children: blogPost.newPosts }))] }), isNew && (_jsx("span", { style: {
593
- backgroundColor: '#f09c0a',
594
- color: '#fff',
595
- borderRadius: '12px',
596
- padding: '2px 8px',
597
- boxShadow: '0 2px 5px rgba(0,0,0,0.15)',
598
- userSelect: 'none',
599
- whiteSpace: 'nowrap',
600
- display: 'inline-flex',
601
- alignItems: 'center',
602
- justifyContent: 'center',
603
- fontSize: '0.9rem',
604
- minWidth: "50px",
605
- maxWidth: "65px",
606
- overflow: 'hidden',
607
- textOverflow: 'ellipsis',
608
- // transform: layoutMode === 'chat' ? 'translate(45px, 0px)' : undefined
609
- transform: layoutMode === 'chat' ? 'translate(5px, -5px)' : undefined
610
- }, children: SDKUI_Localizator.New }))] }), _jsxs("div", { style: {
611
- fontSize: 'calc(1rem - 1px)',
612
- color: isSelected ? "#fff" : !blogPost.isSys ? TMColors.primary : colors.RED
613
- }, children: [(showIconHeader) && blogPost.header && blogPost.classID &&
614
- _jsxs(_Fragment, { children: [_jsx("span", { style: { marginLeft: showIconHeader ? "5px" : "0" }, children: blogPost.ownerName }), _jsx("span", { style: { margin: "0 5px" }, children: "\u2501" })] }), blogPost.creationTime && highlightText(`${Globalization.getDateTimeDisplayValue(blogPost.creationTime)} ${new Date(blogPost.creationTime).toDateString() === new Date().toDateString()
615
- ? `(${SDKUI_Localizator.Today})`
616
- : ''}`, searchText, isSelected), localShowId && (_jsxs(_Fragment, { children: [_jsx("span", { style: { margin: "0 5px" }, children: "\u2501" }), _jsxs("span", { children: ["(ID: ", blogPost.id, ")"] })] }))] })] }), blogPost.attachments && showExtendedAttachments === false && (_jsx("div", { style: { marginTop: "25px", fontSize: "13px", display: "flex", justifyContent: "flex-end" }, children: _jsx(TMTooltip, { content: `${SDKUI_Localizator.Attachments}: ${blogPost.attachments.length}`, children: _jsx(IconAttachment, { fontSize: 20, color: isSelected ? '#fff' : color }) }) }))] }) })] }), _jsx("div", { style: { marginTop: "10px", fontSize: '1rem' }, children: _jsx(TMHtmlContentDisplay, { markup: blogPost.description ?? '-', searchText: searchText, isSelected: isSelected }) }), showExtendedAttachments && blogPost.attachments && blogPost.attachments.length > 0 && attachmentDetails(blogPost.attachments, isSelected)] }, id + "-" + uiId + "-" + blogPost.id));
617
- };
618
- return _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx("div", { ref: scrollRef, style: { backgroundColor: layoutMode === "stacked" ? "rgba(191, 191, 191, 0.15)" : '#fff', height: "100%", padding: "5px", overflowY: "auto", width: "100%" }, children: blogPosts.length === 0 ?
619
- _jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%' }, children: [_jsx(IconBoard, { fontSize: 96 }), searchText.length > 0 ?
620
- _jsx("div", { style: { fontSize: "15px", marginTop: "10px" }, children: SDKUI_Localizator.NoMessagesFound }) :
621
- _jsx("div", { style: { fontSize: "15px", marginTop: "10px" }, children: SDKUI_Localizator.NoMessages })] })
622
- : blogPosts.map((blogPost, index) => {
623
- const isOwnComment = blogPost.ownerID === SDK_Globals.tmSession?.SessionDescr?.userID;
624
- return (_jsxs(React.Fragment, { children: [(firstNewPost && blogPost.id === firstNewPost.id) && (_jsxs("div", { style: { display: 'flex', alignItems: 'center', width: '100%', color: TMColors.primary, fontWeight: '600', fontSize: '0.9rem', userSelect: 'none', marginTop: "12px", marginBottom: "12px" }, children: [_jsx("hr", { style: { flex: 1, border: 'none', borderTop: `1px solid ${TMColors.primary}`, marginRight: '15px' } }), _jsx("span", { children: SDKUI_Localizator.LastRead }), _jsx("hr", { style: { flex: 1, border: 'none', borderTop: `1px solid ${TMColors.primary}`, marginLeft: '15px' } })] })), layoutMode === 'stacked' ? renderBlogPostContent(blogPost, index, isOwnComment) :
625
- _jsx("div", { style: {
626
- display: "flex",
627
- flexDirection: "row",
628
- alignItems: "flex-start",
629
- padding: "2px",
630
- borderRadius: "12px",
631
- cursor: "default",
632
- justifyContent: isOwnComment ? "flex-end" : "flex-start",
633
- }, children: _jsx("div", { style: {
634
- display: "flex",
635
- flexDirection: "column",
636
- alignItems: isOwnComment ? "flex-end" : "flex-start",
637
- textAlign: "left",
638
- maxWidth: '90%',
639
- borderRadius: '8px',
640
- }, children: renderBlogPostContent(blogPost, index, isOwnComment) }) })] }, "blog-post-wrapper-" + id + "-" + blogPost.id));
641
- }) }) });
642
- };
643
- // Function to handle changes in the search text
644
- const handleSearchChange = (value) => {
645
- handleFocusedBlog(undefined);
646
- setSearchText(value); // Update the search text state with the new value
647
- };
648
- // Function to handle changes in the filter (number of posts to show)
649
- const handleFilterChange = (e) => {
650
- if (!e?.target?.value)
651
- return;
652
- const value = e.target.value;
653
- if (value !== undefined) {
654
- setPostsToShow(Number(value));
655
- }
656
- };
657
- // Handle closing the context menu
658
- const closeContextMenu = useCallback(() => {
659
- setAnchorEl(null);
660
- }, []);
661
- const onBackgroundContextMenu = (event) => {
662
- if (event === undefined)
663
- return;
664
- if (event.target.closest('.blog-post-container'))
665
- return;
666
- event.preventDefault();
667
- setAnchorEl(event.currentTarget);
668
- handleFocusedBlog(undefined);
669
- handleFocusedAttachment(undefined);
670
- setRightClickedOnBackground(true);
671
- };
672
- const onCloseDcmtForm = useCallback(() => {
673
- setShowDcmtForm(false);
674
- handleFocusedAttachment(undefined);
675
- }, []);
676
- return _jsxs("div", { style: { height: height ?? '100%', width: width ?? '100%' }, children: [_jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: localShowWaitPanel, showWaitPanelPrimary: localShowPrimary, waitPanelTitle: localWaitPanelTitle, waitPanelTextPrimary: localWaitPanelTextPrimary, waitPanelValuePrimary: localWaitPanelValuePrimary, waitPanelMaxValuePrimary: localWaitPanelMaxValuePrimary, isCancelable: true, abortController: localAbortController, children: [(currentHeader && !isHeaderHidden) && (_jsx("div", { style: { display: 'block', width: '100%', overflowX: 'auto', overflowY: 'hidden', whiteSpace: 'nowrap' }, onContextMenu: e => e.preventDefault(), children: _jsx(ScrollView, { width: "100%", height: "auto", direction: "horizontal", useNative: true, children: _jsxs("div", { style: {
677
- display: 'flex',
678
- flexDirection: 'row',
679
- gap: '8px',
680
- alignItems: 'center',
681
- minWidth: 'max-content',
682
- padding: '10px 0',
683
- }, children: [currentHeader.showSearchBar && (_jsx("div", { style: {
684
- minWidth: isMobile ? '120px' : '160px',
685
- maxWidth: isMobile ? '120px' : '200px',
686
- marginLeft: "10px"
687
- }, children: _jsx(TMSearchBar, { marginLeft: "0px", maxWidth: "100%", searchValue: searchText, onSearchValueChanged: (e) => handleSearchChange(e) }) })), currentHeader.showPostsDropDown && (_jsx("div", { style: {
688
- minWidth: isMobile ? '90px' : '120px',
689
- maxWidth: isMobile ? '90px' : '200px',
690
- }, children: _jsx(TMDropDown, { value: postsToShow, dataSource: postsToShowDataSource, onValueChanged: handleFilterChange }) })), currentHeader.showFilters && (_jsx(TMTreeDropDown, { dataSource: treeDataSource, values: appliedGlobalFilters, setValues: setAppliedGlobalFilters, displayExpr: false, isValidKey: () => true, elementStyle: {
691
- minWidth: isMobile ? '90px' : '120px',
692
- width: isMobile ? '90px' : '150px',
693
- height: '29px',
694
- } }))] }) }) })), _jsxs("div", { style: { height: `calc(100% - ${currentHeader && !isHeaderHidden ? '50px' : '0px'})`, width: "100%", overflow: 'auto', display: 'block' }, onContextMenu: onBackgroundContextMenu, children: [_jsx("div", { style: { width: "100%", height: "100%" }, children: ThumbnailView() }), anchorEl && _jsx(ContextMenu, { ref: contextMenuRef, dataSource: contextMenuItems, target: anchorEl, onHiding: closeContextMenu })] }), (showDcmtForm && focusedAttachment && focusedAttachment.TID && focusedAttachment.DID) && _jsx(TMDcmtForm, { TID: Number(focusedAttachment.TID), DID: Number(focusedAttachment.DID), layoutMode: LayoutModes.Update, onClose: onCloseDcmtForm, isClosable: true, titleModal: SDKUI_Localizator.Attachment + ": " + focusedAttachment.fileName, isModal: true, widthModal: "95%", heightModal: "95%" })] }), (showFloatingCommentButton && showCommentFormCallback && !(context?.engine === 'WorkingGroupEngine' && context?.object?.customData1 === 1)) && _jsx("button", { style: {
695
- position: 'absolute',
696
- bottom: '18px',
697
- right: '20px',
698
- width: '40px',
699
- height: '40px',
700
- borderRadius: "50%",
701
- backgroundColor: "#C2388B",
702
- color: '#fff',
703
- border: 'none',
704
- cursor: 'pointer',
705
- boxShadow: '0 2px 6px rgba(0,0,0,0.2)',
706
- zIndex: 1000,
707
- transition: 'background-color 0.3s ease, transform 0.2s ease',
708
- display: 'flex',
709
- justifyContent: 'center',
710
- alignItems: 'center',
711
- }, onMouseEnter: (e) => {
712
- e.currentTarget.style.backgroundColor = '#D94A9F';
713
- e.currentTarget.style.transform = 'scale(1.1)';
714
- e.currentTarget.style.boxShadow = '0 4px 12px rgba(37, 89, 165, 0.6)';
715
- }, onMouseLeave: (e) => {
716
- e.currentTarget.style.backgroundColor = "#C2388B";
717
- e.currentTarget.style.transform = 'scale(1)';
718
- e.currentTarget.style.boxShadow = '0 2px 6px rgba(0,0,0,0.2)';
719
- }, onClick: () => { showCommentFormCallback(); }, children: _jsx(TMTooltip, { content: SDKUI_Localizator.AddNewComment, children: _jsx("i", { className: "dx-icon-chat", style: { fontSize: '25px' } }) }) })] });
720
- };
721
- export default TMBlogs;