@topconsultnpm/sdkui-react 6.21.0-dev3.2 → 6.21.0-dev3.21
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/NewComponents/ContextMenu/styles.d.ts +4 -4
- package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +2 -2
- package/lib/components/base/TMDataGrid.js +12 -2
- package/lib/components/base/TMDataGridExportForm.js +19 -8
- package/lib/components/base/TMFileManagerDataGridView.js +4 -4
- package/lib/components/base/TMFileManagerThumbnailItems.js +3 -3
- package/lib/components/base/TMFileManagerUtils.d.ts +7 -0
- package/lib/components/base/TMFileManagerUtils.js +14 -1
- package/lib/components/base/TMModal.js +2 -2
- package/lib/components/base/TMTreeView.js +12 -15
- package/lib/components/choosers/TMDynDataListItemChooser.js +6 -1
- package/lib/components/editors/TMEditorStyled.d.ts +6 -6
- package/lib/components/editors/TMMetadataEditor.js +6 -2
- package/lib/components/editors/TMMetadataValues.js +10 -2
- package/lib/components/features/blog/TMBlogCommentForm.js +5 -2
- package/lib/components/features/documents/TMCopyToFolderForm.js +2 -2
- package/lib/components/features/documents/TMDcmtIcon.js +1 -1
- package/lib/components/features/documents/TMMergeToPdfForm.js +2 -2
- package/lib/components/features/documents/TMRelationViewer.js +6 -1
- package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +0 -13
- package/lib/components/features/documents/copyAndMergeDcmtsShared.js +1 -39
- package/lib/components/features/search/TMMetadataOutputForm.d.ts +17 -0
- package/lib/components/features/search/TMMetadataOutputForm.js +225 -0
- package/lib/components/features/search/TMMetadataSorterForm.d.ts +17 -0
- package/lib/components/features/search/TMMetadataSorterForm.js +243 -0
- package/lib/components/features/search/TMSearchQueryEditor.js +14 -8
- package/lib/components/features/search/TMSearchQueryPanel.js +249 -58
- package/lib/components/features/search/TMSearchResult.js +2 -3
- package/lib/components/features/search/TMViewHistoryDcmt.js +1 -1
- package/lib/components/features/search/metadataFormHelper.d.ts +16 -0
- package/lib/components/features/search/metadataFormHelper.js +77 -0
- package/lib/components/grids/TMBlogAttachments.js +2 -2
- package/lib/components/grids/TMBlogsPost.js +5 -3
- package/lib/components/grids/TMBlogsPostUtils.d.ts +1 -0
- package/lib/components/grids/TMBlogsPostUtils.js +3 -1
- package/lib/helper/MergePdfManager.js +7 -4
- package/lib/helper/SDKUI_Globals.js +2 -1
- package/lib/helper/SDKUI_Localizator.d.ts +4 -0
- package/lib/helper/SDKUI_Localizator.js +40 -0
- package/lib/helper/TMUtils.d.ts +23 -0
- package/lib/helper/TMUtils.js +55 -0
- package/lib/helper/checkinCheckoutManager.d.ts +4 -3
- package/lib/helper/checkinCheckoutManager.js +29 -11
- package/lib/hooks/useCheckInOutOperations.d.ts +4 -3
- package/lib/hooks/useDataUserIdItem.js +1 -1
- package/lib/hooks/useDcmtOperations.d.ts +18 -1
- package/lib/hooks/useDcmtOperations.js +67 -21
- package/lib/hooks/useDocumentOperations.js +3 -3
- package/lib/hooks/useRelatedDocuments.js +4 -4
- package/lib/services/platform_services.d.ts +4 -4
- package/package.json +10 -7
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { OrderByItem, SDK_Localizator } from "@topconsultnpm/sdk-ts";
|
|
4
|
+
import { IconAddCircleOutline, IconApply, IconClear, IconDelete, IconDraggabledots, IconUndo, SDKUI_Localizator } from "../../../helper";
|
|
5
|
+
import TMToppyMessage from "../../../helper/TMToppyMessage";
|
|
6
|
+
import { ButtonNames, TMMessageBoxManager } from "../../base/TMPopUp";
|
|
7
|
+
import { TMColors } from "../../../utils/theme";
|
|
8
|
+
import { StyledToolbarForm } from "../../base/Styled";
|
|
9
|
+
import TMButton from "../../base/TMButton";
|
|
10
|
+
import TMModal from "../../base/TMModal";
|
|
11
|
+
import { TMMetadataChooserForm } from "../../choosers/TMMetadataChooser";
|
|
12
|
+
import TMDropDown from "../../editors/TMDropDown";
|
|
13
|
+
import { TMMetadataIcon } from "../../viewers/TMMidViewer";
|
|
14
|
+
import { loadMetadataFromQd, removeDuplicatesByTidMid, areArraysEqual } from "./metadataFormHelper";
|
|
15
|
+
const TMMetadataSorterForm = (props) => {
|
|
16
|
+
const { qd, selectedOrderByItems, allowSysMetadata = true, filterMetadata, onClose, onChoose } = props;
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// STATE
|
|
19
|
+
// =============================================================================
|
|
20
|
+
// Stato iniziale degli OrderByItem (per confronto isModified)
|
|
21
|
+
const initialOrderByItemsRef = useRef((selectedOrderByItems ?? []).map(item => {
|
|
22
|
+
const newItem = new OrderByItem();
|
|
23
|
+
newItem.tid = item.tid;
|
|
24
|
+
newItem.mid = item.mid;
|
|
25
|
+
newItem.asc = item.asc ?? true;
|
|
26
|
+
return newItem;
|
|
27
|
+
}));
|
|
28
|
+
// Lista degli OrderByItem correnti (inizializzata da selectedOrderByItems)
|
|
29
|
+
const [orderByItems, setOrderByItems] = useState(() => {
|
|
30
|
+
// Clona gli OrderByItem iniziali per evitare mutazioni
|
|
31
|
+
return (selectedOrderByItems ?? []).map(item => {
|
|
32
|
+
const newItem = new OrderByItem();
|
|
33
|
+
newItem.tid = item.tid;
|
|
34
|
+
newItem.mid = item.mid;
|
|
35
|
+
newItem.asc = item.asc ?? true;
|
|
36
|
+
return newItem;
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
// Calcola se ci sono modifiche rispetto allo stato iniziale
|
|
40
|
+
const isModified = useMemo(() => {
|
|
41
|
+
return !areArraysEqual(orderByItems, initialOrderByItemsRef.current, (a, b) => a.asc === b.asc);
|
|
42
|
+
}, [orderByItems]);
|
|
43
|
+
// Lista "piatta" di tutti i metadati estratti dai DTD, con chiave univoca
|
|
44
|
+
const [metadataList, setMetadataList] = useState([]);
|
|
45
|
+
// Flag di caricamento
|
|
46
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
47
|
+
// Flag per mostrare il TMMetadataChooserForm
|
|
48
|
+
const [showMetadataChooser, setShowMetadataChooser] = useState(false);
|
|
49
|
+
// Item in fase di drag
|
|
50
|
+
const [draggingItem, setDraggingItem] = useState(undefined);
|
|
51
|
+
// =============================================================================
|
|
52
|
+
// MEMOIZZAZIONI per evitare re-render del TMMetadataChooserForm
|
|
53
|
+
// =============================================================================
|
|
54
|
+
// Lista di TID_MID già selezionati (per escluderli dal chooser)
|
|
55
|
+
const selectedIDs = useMemo(() => orderByItems.map(oi => ({ tid: oi.tid, mid: oi.mid })), [orderByItems]);
|
|
56
|
+
// Callback per chiudere il chooser
|
|
57
|
+
const handleCloseChooser = useCallback(() => {
|
|
58
|
+
setShowMetadataChooser(false);
|
|
59
|
+
}, []);
|
|
60
|
+
// =============================================================================
|
|
61
|
+
// EFFECT: Carica i metadati al mount
|
|
62
|
+
// =============================================================================
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
const load = async () => {
|
|
65
|
+
setIsLoading(true);
|
|
66
|
+
try {
|
|
67
|
+
const { metadata } = await loadMetadataFromQd(qd, filterMetadata);
|
|
68
|
+
setMetadataList(metadata);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
console.error("Errore nel caricamento dei metadati:", error);
|
|
72
|
+
setMetadataList([]);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
setIsLoading(false);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
load();
|
|
79
|
+
}, [qd, filterMetadata]);
|
|
80
|
+
// =============================================================================
|
|
81
|
+
// HELPER: Trova il MetadataDescriptor per un OrderByItem
|
|
82
|
+
// =============================================================================
|
|
83
|
+
const getMetadataForOrderByItem = useCallback((item) => {
|
|
84
|
+
return metadataList.find(md => md.customData1 === item.tid && md.id === item.mid);
|
|
85
|
+
}, [metadataList]);
|
|
86
|
+
// =============================================================================
|
|
87
|
+
// HANDLER: Conferma la scelta dal chooser (sincronizza la lista completa)
|
|
88
|
+
// =============================================================================
|
|
89
|
+
const handleChooseFromChooser = useCallback((tid_mids) => {
|
|
90
|
+
// Se la lista è vuota o undefined, rimuovi tutti
|
|
91
|
+
if (!tid_mids || tid_mids.length === 0) {
|
|
92
|
+
setOrderByItems([]);
|
|
93
|
+
setShowMetadataChooser(false);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
setOrderByItems(prev => {
|
|
97
|
+
// Filtra quelli esistenti che sono ancora selezionati (mantenendo ordine e impostazioni asc/desc)
|
|
98
|
+
const kept = prev.filter(oi => tid_mids.some(tm => tm.tid === oi.tid && tm.mid === oi.mid));
|
|
99
|
+
// Trova i nuovi da aggiungere
|
|
100
|
+
const newItems = [];
|
|
101
|
+
for (const tm of tid_mids) {
|
|
102
|
+
const exists = prev.some(oi => oi.tid === tm.tid && oi.mid === tm.mid);
|
|
103
|
+
if (!exists) {
|
|
104
|
+
const newItem = new OrderByItem();
|
|
105
|
+
newItem.tid = tm.tid;
|
|
106
|
+
newItem.mid = tm.mid;
|
|
107
|
+
newItem.asc = true;
|
|
108
|
+
newItems.push(newItem);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return removeDuplicatesByTidMid([...kept, ...newItems]);
|
|
112
|
+
});
|
|
113
|
+
setShowMetadataChooser(false);
|
|
114
|
+
}, []);
|
|
115
|
+
// =============================================================================
|
|
116
|
+
// HANDLER: Rimuove un ordinamento
|
|
117
|
+
// =============================================================================
|
|
118
|
+
const handleRemoveOrderBy = useCallback((index) => {
|
|
119
|
+
setOrderByItems(prev => prev.filter((_, i) => i !== index));
|
|
120
|
+
}, []);
|
|
121
|
+
// =============================================================================
|
|
122
|
+
// HANDLER: Toggle ascendente/discendente
|
|
123
|
+
// =============================================================================
|
|
124
|
+
const handleChangeAsc = useCallback((index, asc) => {
|
|
125
|
+
setOrderByItems(prev => prev.map((item, i) => {
|
|
126
|
+
if (i !== index)
|
|
127
|
+
return item;
|
|
128
|
+
const newItem = new OrderByItem();
|
|
129
|
+
newItem.tid = item.tid;
|
|
130
|
+
newItem.mid = item.mid;
|
|
131
|
+
newItem.asc = asc;
|
|
132
|
+
return newItem;
|
|
133
|
+
}));
|
|
134
|
+
}, []);
|
|
135
|
+
// =============================================================================
|
|
136
|
+
// DRAG & DROP HANDLERS
|
|
137
|
+
// =============================================================================
|
|
138
|
+
const handleDragStart = useCallback((e, item) => {
|
|
139
|
+
// Previeni il drag se il target è l'icona elimina o il dropdown
|
|
140
|
+
const target = e.target;
|
|
141
|
+
if (target.closest('[data-no-drag="true"]')) {
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
setDraggingItem(item);
|
|
146
|
+
e.dataTransfer.setData('text/plain', '');
|
|
147
|
+
e.dataTransfer.effectAllowed = 'move';
|
|
148
|
+
}, []);
|
|
149
|
+
const handleDragEnd = useCallback(() => {
|
|
150
|
+
setDraggingItem(undefined);
|
|
151
|
+
}, []);
|
|
152
|
+
const handleDragOver = useCallback((e) => {
|
|
153
|
+
e.preventDefault();
|
|
154
|
+
e.dataTransfer.dropEffect = 'move';
|
|
155
|
+
}, []);
|
|
156
|
+
const handleDrop = useCallback((e, targetItem) => {
|
|
157
|
+
e.preventDefault();
|
|
158
|
+
if (!draggingItem)
|
|
159
|
+
return;
|
|
160
|
+
const currentIndex = orderByItems.indexOf(draggingItem);
|
|
161
|
+
const targetIndex = orderByItems.indexOf(targetItem);
|
|
162
|
+
if (currentIndex === -1 || targetIndex === -1 || currentIndex === targetIndex) {
|
|
163
|
+
setDraggingItem(undefined);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const listCopy = [...orderByItems];
|
|
167
|
+
listCopy.splice(currentIndex, 1);
|
|
168
|
+
listCopy.splice(targetIndex, 0, draggingItem);
|
|
169
|
+
setOrderByItems(listCopy);
|
|
170
|
+
setDraggingItem(undefined);
|
|
171
|
+
}, [draggingItem, orderByItems]);
|
|
172
|
+
// =============================================================================
|
|
173
|
+
// HANDLER: Rollback allo stato iniziale
|
|
174
|
+
// =============================================================================
|
|
175
|
+
const handleRollback = useCallback(() => {
|
|
176
|
+
setOrderByItems(initialOrderByItemsRef.current.map(item => {
|
|
177
|
+
const newItem = new OrderByItem();
|
|
178
|
+
newItem.tid = item.tid;
|
|
179
|
+
newItem.mid = item.mid;
|
|
180
|
+
newItem.asc = item.asc;
|
|
181
|
+
return newItem;
|
|
182
|
+
}));
|
|
183
|
+
}, []);
|
|
184
|
+
// =============================================================================
|
|
185
|
+
// HANDLER: Chiusura con conferma se modificato
|
|
186
|
+
// =============================================================================
|
|
187
|
+
const confirmCloseContainerId = "TMMetadataSorterFormConfirmClose";
|
|
188
|
+
const handleClose = useCallback(() => {
|
|
189
|
+
if (!isModified) {
|
|
190
|
+
onClose();
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
TMMessageBoxManager.show({
|
|
194
|
+
parentId: confirmCloseContainerId,
|
|
195
|
+
message: SDKUI_Localizator.ConfirmOnCancel,
|
|
196
|
+
buttons: [ButtonNames.YES, ButtonNames.NO],
|
|
197
|
+
onButtonClick: (buttonClicked) => {
|
|
198
|
+
if (buttonClicked === ButtonNames.YES) {
|
|
199
|
+
onClose();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}, [isModified, onClose]);
|
|
204
|
+
// =============================================================================
|
|
205
|
+
// HANDLER: Conferma la selezione
|
|
206
|
+
// =============================================================================
|
|
207
|
+
const handleConfirm = useCallback(() => {
|
|
208
|
+
onChoose?.(orderByItems.length > 0 ? orderByItems : undefined);
|
|
209
|
+
onClose();
|
|
210
|
+
}, [orderByItems, onChoose, onClose]);
|
|
211
|
+
// =============================================================================
|
|
212
|
+
// RENDER
|
|
213
|
+
// =============================================================================
|
|
214
|
+
return (_jsxs(_Fragment, { children: [_jsxs(TMModal, { title: `${SDKUI_Localizator.Configure} - ${SDK_Localizator.QueryOrderBy}${orderByItems.length > 0 ? ` (${orderByItems.length})` : ''}`, width: "600px", height: "500px", onClose: handleClose, hidePopup: false, askClosingConfirm: isModified, children: [_jsx("div", { id: confirmCloseContainerId }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', height: '100%', gap: '10px' }, children: [_jsxs(StyledToolbarForm, { children: [_jsx(TMButton, { caption: SDKUI_Localizator.Confirm, icon: _jsx(IconApply, {}), btnStyle: "toolbar", color: "success", disabled: !isModified, onClick: handleConfirm }), _jsx(TMButton, { caption: SDKUI_Localizator.Undo, icon: _jsx(IconUndo, {}), btnStyle: "toolbar", color: "tertiary", disabled: !isModified, onClick: handleRollback }), _jsx(TMButton, { caption: SDKUI_Localizator.Add, icon: _jsx(IconAddCircleOutline, {}), btnStyle: "toolbar", onClick: () => setShowMetadataChooser(true) }), _jsx(TMButton, { caption: SDKUI_Localizator.Clear, icon: _jsx(IconClear, {}), btnStyle: "toolbar", disabled: orderByItems.length === 0, onClick: () => setOrderByItems([]) })] }), _jsxs("div", { style: {
|
|
215
|
+
flex: 1,
|
|
216
|
+
overflow: 'auto',
|
|
217
|
+
border: `1px solid ${TMColors.border_normal}`,
|
|
218
|
+
borderRadius: '4px',
|
|
219
|
+
padding: '5px'
|
|
220
|
+
}, children: [isLoading && _jsxs("p", { style: { textAlign: 'center', padding: '20px' }, children: [SDKUI_Localizator.Loading, "..."] }), !isLoading && orderByItems.length === 0 && (_jsx(TMToppyMessage, { message: SDKUI_Localizator.NoSortingApplied, titleTooltip: SDKUI_Localizator.NoSortingApplied })), !isLoading && orderByItems.length > 0 && (_jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '2px' }, children: orderByItems.map((item, index) => {
|
|
221
|
+
const md = getMetadataForOrderByItem(item);
|
|
222
|
+
const isDragging = draggingItem === item;
|
|
223
|
+
return (_jsxs("div", { draggable: true, onDragStart: (e) => handleDragStart(e, item), onDragEnd: handleDragEnd, onDragOver: handleDragOver, onDrop: (e) => handleDrop(e, item), style: {
|
|
224
|
+
display: 'flex',
|
|
225
|
+
alignItems: 'center',
|
|
226
|
+
gap: '6px',
|
|
227
|
+
padding: '4px 8px',
|
|
228
|
+
backgroundColor: isDragging ? TMColors.primary_container : TMColors.default_background,
|
|
229
|
+
borderRadius: '3px',
|
|
230
|
+
border: `1px solid ${isDragging ? TMColors.primaryColor : TMColors.border_normal}`,
|
|
231
|
+
minHeight: '32px',
|
|
232
|
+
cursor: 'grab',
|
|
233
|
+
transition: 'all 0.2s ease',
|
|
234
|
+
transform: isDragging ? 'scale(1.02)' : 'scale(1)',
|
|
235
|
+
boxShadow: isDragging ? '0 4px 12px rgba(0,0,0,0.15)' : 'none',
|
|
236
|
+
opacity: isDragging ? 0.9 : 1,
|
|
237
|
+
}, children: [_jsx("div", { style: { display: 'flex', cursor: 'grab' }, children: _jsx(IconDraggabledots, { fontSize: 15, color: TMColors.button_icon }) }), _jsx(TMMetadataIcon, { tid: item.tid ?? 0, md: md }), _jsx("span", { style: { flex: 1, fontSize: '13px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }, children: md?.name ?? `MID: ${item.mid}` }), _jsx("div", { "data-no-drag": "true", onMouseDown: (e) => e.stopPropagation(), children: _jsx(TMDropDown, { width: "175px", height: "28px", value: item.asc ? 'asc' : 'desc', dataSource: [
|
|
238
|
+
{ value: 'asc', display: SDKUI_Localizator.ValueAscending },
|
|
239
|
+
{ value: 'desc', display: SDKUI_Localizator.ValueDescending }
|
|
240
|
+
], onValueChanged: (e) => handleChangeAsc(index, e.target.value === 'asc') }) }), _jsx("div", { "data-no-drag": "true", onMouseDown: (e) => e.stopPropagation(), children: _jsx(TMButton, { caption: SDKUI_Localizator.Remove, icon: _jsx(IconDelete, { color: TMColors.error }), btnStyle: "icon", onClick: () => handleRemoveOrderBy(index) }) })] }, `${item.tid}_${item.mid}_${index}`));
|
|
241
|
+
}) }))] })] })] }), showMetadataChooser && (_jsx(TMMetadataChooserForm, { allowMultipleSelection: true, height: "600px", width: "700px", allowSysMetadata: allowSysMetadata, filterMetadata: filterMetadata, qd: qd, selectedIDs: selectedIDs, onClose: handleCloseChooser, onChoose: handleChooseFromChooser }))] }));
|
|
242
|
+
};
|
|
243
|
+
export default TMMetadataSorterForm;
|
|
@@ -148,17 +148,23 @@ const TMSearchWhereItemEditor = React.memo(({ whereItem, queryParamsDynDataList,
|
|
|
148
148
|
let dtd = await DcmtTypeListCacheService.GetAsync(whereItem.tid, true);
|
|
149
149
|
return dtd?.metadata?.find(o => o.id === whereItem.mid);
|
|
150
150
|
};
|
|
151
|
-
// Rimuove gli apici singoli da valori separati da virgola: '
|
|
151
|
+
// Rimuove gli apici singoli da valori separati da virgola: 'val1','val2' -> val1,val2
|
|
152
|
+
// Applica trim solo ai valori quotati, preservando gli spazi nei valori non quotati
|
|
152
153
|
const stripQuotes = (value) => {
|
|
153
154
|
if (!value || typeof value !== 'string')
|
|
154
155
|
return value;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
try {
|
|
157
|
+
return value.split(',').map(item => {
|
|
158
|
+
const trimmed = item.trim();
|
|
159
|
+
if (trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
160
|
+
return trimmed.slice(1, -1); // trim + rimuovi apici
|
|
161
|
+
}
|
|
162
|
+
return item; // mantieni originale (con spazi)
|
|
163
|
+
}).join(',');
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return value; // in caso di errore, ritorna il valore iniziale
|
|
167
|
+
}
|
|
162
168
|
};
|
|
163
169
|
const normalizeValue = (value, isForValue1 = true) => {
|
|
164
170
|
let newValues = [];
|