@topconsultnpm/sdkui-react-beta 6.13.25 → 6.13.27

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.
@@ -116,8 +116,10 @@ const StyledAdvancedButton = styled.div `
116
116
  cursor: ${props => !props.$isDisabled ? 'pointer' : 'default'};
117
117
  border-radius: 10px;
118
118
  overflow: hidden;
119
- color: white;
119
+ color: ${({ $isPrimaryOutline }) => $isPrimaryOutline ? TMColors.primaryColor : 'white'};
120
120
  user-select: none;
121
+ border: ${({ $isPrimaryOutline }) => $isPrimaryOutline ? `1px solid ${TMColors.primaryColor}` : 'none'};
122
+ background: ${({ $isPrimaryOutline }) => $isPrimaryOutline ? 'white' : 'unset'};
121
123
  `;
122
124
  const StyledAdvancedButtonIcon = styled.div `
123
125
  display: flex;
@@ -140,6 +142,7 @@ const StyledAdvancedButtonText = styled.div `
140
142
  background-color: ${props => props.$isDisabled ? '#d1d1d1' : props.$color ? props.$color : props.$type === 'success' ? `${TMColors.success}` : props.$type === 'error' ? `${TMColors.error}` : props.$type === 'tertiary' ? `${TMColors.tertiary}` : `${TMColors.primary}`};
141
143
  border-top-right-radius: 10px;
142
144
  border-bottom-right-radius: 10px;
145
+ padding: 5px;
143
146
  `;
144
147
  const TMButton = ({ width, height, keyGesture, btnStyle = 'normal', advancedColor, advancedType = 'primary', color = 'primary', fontSize = FontSize.defaultFontSize, disabled = false, showTooltip = true, caption, icon, description, padding, elementStyle, onClick = () => { } }) => {
145
148
  const [isHovered, setIsHovered] = useState(false);
@@ -189,7 +192,7 @@ const TMButton = ({ width, height, keyGesture, btnStyle = 'normal', advancedColo
189
192
  return (_jsx(StyledIconButton, { color: color, caption: caption, disabled: disabled, fontSize: fontSize, padding: padding, onClick: onClick, children: icon }));
190
193
  }
191
194
  else if (btnStyle === 'advanced') {
192
- return (_jsxs(StyledAdvancedButton, { "$width": width ?? '90px', "$height": height ?? '30px', onMouseOver: () => !disabled && setIsHovered(true), onMouseOut: () => setIsHovered(false), "$isDisabled": disabled, onClick: () => !disabled && onClick?.(), children: [_jsx(StyledAdvancedButtonIcon, { "$color": advancedColor, "$isVisible": isHovered, "$isDisabled": disabled, "$type": advancedType, children: icon }), _jsxs(StyledAdvancedButtonText, { "$color": advancedColor, "$isDisabled": disabled, "$type": advancedType, children: [" ", caption, " "] })] }));
195
+ return (_jsxs(StyledAdvancedButton, { "$width": width ?? '90px', "$height": height ?? '30px', onMouseOver: () => !disabled && setIsHovered(true), onMouseOut: () => setIsHovered(false), "$isDisabled": disabled, "$isPrimaryOutline": advancedType === 'primary' && (advancedColor === 'primaryOutline' || color === 'primaryOutline'), onClick: () => !disabled && onClick?.(), children: [_jsx(StyledAdvancedButtonIcon, { "$color": advancedColor, "$isVisible": isHovered, "$isDisabled": disabled, "$type": advancedType, children: icon }), _jsx(StyledAdvancedButtonText, { "$color": advancedColor, "$isDisabled": disabled, "$type": advancedType, children: caption })] }));
193
196
  }
194
197
  else {
195
198
  return (_jsx(StyledTextButton, { color: color, caption: caption, disabled: disabled, fontSize: fontSize, onClick: onClick, children: caption }));
@@ -6,9 +6,9 @@ import TMContextMenu, { useTMContextMenu } from './TMContextMenu';
6
6
  import { IconApply, IconCloseCircle, IconColumns, IconDown, IconHide, IconShow, IconUp, IconVisible } from '../../helper/TMIcons';
7
7
  import { TMSearchBar } from '../sidebar/TMHeader';
8
8
  import TMTooltip from './TMTooltip';
9
- import { SDKUI_Localizator } from '../../helper';
9
+ import { getContrastColor, SDKUI_Localizator } from '../../helper';
10
10
  import { TMColors } from '../../utils/theme';
11
- const StyledListItem = styled.div ` width: 100%; height: max-content; border-bottom: 1px solid #e5e5e5; background-color: ${props => props.$isSelected ? props.$color ? `${props.$color}99` : '#00000030' : 'transparent'} ; color: ${props => props.$isSelected ? props.$color ? 'white' : '#000000' : '#000000'} ; &:hover{ background-color: ${props => props.$color ? props.$isSelected ? `${props.$color}99` : `${props.$color}40` : props.$isSelected ? '#00000030' : '#00000010'};} `;
11
+ const StyledListItem = styled.div ` width: 100%; height: max-content; border-bottom: 1px solid #e5e5e5; background-color: ${props => props.$isSelected ? props.$color ? `${props.$color}99` : '#00000030' : 'transparent'} ; color: ${props => props.$isSelected ? props.$textColor : '#000000'} ; &:hover{ background-color: ${props => props.$color ? props.$isSelected ? `${props.$color}99` : `${props.$color}40` : props.$isSelected ? '#00000030' : '#00000010'};} `;
12
12
  const StyledListViewContainer = styled.div ` position: relative; display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; width: 100%; height: 100%; `;
