@topconsultnpm/sdkui-react 6.22.0-dev2.44 → 6.22.0-dev2.46
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/TMDataGrid.js +181 -2
- package/lib/components/base/TMTooltip.js +1 -2
- package/lib/components/features/search/TMTreeSelector.js +34 -29
- package/lib/components/sidebar/TMHeader.js +30 -20
- package/lib/components/viewers/TMTidViewer.js +59 -12
- package/lib/helper/SDKUI_Localizator.d.ts +1 -0
- package/lib/helper/SDKUI_Localizator.js +10 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import styled, { css } from 'styled-components';
|
|
3
|
+
import styled, { createGlobalStyle, css } from 'styled-components';
|
|
4
4
|
import DataGrid, { Column, HeaderFilter, Selection, Scrolling, LoadPanel, SearchPanel, Pager, Sorting, Paging, FilterPanel, ColumnChooser, Grouping, GroupPanel, Summary, Editing, FilterRow, StateStoring, RowDragging, MasterDetail, Position, ColumnChooserSearch, ColumnChooserSelection } from 'devextreme-react/data-grid';
|
|
5
5
|
import DataSource from 'devextreme/data/data_source';
|
|
6
6
|
import { IconAll, IconSelected, IconVisible, SDKUI_Globals, SDKUI_Localizator } from '../../helper';
|
|
@@ -382,7 +382,7 @@ const TMDataGrid = React.forwardRef((props, ref) => {
|
|
|
382
382
|
return pager;
|
|
383
383
|
return { ...pager, displayMode: pager.displayMode ?? 'compact' };
|
|
384
384
|
}, [pager, compactPager]);
|
|
385
|
-
return _jsxs(StyledDataGridContainer, { "$compactPager": compactPager, style: { width: "100%", height: "100%" }, children: [_jsx("div", { ref: gridContainerRef, style: { width: "100%", height: counterConfig.show ? "calc(100% - 25px)" : "100%" }, children: _jsxs(DataGrid, { ref: internalRef, id: id, className: `tm-datagrid ${hasFilters ? 'has-filters' : ''}`,
|
|
385
|
+
return _jsxs(StyledDataGridContainer, { "$compactPager": compactPager, style: { width: "100%", height: "100%" }, children: [_jsx(HeaderFilterMenuGlobalStyle, {}), _jsx("div", { ref: gridContainerRef, style: { width: "100%", height: counterConfig.show ? "calc(100% - 25px)" : "100%" }, children: _jsxs(DataGrid, { ref: internalRef, id: id, className: `tm-datagrid ${hasFilters ? 'has-filters' : ''}`,
|
|
386
386
|
// main properties
|
|
387
387
|
keyExpr: keyExpr, dataSource: dataSource, selectedRowKeys: selectedRowKeys, focusedRowEnabled: focusedRowEnabled, hoverStateEnabled: hoverStateEnabled,
|
|
388
388
|
// events and callbacks
|
|
@@ -451,6 +451,185 @@ const StyledDataGridContainer = styled.div `
|
|
|
451
451
|
}
|
|
452
452
|
`}
|
|
453
453
|
`;
|
|
454
|
+
// Stile del pannello del filtro d'intestazione (ricerca, elenco valori, OK/Annulla).
|
|
455
|
+
// Il popup è in portale sul body, fuori da StyledDataGridContainer: le regole sono globali
|
|
456
|
+
// ma tutte sotto .dx-header-filter-menu, classe che DevExtreme applica solo a questo popup.
|
|
457
|
+
const HeaderFilterMenuGlobalStyle = createGlobalStyle `
|
|
458
|
+
.dx-header-filter-menu {
|
|
459
|
+
|
|
460
|
+
&.dx-popup-wrapper > .dx-overlay-content.dx-popup-normal {
|
|
461
|
+
border: 1px solid #E4E8EE;
|
|
462
|
+
border-radius: 8px;
|
|
463
|
+
box-shadow: 0 2px 6px rgba(18, 44, 76, .08), 0 12px 28px rgba(18, 44, 76, .14);
|
|
464
|
+
overflow: hidden;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
&.dx-popup-wrapper .dx-popup-content {
|
|
468
|
+
padding: 10px 10px 4px;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/* Campo di ricerca: TextBox mode "search" resa da List o da TreeView (filtri gerarchici) */
|
|
472
|
+
.dx-searchbox.dx-list-search,
|
|
473
|
+
.dx-searchbox.dx-treeview-search {
|
|
474
|
+
margin-bottom: 8px;
|
|
475
|
+
border-radius: 6px;
|
|
476
|
+
border: 1px solid #CDD2D8;
|
|
477
|
+
background-color: #F4F6F9;
|
|
478
|
+
box-shadow: none;
|
|
479
|
+
transition: border-color .15s ease, background-color .15s ease, box-shadow .15s ease;
|
|
480
|
+
|
|
481
|
+
/* fluent disegna qui la barretta di focus, sostituita da bordo + alone */
|
|
482
|
+
&::before,
|
|
483
|
+
&::after {
|
|
484
|
+
display: none;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
&.dx-state-hover:not(.dx-state-focused) {
|
|
488
|
+
border-color: #AEB6C1;
|
|
489
|
+
background-color: #EEF2F7;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
&.dx-state-focused {
|
|
493
|
+
border-color: #2559A5;
|
|
494
|
+
background-color: #FFFFFF;
|
|
495
|
+
box-shadow: 0 0 0 2px rgba(37, 89, 165, .16);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.dx-icon-search {
|
|
499
|
+
width: 28px;
|
|
500
|
+
color: #8A929B;
|
|
501
|
+
transition: color .15s ease;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
&.dx-state-focused .dx-icon-search {
|
|
505
|
+
color: #2559A5;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.dx-texteditor-input {
|
|
509
|
+
min-height: 28px;
|
|
510
|
+
padding-inline-start: 28px;
|
|
511
|
+
padding-inline-end: 8px;
|
|
512
|
+
font-size: 12px;
|
|
513
|
+
background-color: transparent;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
.dx-placeholder {
|
|
517
|
+
color: #9AA3AD;
|
|
518
|
+
font-size: 12px;
|
|
519
|
+
|
|
520
|
+
&::before {
|
|
521
|
+
padding-inline-start: 28px;
|
|
522
|
+
padding-inline-end: 8px;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
.dx-clear-button-area .dx-icon-clear {
|
|
527
|
+
color: #8A929B;
|
|
528
|
+
transition: color .15s ease;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
.dx-clear-button-area:hover .dx-icon-clear {
|
|
532
|
+
color: #2559A5;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
.dx-list-item {
|
|
537
|
+
border-radius: 4px;
|
|
538
|
+
transition: background-color .12s ease;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
.dx-list-item-content {
|
|
542
|
+
padding: 4px 6px;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.dx-list-item.dx-state-hover,
|
|
546
|
+
.dx-list-item.dx-state-focused {
|
|
547
|
+
background-color: #F1F6FD;
|
|
548
|
+
color: #122C4C;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
.dx-list-select-all {
|
|
552
|
+
padding: 2px 0 6px;
|
|
553
|
+
margin-bottom: 4px;
|
|
554
|
+
border-bottom: 1px solid #ECEFF3;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
.dx-list-select-all-label {
|
|
558
|
+
font-weight: 600;
|
|
559
|
+
color: #122C4C;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
.dx-checkbox-checked .dx-checkbox-icon,
|
|
563
|
+
.dx-checkbox-indeterminate .dx-checkbox-icon {
|
|
564
|
+
border-color: #2559A5;
|
|
565
|
+
background-color: #2559A5;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
.dx-checkbox.dx-state-hover:not(.dx-checkbox-checked) .dx-checkbox-icon {
|
|
569
|
+
border-color: #2559A5;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/* il :not() lascia intatto il fade-out nativo della scrollbar */
|
|
573
|
+
.dx-scrollable-scroll:not(.dx-state-invisible) .dx-scrollable-scroll-content {
|
|
574
|
+
background-color: rgba(18, 44, 76, .28);
|
|
575
|
+
border-radius: 3px;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
&.dx-popup-wrapper .dx-popup-bottom.dx-toolbar {
|
|
579
|
+
padding: 8px 10px 10px;
|
|
580
|
+
border-top: 1px solid #ECEFF3;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.dx-popup-bottom .dx-button {
|
|
584
|
+
border-radius: 5px;
|
|
585
|
+
min-width: 76px;
|
|
586
|
+
margin: 0;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.dx-popup-bottom .dx-toolbar-button + .dx-toolbar-button {
|
|
590
|
+
margin-inline-start: 6px;
|
|
591
|
+
|
|
592
|
+
.dx-button {
|
|
593
|
+
margin: 0;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/* DevExtreme aggiunge prima OK e poi Annulla: individuarli per posizione li rende indipendenti dalla lingua */
|
|
598
|
+
.dx-popup-bottom .dx-toolbar-after > .dx-toolbar-button:first-child .dx-button {
|
|
599
|
+
border-color: transparent;
|
|
600
|
+
background-color: #2559A5;
|
|
601
|
+
|
|
602
|
+
.dx-button-text {
|
|
603
|
+
color: #FFFFFF;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
&.dx-state-hover {
|
|
607
|
+
background-color: #1E4A8C;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
&.dx-state-active {
|
|
611
|
+
background-color: #1A3F78;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
.dx-popup-bottom .dx-toolbar-after > .dx-toolbar-button + .dx-toolbar-button .dx-button {
|
|
616
|
+
border-color: transparent;
|
|
617
|
+
background-color: transparent;
|
|
618
|
+
|
|
619
|
+
.dx-button-text {
|
|
620
|
+
color: #44506B;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
&.dx-state-hover {
|
|
624
|
+
background-color: #F0F3F7;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
&.dx-state-active {
|
|
628
|
+
background-color: #E6EBF2;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
`;
|
|
454
633
|
const getRecordCount = (dataSource) => {
|
|
455
634
|
if (Array.isArray(dataSource)) {
|
|
456
635
|
return dataSource.length; // For array
|
|
@@ -7,9 +7,8 @@ import { DeviceType, useDeviceType } from './TMDeviceProvider';
|
|
|
7
7
|
const HIDE_DELAY_MS = 400;
|
|
8
8
|
const TMTooltip = ({ children, position, content, hideAfterDelay, parentStyle, childStyle, allowContentInteraction = false }) => {
|
|
9
9
|
const [showTooltip, setShowTooltip] = useState(false);
|
|
10
|
-
const [id
|
|
10
|
+
const [id] = useState(() => genUniqueId());
|
|
11
11
|
const hideTimerRef = useRef();
|
|
12
|
-
useEffect(() => { setID(genUniqueId()); }, [children]);
|
|
13
12
|
useEffect(() => {
|
|
14
13
|
const hide = () => setShowTooltip(false);
|
|
15
14
|
window.addEventListener('click', hide);
|
|
@@ -13,6 +13,15 @@ import { TMColors } from '../../../utils/theme';
|
|
|
13
13
|
import styled from 'styled-components';
|
|
14
14
|
import { useOutsideClick } from '../../../hooks/useOutsideClick';
|
|
15
15
|
import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
|
|
16
|
+
const TMTreeDcmtTypeCell = ({ tid, isMobile }) => {
|
|
17
|
+
const [dtd, setDtd] = useState();
|
|
18
|
+
const loadDTD = useCallback(async () => {
|
|
19
|
+
if (isMobile || dtd || !tid)
|
|
20
|
+
return;
|
|
21
|
+
setDtd(await DcmtTypeListCacheService.GetAsync(tid));
|
|
22
|
+
}, [isMobile, dtd, tid]);
|
|
23
|
+
return (_jsxs(StyledTreeDcmtTypeRow, { onMouseEnter: loadDTD, children: [_jsx("span", { style: { cursor: 'pointer', flex: 1, minWidth: 0 }, children: _jsx(TMTidViewer, { tid: tid, showIcon: false }) }), !isMobile && (_jsx("span", { className: 'info-icon', children: _jsx(TMDcmtTypeTooltip, { dtd: dtd, children: _jsx(IconInfo, { color: TMColors.info }) }) }))] }));
|
|
24
|
+
};
|
|
16
25
|
const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelectedTIDChanged, onClosePanel, allowMaximize = true, onMaximizePanel }) => {
|
|
17
26
|
const [trees, setTrees] = useState([]);
|
|
18
27
|
const [treeItems, setTreeItems] = useState([]);
|
|
@@ -66,36 +75,9 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
|
|
|
66
75
|
}, [selectedTreeId, trees]);
|
|
67
76
|
const renderCell = useCallback((data) => {
|
|
68
77
|
const treeItem = data.data;
|
|
69
|
-
const [showInfo, setShowInfo] = useState(false);
|
|
70
78
|
// Documento (DcmtType)
|
|
71
79
|
if (treeItem.type === TreeItemTypes.DcmtType) {
|
|
72
|
-
return (
|
|
73
|
-
alignItems: 'center',
|
|
74
|
-
minWidth: 0,
|
|
75
|
-
width: '100%',
|
|
76
|
-
gap: 2,
|
|
77
|
-
position: 'relative'
|
|
78
|
-
}, onMouseEnter: async () => {
|
|
79
|
-
if (!isMobile) {
|
|
80
|
-
setShowInfo(true);
|
|
81
|
-
let dtd = await DcmtTypeListCacheService.GetAsync(treeItem.tid);
|
|
82
|
-
setInfoDTD(dtd);
|
|
83
|
-
}
|
|
84
|
-
}, onMouseLeave: () => {
|
|
85
|
-
if (!isMobile) {
|
|
86
|
-
setShowInfo(false);
|
|
87
|
-
setInfoDTD(undefined);
|
|
88
|
-
}
|
|
89
|
-
}, children: [_jsx("span", { style: { cursor: 'pointer', flex: 1, minWidth: 0 }, children: _jsx(TMTidViewer, { tid: treeItem.tid, showIcon: false }) }), !isMobile && (_jsx("span", { style: {
|
|
90
|
-
opacity: showInfo ? 1 : 0,
|
|
91
|
-
transition: 'opacity 0.2s',
|
|
92
|
-
pointerEvents: showInfo ? 'auto' : 'none',
|
|
93
|
-
cursor: 'pointer',
|
|
94
|
-
display: 'flex',
|
|
95
|
-
alignItems: 'center',
|
|
96
|
-
marginLeft: 'auto',
|
|
97
|
-
zIndex: 2
|
|
98
|
-
}, children: _jsx(TMDcmtTypeTooltip, { dtd: infoDTD, children: _jsx(IconInfo, { color: TMColors.info }) }) }))] }));
|
|
80
|
+
return _jsx(TMTreeDcmtTypeCell, { tid: treeItem.tid, isMobile: isMobile });
|
|
99
81
|
}
|
|
100
82
|
// Folder (altri tipi)
|
|
101
83
|
return (_jsxs(StyledDivHorizontal, { style: { gap: 5, alignItems: 'center', minWidth: 0 }, children: [_jsx("span", { style: {
|
|
@@ -113,7 +95,7 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
|
|
|
113
95
|
whiteSpace: 'nowrap',
|
|
114
96
|
flex: 1,
|
|
115
97
|
}, children: treeItem.nameLoc })] }));
|
|
116
|
-
}, [isMobile
|
|
98
|
+
}, [isMobile]);
|
|
117
99
|
// Handles selection change in the data grid
|
|
118
100
|
const onSelectionChanged = useCallback((e) => {
|
|
119
101
|
const selectedKeys = e.component.getSelectedRowKeys() ?? [];
|
|
@@ -214,6 +196,29 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
|
|
|
214
196
|
: _jsx("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', fontSize: '1.5rem' }, children: SDKUI_Localizator.TreesNoAvailable }) }));
|
|
215
197
|
};
|
|
216
198
|
export default TMTreeSelector;
|
|
199
|
+
const StyledTreeDcmtTypeRow = styled(StyledDivHorizontal) `
|
|
200
|
+
align-items: center;
|
|
201
|
+
min-width: 0;
|
|
202
|
+
width: 100%;
|
|
203
|
+
gap: 2px;
|
|
204
|
+
position: relative;
|
|
205
|
+
|
|
206
|
+
.info-icon {
|
|
207
|
+
display: flex;
|
|
208
|
+
align-items: center;
|
|
209
|
+
margin-left: auto;
|
|
210
|
+
z-index: 2;
|
|
211
|
+
cursor: pointer;
|
|
212
|
+
opacity: 0;
|
|
213
|
+
pointer-events: none;
|
|
214
|
+
transition: opacity 0.2s;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
&:hover .info-icon {
|
|
218
|
+
opacity: 1;
|
|
219
|
+
pointer-events: auto;
|
|
220
|
+
}
|
|
221
|
+
`;
|
|
217
222
|
const StyledTreeListWrapper = styled.div `
|
|
218
223
|
width: 100%;
|
|
219
224
|
height: 100%;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect, useRef, useMemo } from 'react';
|
|
3
3
|
import six from '../../assets/six.png';
|
|
4
|
-
import { getAvatarColor, IconCloseOutline, IconCopy, openApps, SDKUI_Localizator } from '../../helper';
|
|
4
|
+
import { getAvatarColor, IconCloseOutline, IconCopy, IconOpenInNew, openApps, SDKUI_Localizator, WHATS_NEWS_LINK_URL } from '../../helper';
|
|
5
5
|
import styled, { keyframes } from 'styled-components';
|
|
6
6
|
import { SDK_Globals, AuthenticationModes, AppModules, UserLevels, CultureIDs } from '@topconsultnpm/sdk-ts';
|
|
7
7
|
import { TMColors } from '../../utils/theme';
|
|
@@ -10,6 +10,7 @@ import { DeviceType, useDeviceType } from '../base/TMDeviceProvider';
|
|
|
10
10
|
import { TMAboutApp } from './TMAboutApp';
|
|
11
11
|
import ShowAlert from '../base/TMAlert';
|
|
12
12
|
import TMResizableMenu from '../base/TMResizableMenu';
|
|
13
|
+
import TMTooltip from '../base/TMTooltip';
|
|
13
14
|
import it from '../../assets/italy.svg';
|
|
14
15
|
import de from '../../assets/german.svg';
|
|
15
16
|
import fr from '../../assets/france.svg';
|
|
@@ -253,10 +254,10 @@ const TMHeader = ({ customButtons = _jsx(_Fragment, {}), onMenusOpen, showSettin
|
|
|
253
254
|
e.preventDefault();
|
|
254
255
|
setMenuStatus(prev => !prev);
|
|
255
256
|
}, children: _jsx(UserAvatar, { "$bgColor": avatarColor, children: userInitials }) }), menuStatus &&
|
|
256
|
-
_jsx(TMResizableMenu, { ref: menuRef, isVisible: menuStatus, top: 60, right: 10, resizable: false, maxWidth: 300, minWidth: 300, maxHeight:
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
257
|
+
_jsx(TMResizableMenu, { ref: menuRef, isVisible: menuStatus, top: 60, right: 10, resizable: false, maxWidth: 300, minWidth: 300, maxHeight: 188, minHeight: 188, padding: 0, children: _jsxs(MenuContainer, { children: [_jsxs(UserProfileSection, { children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 12, height: 'max-content', flex: 1, minWidth: 0 }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 12, height: 'max-content' }, children: [_jsx(AvatarContainer, { children: _jsx(UserAvatarLarge, { "$bgColor": avatarColor, children: userInitials }) }), _jsxs(UserInfo, { children: [_jsxs(UserNameContainer, { children: [_jsx(UserName, { children: userName }), _jsx(CultureFlag, { src: cultureFlag, alt: cultureName, title: cultureName })] }), domain && _jsx(SessionInfo, { style: { padding: 0, margin: 0 }, children: `(${domain})` })] })] }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 8 }, children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'flex-start', justifyContent: 'center', gap: 5, flex: 1, minWidth: 0 }, children: [_jsx(SessionInfo, { children: endpoint }), _jsx(SessionInfo, { children: archiveId + ' (' + archiveDesc + ')' })] }), _jsxs(HeaderMenuActions, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.CopyUserInfo, children: _jsx(HeaderMenuActionIcon, { "$color": '#605e5c', onClick: (e) => {
|
|
258
|
+
e.stopPropagation();
|
|
259
|
+
copyUserInfoToClipboard(userName, cultureId, archiveId, archiveDesc, endpoint, domain);
|
|
260
|
+
}, children: _jsx(IconCopy, { fontSize: 14 }) }) }), _jsx(TMTooltip, { content: SDKUI_Localizator.ShowReleaseNotesInfo, children: _jsx(HeaderMenuActionIcon, { as: 'a', "$color": TMColors.primary, href: WHATS_NEWS_LINK_URL, target: '_blank', rel: 'noopener noreferrer', onClick: (e) => e.stopPropagation(), children: _jsx(IconOpenInNew, { fontSize: 14 }) }) })] })] })] }), _jsx(LogoutButton, { onClick: () => {
|
|
260
261
|
setMenuStatus(false);
|
|
261
262
|
onLogout && onLogout();
|
|
262
263
|
}, children: _jsx(LogoutText, { children: SDKUI_Localizator.Logout }) })] }), _jsxs(BottomActionsContainer, { children: [isTopMediaAuth && (_jsx(BottomActionButton, { onClick: () => {
|
|
@@ -468,8 +469,9 @@ const MenuContainer = styled.div `
|
|
|
468
469
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
|
|
469
470
|
`;
|
|
470
471
|
const UserProfileSection = styled.div `
|
|
472
|
+
position: relative;
|
|
471
473
|
display: flex;
|
|
472
|
-
padding: 20px;
|
|
474
|
+
padding: 16px 20px;
|
|
473
475
|
background: linear-gradient(135deg, #f8f9fa 0%, #f1f3f4 100%);
|
|
474
476
|
border-bottom: 1px solid #e1e5e9;
|
|
475
477
|
gap: 12px;
|
|
@@ -515,7 +517,7 @@ const CultureFlag = styled.img `
|
|
|
515
517
|
`;
|
|
516
518
|
const LogoutButton = styled.div `
|
|
517
519
|
position: absolute;
|
|
518
|
-
top:
|
|
520
|
+
top: 16px;
|
|
519
521
|
right: 20px;
|
|
520
522
|
cursor: pointer;
|
|
521
523
|
transition: all 0.2s ease;
|
|
@@ -546,29 +548,37 @@ const AvatarContainer = styled.div `
|
|
|
546
548
|
position: relative;
|
|
547
549
|
flex-shrink: 0;
|
|
548
550
|
`;
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
551
|
+
const HeaderMenuActions = styled.div `
|
|
552
|
+
display: flex;
|
|
553
|
+
flex-direction: column;
|
|
554
|
+
gap: 6px;
|
|
555
|
+
flex-shrink: 0;
|
|
556
|
+
`;
|
|
557
|
+
const HeaderMenuActionIcon = styled.div `
|
|
558
|
+
width: 22px;
|
|
559
|
+
height: 22px;
|
|
555
560
|
background: white;
|
|
556
|
-
border: 1px solid
|
|
561
|
+
border: 1px solid ${props => props.$color}55;
|
|
557
562
|
border-radius: 50%;
|
|
558
563
|
display: flex;
|
|
559
564
|
align-items: center;
|
|
560
565
|
justify-content: center;
|
|
561
566
|
cursor: pointer;
|
|
562
|
-
color: #605e5c;
|
|
563
567
|
transition: all 0.2s ease;
|
|
564
568
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
565
|
-
|
|
566
|
-
opacity: 0.6;
|
|
569
|
+
text-decoration: none;
|
|
567
570
|
|
|
568
|
-
|
|
569
|
-
|
|
571
|
+
/* "&&" alza la specificita': un eventuale "a, a:visited { color: inherit }"
|
|
572
|
+
dell'app ospite vincerebbe sulla singola classe di styled-components */
|
|
573
|
+
&&,
|
|
574
|
+
&&:visited {
|
|
575
|
+
color: ${props => props.$color};
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
&&:hover {
|
|
579
|
+
background: ${props => props.$color};
|
|
580
|
+
border-color: ${props => props.$color};
|
|
570
581
|
color: white;
|
|
571
|
-
opacity: 1;
|
|
572
582
|
}
|
|
573
583
|
|
|
574
584
|
&:active {
|
|
@@ -6,6 +6,7 @@ import TMSpinner from '../base/TMSpinner';
|
|
|
6
6
|
import { StyledDivHorizontal, StyledTooltipContainer, StyledTooltipItem, StyledTooltipSeparatorItem } from '../base/Styled';
|
|
7
7
|
import TMTooltip from '../base/TMTooltip';
|
|
8
8
|
import { TMColors } from '../../utils/theme';
|
|
9
|
+
import styled, { keyframes } from 'styled-components';
|
|
9
10
|
export var ImageIDList;
|
|
10
11
|
(function (ImageIDList) {
|
|
11
12
|
ImageIDList["arrow_001"] = "arrow_001";
|
|
@@ -261,13 +262,54 @@ export const TMDcmtTypeIcon = ({ dtd }) => {
|
|
|
261
262
|
export const TMDcmtTypeTooltip = ({ dtd, children }) => {
|
|
262
263
|
return (_jsx("div", { style: { pointerEvents: 'all' }, children: _jsx(TMTooltip, { allowContentInteraction: true, content: renderDTDTooltipContent(dtd), children: children }) }));
|
|
263
264
|
};
|
|
265
|
+
/** Legge il tipo documento dalle cache dell'SDK senza passare dal mutex. Serve perché
|
|
266
|
+
* l'espansione di una cartella nell'albero ricrea tutte le celle: senza una lettura sincrona
|
|
267
|
+
* ogni riga tornerebbe a mostrare il testo di "nessuna selezione" fino alla fine delle
|
|
268
|
+
* richieste (una per TID, serializzate dal mutex).
|
|
269
|
+
* GetCache restituisce le mappe vive usate dall'SDK, quindi le invalidazioni
|
|
270
|
+
* (RemoveAllWithMetadata, RemoveAllWithoutMetadata, logout) hanno effetto immediato. */
|
|
271
|
+
const getCachedDTD = (tid, tmSession) => {
|
|
272
|
+
if (!tid || tid <= 0)
|
|
273
|
+
return undefined;
|
|
274
|
+
const accessToken = (tmSession ?? SDK_Globals.tmSession)?.SessionDescr?.accessToken;
|
|
275
|
+
if (!accessToken)
|
|
276
|
+
return undefined;
|
|
277
|
+
// La cache senza metadati è popolata dalla login: copre già i tipi documento autorizzati
|
|
278
|
+
return DcmtTypeListCacheService.GetCache(false).get(accessToken)?.find(o => o.id === tid)
|
|
279
|
+
?? DcmtTypeListCacheService.GetCache(true).get(accessToken)?.find(o => o.id === tid);
|
|
280
|
+
};
|
|
281
|
+
const shimmer = keyframes `
|
|
282
|
+
0% { background-position: 200% 0; }
|
|
283
|
+
100% { background-position: -200% 0; }
|
|
284
|
+
`;
|
|
285
|
+
/** Segnaposto animato mostrato al posto del nome durante il caricamento.
|
|
286
|
+
* Grigio semitrasparente: leggibile sia su sfondo chiaro che scuro. */
|
|
287
|
+
const StyledTidSkeleton = styled.span `
|
|
288
|
+
display: inline-block;
|
|
289
|
+
flex: 0 0 auto;
|
|
290
|
+
width: 90px;
|
|
291
|
+
height: 0.9em;
|
|
292
|
+
border-radius: 4px;
|
|
293
|
+
background-image: linear-gradient(90deg, rgba(127, 127, 127, 0.12) 25%, rgba(127, 127, 127, 0.28) 50%, rgba(127, 127, 127, 0.12) 75%);
|
|
294
|
+
background-size: 200% 100%;
|
|
295
|
+
animation: ${shimmer} 1.4s ease-in-out infinite;
|
|
296
|
+
|
|
297
|
+
@media (prefers-reduced-motion: reduce) { animation: none; }
|
|
298
|
+
`;
|
|
264
299
|
const TMTidViewer = ({ tmSession, tid, did, showIcon = false, color, showId = false, noneSelectionText = `<${SDKUI_Localizator.NoneSelection}>` }) => {
|
|
265
|
-
const
|
|
300
|
+
const accessToken = (tmSession ?? SDK_Globals.tmSession)?.SessionDescr?.accessToken;
|
|
301
|
+
const [dtd, setDtd] = useState(() => getCachedDTD(tid, tmSession));
|
|
302
|
+
const [isLoading, setIsLoading] = useState(() => !!tid && tid > 0 && !getCachedDTD(tid, tmSession));
|
|
266
303
|
const fetchData = async (tid, did) => {
|
|
267
304
|
if (!tid || tid <= 0) {
|
|
268
305
|
setDtd(undefined);
|
|
306
|
+
setIsLoading(false);
|
|
269
307
|
return;
|
|
270
308
|
}
|
|
309
|
+
const cached = getCachedDTD(tid, tmSession);
|
|
310
|
+
if (cached)
|
|
311
|
+
setDtd(cached);
|
|
312
|
+
setIsLoading(!cached);
|
|
271
313
|
let count = DcmtTypeListCacheService.CacheCount(true, 'all', tmSession);
|
|
272
314
|
if (count <= 0)
|
|
273
315
|
TMSpinner.show({ description: `${SDKUI_Localizator.Loading} - ${SDK_Localizator.ListDcmtTypeOrView} ...` });
|
|
@@ -281,11 +323,14 @@ const TMTidViewer = ({ tmSession, tid, did, showIcon = false, color, showId = fa
|
|
|
281
323
|
finally {
|
|
282
324
|
if (count <= 0)
|
|
283
325
|
TMSpinner.hide();
|
|
326
|
+
setIsLoading(false);
|
|
284
327
|
}
|
|
285
328
|
};
|
|
329
|
+
// accessToken e non tmSession: la sessione è un oggetto e un'identità nuova a ogni render
|
|
330
|
+
// del chiamante rifarebbe la richiesta senza motivo
|
|
286
331
|
useEffect(() => {
|
|
287
332
|
fetchData(tid, did);
|
|
288
|
-
}, [tid, did]);
|
|
333
|
+
}, [tid, did, accessToken]);
|
|
289
334
|
const displayName = () => {
|
|
290
335
|
if (!dtd)
|
|
291
336
|
return noneSelectionText;
|
|
@@ -295,16 +340,18 @@ const TMTidViewer = ({ tmSession, tid, did, showIcon = false, color, showId = fa
|
|
|
295
340
|
whiteSpace: 'nowrap',
|
|
296
341
|
overflow: 'hidden',
|
|
297
342
|
textOverflow: 'ellipsis'
|
|
298
|
-
}, children: [showIcon && dtd && _jsx(TMDcmtTypeIcon, { dtd: dtd }),
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
343
|
+
}, children: [showIcon && dtd && _jsx(TMDcmtTypeIcon, { dtd: dtd }), isLoading && !dtd
|
|
344
|
+
? _jsx(StyledTidSkeleton, { title: `${SDKUI_Localizator.Loading} ...`, style: { marginLeft: showIcon ? '5px' : undefined } })
|
|
345
|
+
: _jsx("p", { title: displayName(), style: {
|
|
346
|
+
textAlign: 'left',
|
|
347
|
+
margin: 0,
|
|
348
|
+
marginLeft: showIcon ? '5px' : '',
|
|
349
|
+
color: dtd?.isView ? 'red' : (color ?? TMColors.primary),
|
|
350
|
+
whiteSpace: 'nowrap',
|
|
351
|
+
overflow: 'hidden',
|
|
352
|
+
textOverflow: 'ellipsis',
|
|
353
|
+
// paddingRight: '10px'
|
|
354
|
+
}, children: displayName() }), showId && _jsx("p", { style: { padding: '0px 3px', margin: 0 }, children: `(TID: ${tid})` })] }));
|
|
308
355
|
};
|
|
309
356
|
export default TMTidViewer;
|
|
310
357
|
export const cellRenderTID = (data, noneSelectionText) => {
|
|
@@ -808,6 +808,7 @@ export declare class SDKUI_Localizator {
|
|
|
808
808
|
static get ShowLeftPanel(): "Linkes Panel anzeigen" | "Show left panel" | "Mostrar panel izquierdo" | "Afficher le panneau de gauche" | "Mostrar painel esquerdo" | "Mostra il pannello sinistro";
|
|
809
809
|
static get ShowMasterInfo(): string;
|
|
810
810
|
static get ShowPartialResults(): string;
|
|
811
|
+
static get ShowReleaseNotesInfo(): string;
|
|
811
812
|
static get ShowSearch(): "Suche anzeigen" | "Show search" | "Mostrar búsqueda" | "Afficher la recherche" | "Mostrar pesquisa" | "Mostra ricerca";
|
|
812
813
|
static get ShowSharedDocuments(): "Gemeinsame Dokumente anzeigen" | "Show shared documents" | "Mostrar documentos compartidos" | "Afficher les documents partagés" | "Mostrar documentos compartilhados" | "Mostra documenti condivisi";
|
|
813
814
|
static get ShowColumnSeparatingLines(): string;
|
|
@@ -8060,6 +8060,16 @@ export class SDKUI_Localizator {
|
|
|
8060
8060
|
default: return "Mostra risultati parziali";
|
|
8061
8061
|
}
|
|
8062
8062
|
}
|
|
8063
|
+
static get ShowReleaseNotesInfo() {
|
|
8064
|
+
switch (this._cultureID) {
|
|
8065
|
+
case CultureIDs.De_DE: return "Informationen zu den Versionshinweisen anzeigen";
|
|
8066
|
+
case CultureIDs.En_US: return "Show release notes information";
|
|
8067
|
+
case CultureIDs.Es_ES: return "Mostrar información sobre las notas de la versión";
|
|
8068
|
+
case CultureIDs.Fr_FR: return "Afficher les informations sur les notes de version";
|
|
8069
|
+
case CultureIDs.Pt_PT: return "Mostrar informações sobre as notas de versão";
|
|
8070
|
+
default: return "Mostra informazioni sulle note di rilascio";
|
|
8071
|
+
}
|
|
8072
|
+
}
|
|
8063
8073
|
static get ShowSearch() {
|
|
8064
8074
|
switch (this._cultureID) {
|
|
8065
8075
|
case CultureIDs.De_DE: return "Suche anzeigen";
|