@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.
- package/lib/components/base/Styled.d.ts +1 -0
- package/lib/components/base/Styled.js +40 -0
- package/lib/components/base/TMCustomButton.d.ts +11 -0
- package/lib/components/base/TMCustomButton.js +63 -0
- package/lib/components/base/TMFileManagerDataGridView.js +4 -1
- package/lib/components/base/TMLayout.d.ts +2 -1
- package/lib/components/base/TMLayout.js +2 -2
- package/lib/components/base/TMPopUp.js +5 -18
- package/lib/components/base/TMTreeView.js +3 -2
- package/lib/components/editors/TMHtmlEditor.d.ts +5 -0
- package/lib/components/editors/TMHtmlEditor.js +72 -12
- package/lib/components/editors/TMMetadataValues.js +90 -40
- package/lib/components/features/archive/TMArchive.d.ts +10 -0
- package/lib/components/features/archive/TMArchive.js +56 -25
- package/lib/components/features/blog/TMBlogCommentForm.d.ts +4 -4
- package/lib/components/features/blog/TMBlogCommentForm.js +76 -51
- package/lib/components/features/documents/TMDcmtBlog.d.ts +15 -0
- package/lib/components/features/documents/TMDcmtBlog.js +21 -33
- package/lib/components/features/documents/TMDcmtForm.d.ts +17 -3
- package/lib/components/features/documents/TMDcmtForm.js +205 -46
- package/lib/components/features/documents/TMDcmtTasks.d.ts +13 -0
- package/lib/components/features/documents/TMDcmtTasks.js +24 -0
- package/lib/components/features/documents/TMDragDropOverlay.js +2 -1
- package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +8 -1
- package/lib/components/features/documents/TMMasterDetailDcmts.js +6 -6
- package/lib/components/features/documents/TMRelationViewer.d.ts +53 -3
- package/lib/components/features/documents/TMRelationViewer.js +232 -85
- package/lib/components/features/search/TMSearch.d.ts +10 -1
- package/lib/components/features/search/TMSearch.js +14 -5
- package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -1
- package/lib/components/features/search/TMSearchQueryPanel.js +36 -7
- package/lib/components/features/search/TMSearchResult.d.ts +10 -1
- package/lib/components/features/search/TMSearchResult.js +140 -422
- package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -2
- package/lib/components/features/search/TMSearchResultsMenuItems.js +33 -8
- package/lib/components/features/tasks/TMTaskForm.d.ts +38 -0
- package/lib/components/features/tasks/TMTaskForm.js +386 -0
- package/lib/components/features/tasks/TMTasksAgenda.d.ts +17 -0
- package/lib/components/features/tasks/TMTasksAgenda.js +107 -0
- package/lib/components/features/tasks/TMTasksCalendar.d.ts +21 -0
- package/lib/components/features/tasks/TMTasksCalendar.js +240 -0
- package/lib/components/features/tasks/TMTasksHeader.d.ts +14 -0
- package/lib/components/features/tasks/TMTasksHeader.js +37 -0
- package/lib/components/features/tasks/TMTasksPanelContent.d.ts +20 -0
- package/lib/components/features/tasks/TMTasksPanelContent.js +65 -0
- package/lib/components/features/tasks/TMTasksUtils.d.ts +132 -0
- package/lib/components/features/tasks/TMTasksUtils.js +634 -0
- package/lib/components/features/tasks/TMTasksUtilsView.d.ts +39 -0
- package/lib/components/features/tasks/TMTasksUtilsView.js +118 -0
- package/lib/components/features/tasks/TMTasksView.d.ts +40 -0
- package/lib/components/features/tasks/TMTasksView.js +560 -0
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +3 -1
- package/lib/components/features/workflow/TMWorkflowPopup.js +19 -6
- package/lib/components/features/workflow/diagram/RecipientList.js +4 -3
- package/lib/components/forms/Login/Chooser.js +1 -1
- package/lib/components/forms/TMChooserForm.d.ts +1 -1
- package/lib/components/forms/TMChooserForm.js +2 -2
- package/lib/components/grids/TMBlogAttachments.d.ts +42 -0
- package/lib/components/grids/TMBlogAttachments.js +43 -0
- package/lib/components/grids/TMBlogHeader.d.ts +31 -0
- package/lib/components/grids/TMBlogHeader.js +41 -0
- package/lib/components/grids/{TMBlogs.d.ts → TMBlogsPost.d.ts} +42 -58
- package/lib/components/grids/TMBlogsPost.js +628 -0
- package/lib/components/grids/{TMBlogsUtils.d.ts → TMBlogsPostUtils.d.ts} +61 -47
- package/lib/components/grids/{TMBlogsUtils.js → TMBlogsPostUtils.js} +146 -124
- package/lib/components/index.d.ts +14 -1
- package/lib/components/index.js +15 -1
- package/lib/components/layout/panelManager/TMPanelManagerContext.js +7 -0
- package/lib/components/settings/SettingsAppearance.js +8 -0
- package/lib/components/viewers/TMTidViewer.js +20 -2
- package/lib/css/tm-sdkui.css +1 -1
- package/lib/helper/SDKUI_Globals.d.ts +4 -1
- package/lib/helper/SDKUI_Globals.js +10 -1
- package/lib/helper/SDKUI_Localizator.d.ts +62 -4
- package/lib/helper/SDKUI_Localizator.js +618 -25
- package/lib/helper/TMCustomSearchBar.d.ts +8 -0
- package/lib/helper/TMCustomSearchBar.js +54 -0
- package/lib/helper/TMIcons.d.ts +2 -0
- package/lib/helper/TMIcons.js +6 -0
- package/lib/helper/TMImageLibrary.d.ts +3 -2
- package/lib/helper/TMImageLibrary.js +230 -230
- package/lib/helper/TMToppyMessage.d.ts +7 -0
- package/lib/helper/TMToppyMessage.js +42 -0
- package/lib/helper/TMUtils.d.ts +10 -1
- package/lib/helper/TMUtils.js +42 -1
- package/lib/helper/dcmtsHelper.d.ts +2 -0
- package/lib/helper/dcmtsHelper.js +18 -0
- package/lib/helper/helpers.js +1 -0
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/hooks/useRelatedDocuments.d.ts +72 -0
- package/lib/hooks/useRelatedDocuments.js +655 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/ts/types.d.ts +14 -0
- package/lib/ts/types.js +15 -0
- package/lib/utils/theme.d.ts +1 -0
- package/lib/utils/theme.js +1 -0
- package/package.json +7 -7
- package/lib/components/grids/TMBlogs.js +0 -721
- package/lib/stories/TMButton.stories.d.ts +0 -4
- package/lib/stories/TMButton.stories.js +0 -29
- package/lib/stories/TMDataGrid.stories.d.ts +0 -9
- package/lib/stories/TMDataGrid.stories.js +0 -310
- package/lib/stories/TMHtmlContentDisplay.stories.d.ts +0 -6
- package/lib/stories/TMHtmlContentDisplay.stories.js +0 -45
- package/lib/stories/TMHtmlEditor.stories.d.ts +0 -6
- package/lib/stories/TMHtmlEditor.stories.js +0 -49
- package/lib/stories/TMIcons.stories.d.ts +0 -4
- package/lib/stories/TMIcons.stories.js +0 -13
- package/lib/stories/TMSDKUI_Localizator.stories.d.ts +0 -4
- package/lib/stories/TMSDKUI_Localizator.stories.js +0 -123
- package/lib/stories/TMStoriesUtils.d.ts +0 -1
- package/lib/stories/TMStoriesUtils.js +0 -10
- package/lib/stories/TMUserAvatar.stories.d.ts +0 -6
- 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;
|