@topconsultnpm/sdkui-react-beta 6.14.76 → 6.14.78

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.
@@ -84,7 +84,6 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
84
84
  return;
85
85
  if (!currentDTD)
86
86
  return;
87
- console.log('TMMetadataValues: metadataValues', metadataValues);
88
87
  //if no dynamic data list has changed we do not call APIs
89
88
  if (deepCompare(metadataValues.filter(o => o.md?.dataDomain === MetadataDataDomains.DynamicDataList), prevMetadataValues.filter(o => o.md?.dataDomain === MetadataDataDomains.DynamicDataList)))
90
89
  return;
@@ -80,7 +80,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
80
80
  setFetchError(null); // reset errore prima del fetch
81
81
  if (!TID)
82
82
  return;
83
- if (!DID)
83
+ if (!DID && layoutMode === LayoutModes.Update)
84
84
  return;
85
85
  TMSpinner.show({ description: 'Loading Metadata...' });
86
86
  let getMetadataResult;
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useState } from 'react';
3
3
  import { PlatformObjectValidator, WhereItem, SDK_Localizator, OrderByItem, SelectItem, SelectItemVisibilities, SDK_Globals, SavedQueryCacheService, SearchEngine, QueryOperators } from '@topconsultnpm/sdk-ts-beta';
4
4
  import styled from 'styled-components';
5
5
  import TMSearchQueryEditor from './TMSearchQueryEditor';
6
- import Logo from '../../../assets/Toppy-generico.png';
6
+ import Toppy from '../../../assets/Toppy-generico.png';
7
7
  import { getDcmtTypesByQdAsync, SDKUI_Localizator, getQD, IconMenuVertical, IconAddCircleOutline, IconEdit, IconEasy, IconAdvanced, deepCompare, IconSearch, IconClear, getDefaultOperator, prepareQdForSearchAsync, IsParametricQuery, SDKUI_Globals, IconArrowRight } from '../../../helper';
8
8
  import { useQueryParametersDialog } from '../../../hooks/useQueryParametersDialog';
9
9
  import { FormModes } from '../../../ts';
@@ -13,7 +13,7 @@ import ShowAlert from '../../base/TMAlert';
13
13
  import TMButton from '../../base/TMButton';
14
14
  import { useDeviceType, DeviceType } from '../../base/TMDeviceProvider';
15
15
  import TMDropDownMenu from '../../base/TMDropDownMenu';
16
- import TMLayoutContainer, { TMLayoutItem } from '../../base/TMLayout';
16
+ import TMLayoutContainer from '../../base/TMLayout';
17
17
  import { TMExceptionBoxManager } from '../../base/TMPopUp';
18
18
  import TMSpinner from '../../base/TMSpinner';
19
19
  import TMPanel from '../../base/TMPanel';
@@ -248,7 +248,7 @@ const TMSearchQueryPanel = ({ fromDTD, showBackToResultButton, isExpertMode = SD
248
248
  _jsx(TMMetadataChooserForm, { allowMultipleSelection: true, height: '500px', width: '600px', allowSysMetadata: true, qd: qd, selectedIDs: qd?.select?.map((item) => ({ tid: item.tid, mid: item.mid })), onClose: handleCloseOutputConfig, onChoose: handleChooseOutput }), showOrderByConfig &&
249
249
  _jsx(TMMetadataChooserForm, { allowMultipleSelection: true, height: '500px', width: '600px', allowSysMetadata: true, qd: qd, selectedIDs: qd?.orderBy?.map((item) => ({ tid: item.tid, mid: item.mid })), onClose: handleCloseOrderByConfig, onChoose: handleChooseOrderBy })] })
250
250
  :
251
- _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsxs(TMLayoutItem, { width: 'max-content', height: 'max-content', children: [" ", _jsxs(StyledToppyTextContainer, { children: [" ", _jsxs(StyledToppyText, { children: [" ", SDKUI_Localizator.DcmtTypeSelectOrQuickSearch, " "] }), " "] }), " "] }), _jsxs(TMLayoutItem, { width: 'max-content', height: 'max-content', children: [" ", _jsx("img", { src: Logo, width: 120, alt: '' }), " "] })] }), showSqdForm &&
251
+ _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsx(StyledToppyTextContainer, { children: _jsx(StyledToppyText, { children: SDKUI_Localizator.DcmtTypeSelectOrQuickSearch }) }), _jsx("img", { src: Toppy, width: 120, alt: '' })] }), showSqdForm &&
252
252
  _jsx(StyledModalContainer, { style: { backgroundColor: `${TMColors.backgroundColorHeader}12` }, children: _jsx(TMSavedQueryForm, { height: '50%', width: '50%', id: formModeSqdForm === FormModes.Create ? -1 : SQD?.id, title: 'Ricerca rapida', formMode: formModeSqdForm, showBackButton: true, qd: qd, isAdvancedSearch: showAdvancedSearch, isModal: false, onClose: () => { setShowSqdForm(false); }, onSaved: onSqdSaved }) })] }), showDistinctValuesPanel &&
