@topconsultnpm/sdkui-react 6.22.0-dev4.7 → 6.22.0-dev4.8

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.
@@ -3,7 +3,7 @@ import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useSta
3
3
  import styled from 'styled-components';
4
4
  import { LoadIndicator } from 'devextreme-react';
5
5
  import { AppModules, DataColumnTypes, DataListViewModes, DcmtTypeListCacheService, LayoutCacheService, LayoutModes, MetadataDataDomains, SDK_Globals, SystemMIDsAsNumber, UserListCacheService, } from '@topconsultnpm/sdk-ts';
6
- import { customizeSearchByDisplayText, deepCompare, formatDateTimeByMetadataFormat, formatNumberByMetadataFormat, generateUniqueColumnKeys, genUniqueId, getColumnFormatInfo, getDateDisplayText, getNumberDisplayText, getSearchToolbarVisibility, IconAll, IconBoard, IconDcmtTypeSys, IconDelete, IconDuplicate, IconEdit, IconMenuVertical, IconPlatform, IconRefresh, IconSearchCheck, IconShow, isApprovalWorkflowView, isSign4TopEnabled, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, SDKUI_Globals, SDKUI_Localizator, IconCloseOutline, getSearchResultPanelLayout, getSearchResultPanelLayoutSignature, hasSearchResultPanelLayout, saveSearchResultPanelLayout, subscribeSearchResultPanelLayout, VIRTUAL_RENDERING_THRESHOLD } from '../../../helper';
6
+ import { customizeSearchByDisplayText, deepCompare, formatDateTimeByMetadataFormat, formatNumberByMetadataFormat, generateUniqueColumnKeys, genUniqueId, getColumnFormatInfo, getDateDisplayText, getNumberDisplayText, getSearchToolbarVisibility, IconAll, IconBoard, IconDcmtTypeSys, IconDelete, IconDuplicate, IconEdit, IconMenuVertical, IconPlatform, IconRefresh, IconSearchCheck, IconShow, isApprovalWorkflowView, isSign4TopEnabled, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, SDKUI_Globals, SDKUI_Localizator, IconCloseOutline, getSearchResultPanelLayout, getSearchResultPanelLayoutSignature, hasSearchResultPanelLayout, saveSearchResultPanelLayout, subscribeSearchResultPanelLayout, VIRTUAL_RENDERING_THRESHOLD, VIRTUAL_RENDERING_CELL_THRESHOLD } from '../../../helper';
7
7
  import { CounterItemKey, formatCount } from '../../base/TMCounterContainer';
8
8
  import { getDcmtCicoStatus } from '../../../helper/checkinCheckoutManager';
9
9
  import { DcmtOperationTypes, SearchResultContext, } from '../../../ts';
@@ -1403,14 +1403,16 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, i
1403
1403
  const gridSorting = useMemo(() => ({ mode: 'multiple' }), []);
1404
1404
  const gridSelection = useMemo(() => ({ mode: allowMultipleSelection ? 'multiple' : 'single' }), [allowMultipleSelection]);
1405
1405
  const useNativeScrollbar = SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar === 1;
1406
- // Con pagine grandi (oltre VIRTUAL_RENDERING_THRESHOLD righe) il rendering virtuale delle righe evita di creare nel DOM tutte le righe della pagina.
1407
- // Conta le righe effettive della pagina, non pageSize: con pochi risultati la griglia resta in rendering standard.
1406
+ // Rendering virtuale delle righe oltre VIRTUAL_RENDERING_THRESHOLD righe o VIRTUAL_RENDERING_CELL_THRESHOLD celle (righe effettive × colonne)
1408
1407
  const pageRowCount = Math.min(pageSize, dataSource?.length ?? 0);
1408
+ // +1 per la colonna icona (FILEEXT) sempre presente
1409
+ const visibleColumnCount = columns.filter(col => col.visible !== false && col.dataField !== 'FILEEXT').length + 1;
1410
+ const useVirtualRows = pageRowCount > VIRTUAL_RENDERING_THRESHOLD || pageRowCount * visibleColumnCount > VIRTUAL_RENDERING_CELL_THRESHOLD;
1409
1411
  const gridScrolling = useMemo(() => ({
1410
1412
  columnRenderingMode: 'virtual',
1411
- rowRenderingMode: pageRowCount > VIRTUAL_RENDERING_THRESHOLD ? 'virtual' : 'standard',
1413
+ rowRenderingMode: useVirtualRows ? 'virtual' : 'standard',
1412
1414
  useNative: useNativeScrollbar
1413
- }), [useNativeScrollbar, pageRowCount]);
1415
+ }), [useNativeScrollbar, useVirtualRows]);
1414
1416
  // Handles selection change in the data grid
