@topconsultnpm/sdkui-react 6.22.0-dev2.16 → 6.22.0-dev2.18
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/base/TMEditorBase.d.ts +2 -0
- package/lib/components/base/TMTooltip.d.ts +2 -1
- package/lib/components/base/TMTooltip.js +23 -6
- package/lib/components/choosers/TMDcmtTypeChooser.js +4 -3
- package/lib/components/choosers/TMDistinctValues.d.ts +9 -7
- package/lib/components/choosers/TMDistinctValues.js +147 -195
- package/lib/components/choosers/TMMetadataChooser.js +1 -1
- package/lib/components/choosers/TMQuickSearchInfo.d.ts +12 -0
- package/lib/components/choosers/TMQuickSearchInfo.js +279 -0
- package/lib/components/choosers/TMQuickSearchSettingsForm.d.ts +16 -0
- package/lib/components/choosers/TMQuickSearchSettingsForm.js +94 -0
- package/lib/components/choosers/TMSelectedValuesSummary.d.ts +13 -0
- package/lib/components/choosers/TMSelectedValuesSummary.js +91 -0
- package/lib/components/editors/TMDropDown.d.ts +3 -0
- package/lib/components/editors/TMDropDown.js +197 -5
- package/lib/components/features/documents/TMDcmtForm.js +10 -2
- package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +11 -0
- package/lib/components/features/documents/TMDcmtFormActionButtons.js +74 -7
- package/lib/components/features/search/TMSearchResult.js +55 -4
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +10 -0
- package/lib/components/features/workflow/TMWorkflowPopup.js +8 -4
- package/lib/components/viewers/TMMidViewer.js +4 -1
- package/lib/components/viewers/TMTidViewer.js +25 -11
- package/lib/helper/SDKUI_Globals.d.ts +20 -0
- package/lib/helper/SDKUI_Globals.js +44 -0
- package/lib/helper/SDKUI_Localizator.d.ts +1 -0
- package/lib/helper/SDKUI_Localizator.js +10 -0
- package/lib/helper/dataGridSearchHelper.d.ts +28 -0
- package/lib/helper/dataGridSearchHelper.js +51 -0
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/helper/queryHelper.d.ts +2 -0
- package/lib/helper/queryHelper.js +3 -1
- package/lib/hooks/tmDistinctValuesGridHelper.d.ts +16 -0
- package/lib/hooks/tmDistinctValuesGridHelper.js +31 -0
- package/lib/hooks/useCaseFlowApprove.d.ts +56 -0
- package/lib/hooks/useCaseFlowApprove.js +157 -0
- package/lib/hooks/useTMDistinctValuesMetadataDisplay.d.ts +18 -0
- package/lib/hooks/useTMDistinctValuesMetadataDisplay.js +103 -0
- package/lib/hooks/useTMDistinctValuesQuickSearch.d.ts +49 -0
- package/lib/hooks/useTMDistinctValuesQuickSearch.js +307 -0
- package/lib/hooks/useTMDistinctValuesSelection.d.ts +42 -0
- package/lib/hooks/useTMDistinctValuesSelection.js +103 -0
- package/lib/hooks/useTMDistinctValuesSource.d.ts +29 -0
- package/lib/hooks/useTMDistinctValuesSource.js +105 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/services/caseflow/CaseFlowService.d.ts +208 -0
- package/lib/services/caseflow/CaseFlowService.js +623 -0
- package/lib/services/caseflow/CaseFlowTemplateCacheService.d.ts +28 -0
- package/lib/services/caseflow/CaseFlowTemplateCacheService.js +121 -0
- package/lib/services/caseflow/caseFlowNameCache.d.ts +32 -0
- package/lib/services/caseflow/caseFlowNameCache.js +116 -0
- package/lib/services/caseflow/caseFlowWorkItemUtils.d.ts +61 -0
- package/lib/services/caseflow/caseFlowWorkItemUtils.js +113 -0
- package/lib/services/index.d.ts +4 -0
- package/lib/services/index.js +4 -0
- package/lib/services/platform_services.d.ts +1 -1
- package/package.json +1 -1
|
@@ -259,7 +259,7 @@ export const TMDcmtTypeIcon = ({ dtd }) => {
|
|
|
259
259
|
return (_jsx(TMDcmtTypeTooltip, { dtd: dtd, children: icon }));
|
|
260
260
|
};
|
|
261
261
|
export const TMDcmtTypeTooltip = ({ dtd, children }) => {
|
|
262
|
-
return (_jsx("div", { style: { pointerEvents: 'all' }, children: _jsx(TMTooltip, { content: renderDTDTooltipContent(dtd), children: children }) }));
|
|
262
|
+
return (_jsx("div", { style: { pointerEvents: 'all' }, children: _jsx(TMTooltip, { allowContentInteraction: true, content: renderDTDTooltipContent(dtd), children: children }) }));
|
|
263
263
|
};
|
|
264
264
|
const TMTidViewer = ({ tmSession, tid, did, showIcon = false, color, showId = false, noneSelectionText = `<${SDKUI_Localizator.NoneSelection}>` }) => {
|
|
265
265
|
const [dtd, setDtd] = useState();
|
|
@@ -297,29 +297,43 @@ const TMTidViewer = ({ tmSession, tid, did, showIcon = false, color, showId = fa
|
|
|
297
297
|
textOverflow: 'ellipsis'
|
|
298
298
|
}, children: [showIcon && dtd && _jsx(TMDcmtTypeIcon, { dtd: dtd }), _jsx("p", { title: displayName(), style: {
|
|
299
299
|
textAlign: 'left',
|
|
300
|
+
margin: 0,
|
|
300
301
|
marginLeft: showIcon ? '5px' : '',
|
|
301
|
-
color:
|
|
302
|
+
color: dtd?.isView ? 'red' : (color ?? TMColors.primary),
|
|
302
303
|
whiteSpace: 'nowrap',
|
|
303
304
|
overflow: 'hidden',
|
|
304
305
|
textOverflow: 'ellipsis',
|
|
305
306
|
// paddingRight: '10px'
|
|
306
|
-
}, children: displayName() }), showId && _jsx("p", { style: { padding: '0px 3px' }, children: `(TID: ${tid})` })] }));
|
|
307
|
+
}, children: displayName() }), showId && _jsx("p", { style: { padding: '0px 3px', margin: 0 }, children: `(TID: ${tid})` })] }));
|
|
307
308
|
};
|
|
308
309
|
export default TMTidViewer;
|
|
309
310
|
export const cellRenderTID = (data, noneSelectionText) => {
|
|
310
311
|
return (_jsx(TMTidViewer, { tid: data.value, noneSelectionText: noneSelectionText }));
|
|
311
312
|
};
|
|
312
|
-
/**
|
|
313
|
+
/** Metodi di visualizzazione già richiesti, per non ricaricare i metadati ad ogni riapertura del tooltip */
|
|
314
|
+
const displayNameMethodCache = new Map();
|
|
313
315
|
const TMDisplayNameMethodItem = ({ dtd }) => {
|
|
314
|
-
const [displayNameMethod, setDisplayNameMethod] = useState(
|
|
315
|
-
|
|
316
|
-
|
|
316
|
+
const [displayNameMethod, setDisplayNameMethod] = useState(() => dtd.id ? displayNameMethodCache.get(dtd.id) : undefined);
|
|
317
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
318
|
+
const onShowClick = async (e) => {
|
|
319
|
+
/* Un click qualsiasi chiude il tooltip: senza questo il risultato non sarebbe mai visibile */
|
|
320
|
+
e.stopPropagation();
|
|
321
|
+
if (isLoading || displayNameMethod)
|
|
322
|
+
return;
|
|
323
|
+
setIsLoading(true);
|
|
324
|
+
try {
|
|
317
325
|
const method = await getDTDDisplayNameInfo(dtd);
|
|
326
|
+
if (dtd.id)
|
|
327
|
+
displayNameMethodCache.set(dtd.id, method);
|
|
318
328
|
setDisplayNameMethod(method);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
329
|
+
}
|
|
330
|
+
finally {
|
|
331
|
+
setIsLoading(false);
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
return (_jsxs(StyledTooltipItem, { children: [`${SDKUI_Localizator.DisplayNameMethod}: `, displayNameMethod ?? (isLoading
|
|
335
|
+
? `${SDKUI_Localizator.Loading} ...`
|
|
336
|
+
: _jsx("span", { style: { color: TMColors.primary, cursor: 'pointer', textDecoration: 'underline' }, onClick: onShowClick, children: SDKUI_Localizator.Details }))] }));
|
|
323
337
|
};
|
|
324
338
|
export const renderDTDTooltipContent = (dtd) => {
|
|
325
339
|
const mapAccessLevelToLocalizedString = (level) => {
|
|
@@ -67,6 +67,18 @@ export declare class ThemeSettings {
|
|
|
67
67
|
export declare const DEFAULT_PREVIEW_THRESHOLD = 500;
|
|
68
68
|
export declare const DEFAULT_PAGE_SIZE = 100;
|
|
69
69
|
export declare const DEFAULT_MAX_DCMTS_TO_BE_RETURNED = 200;
|
|
70
|
+
export declare const DEFAULT_QUICK_SEARCH_MAX_DCMTS = 1000;
|
|
71
|
+
/** Ricerca rapida configurata come sorgente alternativa dei valori distinti di un campo */
|
|
72
|
+
export declare class DistinctValuesQuickSearchSettings {
|
|
73
|
+
/** Tipo documento su cui viene eseguita la ricerca rapida */
|
|
74
|
+
tid: number | undefined;
|
|
75
|
+
/** ID della ricerca salvata (SavedQueryDescriptor) da eseguire; SYS_ALL_DCMTS_SQD_ID per la ricerca di sistema con tutti i documenti del tipo documento */
|
|
76
|
+
sqdId: number | undefined;
|
|
77
|
+
/** Metadato del risultato da cui viene prelevato il valore */
|
|
78
|
+
mid: number | undefined;
|
|
79
|
+
/** Numero massimo di documenti restituiti dalla ricerca rapida */
|
|
80
|
+
maxDcmtsToBeReturned: number;
|
|
81
|
+
}
|
|
70
82
|
export declare class SearchSettings {
|
|
71
83
|
autoFindReferences: ObjectClasses[];
|
|
72
84
|
invoiceRetrieveFormat: InvoiceRetrieveFormats;
|
|
@@ -86,7 +98,15 @@ export declare class SearchSettings {
|
|
|
86
98
|
};
|
|
87
99
|
relationExpandLevel: number;
|
|
88
100
|
relationShowZeroDcmts: boolean;
|
|
101
|
+
/** Ricerche rapide configurate per i valori distinti: una per ogni campo, con chiave "tid_mid" */
|
|
102
|
+
distinctValuesQuickSearches: {
|
|
103
|
+
[fieldKey: string]: DistinctValuesQuickSearchSettings;
|
|
104
|
+
};
|
|
89
105
|
}
|
|
106
|
+
/** Ricerca rapida configurata per il campo, se presente */
|
|
107
|
+
export declare const getDistinctValuesQuickSearch: (tid: number | undefined, mid: number | undefined) => DistinctValuesQuickSearchSettings | undefined;
|
|
108
|
+
export declare const saveDistinctValuesQuickSearch: (tid: number | undefined, mid: number | undefined, settings: DistinctValuesQuickSearchSettings) => void;
|
|
109
|
+
export declare const removeDistinctValuesQuickSearch: (tid: number | undefined, mid: number | undefined) => void;
|
|
90
110
|
export declare class FloatingMenuBarSettings {
|
|
91
111
|
orientation?: 'horizontal' | 'vertical';
|
|
92
112
|
itemIds?: string[];
|
|
@@ -130,6 +130,20 @@ export class ThemeSettings {
|
|
|
130
130
|
export const DEFAULT_PREVIEW_THRESHOLD = 500; // KB
|
|
131
131
|
export const DEFAULT_PAGE_SIZE = 100;
|
|
132
132
|
export const DEFAULT_MAX_DCMTS_TO_BE_RETURNED = 200;
|
|
133
|
+
export const DEFAULT_QUICK_SEARCH_MAX_DCMTS = 1000;
|
|
134
|
+
/** Ricerca rapida configurata come sorgente alternativa dei valori distinti di un campo */
|
|
135
|
+
export class DistinctValuesQuickSearchSettings {
|
|
136
|
+
constructor() {
|
|
137
|
+
/** Tipo documento su cui viene eseguita la ricerca rapida */
|
|
138
|
+
this.tid = undefined;
|
|
139
|
+
/** ID della ricerca salvata (SavedQueryDescriptor) da eseguire; SYS_ALL_DCMTS_SQD_ID per la ricerca di sistema con tutti i documenti del tipo documento */
|
|
140
|
+
this.sqdId = undefined;
|
|
141
|
+
/** Metadato del risultato da cui viene prelevato il valore */
|
|
142
|
+
this.mid = undefined;
|
|
143
|
+
/** Numero massimo di documenti restituiti dalla ricerca rapida */
|
|
144
|
+
this.maxDcmtsToBeReturned = DEFAULT_QUICK_SEARCH_MAX_DCMTS;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
133
147
|
export class SearchSettings {
|
|
134
148
|
constructor() {
|
|
135
149
|
this.autoFindReferences = [];
|
|
@@ -144,8 +158,38 @@ export class SearchSettings {
|
|
|
144
158
|
this.panelLayout = {};
|
|
145
159
|
this.relationExpandLevel = 4; // Livello di espansione predefinito per le correlazioni
|
|
146
160
|
this.relationShowZeroDcmts = false;
|
|
161
|
+
/** Ricerche rapide configurate per i valori distinti: una per ogni campo, con chiave "tid_mid" */
|
|
162
|
+
this.distinctValuesQuickSearches = {};
|
|
147
163
|
}
|
|
148
164
|
}
|
|
165
|
+
/** Il campo da cui viene aperto il pannello dei valori distinti è identificato dalla coppia (tid, mid) */
|
|
166
|
+
const distinctValuesFieldKey = (tid, mid) => `${tid}_${mid}`;
|
|
167
|
+
/** Ricerca rapida configurata per il campo, se presente */
|
|
168
|
+
export const getDistinctValuesQuickSearch = (tid, mid) => {
|
|
169
|
+
if (!tid || !mid)
|
|
170
|
+
return undefined;
|
|
171
|
+
// Le impostazioni salvate da versioni precedenti non hanno la mappa: va gestita l'assenza
|
|
172
|
+
return SDKUI_Globals.userSettings.searchSettings.distinctValuesQuickSearches?.[distinctValuesFieldKey(tid, mid)];
|
|
173
|
+
};
|
|
174
|
+
export const saveDistinctValuesQuickSearch = (tid, mid, settings) => {
|
|
175
|
+
if (!tid || !mid)
|
|
176
|
+
return;
|
|
177
|
+
// Il proxy delle impostazioni persiste solo intercettando l'assegnazione di una proprietà: la mappa va riassegnata per intero
|
|
178
|
+
SDKUI_Globals.userSettings.searchSettings.distinctValuesQuickSearches = {
|
|
179
|
+
...SDKUI_Globals.userSettings.searchSettings.distinctValuesQuickSearches,
|
|
180
|
+
[distinctValuesFieldKey(tid, mid)]: settings,
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
export const removeDistinctValuesQuickSearch = (tid, mid) => {
|
|
184
|
+
if (!tid || !mid)
|
|
185
|
+
return;
|
|
186
|
+
const fieldKey = distinctValuesFieldKey(tid, mid);
|
|
187
|
+
const quickSearches = SDKUI_Globals.userSettings.searchSettings.distinctValuesQuickSearches;
|
|
188
|
+
if (!quickSearches?.[fieldKey])
|
|
189
|
+
return;
|
|
190
|
+
const { [fieldKey]: removedSettings, ...remainingQuickSearches } = quickSearches;
|
|
191
|
+
SDKUI_Globals.userSettings.searchSettings.distinctValuesQuickSearches = remainingQuickSearches;
|
|
192
|
+
};
|
|
149
193
|
export class FloatingMenuBarSettings {
|
|
150
194
|
}
|
|
151
195
|
export class ArchivingSettings {
|
|
@@ -657,6 +657,7 @@ export declare class SDKUI_Localizator {
|
|
|
657
657
|
static get QueryDefine(): "Abfrage definieren" | "Query define" | "Definir consulta" | "Défine query" | "Definir query" | "Definisci query";
|
|
658
658
|
static get Query_EnterAlias(): "Geben Sie einen Alias ein" | "Enter an alias" | "Introducir un alias" | "Entrez un alias" | "Digite um nome de alias" | "Inserire un alias";
|
|
659
659
|
static get QueryParamBind(): "Query-Parameter erweitern" | "Fill query parameters" | "Valorizar parámetros consulta" | "Ajoute la valeur à les paramètres de la query" | "Melhora parâmetros de query" | "Valorizza parametri query";
|
|
660
|
+
static get QuickSearchSettings_DeleteConfirmFor1(): "Schnellsuche-Konfiguration für '{{0}}' löschen?" | "Delete the quick search setup for '{{0}}'?" | "¿Eliminar la configuración de la búsqueda rápida de '{{0}}'?" | "Supprimer la configuration de la recherche rapide de '{{0}}' ?" | "Eliminar a configuração da pesquisa rápida de '{{0}}'?" | "Eliminare la configurazione della ricerca rapida di '{{0}}'?";
|
|
660
661
|
static get ReadOnly(): "Nur Lesen" | "Read only" | "Solo lectura" | "En lecture seule" | "Somente leitura" | "Solo lettura";
|
|
661
662
|
static get Reassign(): "Neu zuweisen" | "Reassign" | "Reasignar" | "Réaffecter" | "Reatribuir" | "Riassegna";
|
|
662
663
|
static get RefersTo(): string;
|
|
@@ -6542,6 +6542,16 @@ export class SDKUI_Localizator {
|
|
|
6542
6542
|
default: return "Valorizza parametri query";
|
|
6543
6543
|
}
|
|
6544
6544
|
}
|
|
6545
|
+
static get QuickSearchSettings_DeleteConfirmFor1() {
|
|
6546
|
+
switch (this._cultureID) {
|
|
6547
|
+
case CultureIDs.De_DE: return "Schnellsuche-Konfiguration für '{{0}}' löschen?";
|
|
6548
|
+
case CultureIDs.En_US: return "Delete the quick search setup for '{{0}}'?";
|
|
6549
|
+
case CultureIDs.Es_ES: return "¿Eliminar la configuración de la búsqueda rápida de '{{0}}'?";
|
|
6550
|
+
case CultureIDs.Fr_FR: return "Supprimer la configuration de la recherche rapide de '{{0}}' ?";
|
|
6551
|
+
case CultureIDs.Pt_PT: return "Eliminar a configuração da pesquisa rápida de '{{0}}'?";
|
|
6552
|
+
default: return "Eliminare la configurazione della ricerca rapida di '{{0}}'?";
|
|
6553
|
+
}
|
|
6554
|
+
}
|
|
6545
6555
|
static get ReadOnly() {
|
|
6546
6556
|
switch (this._cultureID) {
|
|
6547
6557
|
case CultureIDs.De_DE: return "Nur Lesen";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { MetadataFormats } from '@topconsultnpm/sdk-ts';
|
|
2
|
+
/** Testo mostrato in una colonna per una riga: è quello su cui va cercato ciò che l'utente digita */
|
|
3
|
+
export type SearchTextGetter = (rowData: any) => string;
|
|
4
|
+
/** Testo con cui una data viene mostrata nella griglia: è quello che l'utente vede e quindi quello che cerca */
|
|
5
|
+
export declare const getDateDisplayText: (value: any, format: MetadataFormats | undefined, formatCulture: string | undefined | null) => string;
|
|
6
|
+
/** Testo con cui un numero viene mostrato nella griglia (separatore delle migliaia, valuta, decimali) */
|
|
7
|
+
export declare const getNumberDisplayText: (value: any, format: MetadataFormats | undefined, formatCulture: string) => string;
|
|
8
|
+
/**
|
|
9
|
+
* Dirotta la ricerca della griglia sul testo mostrato, per le colonne indicate (chiave: il `dataField`).
|
|
10
|
+
*
|
|
11
|
+
* La ricerca di DevExtreme lavora sul valore archiviato, quindi non trova nulla dove il testo mostrato è
|
|
12
|
+
* diverso:
|
|
13
|
+
* - **date**, che nei dati sono stringhe ISO: DevExtreme prova a interpretare il testo digitato con il
|
|
14
|
+
* formato della colonna, non riesce (il formato è un formatter personalizzato, non un pattern) e scarta
|
|
15
|
+
* la colonna dalla ricerca — cercando `29/01/2023` non trova nulla;
|
|
16
|
+
* - **numeri formattati**, per lo stesso motivo (separatore delle migliaia, simbolo di valuta);
|
|
17
|
+
* - **liste dati e utenti**, dove viene confrontata la chiave archiviata invece della descrizione
|
|
18
|
+
* visualizzata — cercando `FATTURA` non trova nulla, cercando `TD01` sì.
|
|
19
|
+
*
|
|
20
|
+
* Da passare a `customizeColumns` della griglia. Va fatto lì perché solo lì è disponibile la
|
|
21
|
+
* `calculateFilterExpression` predefinita di DevExtreme, che resta in uso per il filtro di intestazione e
|
|
22
|
+
* per il generatore di filtri: quelli funzionano già correttamente e vanno lasciati intatti.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const searchTextGetters = useMemo(() => new Map([['TM_1_2', (row) => getDateDisplayText(row?.TM_1_2, format, culture)]]), [...]);
|
|
26
|
+
* const customizeColumns = useMemo(() => customizeSearchByDisplayText(searchTextGetters), [searchTextGetters]);
|
|
27
|
+
*/
|
|
28
|
+
export declare const customizeSearchByDisplayText: (searchTextGetters: Map<string, SearchTextGetter>) => (columns: Array<any>) => void;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { formatDateTimeByMetadataFormat, formatNumberByMetadataFormat } from './TMUtils';
|
|
2
|
+
/** Testo con cui una data viene mostrata nella griglia: è quello che l'utente vede e quindi quello che cerca */
|
|
3
|
+
export const getDateDisplayText = (value, format, formatCulture) => {
|
|
4
|
+
if (value === undefined || value === null || value === '')
|
|
5
|
+
return '';
|
|
6
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
7
|
+
return Number.isNaN(date.getTime()) ? '' : formatDateTimeByMetadataFormat(date, format, formatCulture);
|
|
8
|
+
};
|
|
9
|
+
/** Testo con cui un numero viene mostrato nella griglia (separatore delle migliaia, valuta, decimali) */
|
|
10
|
+
export const getNumberDisplayText = (value, format, formatCulture) => {
|
|
11
|
+
if (value === undefined || value === null || value === '')
|
|
12
|
+
return '';
|
|
13
|
+
return formatNumberByMetadataFormat(value, format, formatCulture);
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Dirotta la ricerca della griglia sul testo mostrato, per le colonne indicate (chiave: il `dataField`).
|
|
17
|
+
*
|
|
18
|
+
* La ricerca di DevExtreme lavora sul valore archiviato, quindi non trova nulla dove il testo mostrato è
|
|
19
|
+
* diverso:
|
|
20
|
+
* - **date**, che nei dati sono stringhe ISO: DevExtreme prova a interpretare il testo digitato con il
|
|
21
|
+
* formato della colonna, non riesce (il formato è un formatter personalizzato, non un pattern) e scarta
|
|
22
|
+
* la colonna dalla ricerca — cercando `29/01/2023` non trova nulla;
|
|
23
|
+
* - **numeri formattati**, per lo stesso motivo (separatore delle migliaia, simbolo di valuta);
|
|
24
|
+
* - **liste dati e utenti**, dove viene confrontata la chiave archiviata invece della descrizione
|
|
25
|
+
* visualizzata — cercando `FATTURA` non trova nulla, cercando `TD01` sì.
|
|
26
|
+
*
|
|
27
|
+
* Da passare a `customizeColumns` della griglia. Va fatto lì perché solo lì è disponibile la
|
|
28
|
+
* `calculateFilterExpression` predefinita di DevExtreme, che resta in uso per il filtro di intestazione e
|
|
29
|
+
* per il generatore di filtri: quelli funzionano già correttamente e vanno lasciati intatti.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* const searchTextGetters = useMemo(() => new Map([['TM_1_2', (row) => getDateDisplayText(row?.TM_1_2, format, culture)]]), [...]);
|
|
33
|
+
* const customizeColumns = useMemo(() => customizeSearchByDisplayText(searchTextGetters), [searchTextGetters]);
|
|
34
|
+
*/
|
|
35
|
+
export const customizeSearchByDisplayText = (searchTextGetters) => (columns) => {
|
|
36
|
+
columns.forEach((column) => {
|
|
37
|
+
const getSearchText = column?.dataField ? searchTextGetters.get(column.dataField) : undefined;
|
|
38
|
+
// customizeColumns viene richiamata a ogni aggiornamento delle colonne: senza il marcatore i wrapper si anniderebbero
|
|
39
|
+
if (!getSearchText || column.tmSearchByDisplayText)
|
|
40
|
+
return;
|
|
41
|
+
const defaultCalculateFilterExpression = column.calculateFilterExpression;
|
|
42
|
+
// Senza questo DevExtreme prova a convertire il testo digitato nel tipo della colonna e, non riuscendo, la scarta
|
|
43
|
+
column.parseValue = (text) => text;
|
|
44
|
+
column.calculateFilterExpression = function (filterValue, selectedFilterOperation, target) {
|
|
45
|
+
if (target === 'search')
|
|
46
|
+
return [getSearchText, 'contains', filterValue];
|
|
47
|
+
return defaultCalculateFilterExpression?.apply(this, arguments);
|
|
48
|
+
};
|
|
49
|
+
column.tmSearchByDisplayText = true;
|
|
50
|
+
});
|
|
51
|
+
};
|
package/lib/helper/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './Globalization';
|
|
|
5
5
|
export * from './TMIcons';
|
|
6
6
|
export * from './TMImageLibrary';
|
|
7
7
|
export * from './helpers';
|
|
8
|
+
export * from './dataGridSearchHelper';
|
|
8
9
|
export * from './queryHelper';
|
|
9
10
|
export * from './TMUtils';
|
|
10
11
|
export * from './TMCommandsContextMenu';
|
package/lib/helper/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from './Globalization';
|
|
|
5
5
|
export * from './TMIcons';
|
|
6
6
|
export * from './TMImageLibrary';
|
|
7
7
|
export * from './helpers';
|
|
8
|
+
export * from './dataGridSearchHelper';
|
|
8
9
|
export * from './queryHelper';
|
|
9
10
|
export * from './TMUtils';
|
|
10
11
|
export * from './TMCommandsContextMenu';
|
|
@@ -14,6 +14,8 @@ export declare function addWhereClausesForConnect(qd: QueryDescriptor): void;
|
|
|
14
14
|
export declare function getDefaultOperator(dataDomain: MetadataDataDomains | undefined, dataType: MetadataDataTypes | undefined): QueryOperators.Equal | QueryOperators.Contain | QueryOperators.In;
|
|
15
15
|
export declare const getQD: (tid: number | undefined, easyOr: boolean, newMaxDcmtsToBeReturned: number) => Promise<QueryDescriptor | undefined>;
|
|
16
16
|
export declare const getWorkItemSetIDAsync: (vid: number, did: number) => Promise<string | undefined>;
|
|
17
|
+
/** Id assegnato alla ricerca di sistema con tutti i documenti: non è in cache, va ricostruita a runtime con getSysAllDcmtsSQD */
|
|
18
|
+
export declare const SYS_ALL_DCMTS_SQD_ID = 1;
|
|
17
19
|
export declare const getSysAllDcmtsSQD: (tid: number | undefined, easyOr: boolean) => Promise<SavedQueryDescriptor>;
|
|
18
20
|
export declare const searchResultToMetadataValues: (tid: number | undefined, dtd: DataTableDescriptor | undefined, rows: string[], mids: number[], metadata: MetadataDescriptor[], layoutMode: LayoutModes, isReadOnlyOrigin?: boolean) => MetadataValueDescriptorEx[];
|
|
19
21
|
export declare const handleArchiveVisibility: (md: MetadataDescriptor) => boolean;
|
|
@@ -251,9 +251,11 @@ export const getWorkItemSetIDAsync = async (vid, did) => {
|
|
|
251
251
|
let result = await SDK_Globals.tmSession?.NewSearchEngine().SearchByIDAsync(qd);
|
|
252
252
|
return result?.dtdResult?.rows?.[0]?.[0];
|
|
253
253
|
};
|
|
254
|
+
/** Id assegnato alla ricerca di sistema con tutti i documenti: non è in cache, va ricostruita a runtime con getSysAllDcmtsSQD */
|
|
255
|
+
export const SYS_ALL_DCMTS_SQD_ID = 1;
|
|
254
256
|
export const getSysAllDcmtsSQD = async (tid, easyOr) => {
|
|
255
257
|
let sqd = new SavedQueryDescriptor();
|
|
256
|
-
sqd.id =
|
|
258
|
+
sqd.id = SYS_ALL_DCMTS_SQD_ID;
|
|
257
259
|
sqd.masterTID = tid;
|
|
258
260
|
sqd.isEasyWhere = 1;
|
|
259
261
|
sqd.name = SDKUI_Localizator.AllDcmts;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DataColumnDescriptor, DataColumnTypes, MetadataDescriptor, MetadataFormats } from '@topconsultnpm/sdk-ts';
|
|
2
|
+
/**
|
|
3
|
+
* Funzioni condivise dalle due sorgenti di TMDistinctValues (valori distinti e ricerca rapida):
|
|
4
|
+
* stanno fuori dagli hook perché non dipendono da alcuno stato.
|
|
5
|
+
*/
|
|
6
|
+
export declare const withRowIndex: <T>(rows: Array<T>) => T[];
|
|
7
|
+
export declare const toGridDataType: (dataType: DataColumnTypes | undefined) => "string" | "number" | "datetime" | "boolean";
|
|
8
|
+
export declare const getMetadataName: (columnMd: MetadataDescriptor | undefined) => string | undefined;
|
|
9
|
+
export declare const getDateDisplayFormat: (format: MetadataFormats | undefined, formatCulture: string | undefined | null) => {
|
|
10
|
+
formatter: (value: string | number | Date) => string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Risolve il MID della colonna di un risultato di ricerca: la proprietà estesa è la fonte principale,
|
|
14
|
+
* in mancanza resta l'allineamento posizionale tra selectMIDs e colonne del risultato.
|
|
15
|
+
*/
|
|
16
|
+
export declare const getColumnMid: (column: DataColumnDescriptor | undefined, selectMIDs: number[] | undefined, columnIndex: number) => number;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { DataColumnTypes, SDK_Globals } from '@topconsultnpm/sdk-ts';
|
|
2
|
+
import { formatDateTimeByMetadataFormat } from '../helper';
|
|
3
|
+
/**
|
|
4
|
+
* Funzioni condivise dalle due sorgenti di TMDistinctValues (valori distinti e ricerca rapida):
|
|
5
|
+
* stanno fuori dagli hook perché non dipendono da alcuno stato.
|
|
6
|
+
*/
|
|
7
|
+
// rowIndex è la chiave delle griglie di TMDistinctValues: va riallineato all'ordine finale delle righe
|
|
8
|
+
export const withRowIndex = (rows) => {
|
|
9
|
+
rows.forEach((row, index) => { row.rowIndex = index; });
|
|
10
|
+
return rows;
|
|
11
|
+
};
|
|
12
|
+
export const toGridDataType = (dataType) => {
|
|
13
|
+
switch (dataType) {
|
|
14
|
+
case DataColumnTypes.DateTime: return 'datetime';
|
|
15
|
+
case DataColumnTypes.Bool: return 'boolean';
|
|
16
|
+
case DataColumnTypes.Number: return 'number';
|
|
17
|
+
default: return 'string';
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
// Nome del metadato con cui viene intestata la colonna, nella lingua scelta dall'utente
|
|
21
|
+
export const getMetadataName = (columnMd) => (SDK_Globals.useLocalizedName ? columnMd?.nameLoc : columnMd?.name) ?? columnMd?.name ?? columnMd?.nameLoc ?? undefined;
|
|
22
|
+
// Le date vanno mostrate con il formato definito sul metadato, come nel risultato di ricerca
|
|
23
|
+
export const getDateDisplayFormat = (format, formatCulture) => ({
|
|
24
|
+
// La griglia passa al formatter un oggetto Date già istanziato, ma il valore può arrivare anche come stringa
|
|
25
|
+
formatter: (value) => formatDateTimeByMetadataFormat(value instanceof Date ? value : new Date(value), format, formatCulture)
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* Risolve il MID della colonna di un risultato di ricerca: la proprietà estesa è la fonte principale,
|
|
29
|
+
* in mancanza resta l'allineamento posizionale tra selectMIDs e colonne del risultato.
|
|
30
|
+
*/
|
|
31
|
+
export const getColumnMid = (column, selectMIDs, columnIndex) => Number(column?.extendedProperties?.['MID'] ?? 0) || (selectMIDs?.[columnIndex] ?? 0);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { CaseFlowInstanceDescriptor, CaseFlowWorkItem } from '@topconsultnpm/sdk-ts';
|
|
2
|
+
/**
|
|
3
|
+
* Attività (workitem) delle PRATICHE assegnate all'utente, con il documento su
|
|
4
|
+
* cui lavorano già risolto.
|
|
5
|
+
*
|
|
6
|
+
* Gemello di `useWorkflowApprove` per il modulo CaseFlow: i dati stanno in una
|
|
7
|
+
* cache di modulo e le istanze del hook si sincronizzano con un evento, così il
|
|
8
|
+
* form del documento — da qualunque punto venga aperto — sa che su quel TID/DID
|
|
9
|
+
* c'è una firma da fare o un'approvazione da dare, senza che il chiamante debba
|
|
10
|
+
* passargli nulla.
|
|
11
|
+
*/
|
|
12
|
+
/** Workitem di pratica già risolto sul documento cui si riferisce. */
|
|
13
|
+
export interface CaseFlowDcmtWorkItem {
|
|
14
|
+
caseflow: CaseFlowInstanceDescriptor;
|
|
15
|
+
workItem: CaseFlowWorkItem;
|
|
16
|
+
tid: number;
|
|
17
|
+
did: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Ricarica i workitem di pratica dell'utente. Con `force` ignora la finestra
|
|
21
|
+
* anti-raffica (da usare dopo un'operazione che li ha modificati).
|
|
22
|
+
*/
|
|
23
|
+
export declare const refreshCaseFlowApproveData: (force?: boolean) => Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Workitem di pratica pendenti su quel documento (lettura sincrona dalla cache).
|
|
26
|
+
*
|
|
27
|
+
* TID/DID vanno NORMALIZZATI: pur essendo tipati `number`, arrivano come stringhe
|
|
28
|
+
* quando il documento è aperto da una griglia (righe di datagrid) — per lo stesso
|
|
29
|
+
* motivo il resto della libreria fa `Number(TID)`/`Number(DID)` in ogni confronto.
|
|
30
|
+
* Senza normalizzazione il confronto stretto falliva, e l'attività risultava
|
|
31
|
+
* assente aprendo il documento dalla ricerca mentre compariva dal widget "Per te".
|
|
32
|
+
*/
|
|
33
|
+
export declare const getCaseFlowWorkItemsByDcmt: (tid?: number | string, did?: number | string) => CaseFlowDcmtWorkItem[];
|
|
34
|
+
/** Svuota la cache (logout / cambio archivio). */
|
|
35
|
+
export declare const clearCaseFlowApproveData: () => void;
|
|
36
|
+
/** Completa il workitem di pratica e ricarica la cache. */
|
|
37
|
+
export declare const completeCaseFlowWorkItem: (item: CaseFlowDcmtWorkItem, comment?: string) => Promise<void>;
|
|
38
|
+
/** Rifiuta il workitem di pratica (motivo obbligatorio) e ricarica la cache. */
|
|
39
|
+
export declare const rejectCaseFlowWorkItem: (item: CaseFlowDcmtWorkItem, reason: string) => Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Completa l'attività di FIRMA di una pratica sul documento indicato, se esiste.
|
|
42
|
+
* La chiama il viewer di firma quando la firma è riuscita: è il gemello di quanto
|
|
43
|
+
* già avviene per i workitem del workflow legacy.
|
|
44
|
+
* @returns true se un'attività è stata completata.
|
|
45
|
+
*/
|
|
46
|
+
export declare const completeCaseFlowSignatureForDcmt: (tid: number | string, did: number | string, comment?: string) => Promise<boolean>;
|
|
47
|
+
/**
|
|
48
|
+
* Attività di pratica sul documento indicato. Senza sessione o senza attività
|
|
49
|
+
* l'elenco è vuoto e nulla cambia nella UI.
|
|
50
|
+
*/
|
|
51
|
+
export declare const useCaseFlowApprove: (tid?: number | string, did?: number | string) => {
|
|
52
|
+
caseFlowWorkItems: CaseFlowDcmtWorkItem[];
|
|
53
|
+
refreshCaseFlowApprove: (force?: boolean) => Promise<void>;
|
|
54
|
+
completeCaseFlowWorkItem: (item: CaseFlowDcmtWorkItem, comment?: string) => Promise<void>;
|
|
55
|
+
rejectCaseFlowWorkItem: (item: CaseFlowDcmtWorkItem, reason: string) => Promise<void>;
|
|
56
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { SDK_Globals } from '@topconsultnpm/sdk-ts';
|
|
3
|
+
import { CaseFlowService } from '../services/caseflow/CaseFlowService';
|
|
4
|
+
import { getWorkItemTargetDoc, isMoreInfoWorkItem, isSignatureWorkItem } from '../services/caseflow/caseFlowWorkItemUtils';
|
|
5
|
+
const CASEFLOW_APPROVE_CHANGED_EVENT = 'onCaseFlowApproveChange';
|
|
6
|
+
let cache = [];
|
|
7
|
+
let inFlight;
|
|
8
|
+
let lastLoadedAt = 0;
|
|
9
|
+
/**
|
|
10
|
+
* Finestra minima fra due ricariche: il form del documento chiede un refresh a
|
|
11
|
+
* ogni apertura e la lista è una scansione delle istanze, non una query puntuale.
|
|
12
|
+
*/
|
|
13
|
+
const MIN_RELOAD_INTERVAL_MS = 15000;
|
|
14
|
+
const notifyChanged = () => {
|
|
15
|
+
if (typeof window === 'undefined')
|
|
16
|
+
return;
|
|
17
|
+
window.dispatchEvent(new CustomEvent(CASEFLOW_APPROVE_CHANGED_EVENT));
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Ricarica la cache: i workitem pendenti dell'utente, risolti sul documento su
|
|
21
|
+
* cui lavorano. Le richieste di informazioni sono escluse (si rispondono nella
|
|
22
|
+
* pratica, non sul documento) come i workitem senza documento.
|
|
23
|
+
*/
|
|
24
|
+
const reload = async () => {
|
|
25
|
+
const userId = SDK_Globals.tmSession?.SessionDescr?.userID;
|
|
26
|
+
if (userId == null) {
|
|
27
|
+
cache = [];
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const groups = await CaseFlowService.getMyPendingWorkItems(userId);
|
|
31
|
+
const resolved = [];
|
|
32
|
+
for (const { caseflow, workItems } of groups) {
|
|
33
|
+
// Le richieste di informazioni si rispondono nella pratica, non sul documento.
|
|
34
|
+
const relevant = workItems.filter(wi => !isMoreInfoWorkItem(wi));
|
|
35
|
+
if (relevant.length === 0)
|
|
36
|
+
continue;
|
|
37
|
+
// Il TID dell'azione è autorato sul TEMPLATE e non materializzato
|
|
38
|
+
// sull'istanza: senza template risolto il documento non è calcolabile.
|
|
39
|
+
if (caseflow.cftid != null) {
|
|
40
|
+
await CaseFlowService.getTemplate(caseflow.cftid);
|
|
41
|
+
}
|
|
42
|
+
// I DOCUMENTI AGGANCIATI non arrivano dalla RetrieveAll (che porta solo i
|
|
43
|
+
// dati delle card): serve la Retrieve completa, altrimenti `dcmts` è vuoto
|
|
44
|
+
// e nessun workitem risulterebbe associato a un documento.
|
|
45
|
+
let instance = caseflow;
|
|
46
|
+
if ((instance.dcmts?.length ?? 0) === 0 && instance.id != null) {
|
|
47
|
+
instance = (await CaseFlowService.getCaseflow(instance.id, instance.cftid)) ?? instance;
|
|
48
|
+
}
|
|
49
|
+
for (const wi of relevant) {
|
|
50
|
+
const target = getWorkItemTargetDoc(instance, wi);
|
|
51
|
+
if (!target)
|
|
52
|
+
continue;
|
|
53
|
+
resolved.push({ caseflow: instance, workItem: wi, tid: target.tid, did: target.did });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
cache = resolved;
|
|
57
|
+
lastLoadedAt = Date.now();
|
|
58
|
+
// Diagnostica del bring-up: se il Toppy non compare, qui si vede a che punto
|
|
59
|
+
// la catena si interrompe (nessun workitem / nessun documento risolto).
|
|
60
|
+
// Rimuovibile una volta stabilizzato il flusso.
|
|
61
|
+
console.debug('[CaseFlow] attività su documenti:', {
|
|
62
|
+
istanzeConPendenti: groups.length,
|
|
63
|
+
workItemPendenti: groups.reduce((n, g) => n + g.workItems.length, 0),
|
|
64
|
+
risolteSuDocumento: resolved.length,
|
|
65
|
+
documenti: resolved.map(r => `${r.tid}/${r.did}`),
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Ricarica i workitem di pratica dell'utente. Con `force` ignora la finestra
|
|
70
|
+
* anti-raffica (da usare dopo un'operazione che li ha modificati).
|
|
71
|
+
*/
|
|
72
|
+
export const refreshCaseFlowApproveData = async (force = false) => {
|
|
73
|
+
if (inFlight)
|
|
74
|
+
return inFlight;
|
|
75
|
+
if (!force && lastLoadedAt > 0 && Date.now() - lastLoadedAt < MIN_RELOAD_INTERVAL_MS)
|
|
76
|
+
return;
|
|
77
|
+
inFlight = reload()
|
|
78
|
+
.catch(error => { console.error('Errore nel caricare le attività di pratica sui documenti', error); })
|
|
79
|
+
.finally(() => { inFlight = undefined; notifyChanged(); });
|
|
80
|
+
return inFlight;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Workitem di pratica pendenti su quel documento (lettura sincrona dalla cache).
|
|
84
|
+
*
|
|
85
|
+
* TID/DID vanno NORMALIZZATI: pur essendo tipati `number`, arrivano come stringhe
|
|
86
|
+
* quando il documento è aperto da una griglia (righe di datagrid) — per lo stesso
|
|
87
|
+
* motivo il resto della libreria fa `Number(TID)`/`Number(DID)` in ogni confronto.
|
|
88
|
+
* Senza normalizzazione il confronto stretto falliva, e l'attività risultava
|
|
89
|
+
* assente aprendo il documento dalla ricerca mentre compariva dal widget "Per te".
|
|
90
|
+
*/
|
|
91
|
+
export const getCaseFlowWorkItemsByDcmt = (tid, did) => {
|
|
92
|
+
const t = Number(tid);
|
|
93
|
+
const d = Number(did);
|
|
94
|
+
if (!Number.isFinite(t) || !Number.isFinite(d))
|
|
95
|
+
return [];
|
|
96
|
+
return cache.filter(r => Number(r.tid) === t && Number(r.did) === d);
|
|
97
|
+
};
|
|
98
|
+
/** Svuota la cache (logout / cambio archivio). */
|
|
99
|
+
export const clearCaseFlowApproveData = () => {
|
|
100
|
+
cache = [];
|
|
101
|
+
lastLoadedAt = 0;
|
|
102
|
+
notifyChanged();
|
|
103
|
+
};
|
|
104
|
+
/** Completa il workitem di pratica e ricarica la cache. */
|
|
105
|
+
export const completeCaseFlowWorkItem = async (item, comment) => {
|
|
106
|
+
if (item.caseflow.id == null || item.workItem.id == null)
|
|
107
|
+
return;
|
|
108
|
+
await CaseFlowService.completeWorkItem(item.caseflow.id, item.workItem.id, comment?.trim() || undefined);
|
|
109
|
+
await refreshCaseFlowApproveData(true);
|
|
110
|
+
};
|
|
111
|
+
/** Rifiuta il workitem di pratica (motivo obbligatorio) e ricarica la cache. */
|
|
112
|
+
export const rejectCaseFlowWorkItem = async (item, reason) => {
|
|
113
|
+
if (item.caseflow.id == null || item.workItem.id == null)
|
|
114
|
+
return;
|
|
115
|
+
await CaseFlowService.rejectWorkItem(item.caseflow.id, item.workItem.id, reason);
|
|
116
|
+
await refreshCaseFlowApproveData(true);
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Completa l'attività di FIRMA di una pratica sul documento indicato, se esiste.
|
|
120
|
+
* La chiama il viewer di firma quando la firma è riuscita: è il gemello di quanto
|
|
121
|
+
* già avviene per i workitem del workflow legacy.
|
|
122
|
+
* @returns true se un'attività è stata completata.
|
|
123
|
+
*/
|
|
124
|
+
export const completeCaseFlowSignatureForDcmt = async (tid, did, comment) => {
|
|
125
|
+
const target = getCaseFlowWorkItemsByDcmt(tid, did).find(r => isSignatureWorkItem(r.workItem));
|
|
126
|
+
if (!target)
|
|
127
|
+
return false;
|
|
128
|
+
await completeCaseFlowWorkItem(target, comment);
|
|
129
|
+
return true;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Attività di pratica sul documento indicato. Senza sessione o senza attività
|
|
133
|
+
* l'elenco è vuoto e nulla cambia nella UI.
|
|
134
|
+
*/
|
|
135
|
+
export const useCaseFlowApprove = (tid, did) => {
|
|
136
|
+
const readItems = useCallback(() => getCaseFlowWorkItemsByDcmt(tid, did), [tid, did]);
|
|
137
|
+
const [caseFlowWorkItems, setCaseFlowWorkItems] = useState(readItems);
|
|
138
|
+
useEffect(() => { setCaseFlowWorkItems(readItems()); }, [readItems]);
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
const handleChange = () => setCaseFlowWorkItems(readItems());
|
|
141
|
+
window.addEventListener(CASEFLOW_APPROVE_CHANGED_EVENT, handleChange);
|
|
142
|
+
return () => window.removeEventListener(CASEFLOW_APPROVE_CHANGED_EVENT, handleChange);
|
|
143
|
+
}, [readItems]);
|
|
144
|
+
// All'apertura di un documento la cache può essere vecchia (attività assegnate
|
|
145
|
+
// dopo l'ultimo caricamento) o non ancora popolata.
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
if (tid == null || did == null)
|
|
148
|
+
return;
|
|
149
|
+
void refreshCaseFlowApproveData();
|
|
150
|
+
}, [tid, did]);
|
|
151
|
+
return {
|
|
152
|
+
caseFlowWorkItems,
|
|
153
|
+
refreshCaseFlowApprove: refreshCaseFlowApproveData,
|
|
154
|
+
completeCaseFlowWorkItem,
|
|
155
|
+
rejectCaseFlowWorkItem,
|
|
156
|
+
};
|
|
157
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { MetadataDescriptor } from '@topconsultnpm/sdk-ts';
|
|
2
|
+
import { IColumnProps } from 'devextreme-react/data-grid';
|
|
3
|
+
export declare const needsDisplayValue: (columnMd: MetadataDescriptor | undefined) => boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Resa dei valori nelle griglie di TMDistinctValues: al posto della chiave archiviata mostra la descrizione
|
|
6
|
+
* presa dalle cache di liste dati e utenti, tenendole allineate alle colonne effettivamente visualizzate.
|
|
7
|
+
*
|
|
8
|
+
* Vale per entrambe le sorgenti del pannello (valori distinti e ricerca rapida, che può essere su un altro
|
|
9
|
+
* tipo documento): le chiavi delle due sorgenti vengono accumulate e ricaricate sempre insieme, altrimenti
|
|
10
|
+
* un caricamento farebbe perdere le descrizioni dell'altra sorgente.
|
|
11
|
+
*/
|
|
12
|
+
export declare const useTMDistinctValuesMetadataDisplay: () => {
|
|
13
|
+
loadDisplayCachesAsync: (columnsMd: Array<MetadataDescriptor | undefined>, rows: string[][] | undefined) => Promise<void>;
|
|
14
|
+
getMetadataDisplayValue: (columnMd: MetadataDescriptor | undefined, value: any) => any;
|
|
15
|
+
displayValueColumnProps: (columnMd: MetadataDescriptor | undefined, dataField: string) => Partial<IColumnProps>;
|
|
16
|
+
};
|
|
17
|
+
/** Tipo di ritorno dell'hook: le sorgenti di TMDistinctValues lo ricevono come dipendenza */
|
|
18
|
+
export type TMDistinctValuesMetadataDisplay = ReturnType<typeof useTMDistinctValuesMetadataDisplay>;
|