253
253
  _jsx(TMDistinctValues, { isModal: true, tid: focusedTidMid?.tid, mid: focusedTidMid?.mid, separator: ',', onClosePanelCallback: () => setShowDistinctValuesPanel(false), onSelectionChanged: (e) => {
254
254
  if (!e)
@@ -328,13 +328,20 @@ export const refreshLastSearch = async (qd) => {
328
328
  return searchResults;
329
329
  };
330
330
  export const StyledToppyTextContainer = styled.div `
331
- padding: 30px 50px;
332
- max-width: 345px;
331
+ padding: 30px 5vw;
332
+ width: 100%;
333
+ max-width: 345px;
333
334
  border: 1px solid #2559A5;
334
335
  border-radius: 30px;
335
336
  display: flex;
336
337
  align-items: center;
337
338
  justify-content: center;
339
+ box-sizing: border-box;
340
+
341
+ @media (max-width: 400px) {
342
+ padding: 20px 10px;
343
+ max-width: 98vw;
344
+ }
338
345
  `;
339
346
  export const StyledToppyText = styled.p `
340
347
  text-align: center;
@@ -1,27 +1,32 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useState } from 'react';
3
- import { LayoutModes, SDK_Localizator, TreeCacheService, TreeItemTypes } from '@topconsultnpm/sdk-ts-beta';
3
+ import { DcmtTypeListCacheService, LayoutModes, SDK_Localizator, TreeCacheService, TreeItemTypes } from '@topconsultnpm/sdk-ts-beta';
4
4
  import { TreeList, Column, Scrolling, Selection } from 'devextreme-react/tree-list';
5
5
  import { DropDownBox } from 'devextreme-react';
6
- import { IconStarRemove, IconStar, SDKUI_Localizator, SDKUI_Globals, IconFolder } from '../../../helper';
7
- import { StyledDivHorizontal } from '../../base/Styled';
6
+ import { IconStarRemove, IconStar, SDKUI_Localizator, SDKUI_Globals, IconFolder, IconInfo, IconCloseOutline } from '../../../helper';
7
+ import { StyledDivHorizontal, StyledOffCanvasPanel } from '../../base/Styled';
8
8
  import TMButton from '../../base/TMButton';
9
9
  import TMDataGrid from '../../base/TMDataGrid';
10
- import TMLayoutContainer, { TMLayoutItem } from '../../base/TMLayout';
11
10
  import TMPanel from '../../base/TMPanel';
12
- import TMTidViewer from '../../viewers/TMTidViewer';
11
+ import TMTidViewer, { renderDTDTooltipContent, TMDcmtTypeTooltip } from '../../viewers/TMTidViewer';
13
12
  import { TMColors } from '../../../utils/theme';
14
13
  import styled from 'styled-components';
14
+ import { useOutsideClick } from '../../../hooks/useOutsideClick';
15
+ import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
15
16
  const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelectedTIDChanged, onClosePanel, allowMaximize = true, onMaximizePanel }) => {
16
17
  const [trees, setTrees] = useState([]);
17
18
  const [treeItems, setTreeItems] = useState([]);
18
19
  const [selectedTreeId, setSelectedTreeId] = useState(0);
20
+ const [infoDTD, setInfoDTD] = useState();
19
21
  // State to store selected row keys
20
22
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);
21
23
  // State hook to store the currently focused row key, initially set to undefined
22
24
  const [focusedRowKey, setFocusedRowKey] = useState(undefined);
23
25
  const [isGridBoxOpened, setIsGridBoxOpened] = useState(false);
24
26
  const [defaultTreeId, setDefaultTreeId] = useState(-1);
27
+ const deviceType = useDeviceType();
28
+ const isMobile = deviceType === DeviceType.MOBILE;
29
+ const panelRef = useOutsideClick(() => setInfoDTD(undefined));
25
30
  useEffect(() => {
26
31
  if (treeItems.length > 0 && treeItems[0].id) {
27
32
  setSelectedRowKeys([treeItems[0].id]);
@@ -59,10 +64,56 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
59
64
  setTreeItems(newTreeItems);
60
65
  }, [selectedTreeId]);
61
66
  const renderCell = (data) => {
62
- let treeItem = data.data;
63
- if (treeItem.type == TreeItemTypes.DcmtType)
64
- return (_jsx(TMTidViewer, { tid: treeItem.tid, color: TMColors.primaryColor, showIcon: false }));
65
- return (_jsxs(StyledDivHorizontal, { style: { gap: 5 }, children: [_jsx(IconFolder, { fontSize: 24, color: TMColors.iconLight }), _jsx("p", { style: { color: TMColors.primaryColor }, children: treeItem.nameLoc })] }));
67
+ const treeItem = data.data;
68
+ const [showInfo, setShowInfo] = useState(false);
69
+ // Documento (DcmtType)
70
+ if (treeItem.type === TreeItemTypes.DcmtType) {
71
+ return (_jsxs(StyledDivHorizontal, { style: {
72
+ alignItems: 'center',
73
+ minWidth: 0,
74
+ width: '100%',
75
+ gap: 6,
76
+ position: 'relative'
77
+ }, onMouseEnter: async () => {
78
+ if (!isMobile) {
79
+ setShowInfo(true);
80
+ let dtd = await DcmtTypeListCacheService.GetAsync(treeItem.tid);
81
+ setInfoDTD(dtd);
82
+ }
83
+ }, onMouseLeave: () => {
84
+ if (!isMobile) {
85
+ setShowInfo(false);
86
+ setInfoDTD(undefined);
87
+ }
88
+ }, children: [!isMobile && (_jsx("span", { style: {
89
+ opacity: showInfo ? 1 : 0,
90
+ transition: 'opacity 0.2s',
91
+ pointerEvents: showInfo ? 'auto' : 'none',
92
+ cursor: 'pointer',
93
+ marginRight: 4,
94
+ display: 'flex',
95
+ alignItems: 'center',
96
+ position: 'relative',
97
+ left: 0,
98
+ zIndex: 2
99
+ }, children: _jsx(TMDcmtTypeTooltip, { dtd: infoDTD, children: _jsx(IconInfo, { color: TMColors.info }) }) })), _jsx("span", { style: { cursor: 'pointer', flex: 1, minWidth: 0 }, children: _jsx(TMTidViewer, { tid: treeItem.tid, color: TMColors.primaryColor, showIcon: false }) })] }));
100
+ }
101
+ // Folder (altri tipi)
102
+ return (_jsxs(StyledDivHorizontal, { style: { gap: 5, alignItems: 'center', minWidth: 0 }, children: [_jsx("span", { style: {
103
+ flex: '0 0 auto',
104
+ width: 24,
105
+ height: 24,
106
+ display: 'flex',
107
+ alignItems: 'center',
108
+ justifyContent: 'center'
109
+ }, children: _jsx(IconFolder, { fontSize: 24, color: TMColors.iconLight }) }), _jsx("span", { style: {
110
+ color: TMColors.primaryColor,
111
+ minWidth: 0,
112
+ overflow: 'hidden',
113
+ textOverflow: 'ellipsis',
114
+ whiteSpace: 'nowrap',
115
+ flex: 1,
116
+ }, children: treeItem.nameLoc })] }));
66
117
  };
67
118
  // Handles selection change in the data grid
68
119
  const onSelectionChanged = useCallback((e) => {
@@ -102,23 +153,89 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
102
153
  }
103
154
  } }), children: trees.length > 0
104
155
  ?
105
- _jsx("div", { style: { display: 'flex', flexDirection: 'column', height: '100%', width: '100%', padding: '10px 5px' }, children: _jsxs(TMLayoutContainer, { gap: 10, children: [_jsx(TMLayoutItem, { height: '30px', children: _jsx(DropDownBox, { dropDownOptions: {
106
- resizeEnabled: true,
107
- minWidth: "100%",
108
- height: trees.length <= 10 ? 300 : 500,
109
- maxWidth: "100%"
110
- }, value: selectedTreeId, opened: isGridBoxOpened, valueExpr: "id", displayExpr: "nameLoc", deferRendering: false, dataSource: trees, onValueChanged: syncDataGridSelection, onOptionChanged: onGridBoxOpened, children: _jsx(TMDataGrid, { height: "100%", width: "100%", dataSource: trees, dataColumns: [
111
- { dataField: 'nameLoc', caption: SDKUI_Localizator.Name, width: 'auto' },
112
- { dataField: 'description', caption: SDKUI_Localizator.Description, width: 'auto' },
113
- ], selection: { mode: 'single', showCheckBoxesMode: "none" }, showHeaderFilter: false, selectedRowKeys: selectedRowKeys, onSelectionChanged: onSelectionChanged, focusedRowKey: focusedRowKey, onFocusedRowChanged: onFocusedRowChanged }) }) }), _jsx(TMLayoutItem, { height: 'calc(100% - 50px)', children: _jsx(StyledTreeListWrapper, { style: { width: "100%", height: "100%" }, children: _jsxs(TreeList, { height: "100%", dataSource: treeItems, showRowLines: false, showColumnLines: false, showBorders: false, columnAutoWidth: false, keyExpr: "id", parentIdExpr: "parentID", dataStructure: "plain", showColumnHeaders: false, onContentReady: (e) => e.component.clearSelection(), onSelectionChanged: (e) => {
114
- if (e.selectedRowsData[0] && e.selectedRowsData[0].type == TreeItemTypes.DcmtType) {
115
- onSelectedTIDChanged?.(e.selectedRowsData[0].tid, selectedTreeId);
116
- }
117
- }, children: [_jsx(Column, { dataField: "nameLoc", caption: SDKUI_Localizator.Name, cellRender: renderCell, width: "100%" }), _jsx(Scrolling, { mode: "virtual", useNative: Number(SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar) === 1 }), _jsx(Selection, { mode: "single" })] }) }) })] }) })
156
+ _jsxs("div", { style: {
157
+ display: 'flex',
158
+ flexDirection: 'column',
159
+ height: '100%',
160
+ width: '100%',
161
+ boxSizing: 'border-box',
162
+ minHeight: 0,
163
+ }, children: [_jsx("div", { style: { padding: '10px' }, children: _jsx(DropDownBox, { dropDownOptions: {
164
+ resizeEnabled: true,
165
+ minWidth: "100%",
166
+ height: trees.length <= 10 ? 300 : 500,
167
+ maxWidth: "100%"
168
+ }, value: selectedTreeId, opened: isGridBoxOpened, valueExpr: "id", displayExpr: "nameLoc", deferRendering: false, dataSource: trees, onValueChanged: syncDataGridSelection, onOptionChanged: onGridBoxOpened, style: { height: 30, padding: '5px' }, children: _jsx(TMDataGrid, { height: "100%", width: "100%", dataSource: trees, dataColumns: [
169
+ { dataField: 'nameLoc', caption: SDKUI_Localizator.Name, width: 'auto' },
170
+ { dataField: 'description', caption: SDKUI_Localizator.Description, width: 'auto' },
171
+ ], selection: { mode: 'single', showCheckBoxesMode: "none" }, showHeaderFilter: false, selectedRowKeys: selectedRowKeys, onSelectionChanged: onSelectionChanged, focusedRowKey: focusedRowKey, onFocusedRowChanged: onFocusedRowChanged }) }) }), _jsxs(StyledTreeListWrapper, { children: [_jsxs(TreeList, { height: "100%", dataSource: treeItems, showRowLines: false, showColumnLines: false, showBorders: false, columnAutoWidth: false, keyExpr: "id", parentIdExpr: "parentID", dataStructure: "plain", showColumnHeaders: false, onContentReady: (e) => e.component.clearSelection(), onSelectionChanged: (e) => {
172
+ if (e.selectedRowsData[0] && e.selectedRowsData[0].type == TreeItemTypes.DcmtType) {
173
+ onSelectedTIDChanged?.(e.selectedRowsData[0].tid, selectedTreeId);
174
+ }
175
+ }, children: [_jsx(Column, { dataField: "nameLoc", caption: SDKUI_Localizator.Name, cellRender: renderCell, width: "100%" }), _jsx(Scrolling, { mode: "virtual", useNative: Number(SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar) === 1 }), _jsx(Selection, { mode: "single" })] }), _jsxs(StyledOffCanvasPanel, { ref: panelRef, "$isOpen": isMobile && infoDTD !== undefined, children: [_jsxs(StyledDivHorizontal, { style: { gap: 10, padding: '10px 8px', width: '100%', alignItems: 'center' }, children: [_jsx("p", { style: { fontSize: '1.1rem', fontWeight: 'bold' }, children: `${SDKUI_Localizator.DcmtType} - ${SDKUI_Localizator.About}` }), _jsx(IconCloseOutline, { style: { marginLeft: 'auto', cursor: 'pointer' }, onClick: () => setInfoDTD(undefined) })] }), renderDTDTooltipContent(infoDTD)] })] })] })
118
176
  : _jsx("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', fontSize: '1.5rem' }, children: SDKUI_Localizator.TreesNoAvailable }) }));
119
177
  };
120
178
  export default TMTreeSelector;
179
+ const StyledTidItem = styled.div `
180
+ display: flex;
181
+ flex-direction: column;
182
+ align-items: stretch;
183
+ min-width: 0;
184
+ /* padding: 10px; */
185
+ position: relative;
186
+
187
+ &:hover {
188
+ cursor: pointer;
189
+ }
190
+
191
+ .info-icon {
192
+ position: absolute;
193
+ left: -7px;
194
+ top: calc(50% - 5px);
195
+ transform: translateY(-50%);
196
+ opacity: 0;
197
+ transition: opacity 0.2s;
198
+ pointer-events: none;
199
+ // On mobile, never show
200
+ ${({ $isMobile }) => $isMobile && `
201
+ display: none !important;
202
+ `}
203
+ }
204
+
205
+ &:hover .info-icon {
206
+ opacity: 1;
207
+ pointer-events: auto;
208
+ }
209
+ `;
121
210
  const StyledTreeListWrapper = styled.div `
211
+ width: 100%;
212
+ height: 100%;
213
+ min-height: 0;
214
+ flex: 1;
215
+ display: flex;
216
+ flex-direction: column;
217
+
218
+ .dx-treelist,
219
+ .dx-treelist-rowsview,
220
+ .dx-scrollable,
221
+ .dx-scrollable-wrapper,
222
+ .dx-scrollable-container,
223
+ .dx-scrollable-content {
224
+ height: 100% !important;
225
+ min-height: 0 !important;
226
+ max-height: 100% !important;
227
+ box-sizing: border-box;
228
+ }
229
+
230
+ .dx-scrollable-scrollbar.dx-scrollbar-vertical {
231
+ /* Mostra solo quando serve */
232
+ opacity: 1 !important;
233
+ }
234
+
235
+ .dx-scrollable-scrollbar.dx-scrollbar-horizontal {
236
+ display: none !important;
237
+ }
238
+
122
239
  .dx-treelist-container>.dx-treelist-headers,
123
240
  .dx-treelist-container>.dx-treelist-rowsview {
124
241
  background-color: transparent;
@@ -132,7 +249,7 @@ const StyledTreeListWrapper = styled.div `
132
249
  }
133
250
 
134
251
  .dx-row > td {
135
- padding: 10px 15px;
252
+ padding: 10px;
136
253
  font-size: 1rem;
137
254
  white-space: nowrap;
138
255
  overflow: hidden;
@@ -10,8 +10,6 @@ interface TMBlogsProps {
10
10
  allData: Array<BlogPost | HomeBlogPost>;
11
11
  /** Optional flag to show extended attachments */
12
12
  showExtendedAttachments?: boolean;
13
- /** Optional view mode for displaying blog posts ('thumbnails' or 'details') */
14
- viewMode?: 'thumbnails' | 'details';
15
13
  /** Optional flag to automatically scroll to the bottom of the list */
16
14
  scrollToBottom?: boolean;
17
15
  /** Optional height of the component (CSS value) */
@@ -3,7 +3,6 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
3
3
  import { DcmtTypeListCacheService, LayoutModes, ResultTypes, SDK_Globals, WorkingGroupEngine } from "@topconsultnpm/sdk-ts-beta";
4
4
  import { ContextMenu, ScrollView } from 'devextreme-react';
5
5
  import { SDKUI_Localizator, IconAttachment, getExceptionMessage, Globalization, IconBoard } from '../../helper';
6
- import TMDataGrid from '../base/TMDataGrid';
7
6
  import { useDeviceType, DeviceType } from '../base/TMDeviceProvider';
8
7
  import { TMMessageBoxManager, ButtonNames } from '../base/TMPopUp';
9
8
  import TMTooltip from '../base/TMTooltip';
@@ -20,7 +19,7 @@ import TMDcmtForm from '../features/documents/TMDcmtForm';
20
19
  import { TMColors } from '../../utils/theme';
21
20
  let localAbortController = new AbortController();
22
21
  const TMBlogs = (props) => {
23
- const { id, allData, showExtendedAttachments = true, treeFs, draftLatestInfoMap, archivedDocumentMap, updateVisualizedBlogCallback, height, width, scrollToBottom = true, viewMode = 'thumbnails', header, showIconHeader = true, color = colors.PRIMARY_BLUE, handleNavigateToWGs, showId, setShowId, contextMenuParams = {
22
+ 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
23
  isShowHideFilterEnabled: true,
25
24
  isShowHideIDEnaled: true,
26
25
  isCommentEnabled: false,
@@ -37,8 +36,6 @@ const TMBlogs = (props) => {
37
36
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
38
37
  // This avoids unnecessary re-renders by only recalculating when deviceType changes.
39
38
  let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
40
- // State to manage the current rendering mode of the component (either 'thumbnails' or 'details')
41
- const [renderMode, setRenderMode] = useState('thumbnails');
42
39
  // State to store an array of blog posts, which can be either BlogPost or HomeBlogPost type
43
40
  const [blogPosts, setBlogPosts] = useState([]);
44
41
  // State to manage the data source for a tree component
@@ -414,10 +411,6 @@ const TMBlogs = (props) => {
414
411
  if (focusedBlog && focusedBlog.id && filteredBlogs.find(filteredBlog => focusedBlog.id === filteredBlog.id) === undefined)
415
412
  handleFocusedBlog(undefined);
416
413
  }, [allData, appliedGlobalFilters, searchText, postsToShow, currentHeader]);
417
- useEffect(() => {
418
- if (viewMode)
419
- setRenderMode(viewMode);
420
- }, [viewMode]);
421
414
  // Scroll the focused blog post into view
422
415
  useEffect(() => {
423
416
  if (focusedBlog && focusedBlog.id && containerRef.current) {
@@ -441,7 +434,7 @@ const TMBlogs = (props) => {
441
434
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
442
435
  }
443
436
  }
444
- }, [blogPosts, viewMode, focusedBlog]);
437
+ }, [blogPosts, focusedBlog]);
445
438
  const attachmentDetails = (attachments, isSelected) => {
446
439
  return _jsx("div", { style: { marginTop: "10px", overflow: "hidden" }, children: attachments.map(attachment => {
447
440
  return AttachmentElement(attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText, color, downloadDcmtsAsync, handleFocusedAttachment, setAnchorEl, contextMenuRef);
@@ -567,100 +560,6 @@ const TMBlogs = (props) => {
567
560
  }, children: renderBlogPostContent(blogPost, index, isOwnComment) }) }, 'blogPostChat-' + id + "-" + blogPost.id)] }, "blog-post-wrapper-" + id + "-" + blogPost.id));
568
561
  }) }) });
569
562
  };
570
- const DataGridView = () => {
571
- const gridRef = useRef(null);
572
- const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
573
- useEffect(() => {
574
- if (gridRef.current && renderMode === 'details') {
575
- const dataGrid = gridRef.current.instance();
576
- dataGrid.repaint(); // Repaint the grid first
577
- }
578
- if (scrollToBottom && gridRef.current) {
579
- const dataGrid = gridRef.current.instance();
580
- const scrollable = dataGrid.getScrollable();
581
- if (scrollable && scrollable.scrollHeight()) {
582
- // Wait for repaint to finish (if repaint causes a reflow/re-rendering of the grid)
583
- setTimeout(() => {
584
- scrollable.scrollTo({ y: scrollable.scrollHeight() });
585
- }, 0); // Use setTimeout with 0 delay to defer scrolling until after repaint
586
- }
587
- }
588
- }, [renderMode, scrollToBottom]); // Ensure to include scrollToBottom in the dependency array
589
- const cellDefaultRender = useCallback((cellData) => {
590
- const blogPost = cellData.data;
591
- const { isDel, isSys } = blogPost;
592
- return _jsx("div", { style: { color: isSys ? colors.RED : colors.BLACK, textDecoration: isDel ? 'line-through' : 'none' }, children: highlightText(cellData.value, searchText, false) });
593
- }, [searchText]);
594
- const cellOwnerRender = useCallback((cellData) => {
595
- const blogPost = cellData.data;
596
- const { isDel, isSys } = blogPost;
597
- return _jsxs("span", { style: { display: 'inline-flex', alignItems: 'center', }, children: [OwnerInitialsBadge(blogPost), _jsx("span", { style: { color: isSys ? colors.RED : colors.BLACK, textDecoration: isDel ? 'line-through' : 'none', display: 'inline-block' }, children: highlightText(cellData.value, searchText, false) })] });
598
- }, [searchText]);
599
- const cellDescriptionRender = useCallback((cellData) => {
600
- const blogPost = cellData.data;
601
- const { isDel, isSys } = blogPost;
602
- return _jsx("span", { style: { color: isSys ? colors.RED : colors.BLACK, textDecoration: isDel ? 'line-through' : 'none' }, children: _jsx(TMHtmlContentDisplay, { markup: blogPost.description ?? '-', searchText: searchText, isSelected: false }) });
603
- }, [searchText]);
604
- const cellClassIdRender = useCallback((cellData) => {
605
- const blogPost = cellData.data;
606
- let textColor = blogPost.isSys ? colors.RED : colors.BLACK;
607
- let iconColor = textColor;
608
- const classID = blogPost.classID;
609
- if (classID) {
610
- if (classID === 'DS')
611
- iconColor = colors.PRIMARY_ORANGE;
612
- if (classID === 'WG')
613
- iconColor = colors.PRIMARY_GREEN;
614
- }
615
- const headerClickCallback = () => {
616
- const id = blogPost.id;
617
- if (handleNavigateToWGs && id && classID === 'WG')
618
- handleNavigateToWGs(id);
619
- };
620
- return IconAndHeaderElement(blogPost, iconColor, false, headerClickCallback, searchText);
621
- }, []);
622
- const cellAttachmentsRender = useCallback((cellData) => {
623
- const data = cellData.data;
624
- const { attachments } = data;
625
- return _jsx("div", { style: { marginTop: "10px", overflow: "hidden" }, children: (attachments && attachments.length > 0) ? attachments.map(attachment => {
626
- return AttachmentElement(attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, false, searchText, color, downloadDcmtsAsync, handleFocusedAttachment, setAnchorEl, contextMenuRef);
627
- }) : '' });
628
- }, [treeFs, draftLatestInfoMap, dcmtTypeDescriptors, color, searchText]);
629
- const cellDatetimeRender = useCallback((cellData) => {
630
- const data = cellData.data;
631
- const { value } = cellData;
632
- const { isDel, isSys } = data;
633
- const formattedDate = value ? new Date(value).toLocaleString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }) : '';
634
- return _jsx("div", { style: { color: isSys ? colors.RED : colors.BLACK, textDecoration: isDel ? 'line-through' : 'none' }, children: formattedDate });
635
- }, []);
636
- // Handles focus change in the data grid
637
- const onFocusedRowChanged = useCallback((e) => {
638
- if (e.row)
639
- handleFocusedBlog(e.row.data);
640
- }, []);
641
- const onContextMenuPreparing = (e) => {
642
- if (e === undefined)
643
- return;
644
- if (e.target === 'content') {
645
- e.items = e.items || [];
646
- e.items = contextMenuItems;
647
- }
648
- };
649
- const dataColumns = useMemo(() => {
650
- return [
651
- { dataField: "id", caption: "ID", dataType: 'string', visible: localShowId, cellRender: cellDefaultRender },
652
- { dataField: "ownerName", caption: SDKUI_Localizator.Author, dataType: 'string', visible: true, cellRender: cellOwnerRender },
653
- { dataField: "classID", caption: SDKUI_Localizator.Type, dataType: 'string', visible: showIconHeader, cellRender: cellClassIdRender },
654
- { dataField: "description", caption: SDKUI_Localizator.Description, dataType: 'string', visible: true, cellRender: cellDescriptionRender },
655
- { dataField: "creationTime", caption: SDKUI_Localizator.CreationTime, dataType: 'datetime', visible: true, format: 'dd/MM/yyyy HH:mm', cellRender: cellDatetimeRender },
656
- { dataField: "attachments", caption: SDKUI_Localizator.RefersTo, dataType: 'string', visible: true, cellRender: cellAttachmentsRender },
657
- ];
658
- }, [localShowId, showIconHeader, searchText]);
659
- 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(TMDataGrid, { ref: gridRef, showSearchPanel: false, dataSource: blogPosts ?? [], dataColumns: dataColumns, selection: { mode: 'none' }, focusedRowKey: focusedBlog?.id, onFocusedRowChanged: onFocusedRowChanged, onContextMenuPreparing: onContextMenuPreparing }) });
660
- };
661
- const toggleViewMode = () => {
662
- setRenderMode((prevViewMode) => (prevViewMode === 'details' ? 'thumbnails' : 'details'));
663
- };
664
563
  // Function to handle changes in the search text
665
564
  const handleSearchChange = (value) => {
666
565
  handleFocusedBlog(undefined);
@@ -709,7 +608,7 @@ const TMBlogs = (props) => {
709
608
  minWidth: isMobile ? '90px' : '120px',
710
609
  width: isMobile ? '90px' : '150px',
711
610
  height: '29px',
712
- } }))] }) }) })), _jsxs("div", { style: { height: `calc(100% - ${currentHeader && !isHeaderHidden ? '50px' : '0px'})`, width: "100%", overflow: 'auto', display: 'block' }, onContextMenu: onContextMenu, children: [_jsx("div", { style: { display: renderMode === 'thumbnails' ? 'block' : 'none', width: "100%", height: "100%" }, children: ThumbnailView() }), _jsx("div", { style: { display: renderMode === 'details' ? 'block' : 'none', width: "100%", height: "100%" }, children: DataGridView() }), 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) && _jsx("button", { style: {
611
+ } }))] }) }) })), _jsxs("div", { style: { height: `calc(100% - ${currentHeader && !isHeaderHidden ? '50px' : '0px'})`, width: "100%", overflow: 'auto', display: 'block' }, onContextMenu: onContextMenu, 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) && _jsx("button", { style: {
713
612
  position: 'absolute',
714
613
  bottom: '20px',
715
614
  right: '20px',
@@ -726,14 +625,17 @@ const TMBlogs = (props) => {
726
625
  display: 'flex',
727
626
  justifyContent: 'center',
728
627
  alignItems: 'center',
628
+ opacity: 0.3,
729
629
  }, onMouseEnter: (e) => {
730
630
  e.currentTarget.style.backgroundColor = '#D94A9F';
731
631
  e.currentTarget.style.transform = 'scale(1.1)';
732
632
  e.currentTarget.style.boxShadow = '0 4px 12px rgba(37, 89, 165, 0.6)';
633
+ e.currentTarget.style.opacity = '1';
733
634
  }, onMouseLeave: (e) => {
734
635
  e.currentTarget.style.backgroundColor = "#C2388B";
735
636
  e.currentTarget.style.transform = 'scale(1)';
736
637
  e.currentTarget.style.boxShadow = '0 2px 6px rgba(0,0,0,0.2)';
638
+ e.currentTarget.style.opacity = '0.3';
737
639
  }, onClick: () => { showCommentFormCallback(); }, children: _jsx(TMTooltip, { content: SDKUI_Localizator.AddNewComment, children: _jsx("i", { className: "dx-icon-chat", style: { fontSize: !isMobile ? '30px' : '25px' } }) }) })] }) });
738
640
  };
739
641
  export default TMBlogs;
@@ -18,26 +18,26 @@ const StyledRecentTidItem = styled.div `
18
18
  min-width: 0;
19
19
  padding: 10px;
20
20
  position: relative;
21
- /* border-bottom: 1px solid #00A99D; // separator line */
21
+ gap: 0;
22
22
 
23
23
  &:hover {
24
24
  cursor: pointer;
25
25
  }
26
26
 
27
27
  .info-icon {
28
- position: absolute;
29
- left: -7px;
30
- top: calc(50% - 5px);
31
- transform: translateY(-50%);
32
28
  opacity: 0;
33
- transition: opacity 0.2s;
34
29
  pointer-events: none;
35
- // On mobile, never show
30
+ transition: opacity 0.2s;
36
31
  ${({ $isMobile }) => $isMobile && `
37
32
  display: none !important;
38
33
  `}
39
34
  }
40
35
 
36
+ &:hover .info-icon {
37
+ opacity: 1;
38
+ pointer-events: auto;
39
+ }
40
+
41
41
  &::after {
42
42
  content: '';
43
43
  display: block;
@@ -47,13 +47,8 @@ const StyledRecentTidItem = styled.div `
47
47
  margin-top: 8px;
48
48
  }
49
49
 
50
- &:hover .info-icon {
51
- opacity: 1;
52
- pointer-events: auto;
53
- }
54
-
55
50
  &:last-child {
56
- border-bottom: none; // remove border for last item
51
+ border-bottom: none;
57
52
  margin-bottom: 0;
58
53
  }
59
54
  `;
@@ -82,7 +77,28 @@ const TMRecentsManager = ({ deviceType, mruTIDs, currentMruTID, onSelectedTID, o
82
77
  overflow: 'hidden',
83
78
  textOverflow: 'ellipsis'
84
79
  }, children: `${SDKUI_Localizator.AllDcmtTypes} (${DcmtTypeListCacheService.CacheCount(true)})` }) }) }, 0), recentDcmtTypes.map((dtd) => {
85
- return (_jsxs(StyledRecentTidItem, { id: `tid-${dtd.id}`, "$isMobile": isMobile, onClick: () => { onSelectedTID?.(dtd.id ?? 0); }, children: [_jsx("span", { className: "info-icon", children: _jsx(TMDcmtTypeTooltip, { dtd: dtd, children: _jsx(IconInfo, { color: TMColors.info }) }) }), _jsx("div", { style: { display: 'flex', justifyContent: 'center', width: '100%' }, children: _jsx(TMTidViewer, { tid: dtd.id, color: TMColors.primaryColor, showIcon: false }) }), _jsx(ContextMenu, { dataSource: [
80
+ const isCurrent = currentMruTID == dtd.id;
81
+ return (_jsxs(StyledRecentTidItem, { id: `tid-${dtd.id}`, "$isMobile": isMobile, onClick: () => { onSelectedTID?.(dtd.id ?? 0); }, children: [_jsxs(StyledDivHorizontal, { style: { alignItems: 'center', gap: 8, width: '100%' }, children: [!isMobile && (_jsx("span", { className: "info-icon", style: {
82
+ marginRight: 4,
83
+ display: 'flex',
84
+ alignItems: 'center'
85
+ }, children: _jsx(TMDcmtTypeTooltip, { dtd: dtd, children: _jsx(IconInfo, { color: TMColors.info }) }) })), _jsx("div", { style: {
86
+ flex: 1,
87
+ display: 'flex',
88
+ alignItems: 'center',
89
+ justifyContent: 'center',
90
+ minWidth: 0
91
+ }, children: _jsx(TMTidViewer, { tid: dtd.id, color: TMColors.primaryColor, showIcon: false }) }), isCurrent && (_jsx("span", { style: {
92
+ width: 24,
93
+ height: 24,
94
+ borderRadius: 24,
95
+ display: 'flex',
96
+ alignItems: 'center',
97
+ justifyContent: 'center',
98
+ fontSize: '1rem',
99
+ fontWeight: 'bold',
100
+ marginLeft: 8
101
+ }, children: _jsx(IconApply, { fontSize: 24, color: 'green' }) }))] }), _jsx(ContextMenu, { dataSource: [
86
102
  {
87
103
  text: SDKUI_Localizator.Remove,
88
104
  icon: iconDelete(),
@@ -95,20 +111,7 @@ const TMRecentsManager = ({ deviceType, mruTIDs, currentMruTID, onSelectedTID, o
95
111
  onClick: () => { setInfoDTD(dtd); }
96
112
  }
97
113
  ] : [])
98
- ], target: `#tid-${dtd.id}` }), currentMruTID == dtd.id &&
99
- _jsx("div", { style: {
100
- width: '24px',
101
- height: '24px',
102
- borderRadius: '24px',
103
- position: 'absolute',
104
- top: '5px',
105
- right: '0px',
106
- display: 'flex',
107
- alignItems: 'center',
108
- justifyContent: 'center',
109
- fontSize: '1rem',
110
- fontWeight: 'bold'
111
- }, children: _jsx(IconApply, { fontSize: 24, color: 'green' }) })] }, dtd.id));
114
+ ], target: `#tid-${dtd.id}` })] }, dtd.id));
112
115
  })] }), showDcmtTypeChooser && _jsx(TMDcmtTypeChooserForm, { onClose: () => setShowDcmtTypeChooser(false), onChoose: (tids) => { onSelectedTID?.(tids?.[0] ?? 0); } }), _jsxs(StyledOffCanvasPanel, { ref: panelRef, "$isOpen": isMobile && infoDTD !== undefined, children: [_jsxs(StyledDivHorizontal, { style: { gap: 10, padding: '10px 8px', width: '100%', alignItems: 'center' }, children: [_jsx("p", { style: { fontSize: '1.1rem', fontWeight: 'bold' }, children: `${SDKUI_Localizator.DcmtType} - ${SDKUI_Localizator.About}` }), _jsx(IconCloseOutline, { style: { marginLeft: 'auto', cursor: 'pointer' }, onClick: () => setInfoDTD(undefined) })] }), renderDTDTooltipContent(infoDTD)] })] }));
113
116
  };
114
117
  export default TMRecentsManager;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.14.76",
3
+ "version": "6.14.78",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",