13
13
  const StyledSearchContainer = styled.div ` width: 100%; height: max-content; padding: 5px; border-bottom: 1px solid #e5e5e5; display: flex; align-items: center; gap: 10px; `;
14
14
  const StyledListViewFooter = styled.div ` background-color: ${props => props.$bgColor}; width: 100%; height: 25px; padding: 5px 15px; border-top: 1px solid #e5e5e5; display: flex; align-items: center; gap: 10px; `;
@@ -257,7 +257,7 @@ const TMListView = ({ customGroupingHeaders, headerBackGroundColor, header, show
257
257
  }
258
258
  // map memo
259
259
  const memoList = useMemo(() => currentDataSource.map((data, index) => {
260
- return (_jsx(StyledListItem, { "$isSelected": isSelected(data), "$color": customColor, onClick: () => { onSelectionChanged && onSelectionChanged(data); onItemClick && onItemClick(data); }, onDoubleClick: () => onItemDblClick && onItemDblClick(data), children: _jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'flex-start', justifyContent: 'flex-start', gap: 5, padding: '5px 5px' }, children: [localShowId && _jsxs("p", { style: { color: isSelected(data) ? 'white' : 'black', backgroundColor: `${customColor}20`, width: '100%', padding: '2px 5px', borderRadius: '5px', height: 'max-content', textAlign: 'left' }, children: [" ", exprKey + ' : ' + data[exprKey], " "] }), _jsxs("div", { style: { width: '100%', height: '100%' }, children: [" ", itemTemplate ? itemTemplate(data) : _jsx("div", {})] })] }) }, index));
260
+ return (_jsx(StyledListItem, { "$isSelected": isSelected(data), "$color": getContrastColor(customColor).bgColor, "$textColor": getContrastColor(customColor).textColor, onClick: () => { onSelectionChanged && onSelectionChanged(data); onItemClick && onItemClick(data); }, onDoubleClick: () => onItemDblClick && onItemDblClick(data), children: _jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'flex-start', justifyContent: 'flex-start', gap: 5, padding: '5px 5px' }, children: [localShowId && _jsxs("p", { style: { color: isSelected(data) ? 'red' : 'black', backgroundColor: `${customColor}20`, width: '100%', padding: '2px 5px', borderRadius: '5px', height: 'max-content', textAlign: 'left' }, children: [" ", exprKey + ' : ' + data[exprKey], " "] }), _jsxs("div", { style: { width: '100%', height: '100%' }, children: [" ", itemTemplate ? itemTemplate(data) : _jsx("div", {})] })] }) }, index));
261
261
  }), [currentDataSource, selectedItem, localShowId, customColor]);
262
262
  const groupedMemoList = useMemo(() => groupKeys.map((key, index) => {
263
263
  const groupingText = () => {
@@ -282,9 +282,9 @@ const TMListView = ({ customGroupingHeaders, headerBackGroundColor, header, show
282
282
  customGroupingHeaders[index] ?
283
283
  _jsx("div", { style: { width: '100%', height: '100%', display: 'flex', alignItems: 'center' }, children: customGroupingHeaders[index] })
284
284
  :
285
- _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 10 }, children: [_jsx("p", { children: groupingText() }), _jsx("div", { style: { width: '16px', height: '16px', display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: customColor, color: 'white', boxShadow: '1px 1px 2px #00000020', borderRadius: '30px', fontWeight: 'bold' }, children: groupByKey(currentDataSource, grouping)[key].length })] })
285
+ _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 10 }, children: [_jsx("p", { children: groupingText() }), _jsx("div", { style: { width: '16px', height: '16px', display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: getContrastColor(customColor).textColor, color: getContrastColor(customColor).bgColor, boxShadow: '1px 1px 2px #00000020', borderRadius: '30px', fontWeight: 'bold' }, children: groupByKey(currentDataSource, grouping)[key].length })] })
286
286
  :
