@topconsultnpm/sdkui-react 6.22.0-dev2.21 → 6.22.0-dev2.22
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.
|
@@ -46,13 +46,14 @@ export interface ArchiveRow {
|
|
|
46
46
|
* stringhe, quindi il `value` generico di DevExtreme si restringe
|
|
47
47
|
*/
|
|
48
48
|
export type ArchiveRowCell = Omit<DataGridTypes.ColumnCellTemplateData<ArchiveRow, number>, 'value'> & {
|
|
49
|
-
readonly value?: string;
|
|
49
|
+
readonly value?: string | number;
|
|
50
50
|
};
|
|
51
51
|
/**
|
|
52
52
|
* Modifiche di una riga in arrivo dalla griglia (mid -> nuovo valore): in modifica diretta ci sono
|
|
53
|
-
*
|
|
53
|
+
* i metadati testuali e numerici (vedi isInlineEditableMetadata), quindi stringhe e numeri,
|
|
54
|
+
* e l'editor svuotato restituisce null
|
|
54
55
|
*/
|
|
55
|
-
export type ArchiveRowChanges = Record<string, string | null | undefined>;
|
|
56
|
+
export type ArchiveRowChanges = Record<string, string | number | null | undefined>;
|
|
56
57
|
/** Aggiornamento di una riga della griglia, con le sole modifiche possibili in linea */
|
|
57
58
|
export type ArchiveRowUpdatingEvent = Omit<DataGridTypes.RowUpdatingEvent<ArchiveRow, number>, 'newData'> & {
|
|
58
59
|
newData: ArchiveRowChanges;
|
|
@@ -70,10 +71,15 @@ export declare const canArchive: (dtd?: DcmtTypeDescriptor) => boolean;
|
|
|
70
71
|
*/
|
|
71
72
|
export declare const INLINE_EDITABLE_CELL_CLASS = "tm-cell-inline-editable";
|
|
72
73
|
/**
|
|
73
|
-
* Modifica diretta in griglia:
|
|
74
|
-
* hanno editor e vincoli propri, date
|
|
74
|
+
* Modifica diretta in griglia: testo libero e numeri. Liste dati, calcolati, numeratori e speciali
|
|
75
|
+
* hanno editor e vincoli propri, le date una formattazione dedicata: restano al form
|
|
75
76
|
*/
|
|
76
77
|
export declare const isInlineEditableMetadata: (md: MetadataDescriptor) => boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Valore di una cella numerica: l'editor della griglia vuole un numero, non la stringa che
|
|
80
|
+
* la riga porta in `__values` per l'archiviazione. Vuoto o non numerico: cella vuota
|
|
81
|
+
*/
|
|
82
|
+
export declare const toGridNumber: (value: unknown) => number | undefined;
|
|
77
83
|
/** Colonne della griglia di riepilogo dai metadati (utente) del tipo documento */
|
|
78
84
|
export declare const buildColumnsFromDtd: (dtd: DcmtTypeDescriptor | undefined, renderDataListCell: (value: string | Date | number | undefined, dataListID: number, viewMode: DataListViewModes) => React.ReactElement) => Array<IColumnProps>;
|
|
79
85
|
export declare const getDetailDtdAsync: (detailTID: number | undefined) => Promise<DcmtTypeDescriptor | undefined>;
|
|
@@ -27,12 +27,22 @@ export const canArchive = (dtd) => dtd?.perm?.canArchive === AccessLevelsEx.Yes
|
|
|
27
27
|
*/
|
|
28
28
|
export const INLINE_EDITABLE_CELL_CLASS = 'tm-cell-inline-editable';
|
|
29
29
|
/**
|
|
30
|
-
* Modifica diretta in griglia:
|
|
31
|
-
* hanno editor e vincoli propri, date
|
|
30
|
+
* Modifica diretta in griglia: testo libero e numeri. Liste dati, calcolati, numeratori e speciali
|
|
31
|
+
* hanno editor e vincoli propri, le date una formattazione dedicata: restano al form
|
|
32
32
|
*/
|
|
33
|
-
export const isInlineEditableMetadata = (md) => md.dataType === MetadataDataTypes.Varchar
|
|
33
|
+
export const isInlineEditableMetadata = (md) => (md.dataType === MetadataDataTypes.Varchar || md.dataType === MetadataDataTypes.Number)
|
|
34
34
|
&& (md.dataDomain === undefined || md.dataDomain === MetadataDataDomains.None)
|
|
35
35
|
&& md.isSystem !== 1 && md.isSystemDerived !== 1;
|
|
36
|
+
/**
|
|
37
|
+
* Valore di una cella numerica: l'editor della griglia vuole un numero, non la stringa che
|
|
38
|
+
* la riga porta in `__values` per l'archiviazione. Vuoto o non numerico: cella vuota
|
|
39
|
+
*/
|
|
40
|
+
export const toGridNumber = (value) => {
|
|
41
|
+
if (value === undefined || value === null || value === '')
|
|
42
|
+
return undefined;
|
|
43
|
+
const parsed = typeof value === 'number' ? value : Number(value);
|
|
44
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
45
|
+
};
|
|
36
46
|
/** Colonne della griglia di riepilogo dai metadati (utente) del tipo documento */
|
|
37
47
|
export const buildColumnsFromDtd = (dtd, renderDataListCell) => getUserMetadataSorted(dtd).map(md => {
|
|
38
48
|
const dataListID = md.dataListID ?? 0;
|
|
@@ -41,21 +51,25 @@ export const buildColumnsFromDtd = (dtd, renderDataListCell) => getUserMetadataS
|
|
|
41
51
|
const dataType = md.dataType;
|
|
42
52
|
const format = md.format?.format;
|
|
43
53
|
const formatCulture = md.format?.formatCulture;
|
|
44
|
-
// Date e numeri usano la formattazione scalare; le liste dati il render comune
|
|
45
|
-
const needsScalarFormat = !isDataList && (dataType === MetadataDataTypes.DateTime || dataType === MetadataDataTypes.Number);
|
|
46
54
|
const isInlineEditable = isInlineEditableMetadata(md);
|
|
55
|
+
const isNumber = dataType === MetadataDataTypes.Number;
|
|
56
|
+
// Date e numeri usano la formattazione scalare; le liste dati il render comune. La cella
|
|
57
|
+
// modificabile mostra sempre l'editor, quindi non ha un proprio render
|
|
58
|
+
const needsScalarFormat = !isDataList && !isInlineEditable && (dataType === MetadataDataTypes.DateTime || isNumber);
|
|
47
59
|
return {
|
|
48
60
|
dataField: String(md.id),
|
|
49
61
|
caption: (SDK_Globals.useLocalizedName ? md.nameLoc : md.name) ?? md.name ?? '',
|
|
50
62
|
// La colonna modificabile dichiara il tipo: senza valori DevExtreme non saprebbe che editor usare
|
|
51
63
|
...(isInlineEditable
|
|
52
64
|
? {
|
|
53
|
-
|
|
65
|
+
// I numeri arrivano in cella già come numeri (vedi buildArchiveRow): l'editor è la casella numerica
|
|
66
|
+
dataType: isNumber ? 'number' : 'string',
|
|
54
67
|
allowEditing: true,
|
|
55
68
|
showEditorAlways: true,
|
|
56
69
|
cssClass: INLINE_EDITABLE_CELL_CLASS,
|
|
57
|
-
// Lunghezza e obbligatorietà del metadato valgono anche in griglia
|
|
58
|
-
|
|
70
|
+
// Lunghezza e obbligatorietà del metadato valgono anche in griglia; sui numeri
|
|
71
|
+
// i limiti restano all'API, in cella basta che sia un numero
|
|
72
|
+
editorOptions: !isNumber && md.length ? { maxLength: md.length } : undefined,
|
|
59
73
|
validationRules: String(md.isRequired) === '1' ? [{ type: 'required', message: SDKUI_Localizator.RequiredField }] : undefined,
|
|
60
74
|
}
|
|
61
75
|
: { allowEditing: false }),
|
|
@@ -8,7 +8,7 @@ import TMSpinner from '../components/base/TMSpinner';
|
|
|
8
8
|
import ShowAlert from '../components/base/TMAlert';
|
|
9
9
|
import { TMResultManager } from '../components/forms/TMResultDialog';
|
|
10
10
|
import { useDataListItem } from './useDataListItem';
|
|
11
|
-
import { buildColumnsFromDtd, canArchive, canUpdateMasterCallback, getDetailDtdAsync } from '../components/features/documents/TMMultiMasterDetailDcmtsUtils';
|
|
11
|
+
import { buildColumnsFromDtd, canArchive, canUpdateMasterCallback, getDetailDtdAsync, toGridNumber } from '../components/features/documents/TMMultiMasterDetailDcmtsUtils';
|
|
12
12
|
/** Fasi del flusso di archiviazione multipla dei dettagli */
|
|
13
13
|
export var MultiDetailArchivePhase;
|
|
14
14
|
(function (MultiDetailArchivePhase) {
|
|
@@ -44,6 +44,8 @@ export const useMultiMasterDetailDcmts = ({ dtd, masterDcmt, onClose }) => {
|
|
|
44
44
|
// Struttura del tipo documento selezionato
|
|
45
45
|
const [detailColumns, setDetailColumns] = useState([]);
|
|
46
46
|
const [detailSupportsFile, setDetailSupportsFile] = useState(false);
|
|
47
|
+
// Mid numerici del tipo di dettaglio: in griglia le loro celle portano il numero (vedi buildArchiveRow)
|
|
48
|
+
const numericMidsRef = useRef(new Set());
|
|
47
49
|
// Dettagli già archiviati del tipo selezionato, collegati al master
|
|
48
50
|
const [archivedDetailResults, setArchivedDetailResults] = useState([]);
|
|
49
51
|
const [isLoadingArchivedDetails, setIsLoadingArchivedDetails] = useState(false);
|
|
@@ -146,6 +148,7 @@ export const useMultiMasterDetailDcmts = ({ dtd, masterDcmt, onClose }) => {
|
|
|
146
148
|
if (!selectedRelation?.detailTID) {
|
|
147
149
|
setDetailColumns([]);
|
|
148
150
|
setDetailSupportsFile(false);
|
|
151
|
+
numericMidsRef.current = new Set();
|
|
149
152
|
return;
|
|
150
153
|
}
|
|
151
154
|
try {
|
|
@@ -153,16 +156,21 @@ export const useMultiMasterDetailDcmts = ({ dtd, masterDcmt, onClose }) => {
|
|
|
153
156
|
setDetailSupportsFile(detailDtd?.archiveConstraint !== ArchiveConstraints.OnlyMetadata);
|
|
154
157
|
// Liste dati referenziate dai metadati, servono al render delle celle
|
|
155
158
|
const dataListIDs = new Set();
|
|
159
|
+
const numericMids = new Set();
|
|
156
160
|
(detailDtd?.metadata ?? []).forEach(md => {
|
|
157
161
|
if (md.dataDomain === MetadataDataDomains.DataList && md.dataListID)
|
|
158
162
|
dataListIDs.add(md.dataListID);
|
|
163
|
+
if (md.dataType === MetadataDataTypes.Number && md.id !== undefined)
|
|
164
|
+
numericMids.add(md.id);
|
|
159
165
|
});
|
|
166
|
+
numericMidsRef.current = numericMids;
|
|
160
167
|
await loadDataListsAsync(dataListIDs);
|
|
161
168
|
setDetailColumns(buildColumnsFromDtd(detailDtd, renderDataListCell));
|
|
162
169
|
}
|
|
163
170
|
catch {
|
|
164
171
|
setDetailColumns([]);
|
|
165
172
|
setDetailSupportsFile(false);
|
|
173
|
+
numericMidsRef.current = new Set();
|
|
166
174
|
}
|
|
167
175
|
};
|
|
168
176
|
loadDetailStructureAsync();
|
|
@@ -315,11 +323,13 @@ export const useMultiMasterDetailDcmts = ({ dtd, masterDcmt, onClose }) => {
|
|
|
315
323
|
},
|
|
316
324
|
});
|
|
317
325
|
}, []);
|
|
326
|
+
// I valori del form sono stringhe: le celle numeriche vogliono il numero, richiesto dal loro editor
|
|
318
327
|
const buildArchiveRow = useCallback((id, tid, values, file) => {
|
|
319
328
|
const row = { id, __tid: tid, __values: values, __file: file };
|
|
320
329
|
for (const v of values) {
|
|
321
|
-
if (v.mid
|
|
322
|
-
|
|
330
|
+
if (v.mid === undefined)
|
|
331
|
+
continue;
|
|
332
|
+
row[String(v.mid)] = numericMidsRef.current.has(v.mid) ? toGridNumber(v.value) : (v.value ?? '');
|
|
323
333
|
}
|
|
324
334
|
return row;
|
|
325
335
|
}, []);
|
|
@@ -338,7 +348,7 @@ export const useMultiMasterDetailDcmts = ({ dtd, masterDcmt, onClose }) => {
|
|
|
338
348
|
closeAddForm();
|
|
339
349
|
};
|
|
340
350
|
/**
|
|
341
|
-
* Modifica diretta in griglia di uno o più metadati testuali (changes: mid -> valore).
|
|
351
|
+
* Modifica diretta in griglia di uno o più metadati testuali o numerici (changes: mid -> valore).
|
|
342
352
|
* La riga e i suoi __values sono ricreati: il duplicato, che condivide __values per
|
|
343
353
|
* riferimento, resta invariato
|
|
344
354
|
*/
|
|
@@ -346,9 +356,10 @@ export const useMultiMasterDetailDcmts = ({ dtd, masterDcmt, onClose }) => {
|
|
|
346
356
|
const changedMids = Object.keys(changes);
|
|
347
357
|
if (changedMids.length === 0)
|
|
348
358
|
return;
|
|
349
|
-
//
|
|
359
|
+
// I __values vanno a sistema come stringhe, anche quelli che in griglia sono numeri. La griglia
|
|
360
|
+
// restituisce null sull'editor svuotato: a sistema il metadato va vuoto, non nullo
|
|
350
361
|
const normalized = {};
|
|
351
|
-
changedMids.forEach(mid => { normalized[mid] = changes[mid]
|
|
362
|
+
changedMids.forEach(mid => { normalized[mid] = changes[mid] === null || changes[mid] === undefined ? '' : String(changes[mid]); });
|
|
352
363
|
setArchiveRows(prev => prev.map(r => {
|
|
353
364
|
if (r.id !== rowId)
|
|
354
365
|
return r;
|
|
@@ -364,7 +375,8 @@ export const useMultiMasterDetailDcmts = ({ dtd, masterDcmt, onClose }) => {
|
|
|
364
375
|
values.push(added);
|
|
365
376
|
});
|
|
366
377
|
const updated = { ...r, __values: values };
|
|
367
|
-
|
|
378
|
+
// In cella il numero resta un numero, come lo vuole il suo editor
|
|
379
|
+
changedMids.forEach(mid => { updated[mid] = numericMidsRef.current.has(Number(mid)) ? toGridNumber(normalized[mid]) : normalized[mid]; });
|
|
368
380
|
return updated;
|
|
369
381
|
}));
|
|
370
382
|
}, []);
|