@topconsultnpm/sdkui-react-beta 6.6.1 → 6.6.3

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.
@@ -1,321 +1,284 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React, { useEffect, useState } from 'react';
2
+ import { useEffect, useMemo, useRef, useState } from 'react';
3
3
  import styled from 'styled-components';
4
- import { Colors, FontSize } from '../../utils/theme';
5
- import { getColor } from '../../helper/helpers';
6
- import { IconCloseCircle, IconDown, IconInsertAbove, IconInsertBelow, IconSearch, IconUp } from '../../helper';
7
- const StyledContainer = styled.div `
8
- z-index: -1;
9
- border: 1px solid;
10
- border-color: ${props => getColor(props.$color)} ;
11
- overflow: auto;
12
- max-height: ${props => props.$maxHight};
13
- `;
14
- const StyledListViewWrapper = styled.div `
15
- display: flex;
16
- flex-direction: column;
17
- justify-content: flex-start;
18
- align-items: flex-start;
19
- font-size: ${props => props.$fontSize} ;
20
- `;
21
- const StyledListItemContainer = styled.div `
22
- display: flex;
23
- width: 100%;
24
- flex-direction: row;
25
- justify-content: space-between;
26
- align-items: center;
27
- padding: 5px;
28
- background-color: ${props => !props.$isSelected ? props.$index % 2 === 0 ? 'white' : Colors.colore_sul_primary : Colors.secondary};
29
- font-size: ${props => props.$fontSize};
30
- color: ${props => !props.$isSelected ? Colors.primary : 'white'};
31
- z-index: 1;
32
- `;
33
- const StyledLsitItemCheck = styled.input `
34
- margin-right: 5px;
35
- cursor: pointer;
36
- `;
37
- const StyledListItem = styled.li `
38
- padding: 3px;
39
- list-style: none;
40
- text-decoration: none;
41
- color: ${props => props.$color};
42
- `;
43
- const StyledListViewItemDetails = styled.div `
44
- display: flex;
45
- flex-direction: column;
46
- align-items: flex-start;
47
- justify-content: flex-start;
48
- padding: 5px;
49
- background-color: ${Colors.contenitore_su_colore_primary};
50
- color: white;
51
- width: 100%;
52
- `;
53
- const StyledDetailsToggleButton = styled.button `
54
- border: none;
55
- background-color: transparent;
56
- cursor: pointer;
57
- color: ${props => props.$isSelected ? 'white' : Colors.primary};
58
- `;
59
- const StyledListViewSearchContainer = styled.div `
60
- position: sticky;
61
- padding: 5px;
62
- top: 0px;
63
- display: flex;
64
- flex-direction: row;
65
- align-items: center;
66
- justify-content: flex-start;
67
- padding-bottom: 5px;
68
- border-bottom: 1px solid ${props => getColor(props.$color)};
69
- background-color: ${props => getColor(props.$color)};
70
- z-index: 100;
71
- `;
72
- const StyledSelectOptionCheckBox = styled.input `
73
- margin-right: 5px;
74
- margin-left: 2px;
75
- cursor: pointer;
76
- width: 20px;
77
- height: 20px;
78
- `;
79
- const StyledListViewSearchInput = styled.input `
80
- width: 100%;
81
- padding: 3px 10px;
82
- border-radius: 5px;
83
- border-width: 1px ;
84
- border-color: ${props => getColor(props.$color)};
85
- border-style: solid;
86
- color: ${props => getColor(props.$color)};
87
- &::placeholder{
88
- color: ${props => getColor(props.$color)};
89
- }
90
- &:focus{
91
- outline: none;
92
- background-color: #fbf5ca;
93
- }
94
- `;
95
- const StyledListViewSearchIcon = styled.button `
96
- background-color: transparent;
97
- border: none;
98
- cursor: ${props => props.$isSearch ? 'pointer' : 'default'};
99
- color: ${props => getColor(props.$color)};
100
- position: absolute;
101
- right: 10px;
102
- top: 10px;
103
- &:focus{
104
- outline: ${props => !props.$isSearch && 'none'};
105
- }
106
- `;
107
- const StyledListViewFooter = styled.div `
108
- z-index: 100;
109
- position: sticky;
110
- bottom: 0px;
111
- width: 100%;
112
- padding: 5px;
113
- background-color: ${props => getColor(props.$color)};
114
- color: white;
115
- font-size: 1rem;
116
- `;
117
- const StyledShowHideDetailsButton = styled.button `
118
- background-color: transparent;
119
- border: none;
120
- margin-right: 10px;
121
- /* color: ${props => getColor(props.$color)}; */
122
- color: white;
123
- cursor: pointer;
124
- transform: translateY(1.5px);
125
- `;
126
- const TMListView = ({ maxHeight = '100%', selectedValues = [], color = 'primary', footer = false, header = false, customItemDetails, customListViewItem, hasItemDetails = false, detailsFields, dataSource, displayField, searchable, elementStyle, selectedListItems, multipleSelect = false, fontSize = FontSize.defaultFontSize }) => {
127
- const [focusedItem, setFocusedItem] = useState(undefined);
128
- const [selectedItems, setSelectedItems] = useState([]);
129
- const [detailRequestItems, setDetailRequestItems] = useState([]);
130
- const [currentDetailsFields, setCurrentDetailsField] = useState(detailsFields);
4
+ import { ObjectClasses } from '@topconsultnpm/sdk-ts-beta';
5
+ import TMContextMenu, { useTMContextMenu } from './TMContextMenu';
6
+ import { IconApply, IconCloseCircle, IconColumns, IconDown, IconHide, IconShow, IconUp, IconVisible } from '../../helper/TMIcons';
7
+ import { TMSearchBar } from '../sidebar/TMHeader';
8
+ import TMTooltip from './TMTooltip';
9
+ 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'};} `;
10
+ const StyledListViewContainer = styled.div ` position: relative; display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; width: 100%; height: 100%; `;
11
+ const StyledSearchContainer = styled.div ` width: 100%; height: max-content; padding: 5px; border-bottom: 1px solid #e5e5e5; display: flex; align-items: center; gap: 10px; `;
12
+ 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; `;
13
+ const TMListView = ({ grouping = '', orderBy, id, onScrollChange, scroll, searchKeys = [], searchable = false, itemTemplate, customColor, dataSource = [], exprKey = 'id', onSelectionChanged, onItemClick, onItemDblClick, selectedItem }) => {
14
+ const listRef = useRef(null);
15
+ const contRef = useRef(null);
16
+ const orderRef = useRef(null);
17
+ const [showId, setShowId] = useState(false);
18
+ const [showSearch, setShowSearch] = useState(searchable);
131
19
  const [searchValue, setSearchValue] = useState('');
132
- const [currentDataSource, setCurrentDataSource] = useState([]);
133
- const [usedFields, setUsedFields] = useState([]);
134
- useEffect(() => {
135
- if (!selectedValues.fieldName) {
136
- setSelectedItems(selectedValues);
137
- }
138
- else {
139
- let data = [];
140
- for (let value of selectedValues.fieldValues) {
141
- for (let d of currentDataSource) {
142
- if (value === d[selectedValues.fieldName]) {
143
- data.push(d);
144
- }
145
- }
20
+ const [currentDataSource, setCurrentDataSource] = useState(dataSource);
21
+ const [keys, setKeys] = useState(searchKeys);
22
+ const [orderedBy, setOrderedBy] = useState(orderBy || '');
23
+ const [orderDir, setOrderDir] = useState(true);
24
+ const [isFocused, setIsFocused] = useState(false);
25
+ const [showOrderMenu, setShowOrderMenu] = useState(false);
26
+ const [showOrderOptions, setShowOrderOptions] = useState(false);
27
+ useEffect(() => { setCurrentDataSource(dataSource); }, [dataSource]);
28
+ const openContextMenu = (e) => { setIsFocused(true); };
29
+ let [coords, show] = useTMContextMenu(contRef);
30
+ useEffect(() => { if (orderBy) {
31
+ setOrderedBy(orderBy);
32
+ } }, [orderBy]);
33
+ // is list item selected
34
+ const isSelected = (item) => {
35
+ if (selectedItem) {
36
+ if (item[exprKey] === selectedItem[exprKey]) {
37
+ return true;
146
38
  }
147
- setSelectedItems(data);
39
+ else
40
+ return false;
148
41
  }
149
- }, [currentDataSource]);
150
- useEffect(() => { selectedListItems && selectedListItems(selectedItems); }, [selectedItems]);
151
- useEffect(() => {
152
- const selectByKey = (e) => { if (e.code === 'Space' && focusedItem) {
153
- onListItemClick();
154
- } };
155
- window.addEventListener('keyup', selectByKey);
156
- return () => window.removeEventListener('keyup', selectByKey);
157
- }, [focusedItem, selectedItems]);
158
- useEffect(() => {
159
- let arr = [];
160
- if (customListViewItem) {
161
- for (let key of Object.keys(customListViewItem.props)) {
162
- arr.push(customListViewItem.props[key]);
163
- }
164
- }
165
- else {
166
- arr.push(displayField);
167
- }
168
- if (customItemDetails) {
169
- for (let key of Object.keys(customItemDetails.props)) {
170
- arr.push(customItemDetails.props[key]);
171
- }
172
- }
173
- else if (currentDetailsFields) {
174
- for (let field of currentDetailsFields) {
175
- arr.push(field);
176
- }
177
- }
178
- setUsedFields(arr);
179
- }, [customItemDetails, customListViewItem, displayField, detailsFields]);
180
- useEffect(() => {
181
- if (hasItemDetails) {
182
- let keys = Object.keys(dataSource[0]);
183
- if (!displayField) {
184
- let detailsKeys = keys.filter(key => key !== displayField);
185
- if (!detailsFields) {
186
- setCurrentDetailsField(detailsKeys);
187
- }
188
- else {
189
- setCurrentDetailsField(detailsFields);
190
- }
42
+ else
43
+ return false;
44
+ };
45
+ // order by key
46
+ const orderByKey = (array) => {
47
+ let arr = [...array];
48
+ if (arr.length > 0 && arr[0][orderedBy]) {
49
+ if (typeof arr[0][orderedBy] === 'string') {
50
+ arr.sort((a, b) => { if (a[orderedBy].toLowerCase() < b[orderedBy].toLowerCase()) {
51
+ return -1;
52
+ } if (a[orderedBy].toLowerCase() > b[orderedBy].toLowerCase()) {
53
+ return 1;
54
+ } return 0; });
191
55
  }
192
56
  else {
193
- if (!detailsFields) {
194
- setCurrentDetailsField(keys);
195
- }
196
- else {
197
- setCurrentDetailsField(detailsFields);
198
- }
57
+ arr.sort((a, b) => { if (a[orderedBy] < b[orderedBy]) {
58
+ return -1;
59
+ } if (a[orderedBy] > b[orderedBy]) {
60
+ return 1;
61
+ } return 0; });
199
62
  }
200
63
  }
201
- }, [hasItemDetails, detailsFields, displayField]);
64
+ return orderDir ? arr : arr.reverse();
65
+ };
66
+ // search keys
202
67
  useEffect(() => {
203
- if (searchable) {
204
- if (searchValue.length > 0) {
205
- filter(dataSource, searchValue);
68
+ if (currentDataSource && currentDataSource.length > 0) {
69
+ if (searchKeys.length === 0) {
70
+ setKeys(Object.keys(currentDataSource[0]));
206
71
  }
207
72
  else {
208
- setCurrentDataSource(dataSource);
73
+ setKeys(searchKeys);
209
74
  }
210
75
  }
211
- else {
212
- setCurrentDataSource(dataSource);
213
- }
214
- }, [dataSource, searchValue, searchable]);
215
- const showHideDetails = () => {
216
- if (detailRequestItems.length > 0) {
217
- setDetailRequestItems([]);
218
- }
219
- else {
220
- setDetailRequestItems(currentDataSource);
221
- }
222
- };
223
- const filter = (dataSource, value) => {
76
+ }, []);
77
+ // search logic
78
+ useEffect(() => {
224
79
  let arr = [];
225
- for (let data of dataSource) {
226
- if (typeof data === 'string') {
227
- setCurrentDataSource(dataSource.filter(item => item.toString().toLowerCase().includes(value.toLowerCase())));
228
- }
229
- else {
230
- for (let key of usedFields) {
231
- if (data[key].toString().toLowerCase().includes(value.toLowerCase())) {
232
- if (!arr.includes(data)) {
233
- arr.push(data);
80
+ if (searchValue.length > 0) {
81
+ for (let data of dataSource) {
82
+ for (let key of keys) {
83
+ if (typeof data[key] === 'string' || typeof data[key] === 'number') {
84
+ if (data[key].toString().toLowerCase().includes(searchValue.toLowerCase())) {
85
+ if (!arr.includes(data)) {
86
+ arr.push(data);
87
+ }
234
88
  }
235
89
  }
236
90
  }
237
- ;
91
+ }
92
+ if (orderedBy.length === 0) {
238
93
  setCurrentDataSource(arr);
239
94
  }
95
+ else {
96
+ setCurrentDataSource(orderByKey(arr));
97
+ }
240
98
  }
241
- };
242
- const onListItemClick = () => {
243
- if (multipleSelect) {
244
- if (!hasItem(selectedItems, focusedItem)) {
245
- setSelectedItems(prev => [...prev, focusedItem]);
99
+ else {
100
+ if (orderedBy.length === 0) {
101
+ setCurrentDataSource(dataSource);
246
102
  }
247
103
  else {
248
- (setSelectedItems(selectedItems.filter(item => JSON.stringify(item) !== JSON.stringify(focusedItem))));
104
+ setCurrentDataSource(orderByKey(dataSource));
249
105
  }
250
106
  }
251
- else {
252
- setSelectedItems([]);
253
- setSelectedItems(prev => [...prev, focusedItem]);
107
+ }, [searchValue, keys, orderedBy, dataSource]);
108
+ useEffect(() => { if (!showSearch) {
109
+ setSearchValue('');
110
+ } }, [showSearch]);
111
+ // order logic
112
+ useEffect(() => { if (orderedBy.length > 0) {
113
+ setCurrentDataSource(orderByKey(currentDataSource));
114
+ } }, [orderedBy, orderDir]);
115
+ // change items by arrow keys logic
116
+ useEffect(() => {
117
+ let selectedItemIndex = currentDataSource.indexOf(selectedItem);
118
+ const canNext = selectedItem !== currentDataSource[currentDataSource.length - 1];
119
+ const canPrev = selectedItem !== currentDataSource[0];
120
+ let cont = listRef.current;
121
+ let next = currentDataSource.indexOf(selectedItem) + 1;
122
+ let before = currentDataSource.indexOf(selectedItem) - 1;
123
+ const changeIndex = (e) => {
124
+ if (isFocused) {
125
+ if (e.key === 'ArrowDown') {
126
+ e.preventDefault();
127
+ if (canNext) {
128
+ onSelectionChanged && onSelectionChanged(currentDataSource[selectedItemIndex + 1]);
129
+ if (selectedItem && cont) {
130
+ let diff = cont.scrollTop;
131
+ let xNext = cont.children.item(next);
132
+ if (xNext) {
133
+ if (xNext.getBoundingClientRect().bottom > (cont.getBoundingClientRect().height + cont.getBoundingClientRect().top)) {
134
+ diff += xNext.getBoundingClientRect().bottom - (cont.getBoundingClientRect().height + cont.getBoundingClientRect().top);
135
+ }
136
+ }
137
+ cont.scrollTo(0, diff);
138
+ }
139
+ }
140
+ }
141
+ if (e.key === 'ArrowUp') {
142
+ e.preventDefault();
143
+ if (canPrev) {
144
+ onSelectionChanged && onSelectionChanged(currentDataSource[selectedItemIndex - 1]);
145
+ if (selectedItem && cont) {
146
+ let diff = cont.scrollTop;
147
+ let xBefore = cont.children.item(before);
148
+ if (xBefore) {
149
+ if (xBefore.getBoundingClientRect().top < (cont.getBoundingClientRect().top)) {
150
+ diff -= cont.getBoundingClientRect().top - xBefore.getBoundingClientRect().top;
151
+ }
152
+ }
153
+ cont.scrollTo(0, diff);
154
+ }
155
+ }
156
+ }
157
+ if (e.key === 'ArrowLeft') {
158
+ e.preventDefault();
159
+ if (cont) {
160
+ cont.scrollBy(-20, 0);
161
+ }
162
+ }
163
+ if (e.key === 'ArrowRight') {
164
+ e.preventDefault();
165
+ if (cont) {
166
+ cont.scrollBy(20, 0);
167
+ }
168
+ }
169
+ }
170
+ };
171
+ if (selectedItem) {
172
+ document.addEventListener('keydown', changeIndex);
254
173
  }
255
- };
256
- const onCheckClick = () => { if (hasItem(selectedItems, focusedItem)) {
257
- setSelectedItems(selectedItems.filter(item => JSON.stringify(item) !== JSON.stringify(focusedItem)));
258
- } };
259
- const detailsToggle = (e) => {
260
- if (detailRequestItems.includes(focusedItem)) {
261
- setDetailRequestItems(detailRequestItems.filter(item => item !== focusedItem));
174
+ return () => { document?.removeEventListener('keydown', changeIndex); };
175
+ }, [selectedItem, isFocused]);
176
+ // deselect an onBlur listview logic
177
+ useEffect(() => {
178
+ const list = listRef.current;
179
+ const deSelectAll = (e) => { if (list && !list.contains(e.target)) {
180
+ setIsFocused(false);
181
+ } };
182
+ window.addEventListener('click', deSelectAll);
183
+ window.addEventListener('contextmenu', deSelectAll);
184
+ return () => { window.removeEventListener('click', deSelectAll); window.removeEventListener('contextmenu', deSelectAll); };
185
+ }, []);
186
+ // scroll logic
187
+ useEffect(() => {
188
+ let cont = listRef.current;
189
+ if (cont && scroll) {
190
+ cont.addEventListener('scroll', () => onScrollChange && onScrollChange({ x: cont?.scrollLeft, y: cont?.scrollTop }));
262
191
  }
263
- else {
264
- setDetailRequestItems(prev => [...prev, focusedItem]);
192
+ return () => cont?.removeEventListener('scroll', () => onScrollChange && onScrollChange({ x: cont?.scrollLeft, y: cont?.scrollTop }));
193
+ }, [listRef.current]);
194
+ useEffect(() => { let cont = listRef.current; if (cont && scroll) {
195
+ cont.scrollTo(scroll.x, scroll.y);
196
+ } ; }, [scroll, listRef.current]);
197
+ //order options
198
+ const orderMenuItems = () => {
199
+ let arr = [];
200
+ if (searchKeys.length > 0) {
201
+ for (let key of searchKeys) {
202
+ arr.push({
203
+ disabled: !showId && key === exprKey,
204
+ isSelected: key === orderedBy,
205
+ onItemClick: () => { setOrderedBy(key); setShowOrderOptions(false); },
206
+ icon: _jsx(IconColumns, { fontSize: 16 }),
207
+ text: _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 10 }, children: [key, " ", key === orderedBy && _jsx(IconApply, { fontSize: 14, color: 'gray' })] })
208
+ });
209
+ }
265
210
  }
211
+ return arr;
266
212
  };
267
- const obj = (data, type) => {
268
- let object = {};
269
- switch (type) {
270
- case 'item':
271
- for (let key of Object.keys(customListViewItem?.props)) {
272
- object[key] = data[customListViewItem?.props[key]];
273
- }
274
- break;
275
- case 'details':
276
- for (let key of Object.keys(customItemDetails?.props)) {
277
- object[key] = data[customItemDetails?.props[key]];
213
+ // grouping loginc
214
+ const groupKeys = Object.keys(groupByKey(currentDataSource, grouping));
215
+ const [openList, setOpenList] = useState([true, false, false]);
216
+ function groupByKey(array, key) {
217
+ return array
218
+ .reduce((hash, obj) => {
219
+ if (obj[key] === undefined)
220
+ return hash;
221
+ return Object.assign(hash, { [obj[key]]: (hash[obj[key]] || []).concat(obj) });
222
+ }, {});
223
+ }
224
+ // map memo
225
+ const memoList = useMemo(() => currentDataSource.map((data, index) => {
226
+ 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: [showId && _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));
227
+ }), [currentDataSource, selectedItem, showId, customColor]);
228
+ const groupedMemoList = useMemo(() => groupKeys.map((key, index) => {
229
+ const groupingText = () => {
230
+ if (grouping === 'objectClass') {
231
+ if (key === ObjectClasses.Dossier) {
232
+ return 'Pratiche';
278
233
  }
279
- break;
280
- }
281
- return object;
282
- };
283
- const hasItem = (arr, el) => {
284
- let bool = false;
285
- for (let item of arr) {
286
- if (typeof item === 'string') {
287
- if (item === el) {
288
- bool = true;
289
- break;
234
+ else if (key === ObjectClasses.WorkingGroup) {
235
+ return 'Gruppi di lavoro';
290
236
  }
291
- else {
292
- bool = false;
237
+ else if (key === ObjectClasses.SavedQuery) {
238
+ return 'Ricerche rapide';
293
239
  }
240
+ else
241
+ return '';
294
242
  }
295
243
  else {
296
- if (JSON.stringify(item) == JSON.stringify(el)) {
297
- bool = true;
298
- break;
299
- }
300
- else {
301
- bool = false;
302
- }
244
+ return key;
245
+ }
246
+ };
247
+ return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'flex-start', width: '100%', height: 'max-content' }, children: [_jsx("div", { style: { borderBottom: `1px solid ${customColor}20`, display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '5px', width: '100%', backgroundColor: `${customColor}30` }, children: _jsxs("div", { style: { width: '100%', height: 'max-content', display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }, children: [_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: [showId && _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));
248
+ }), [currentDataSource, selectedItem, showId, customColor, openList, grouping]);
249
+ // List height
250
+ const listHeight = () => {
251
+ if (showSearch) {
252
+ if (showOrderMenu || searchValue.length > 0) {
253
+ return 'calc(100% - 55px)';
254
+ }
255
+ else {
256
+ return 'calc(100% - 30px)';
303
257
  }
304
258
  }
305
- return bool;
306
- };
307
- const selectDeselectAll = () => { if (selectedItems.length > 0) {
308
- setSelectedItems([]);
309
- }
310
- else {
311
- setSelectedItems(currentDataSource);
312
- } };
313
- const renderedList = () => {
314
- return (currentDataSource?.map((d, index) => (_jsxs(StyledListViewWrapper, { "$fontSize": fontSize, children: [_jsxs(StyledListItemContainer, { "$isFocused": focusedItem === d, "$isSelected": hasItem(selectedItems, d), "$fontSize": fontSize, tabIndex: 0, "$index": index, onFocus: () => setFocusedItem(d), children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center', width: '100%' }, onClick: onListItemClick, children: [multipleSelect && _jsx(StyledLsitItemCheck, { checked: hasItem(selectedItems, d), onChange: onCheckClick, tabIndex: -1, type: "checkbox" }), !customListViewItem ? _jsx(StyledListItem, { "$color": color, children: displayField ? d[displayField] : d }) : React.cloneElement(customListViewItem, obj(d, 'item'))] }), hasItemDetails && _jsx(StyledDetailsToggleButton, { "$isSelected": hasItem(selectedItems, d), onClick: (e) => detailsToggle(e), children: detailRequestItems.includes(d) ? _jsx(IconUp, {}) : _jsx(IconDown, {}) })] }), detailRequestItems.includes(d) && _jsxs(StyledListViewItemDetails, { children: [" ", !customItemDetails ? currentDetailsFields.map((detail, index) => (_jsxs("div", { children: [detail, ": ", d[detail]] }, index))) : React.cloneElement(customItemDetails, obj(d, 'details')), " "] })] }, index))));
315
- };
316
- const renderedHeader = () => {
317
- return (_jsxs(StyledListViewSearchContainer, { "$color": color, children: [multipleSelect && _jsx(StyledSelectOptionCheckBox, { "$color": color, "$fontsize": fontSize, type: 'checkbox', checked: selectedItems.length > 0, onChange: selectDeselectAll }), hasItemDetails && _jsx(StyledShowHideDetailsButton, { "$color": color, onClick: showHideDetails, children: detailRequestItems.length > 0 ? _jsx(IconInsertBelow, {}) : _jsx(IconInsertAbove, {}) }), searchable && _jsx(StyledListViewSearchInput, { "$color": color, value: searchValue, onChange: (e) => setSearchValue(e.target.value), placeholder: 'search' }), searchable && _jsx(StyledListViewSearchIcon, { onClick: () => searchValue.length > 0 && setSearchValue(''), "$isSearch": searchValue.length > 0, "$color": color, children: searchValue.length > 0 ? _jsx(IconCloseCircle, {}) : _jsx(IconSearch, {}) })] }));
259
+ else if (showOrderMenu || searchValue.length > 0) {
260
+ return 'calc(100% - 25px)';
261
+ }
262
+ else
263
+ return '100%';
318
264
  };
319
- return (_jsx("div", { style: elementStyle, children: _jsxs(StyledContainer, { "$maxHight": maxHeight, "$color": color, children: [" ", (searchable || multipleSelect) && renderedHeader(), " ", _jsx("ul", { children: renderedList() }), " ", multipleSelect && footer && _jsxs(StyledListViewFooter, { "$color": color, children: ["Selected items: ", selectedItems.length, " | Visible items: ", currentDataSource.length] })] }) }));
265
+ return (_jsxs(StyledListViewContainer, { ref: contRef, onContextMenu: openContextMenu, children: [show &&
266
+ _jsx(TMContextMenu, { coords: coords, items: grouping.length === 0 ?
267
+ [
268
+ { icon: showSearch ? _jsx(IconHide, { fontSize: 16 }) : _jsx(IconShow, { fontSize: 16 }), onItemClick: () => { setShowSearch(!showSearch); }, text: showSearch ? 'Nascondi ricerca' : 'Mostra ricerca' },
269
+ { icon: showId ? _jsx(IconHide, { fontSize: 16 }) : _jsx(IconShow, { fontSize: 16 }), onItemClick: () => { setShowId(!showId); }, text: showId ? 'Nascondi ' + exprKey : 'Mostra ' + exprKey },
270
+ { icon: showOrderMenu ? _jsx(IconHide, { fontSize: 16 }) : _jsx(IconShow, { fontSize: 16 }), disabled: searchKeys.length === 0, onItemClick: () => { setShowOrderMenu(!showOrderMenu); }, text: showOrderMenu ? 'Nascondi menu di ordinamento' : 'Mostra menu di ordinamento' },
271
+ ] :
272
+ [
273
+ { icon: showSearch ? _jsx(IconHide, { fontSize: 16 }) : _jsx(IconShow, { fontSize: 16 }), onItemClick: () => { setShowSearch(!showSearch); }, text: showSearch ? 'Nascondi ricerca' : 'Mostra ricerca' },
274
+ { icon: showId ? _jsx(IconHide, { fontSize: 16 }) : _jsx(IconShow, { fontSize: 16 }), onItemClick: () => { setShowId(!showId); }, text: showId ? 'Nascondi ' + exprKey : 'Mostra ' + exprKey },
275
+ ] }), showOrderOptions &&
276
+ _jsx(TMContextMenu, { items: orderMenuItems(), coords: { x: orderRef.current?.getBoundingClientRect().left, y: orderRef.current?.getBoundingClientRect().top - (searchKeys.length * 30) - 10 } }), showSearch &&
277
+ _jsx(StyledSearchContainer, { children: _jsxs(StyledSearchContainer, { children: [_jsx(TMSearchBar, { marginLeft: '0px', maxWidth: '300px', searchValue: searchValue, onSearchValueChanged: (e) => setSearchValue(e) }), _jsx(TMTooltip, { content: 'Nascondi ricerca', children: _jsx(IconCloseCircle, { style: { cursor: 'pointer' }, color: 'red', fontSize: 14, onClick: () => { setSearchValue(''); setShowSearch(false); } }) })] }) }), _jsx("div", { ref: listRef, onClick: () => setIsFocused(true), style: { width: '100%', overflow: 'auto', height: listHeight() }, children: currentDataSource.length > 0 ?
278
+ grouping.length === 0 ? memoList : groupedMemoList :
279
+ searchValue.length > 0 ? _jsx("div", { style: { width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: "No data found" }) :
280
+ _jsx("div", { style: { width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: "No data" }) }), (searchValue.length > 0 || showOrderMenu) &&
281
+ _jsxs(StyledListViewFooter, { "$bgColor": `${customColor}20`, children: [showOrderMenu &&
282
+ _jsxs("div", { style: { width: 'max-content', display: 'flex', alignItems: 'center', gap: 5 }, children: [_jsx("div", { style: { width: 'max-content' }, children: "Ordinato per" }), _jsx("div", { ref: orderRef, onClick: () => { setShowOrderOptions(!showOrderOptions); }, style: { cursor: 'pointer', fontWeight: 'bold' }, children: orderedBy.length > 0 ? orderedBy : 'Nulla' }), orderedBy.length > 0 && _jsxs(TMTooltip, { content: orderDir ? 'ASC' : 'DESC', children: [" ", orderDir ? _jsx(IconUp, { style: { cursor: 'pointer' }, onClick: () => setOrderDir(false), fontSize: 14 }) : _jsx(IconDown, { style: { cursor: 'pointer' }, onClick: () => setOrderDir(true), fontSize: 14 }), " "] }), _jsx(TMTooltip, { content: 'Annulla ordinamento', children: _jsx(IconCloseCircle, { style: { cursor: 'pointer' }, color: 'red', fontSize: 14, onClick: () => { setOrderedBy(''); setShowOrderMenu(false); setShowOrderOptions(false); } }) })] }), searchValue.length > 0 && _jsxs("div", { style: { display: 'flex', alignItems: 'center', width: '100%', justifyContent: 'flex-end', gap: 5 }, children: [_jsx(TMTooltip, { content: 'Visibili', children: _jsx(IconVisible, { fontSize: 14 }) }), currentDataSource.length] })] })] }));
320
283
  };
321
284
  export default TMListView;
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { ITMEditorBase, Colors as C } from './TMEditorBase';
3
+ type SelectedValueType = {
4
+ fieldName: string;
5
+ fieldValues: any[];
6
+ };
7
+ interface ITMListView extends ITMEditorBase {
8
+ dataSource?: any[];
9
+ multipleSelect?: boolean;
10
+ searchable?: boolean;
11
+ header?: boolean;
12
+ footer?: boolean;
13
+ selectedListItems?: (e: any[]) => void;
14
+ displayField?: string;
15
+ customListViewItem?: JSX.Element;
16
+ customItemDetails?: JSX.Element;
17
+ hasItemDetails?: boolean;
18
+ detailsFields?: string[];
19
+ color?: C;
20
+ selectedValues?: any[] | SelectedValueType;
21
+ maxHeight?: string;
22
+ }
23
+ declare const TMListViewOLD: React.FC<ITMListView>;
24
+ export default TMListViewOLD;