287
- _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 10 }, children: [_jsx("p", { children: groupingText() }), _jsx("div", { style: { width: '16px', height: '16px', display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: customColor, color: 'white', boxShadow: '1px 1px 2px #00000020', borderRadius: '30px', fontWeight: 'bold' }, children: groupByKey(currentDataSource, grouping)[key].length })] }), _jsxs("div", { style: { cursor: 'pointer' }, onClick: () => { let arr = [...openList]; arr[index] = !arr[index]; setOpenList(arr); }, children: [" ", openList[index] ? _jsx(IconUp, { fontSize: 12 }) : _jsx(IconDown, { fontSize: 12 }), " "] })] }) }), openList[index] && _jsx("div", { style: { width: '100%', height: '100%' }, children: groupByKey(currentDataSource, grouping)[key].map((data, index2) => (_jsx(StyledListItem, { "$isSelected": data === selectedItem, "$color": customColor, onClick: () => { onSelectionChanged && onSelectionChanged(data); onItemClick && onItemClick(data); }, onDoubleClick: () => { onItemDblClick && onItemDblClick(data); }, children: _jsxs("div", { style: { width: '100%', height: 'max-content', display: 'flex', flexDirection: 'column', padding: '5px 5px' }, children: [localShowId && _jsxs("p", { style: { color: data === selectedItem ? 'white' : 'black', backgroundColor: `${customColor}20`, width: '100%', padding: '2px 5px', borderRadius: '5px', height: 'max-content', textAlign: 'left' }, children: [" ", 'ID: ' + data.id, " "] }), _jsxs("div", { style: { width: '100%', height: '100%' }, children: [" ", itemTemplate ? itemTemplate(data) : _jsx("div", {})] })] }) }, index2))) })] }, index));
287
+ _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 10 }, children: [_jsx("p", { children: groupingText() }), _jsx("div", { style: { width: '16px', height: '16px', display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: getContrastColor(customColor).textColor, color: getContrastColor(customColor).bgColor, boxShadow: '1px 1px 2px #00000020', borderRadius: '30px', fontWeight: 'bold' }, children: groupByKey(currentDataSource, grouping)[key].length })] }), _jsxs("div", { style: { cursor: 'pointer' }, onClick: () => { let arr = [...openList]; arr[index] = !arr[index]; setOpenList(arr); }, children: [" ", openList[index] ? _jsx(IconUp, { fontSize: 12 }) : _jsx(IconDown, { fontSize: 12 }), " "] })] }) }), openList[index] && _jsx("div", { style: { width: '100%', height: '100%' }, children: groupByKey(currentDataSource, grouping)[key].map((data, index2) => (_jsx(StyledListItem, { "$isSelected": data === selectedItem, "$color": getContrastColor(customColor).bgColor, "$textColor": getContrastColor(customColor).textColor, onClick: () => { onSelectionChanged && onSelectionChanged(data); onItemClick && onItemClick(data); }, onDoubleClick: () => { onItemDblClick && onItemDblClick(data); }, children: _jsxs("div", { style: { width: '100%', height: 'max-content', display: 'flex', flexDirection: 'column', padding: '5px 5px' }, children: [localShowId && _jsxs("p", { style: { color: data === selectedItem ? 'red' : 'black', backgroundColor: `${customColor}20`, width: '100%', padding: '2px 5px', borderRadius: '5px', height: 'max-content', textAlign: 'left' }, children: [" ", 'ID: ' + data.id, " "] }), _jsxs("div", { style: { width: '100%', height: '100%' }, children: [" ", itemTemplate ? itemTemplate(data) : _jsx("div", {})] })] }) }, index2))) })] }, index));
288
288
  }), [currentDataSource, selectedItem, localShowId, customColor, openList, grouping, customGroupingHeaders]);
289
289
  // List height