1415
1417
  const handleSelectionChange = useCallback((e) => {
1416
1418
  if (onSelectionChanged === undefined)
@@ -1536,9 +1538,9 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, i
1536
1538
  return _jsxs("div", { style: { width: "100%", height: "100%" }, children: [!isDataGridReady && (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', gap: '10px' }, children: [_jsx(LoadIndicator, { height: 60, width: 60 }), _jsx("div", { children: SDKUI_Localizator.Loading })] })), isDataGridReady && _jsx(TMDataGrid, { ref: dataGridRef, id: "tm-search-result", keyExpr: "rowIndex", dataColumns: dataColumns, dataSource: dataSource, customizeColumns: customizeColumns, repaintChangesOnly: true, selectedRowKeys: selectedRowKeys, focusedRowKey: disableAutoFocus ? undefined : Number(focusedItem?.rowIndex ?? 0), showSearchPanel: showSearchTMDatagrid, showFilterPanel: true, sorting: gridSorting, selection: gridSelection, scrolling: gridScrolling, pageSize: pageSize, compactPager: compactPager, onSelectionChanged: handleSelectionChange, onFocusedRowChanged: handleFocusedRowChange, onRowDblClick: onRowDblClick, onContentReady: onContentReady, showHeaderColumnChooser: true, onKeyDown: onKeyDown, customContextMenuItems: operationItems, counterConfig: gridCounterConfig })] });
1537
1539
  };
1538
1540
  //#region TMSearchResultSelector
1539
- const StyledItemTemplate = styled.div `
1540
- background: ${(props) => props.$isSelected ? 'oklch(from var(--dx-color-primary) l c h / .2) !important' : 'transparent'};
1541
- cursor: pointer;
1541
+ const StyledItemTemplate = styled.div `
1542
+ background: ${(props) => props.$isSelected ? 'oklch(from var(--dx-color-primary) l c h / .2) !important' : 'transparent'};
1543
+ cursor: pointer;
1542
1544
  `;
1543
1545
  const MemoizedStyledItemTemplate = React.memo(StyledItemTemplate);
1544
1546
  const TMSearchResultSelector = ({ searchResults = [], disableAccordionIfSingleCategory = false, selectedTID, selectedSearchResult, autoSelectFirst = true, onSelectionChanged }) => {
@@ -1745,85 +1747,85 @@ const TMDcmtPreviewWrapper = ({ refreshPreviewTrigger, currentDcmt, isVisible, i
1745
1747
  return (_jsx(TMDcmtPreview, { dcmtData: currentDcmt, onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, onBack: onBack, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, isResizingActive: isResizingActive, isVisible: isVisible && isPageVisible }, refreshPreviewTrigger));
1746
1748
  };
1747
1749
  // Styled Components
1748
- const StyledPlaceholder = styled.div `
1749
- padding: 20px;
1750
- text-align: center;
1751
- color: #888;
1750
+ const StyledPlaceholder = styled.div `
1751
+ padding: 20px;
1752
+ text-align: center;
1753
+ color: #888;
1752
1754
  `;
1753
- const StyledIndexingInfoSection = styled.div `
1754
- padding: 15px;
1755
- border-top: 1px solid #e0e0e0;
1756
- background: linear-gradient(to bottom, #f9f9f9, #f5f5f5);
1757
- display: flex;
1758
- flex-direction: column;
1759
- gap: 10px;
1755
+ const StyledIndexingInfoSection = styled.div `
1756
+ padding: 15px;
1757
+ border-top: 1px solid #e0e0e0;
1758
+ background: linear-gradient(to bottom, #f9f9f9, #f5f5f5);
1759
+ display: flex;
1760
+ flex-direction: column;
1761
+ gap: 10px;
1760
1762
  `;
1761
- const StyledIndexingToggle = styled.button `
1762
- display: flex;
1763
- align-items: center;
1764
- justify-content: space-between;
1765
- width: 100%;
1766
- padding: 10px 16px;
1767
- background: white;
1768
- border: 1px solid #d0d0d0;
1769
- border-radius: 6px;
1770
- cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};
1771
- transition: all 0.2s ease;
1772
- font-size: 14px;
1773
- font-weight: 500;
1774
- color: #333;
1775
- opacity: ${props => props.disabled ? 0.6 : 1};
1776
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
1777
-
1778
- &:hover:not(:disabled) {
1779
- background: #f8f8f8;
1780
- border-color: #2196F3;
1781
- box-shadow: 0 2px 4px rgba(33, 150, 243, 0.2);
1782
- }
1783
-
1784
- &:active:not(:disabled) {
1785
- transform: translateY(1px);
1786
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
1787
- }
1763
+ const StyledIndexingToggle = styled.button `
1764
+ display: flex;
1765
+ align-items: center;
1766
+ justify-content: space-between;
1767
+ width: 100%;
1768
+ padding: 10px 16px;
1769
+ background: white;
1770
+ border: 1px solid #d0d0d0;
1771
+ border-radius: 6px;
1772
+ cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};
1773
+ transition: all 0.2s ease;
1774
+ font-size: 14px;
1775
+ font-weight: 500;
1776
+ color: #333;
1777
+ opacity: ${props => props.disabled ? 0.6 : 1};
1778
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
1779
+
1780
+ &:hover:not(:disabled) {
1781
+ background: #f8f8f8;
1782
+ border-color: #2196F3;
1783
+ box-shadow: 0 2px 4px rgba(33, 150, 243, 0.2);
1784
+ }
1785
+
1786
+ &:active:not(:disabled) {
1787
+ transform: translateY(1px);
1788
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
1789
+ }
1788
1790
  `;
1789
- const StyledLeftContent = styled.div `
1790
- display: flex;
1791
- align-items: center;
1792
- gap: 8px;
1791
+ const StyledLeftContent = styled.div `
1792
+ display: flex;
1793
+ align-items: center;
1794
+ gap: 8px;
1793
1795
  `;
1794
- const StyledRightContent = styled.div `
1795
- display: flex;
1796
- align-items: center;
1797
- gap: 8px;
1796
+ const StyledRightContent = styled.div `
1797
+ display: flex;
1798
+ align-items: center;
1799
+ gap: 8px;
1798
1800
  `;
1799
- const StyledChevron = styled.span `
1800
- transition: transform 0.2s ease;
1801
- transform: ${props => props.$isOpen ? 'rotate(180deg)' : 'rotate(0deg)'};
1802
- color: #666;
1803
- font-size: 12px;
1801
+ const StyledChevron = styled.span `
1802
+ transition: transform 0.2s ease;
1803
+ transform: ${props => props.$isOpen ? 'rotate(180deg)' : 'rotate(0deg)'};
1804
+ color: #666;
1805
+ font-size: 12px;
1804
1806
  `;
1805
- const StyledIndexingInfoBox = styled.div `
1806
- position: relative;
1807
- background: white;
1808
- border: 1px solid #e0e0e0;
1809
- border-radius: 6px;
1810
- padding: 12px;
1811
- max-height: 200px;
1812
- overflow: auto;
1813
- font-family: 'Courier New', monospace;
1814
- font-size: 12px;
1815
- color: #333;
1816
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
1817
- animation: slideDown 0.2s ease;
1818
-
1819
- @keyframes slideDown {
1820
- from {
1821
- opacity: 0;
1822
- transform: translateY(-10px);
1823
- }
1824
- to {
1825
- opacity: 1;
1826
- transform: translateY(0);
1827
- }
1828
- }
1807
+ const StyledIndexingInfoBox = styled.div `
1808
+ position: relative;
1809
+ background: white;
1810
+ border: 1px solid #e0e0e0;
1811
+ border-radius: 6px;
1812
+ padding: 12px;
1813
+ max-height: 200px;
1814
+ overflow: auto;
1815
+ font-family: 'Courier New', monospace;
1816
+ font-size: 12px;
1817
+ color: #333;
1818
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
1819
+ animation: slideDown 0.2s ease;
1820
+
1821
+ @keyframes slideDown {
1822
+ from {
1823
+ opacity: 0;
1824
+ transform: translateY(-10px);
1825
+ }
1826
+ to {
1827
+ opacity: 1;
1828
+ transform: translateY(0);
1829
+ }
1830
+ }
1829
1831
  `;
@@ -69,6 +69,9 @@ export declare const DEFAULT_PREVIEW_THRESHOLD = 500;
69
69
  export declare const DEFAULT_PAGE_SIZE = 200;
70
70
  /** Oltre questo numero di righe per pagina la griglia dei risultati usa il rendering virtuale delle righe */
71
71
  export declare const VIRTUAL_RENDERING_THRESHOLD = 500;
72
+ /** Oltre questo numero di celle per pagina (righe × colonne visibili) la griglia dei risultati usa il rendering virtuale delle righe:
73
+ * il costo di rendering, selezione e repaint cresce con le celle, non solo con le righe */
74
+ export declare const VIRTUAL_RENDERING_CELL_THRESHOLD = 3000;
72
75
  export declare const DEFAULT_MAX_DCMTS_TO_BE_RETURNED = 1000;
73
76
  export declare const DEFAULT_QUICK_SEARCH_MAX_DCMTS = 1000;
74
77
  /** Ricerca rapida configurata come sorgente alternativa dei valori distinti di un campo */
@@ -132,6 +132,9 @@ export const DEFAULT_PREVIEW_THRESHOLD = 500; // KB
132
132
  export const DEFAULT_PAGE_SIZE = 200;
133
133
  /** Oltre questo numero di righe per pagina la griglia dei risultati usa il rendering virtuale delle righe */
134
134
  export const VIRTUAL_RENDERING_THRESHOLD = 500;
135
+ /** Oltre questo numero di celle per pagina (righe × colonne visibili) la griglia dei risultati usa il rendering virtuale delle righe:
136
+ * il costo di rendering, selezione e repaint cresce con le celle, non solo con le righe */
137
+ export const VIRTUAL_RENDERING_CELL_THRESHOLD = 3000;
135
138
  export const DEFAULT_MAX_DCMTS_TO_BE_RETURNED = 1000;
136
139
  export const DEFAULT_QUICK_SEARCH_MAX_DCMTS = 1000;
137
140
  /** Ricerca rapida configurata come sorgente alternativa dei valori distinti di un campo */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.22.0-dev4.7",
3
+ "version": "6.22.0-dev4.8",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" \u0026\u0026 exit 1",