290
290
  const listHeight = () => {
@@ -1,14 +1,19 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { getListMaxItems } from '../../helper';
3
- import { TMColors } from '../../utils/theme';
4
3
  import TMButton from './TMButton';
5
4
  import { useDeviceType, DeviceType } from './TMDeviceProvider';
6
5
  const TMShowAllOrMaxItemsButton = ({ showAll, dataSourceLength, onClick }) => {
7
6
  const deviceType = useDeviceType();
8
7
  let maxItems = getListMaxItems(deviceType ?? DeviceType.DESKTOP);
9
- const captionText = showAll ? "Mostra meno" : `Mostra tutti (+${dataSourceLength - maxItems})`;
10
- return (_jsx(TMButton, { elementStyle: { position: 'absolute', right: '10px' }, btnStyle: 'icon', caption: captionText, icon: showAll ?
11
- _jsx("div", { style: { backgroundColor: TMColors.primaryColor, minWidth: '30px', minHeight: '30px', borderRadius: '10px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx("p", { style: { color: 'white' }, children: `-${dataSourceLength - maxItems}` }) }) :
12
- _jsx("div", { style: { backgroundColor: TMColors.primaryColor, minWidth: '30px', minHeight: '30px', borderRadius: '10px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx("p", { style: { color: 'white' }, children: `+${dataSourceLength - maxItems}` }) }), onClick: () => onClick?.() }));
8
+ const captionText = showAll ? "Mostra meno" : `Mostra tutti`;
9
+ const isMobile = deviceType === DeviceType.MOBILE;
10
+ return (_jsx(_Fragment, { children: isMobile ?
11
+ _jsx(TMButton, { elementStyle: { position: 'absolute', right: '10px' }, btnStyle: 'icon', caption: captionText, icon: showAll ?
12
+ _jsx("div", { style: { backgroundColor: '#4A96D2', minWidth: '30px', minHeight: '30px', borderRadius: '10px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx("p", { style: { color: 'white' }, children: `-${dataSourceLength - maxItems}` }) }) :
13
+ _jsx("div", { style: { backgroundColor: '#4A96D2', minWidth: '30px', minHeight: '30px', borderRadius: '10px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx("p", { style: { color: 'white' }, children: `+${dataSourceLength - maxItems}` }) }), onClick: () => onClick?.() })
14
+ :
15
+ _jsx(TMButton, { elementStyle: { position: 'absolute', right: '10px' }, width: 'auto', btnStyle: 'advanced', advancedColor: '#4A96D2', caption: captionText, showTooltip: false, icon: showAll
16
+ ? _jsx("p", { style: { color: 'white' }, children: `-${dataSourceLength - maxItems}` })
17
+ : _jsx("p", { style: { color: 'white' }, children: `+${dataSourceLength - maxItems}` }), onClick: () => onClick?.() }) }));
13
18
  };
14
19
  export default TMShowAllOrMaxItemsButton;
@@ -1,16 +1,18 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React, { useEffect, useState } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import { SharingModes, SDK_Globals, SDK_Localizator } from '@topconsultnpm/sdk-ts-beta';
5
5
  import { LocalizeSharingModes } from '../../../helper/Enum_Localizator';
6
6
  import ContextMenu from 'devextreme-react/cjs/context-menu';
7
- import { SDKUI_Localizator, Globalization, svgToString, IconStar, IconDelete, IconDashboard, IconApply } from '../../../helper';
7
+ import { SDKUI_Localizator, Globalization, svgToString, IconStar, IconDelete, IconDashboard, IconSavedQuery, IconApply, IconInfo } from '../../../helper';
8
8
  import { TMColors } from '../../../utils/theme';
9
9
  import ShowAlert from '../../base/TMAlert';
10
10
  import TMButton from '../../base/TMButton';
11
11
  import { TMMessageBoxManager, ButtonNames, TMExceptionBoxManager } from '../../base/TMPopUp';
12
12
  import TMSpinner from '../../base/TMSpinner';
13
+ import TMTooltip from '../../base/TMTooltip';
13
14
  import { TMSearchBar } from '../../sidebar/TMHeader';
15
+ import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
14
16
  const StyledSqdItem = styled.div `
15
17
  display: flex;
16
18
  flex-direction: column;
@@ -26,6 +28,21 @@ const StyledSqdItem = styled.div `
26
28
  cursor: pointer;
27
29
  }
28
30
 
31
+ .info-icon {
32
+ position: absolute;
33
+ left: -2px;
34
+ top: 50%;
35
+ transform: translateY(-50%);
36
+ opacity: ${({ $isMobile }) => ($isMobile ? 1 : 0)};
37
+ transition: opacity 0.2s;
38
+ pointer-events: ${({ $isMobile }) => ($isMobile ? 'auto' : 'none')};
39
+ }
40
+
41
+ &:hover .info-icon {
42
+ opacity: 1;
43
+ pointer-events: auto;
44
+ }
45
+
29
46
  &:last-child {
30
47
  border-bottom: none; // remove border for last item
31
48
  margin-bottom: 0;
@@ -42,7 +59,7 @@ const getSharingModeColor = (sharingMode) => {
42
59
  export const getTooltipBySqd = (sqd) => {
43
60
  if (!sqd)
44
61
  return null;
45
- return (_jsxs("div", { style: { textAlign: "left" }, children: [_jsxs("div", { children: ["ID: ", sqd.id] }), _jsxs("div", { children: ["Master TID: ", sqd.masterTID] }), _jsx("div", { children: sqd.description }), _jsx("hr", {}), _jsxs("div", { children: [SDKUI_Localizator.OwnerName, ": ", sqd.ownerName, " (", sqd.ownerID, ")"] }), _jsx("div", { children: LocalizeSharingModes(sqd.sharingMode) }), _jsxs("div", { children: ["Default: ", sqd.isDefault == 1 ? SDKUI_Localizator.Yes : SDKUI_Localizator.No] }), _jsxs("div", { children: ["Filtro semplice", ": ", sqd.isEasyWhere == 1 ? SDKUI_Localizator.Yes : SDKUI_Localizator.No] }), _jsxs("div", { children: ["Esegui ricerca immediatamente", ": ", sqd.runSearchWhenSelected == 1 ? SDKUI_Localizator.Yes : SDKUI_Localizator.No] }), _jsx("hr", {}), _jsxs("div", { children: [SDKUI_Localizator.CreationTime, ": ", Globalization.getDateTimeDisplayValue(sqd.creationTime)] }), _jsxs("div", { children: [SDKUI_Localizator.LastUpdateTime, ": ", Globalization.getDateTimeDisplayValue(sqd.lastUpdateTime)] })] }));
62
+ return (_jsxs("div", { style: { textAlign: "left" }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 10 }, children: [_jsx(IconSavedQuery, { color: getSharingModeColor(sqd.sharingMode), fontSize: 20, style: { flexShrink: 0 } }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs("div", { children: ["ID: ", sqd.id] }), _jsxs("div", { children: ["Master TID: ", sqd.masterTID] }), sqd.description && _jsx("div", { children: `${SDKUI_Localizator.Description}: ${sqd.description}` })] })] }), _jsx("hr", {}), _jsxs("div", { children: [SDKUI_Localizator.OwnerName, ": ", sqd.ownerName, " (", sqd.ownerID, ")"] }), _jsx("div", { children: LocalizeSharingModes(sqd.sharingMode) }), _jsxs("div", { children: ["Default: ", sqd.isDefault == 1 ? SDKUI_Localizator.Yes : SDKUI_Localizator.No] }), _jsxs("div", { children: ["Filtro semplice", ": ", sqd.isEasyWhere == 1 ? SDKUI_Localizator.Yes : SDKUI_Localizator.No] }), _jsxs("div", { children: ["Esegui ricerca immediatamente", ": ", sqd.runSearchWhenSelected == 1 ? SDKUI_Localizator.Yes : SDKUI_Localizator.No] }), _jsx("hr", {}), _jsxs("div", { children: [SDKUI_Localizator.CreationTime, ": ", Globalization.getDateTimeDisplayValue(sqd.creationTime)] }), _jsxs("div", { children: [SDKUI_Localizator.LastUpdateTime, ": ", Globalization.getDateTimeDisplayValue(sqd.lastUpdateTime)] })] }));
46
63
  };
47
64
  const initialSQDsMaxItems = 12;
48
65
  const SavedQueryContexMenu = ({ sqd, manageDefault, deleteAsync, favManageAsync, setDefaultAsync }) => _jsx(ContextMenu, { items: manageDefault ? [
@@ -65,6 +82,8 @@ const TMSavedQuerySelector = React.memo(({ items, selectedId, allowShowSearch =
65
82
  const [selectedItem, setSelectedItem] = useState();
66
83
  const [searchText, setSearchText] = useState('');
67
84
  const [showAllRoot, setShowAllRoot] = useState(false);
85
+ const deviceType = useDeviceType();
86
+ const isMobile = deviceType === DeviceType.MOBILE;
68
87
  useEffect(() => { loadDataAsync(false); }, [items]);
69
88
  useEffect(() => { setSelectedItem(dataSource.find(o => o.id == selectedId)); }, [selectedId, dataSource]);
70
89
  const loadDataAsync = async (refreshCache) => {
@@ -121,13 +140,13 @@ const TMSavedQuerySelector = React.memo(({ items, selectedId, allowShowSearch =
121
140
  display: 'flex',
122
141
  flexDirection: 'column',
123
142
  width: '100%',
124
- padding: '5px',
143
+ padding: '5px 10px',
125
144
  gap: '3px',
126
145
  overflow: 'auto'
127
- }, children: dataSource.slice(0, showAllRoot || searchText.length > 0 ? dataSource.length : initialSQDsMaxItems).filter(o => searchText.length <= 0 || (searchText.length > 0 && o.name?.toLocaleLowerCase().includes(searchText.toLocaleLowerCase())) || o.description?.toLocaleLowerCase().includes(searchText.toLocaleLowerCase())).map((sqd, index) => (_jsxs(StyledSqdItem, { id: `sqd-item-${sqd.id}`, onClick: () => {
146
+ }, children: dataSource.slice(0, showAllRoot || searchText.length > 0 ? dataSource.length : initialSQDsMaxItems).filter(o => searchText.length <= 0 || (searchText.length > 0 && o.name?.toLocaleLowerCase().includes(searchText.toLocaleLowerCase())) || o.description?.toLocaleLowerCase().includes(searchText.toLocaleLowerCase())).map((sqd, index) => (_jsxs(StyledSqdItem, { id: `sqd-item-${sqd.id}`, "$isMobile": isMobile, onClick: () => {
128
147
  setSelectedItem(sqd);
129
148
  onItemClick?.(sqd);
130
- }, children: [_jsxs("div", { style: {
149
+ }, children: [_jsx("span", { className: "info-icon", children: _jsx(TMTooltip, { content: getTooltipBySqd(sqd), children: _jsx(IconInfo, { color: TMColors.primaryColor }) }) }), _jsxs("div", { style: {
131
150
  display: 'flex',
132
151
  flexDirection: 'row',
133
152
  justifyContent: 'center',
@@ -22,6 +22,7 @@ import { TMMetadataChooserForm } from '../../choosers/TMMetadataChooser';
22
22
  import TMQueryEditor from '../../query/TMQueryEditor';
23
23
  import TMSavedQueryForm from './TMSavedQueryForm';
24
24
  import { AdvancedMenuButtons } from '../../editors/TMMetadataValues';
25
+ import TMShowAllOrMaxItemsButton from '../../base/TMShowAllOrMaxItemsButton';
25
26
  const TMSearchQueryPanel = ({ fromDTD, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, SQD, onSearchCompleted, onFocusedMetadataChanged, onSqdSaved, onBack }) => {
26
27
  const [confirmQueryParams, ConfirmQueryParamsDialog] = useQueryParametersDialog();
27
28
  const [qd, setQd] = useState();
@@ -120,9 +121,8 @@ const TMSearchQueryPanel = ({ fromDTD, isExpertMode = SDKUI_Globals.userSettings
120
121
  setShowDistinctValuesPanel(true);
121
122
  }
122
123
  }, onQdChanged: (newQd) => { if (!deepCompare(qd, newQd))
123
- setQd(newQd); } }), _jsxs("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '80px', padding: '15px', position: 'relative' }, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '8px' }, children: [_jsx(TMButton, { btnStyle: 'advanced', icon: _jsx(IconSearch, {}), showTooltip: false, caption: SDKUI_Localizator.Search, onClick: async () => await searchAsync(qd, showAdvancedSearch), advancedColor: '#f09c0a' }), _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, caption: SDKUI_Localizator.Clear, icon: _jsx(IconClear, {}), advancedColor: TMColors.primaryColor, onClick: clearFilters })] }), (!showAdvancedSearch && qd?.where && qd?.where?.length > initialMaxItems) && _jsx(TMButton, { elementStyle: { position: 'absolute', right: '10px' }, btnStyle: 'icon', caption: showAllMdWhere ? "Mostra meno" : `Mostra tutti i metadati (+${qd?.where?.length - initialMaxItems})`, icon: showAllMdWhere ?
124
- _jsx("div", { style: { backgroundColor: TMColors.primaryColor, minWidth: '30px', minHeight: '30px', borderRadius: '10px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx("p", { style: { color: 'white' }, children: `-${qd?.where?.length - initialMaxItems}` }) }) :
125
- _jsx("div", { style: { backgroundColor: TMColors.primaryColor, minWidth: '30px', minHeight: '30px', borderRadius: '10px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx("p", { style: { color: 'white' }, children: `+${qd?.where?.length - initialMaxItems}` }) }), onClick: () => setShowAllMdWhere(!showAllMdWhere) })] }), showFiltersConfig &&
124
+ setQd(newQd); } }), _jsxs("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '80px', padding: '15px', position: 'relative' }, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '8px' }, children: [_jsx(TMButton, { btnStyle: 'advanced', icon: _jsx(IconSearch, {}), showTooltip: false, caption: SDKUI_Localizator.Search, advancedColor: '#4A96D2', onClick: async () => await searchAsync(qd, showAdvancedSearch) }), _jsx(TMButton, { btnStyle: 'advanced', advancedType: 'primary', showTooltip: false, caption: SDKUI_Localizator.Clear, icon: _jsx(IconClear, {}), advancedColor: 'white', color: 'primaryOutline', onClick: clearFilters })] }), (!showAdvancedSearch && qd?.where && qd?.where?.length > initialMaxItems) &&
125
+ _jsx(TMShowAllOrMaxItemsButton, { showAll: showAllMdWhere, dataSourceLength: qd?.where?.length, onClick: () => { setShowAllMdWhere(!showAllMdWhere); } })] }), showFiltersConfig &&
126
126
  _jsx(TMMetadataChooserForm, { allowMultipleSelection: true, height: '500px', width: '600px', allowSysMetadata: true, qd: qd, selectedIDs: qd?.where?.map((w) => ({ tid: w.tid, mid: w.mid })), onClose: () => setShowFiltersConfig(false), onChoose: (tid_mids) => {
127
127
  if (!fromDTD?.metadata)
128
128
  return;
@@ -63,7 +63,7 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, onSelectedTIDChanged,
63
63
  if (treeItem.type == TreeItemTypes.DcmtType)
64
64
  return (_jsx(TMTidViewer, { tid: treeItem.tid, color: TMColors.primaryColor, showIcon: false }));
65
65
  else
66
- return (_jsxs(StyledDivHorizontal, { style: { gap: 5 }, children: [_jsx(IconFolder, { fontSize: 18 }), _jsx("p", { children: treeItem.nameLoc })] }));
66
+ return (_jsxs(StyledDivHorizontal, { style: { gap: 5 }, children: [_jsx(IconFolder, { fontSize: 18 }), _jsx("p", { style: { color: TMColors.primaryColor }, children: treeItem.nameLoc })] }));
67
67
  };
68
68
  // Handles selection change in the data grid
69
69
  const onSelectionChanged = useCallback((e) => {
@@ -1,14 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import styled from 'styled-components';
3
- import { useState } from 'react';
3
+ import { useEffect, useState } from 'react';
4
4
  import ReactDOMServer from 'react-dom/server';
5
5
  import { DcmtTypeListCacheService } from '@topconsultnpm/sdk-ts-beta';
6
6
  import ContextMenu from 'devextreme-react/cjs/context-menu';
7
- import { IconDelete, SDKUI_Localizator, IconApply } from '../../helper';
7
+ import { IconDelete, SDKUI_Localizator, IconApply, IconInfo } from '../../helper';
8
8
  import { TMColors } from '../../utils/theme';
9
9
  import { DeviceType } from '../base/TMDeviceProvider';
10
10
  import { TMDcmtTypeChooserForm } from '../choosers/TMDcmtTypeChooser';
11
- import TMTidViewer from '../viewers/TMTidViewer';
11
+ import TMTidViewer, { TMDcmtTypeTooltip } from '../viewers/TMTidViewer';
12
12
  const StyledRecentTidItem = styled.div `
13
13
  display: flex;
14
14
  flex-direction: column;
@@ -22,6 +22,21 @@ const StyledRecentTidItem = styled.div `
22
22
  cursor: pointer;
23
23
  }
24
24
 
25
+ .info-icon {
26
+ position: absolute;
27
+ left: -7px;
28
+ top: 50%;
29
+ transform: translateY(-50%);
30
+ opacity: 0;
31
+ transition: opacity 0.2s;
32
+ pointer-events: none;
33
+ }
34
+
35
+ &:hover .info-icon {
36
+ opacity: 1;
37
+ pointer-events: auto;
38
+ }
39
+
25
40
  &:last-child {
26
41
  border-bottom: none; // remove border for last item
27
42
  margin-bottom: 0;
@@ -30,6 +45,13 @@ const StyledRecentTidItem = styled.div `
30
45
  const iconDelete = () => ReactDOMServer.renderToString(_jsx(IconDelete, {}));
31
46
  const TMRecentsManager = ({ deviceType, mruTIDs, currentMruTID, onSelectedTID, onDeletedTID }) => {
32
47
  const [showDcmtTypeChooser, setShowDcmtTypeChooser] = useState(false);
48
+ const [recentDcmtTypes, setRecentDcmtTypes] = useState([]);
49
+ useEffect(() => {
50
+ DcmtTypeListCacheService.GetAllWithoutMetadataAsync().then((allTypes) => {
51
+ const filtered = allTypes.filter(dt => mruTIDs.includes(dt.id));
52
+ setRecentDcmtTypes(filtered);
53
+ });
54
+ }, [mruTIDs]);
33
55
  return (_jsxs(_Fragment, { children: [_jsxs("div", { style: { overflowY: deviceType === DeviceType.MOBILE ? 'auto' : undefined, display: 'flex', flexDirection: 'column', padding: '5px', width: '100%' }, children: [_jsx(StyledRecentTidItem, { id: `tid-${0}`, onClick: () => { setShowDcmtTypeChooser(true); }, children: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '100%' }, children: _jsx("p", { style: {
34
56
  color: TMColors.primaryColor,
35
57
  fontSize: '1rem',
@@ -37,8 +59,8 @@ const TMRecentsManager = ({ deviceType, mruTIDs, currentMruTID, onSelectedTID, o
37
59
  whiteSpace: 'nowrap',
38
60
  overflow: 'hidden',
39
61
  textOverflow: 'ellipsis'
40
- }, children: `${SDKUI_Localizator.AllDcmtTypes} (${DcmtTypeListCacheService.CacheCount(true)})` }) }) }, 0), mruTIDs.map((tid) => {
41
- return (_jsxs(StyledRecentTidItem, { id: `tid-${tid}`, onClick: () => { onSelectedTID?.(tid); }, children: [_jsx("div", { style: { display: 'flex', justifyContent: 'center', width: '100%' }, children: _jsx(TMTidViewer, { tid: tid, color: TMColors.primaryColor, showIcon: false }) }), _jsx(ContextMenu, { dataSource: [{ text: SDKUI_Localizator.Remove, icon: iconDelete(), }], target: `#tid-${tid}`, onItemClick: () => { onDeletedTID?.(tid); } }), currentMruTID == tid &&
62
+ }, children: `${SDKUI_Localizator.AllDcmtTypes} (${DcmtTypeListCacheService.CacheCount(true)})` }) }) }, 0), recentDcmtTypes.map((dtd) => {
63
+ return (_jsxs(StyledRecentTidItem, { id: `tid-${dtd.id}`, onClick: () => { onSelectedTID?.(dtd.id ?? 0); }, children: [_jsx("span", { className: "info-icon", children: _jsx(TMDcmtTypeTooltip, { dtd: dtd, children: _jsx(IconInfo, { color: TMColors.primaryColor }) }) }), _jsx("div", { style: { display: 'flex', justifyContent: 'center', width: '100%' }, children: _jsx(TMTidViewer, { tid: dtd.id, color: TMColors.primaryColor, showIcon: false }) }), _jsx(ContextMenu, { dataSource: [{ text: SDKUI_Localizator.Remove, icon: iconDelete(), }], target: `#tid-${dtd.id}`, onItemClick: () => { onDeletedTID?.(dtd.id ?? 0); } }), currentMruTID == dtd.id &&
42
64
  _jsx("div", { style: {
43
65
  width: '24px',
44
66
  height: '24px',
@@ -51,7 +73,7 @@ const TMRecentsManager = ({ deviceType, mruTIDs, currentMruTID, onSelectedTID, o
51
73
  justifyContent: 'center',
52
74
  fontSize: '1rem',
53
75
  fontWeight: 'bold'
54
- }, children: _jsx(IconApply, { fontSize: 24, color: 'green' }) })] }, tid));
76
+ }, children: _jsx(IconApply, { fontSize: 24, color: 'green' }) })] }, dtd.id));
55
77
  })] }), showDcmtTypeChooser && _jsx(TMDcmtTypeChooserForm, { onClose: () => setShowDcmtTypeChooser(false), onChoose: (tids) => { onSelectedTID?.(tids?.[0] ?? 0); } })] }));
56
78
  };
57
79
  export default TMRecentsManager;
@@ -40,3 +40,7 @@ export declare function isPositiveNumber(val: unknown): val is number;
40
40
  export declare function sleep(ms: number): Promise<void>;
41
41
  export declare const dialogConfirmOperation: (title: string, msg: string, operationAsync: () => Promise<void>) => void;
42
42
  export declare function getExceptionMessage(ex: any): string;
43
+ export declare function getContrastColor(inputColor: string): {
44
+ bgColor: string;
45
+ textColor: string;
46
+ };
@@ -664,3 +664,39 @@ export function getExceptionMessage(ex) {
664
664
  let msg = ex.isApiException ? ex.response.title : ex.message;
665
665
  return msg ?? ex.toString();
666
666
  }
667
+ export function getContrastColor(inputColor) {
668
+ let hex = inputColor;
669
+ if (!/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(inputColor)) {
670
+ const temp = document.createElement('div');
671
+ temp.style.color = inputColor;
672
+ document.body.appendChild(temp);
673
+ const rgb = getComputedStyle(temp).color;
674
+ document.body.removeChild(temp);
675
+ const regex = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/;
676
+ const match = regex.exec(rgb);
677
+ if (match) {
678
+ const r = parseInt(match[1]).toString(16).padStart(2, '0');
679
+ const g = parseInt(match[2]).toString(16).padStart(2, '0');
680
+ const b = parseInt(match[3]).toString(16).padStart(2, '0');
681
+ hex = `#${r}${g}${b}`;
682
+ }
683
+ else {
684
+ hex = '#000000';
685
+ }
686
+ }
687
+ const color = hex.replace('#', '');
688
+ const r = parseInt(color.substring(0, 2), 16);
689
+ const g = parseInt(color.substring(2, 4), 16);
690
+ const b = parseInt(color.substring(4, 6), 16);
691
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
692
+ if (inputColor === 'transparent' || inputColor === 'rgba(255, 255, 255, 0)' || inputColor === 'none' || inputColor === 'white' || inputColor === '#ffffff' || inputColor === '#fff') {
693
+ return {
694
+ bgColor: '#aeaeae',
695
+ textColor: '#393939'
696
+ };
697
+ }
698
+ return {
699
+ bgColor: hex,
700
+ textColor: luminance > 0.6 ? '#000000' : '#FFFFFF'
701
+ };
702
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.13.25",
3
+ "version": "6.13.27",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",