@topconsultnpm/sdkui-react 6.19.0-dev1.5 → 6.19.0-dev1.50
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/Styled.d.ts +1 -0
- package/lib/components/base/Styled.js +40 -0
- package/lib/components/base/TMFileManagerDataGridView.js +4 -1
- package/lib/components/base/TMTreeView.js +3 -2
- package/lib/components/editors/TMHtmlEditor.d.ts +5 -0
- package/lib/components/editors/TMHtmlEditor.js +72 -12
- package/lib/components/editors/TMMetadataValues.js +90 -40
- package/lib/components/features/archive/TMArchive.d.ts +2 -0
- package/lib/components/features/archive/TMArchive.js +56 -25
- package/lib/components/features/blog/TMBlogCommentForm.js +57 -41
- package/lib/components/features/documents/TMDcmtForm.d.ts +10 -3
- package/lib/components/features/documents/TMDcmtForm.js +134 -36
- package/lib/components/features/documents/TMDragDropOverlay.js +2 -1
- package/lib/components/features/documents/TMMasterDetailDcmts.js +1 -1
- package/lib/components/features/documents/TMRelationViewer.d.ts +53 -3
- package/lib/components/features/documents/TMRelationViewer.js +232 -85
- package/lib/components/features/search/TMSearch.d.ts +3 -1
- package/lib/components/features/search/TMSearch.js +13 -4
- package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -1
- package/lib/components/features/search/TMSearchQueryPanel.js +36 -7
- package/lib/components/features/search/TMSearchResult.d.ts +3 -1
- package/lib/components/features/search/TMSearchResult.js +102 -328
- package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -2
- package/lib/components/features/search/TMSearchResultsMenuItems.js +32 -15
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +3 -1
- package/lib/components/features/workflow/TMWorkflowPopup.js +17 -4
- package/lib/components/forms/TMChooserForm.d.ts +1 -1
- package/lib/components/forms/TMChooserForm.js +2 -2
- package/lib/components/grids/TMBlogsUtils.d.ts +1 -0
- package/lib/components/grids/TMBlogsUtils.js +40 -4
- package/lib/components/index.d.ts +3 -0
- package/lib/components/index.js +3 -0
- package/lib/components/viewers/TMTidViewer.js +29 -4
- package/lib/css/tm-sdkui.css +1 -1
- package/lib/helper/SDKUI_Globals.d.ts +2 -1
- package/lib/helper/SDKUI_Globals.js +1 -0
- package/lib/helper/SDKUI_Localizator.d.ts +4 -0
- package/lib/helper/SDKUI_Localizator.js +46 -0
- package/lib/helper/TMIcons.d.ts +2 -0
- package/lib/helper/TMIcons.js +6 -0
- package/lib/helper/TMToppyMessage.d.ts +7 -0
- package/lib/helper/TMToppyMessage.js +42 -0
- package/lib/helper/TMUtils.d.ts +7 -0
- package/lib/helper/TMUtils.js +16 -0
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/hooks/useRelatedDocuments.d.ts +72 -0
- package/lib/hooks/useRelatedDocuments.js +655 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/ts/types.d.ts +14 -0
- package/lib/ts/types.js +15 -0
- package/lib/utils/theme.d.ts +1 -0
- package/lib/utils/theme.js +1 -0
- package/package.json +2 -2
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import TMDcmtPreview from './TMDcmtPreview';
|
|
4
|
-
import { AccessLevels, ArchiveConstraints, ArchiveEngineByID, DcmtTypeListCacheService, LayoutModes, MetadataDataTypes, ResultTypes, SDK_Globals, SDK_Localizator, SystemMIDsAsNumber, SystemTIDs, Task_States, TemplateTIDs, UpdateEngineByID, ValidationItem, WorkflowCacheService, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
|
|
4
|
+
import { AccessLevels, ArchiveConstraints, ArchiveEngineByID, DcmtTypeListCacheService, LayoutCacheService, LayoutModes, MetadataDataTypes, ObjectClasses, ResultTypes, SDK_Globals, SDK_Localizator, SystemMIDsAsNumber, SystemTIDs, Task_States, TemplateTIDs, TID_DID, UpdateEngineByID, ValidationItem, WorkflowCacheService, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
|
|
5
5
|
import { ContextMenu } from 'devextreme-react';
|
|
6
6
|
import { WorkFlowApproveRejectPopUp, WorkFlowMoreInfoPopUp, WorkFlowOperationButtons, WorkFlowReAssignPopUp } from '../workflow/TMWorkflowPopup';
|
|
7
7
|
import { DownloadTypes, FormModes } from '../../../ts';
|
|
8
8
|
import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
|
|
9
9
|
import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
|
|
10
10
|
import { getWorkItemSetIDAsync, handleArchiveVisibility, searchResultToMetadataValues } from '../../../helper/queryHelper';
|
|
11
|
-
import { genUniqueId, IconShow, SDKUI_Localizator, updateMruTids, IconBoard, IconDcmtTypeSys, IconDetailDcmts, svgToString, IconDownload, calcIsModified, IconMenuVertical, Globalization, getListMaxItems, getSystemMetadata, IconBoxArchiveIn, IconClear, IconUndo, SDKUI_Globals, IconPreview, isTaskMoreInfo, IconWorkflow, IconSearch, deepCompare } from '../../../helper';
|
|
11
|
+
import { genUniqueId, IconShow, SDKUI_Localizator, updateMruTids, IconBoard, IconDcmtTypeSys, IconDetailDcmts, svgToString, IconDownload, calcIsModified, IconMenuVertical, Globalization, getListMaxItems, getSystemMetadata, IconBoxArchiveIn, IconClear, IconUndo, SDKUI_Globals, IconPreview, isTaskMoreInfo, IconWorkflow, IconSearch, deepCompare, IconCheck } from '../../../helper';
|
|
12
12
|
import { hasDetailRelations, hasMasterRelations, isXMLFileExt } from '../../../helper/dcmtsHelper';
|
|
13
13
|
import { Gutters, TMColors } from '../../../utils/theme';
|
|
14
|
-
import { StyledFormButtonsContainer, StyledLoadingContainer, StyledModalContainer, StyledSpinner, StyledToolbarCardContainer } from '../../base/Styled';
|
|
14
|
+
import { StyledFormButtonsContainer, StyledLoadingContainer, StyledModalContainer, StyledReferenceButton, StyledSpinner, StyledToolbarCardContainer } from '../../base/Styled';
|
|
15
15
|
import ShowAlert from '../../base/TMAlert';
|
|
16
16
|
import TMButton from '../../base/TMButton';
|
|
17
17
|
import { TMExceptionBoxManager, TMMessageBoxManager, ButtonNames } from '../../base/TMPopUp';
|
|
@@ -37,7 +37,7 @@ import WFDiagram from '../workflow/diagram/WFDiagram';
|
|
|
37
37
|
import TMTooltip from '../../base/TMTooltip';
|
|
38
38
|
let abortControllerLocal = new AbortController();
|
|
39
39
|
//#endregion
|
|
40
|
-
const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes.Update, onClose, onSavedAsyncCallback, TID, DID, formMode = FormModes.Update, canNext, canPrev, count, itemIndex, onNext, onPrev, allowNavigation = true, allowRelations = true, isClosable = false, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, showDcmtFormSidebar = true, invokedByTodo = false, titleModal, isModal = false, widthModal = "100%", heightModal = "100%", groupId, onWFOperationCompleted, onTaskCompleted, inputFile = null, taskFormDialogComponent, taskMoreInfo, connectorFileSave = undefined, inputMids = [], onOpenS4TViewerRequest, s4TViewerDialogComponent, enableDragDropOverlay = false, passToSearch }) => {
|
|
40
|
+
const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes.Update, showBackButton = true, onClose, onSavedAsyncCallback, TID, DID, formMode = FormModes.Update, canNext, canPrev, count, itemIndex, onNext, onPrev, allowNavigation = true, allowRelations = true, isClosable = false, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, showDcmtFormSidebar = true, invokedByTodo = false, titleModal, isModal = false, widthModal = "100%", heightModal = "100%", groupId, onWFOperationCompleted, onTaskCompleted, inputFile = null, taskFormDialogComponent, taskMoreInfo, connectorFileSave = undefined, inputMids = [], onOpenS4TViewerRequest, s4TViewerDialogComponent, enableDragDropOverlay = false, passToSearch, isSharedDcmt = false, sharedSourceTID, sharedSourceDID, allowButtonsRefs = false, onReferenceClick, }) => {
|
|
41
41
|
const [id, setID] = useState('');
|
|
42
42
|
const [showWaitPanelLocal, setShowWaitPanelLocal] = useState(false);
|
|
43
43
|
const [waitPanelTitleLocal, setWaitPanelTitleLocal] = useState('');
|
|
@@ -59,6 +59,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
59
59
|
const [showReAssignPopup, setShowReAssignPopup] = useState(false);
|
|
60
60
|
const [showMoreInfoPopup, setShowMoreInfoPopup] = useState(false);
|
|
61
61
|
const [layout, setLayout] = useState();
|
|
62
|
+
const [customButtonsLayout, setCustomButtonsLayout] = useState();
|
|
62
63
|
const appliedInputMidsRef = useRef(null);
|
|
63
64
|
// Refs per evitare stale closure nei callback
|
|
64
65
|
// I useCallback catturano i valori delle dipendenze al momento della creazione.
|
|
@@ -67,6 +68,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
67
68
|
const formDataOrigRef = useRef([]);
|
|
68
69
|
const formDataRef = useRef([]);
|
|
69
70
|
const fromDTDRef = useRef();
|
|
71
|
+
const dcmtFileRef = useRef(null);
|
|
70
72
|
const [isOpenDetails, setIsOpenDetails] = useState(false);
|
|
71
73
|
const [isOpenMaster, setIsOpenMaster] = useState(false);
|
|
72
74
|
const [secondaryMasterDcmts, setSecondaryMasterDcmts] = useState([]);
|
|
@@ -85,6 +87,11 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
85
87
|
const [showCommentForm, setShowCommentForm] = useState(false);
|
|
86
88
|
const [isInitialLoading, setIsInitialLoading] = useState(true);
|
|
87
89
|
const [isNavigating, setIsNavigating] = useState(false);
|
|
90
|
+
const [dcmtReferences, setDcmtReferences] = useState(undefined);
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (!allowButtonsRefs)
|
|
93
|
+
setDcmtReferences(undefined);
|
|
94
|
+
}, [allowButtonsRefs]);
|
|
88
95
|
const { openConfirmAttachmentsDialog, ConfirmAttachmentsDialog } = useInputAttachmentsDialog();
|
|
89
96
|
const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
|
|
90
97
|
// Custom hook to manage workflow approval data
|
|
@@ -152,9 +159,37 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
152
159
|
return;
|
|
153
160
|
if (!DID && layoutMode === LayoutModes.Update)
|
|
154
161
|
return;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
162
|
+
// Esegui chiamate in parallelo per ottimizzare le performance
|
|
163
|
+
const parallelCalls = [
|
|
164
|
+
// 1. GetMetadataAsync - solo se layoutMode === Update
|
|
165
|
+
layoutMode === LayoutModes.Update
|
|
166
|
+
? SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(TID, DID, true) ?? Promise.resolve(undefined)
|
|
167
|
+
: Promise.resolve(undefined),
|
|
168
|
+
// 2. Layout per il layoutMode corrente
|
|
169
|
+
LayoutCacheService.GetAsync(TID, layoutMode),
|
|
170
|
+
// 3. CustomButtonsLayout - solo se layoutMode === Update
|
|
171
|
+
layoutMode === LayoutModes.Update
|
|
172
|
+
? LayoutCacheService.GetAsync(TID, LayoutModes.None)
|
|
173
|
+
: Promise.resolve(undefined),
|
|
174
|
+
// 4. Opcionalmente FindAllReferencesAsync se abilitato nelle impostazioni e se i bottoni sono richiesti
|
|
175
|
+
(allowButtonsRefs && SDKUI_Globals.userSettings.searchSettings.autoFindReferences.length > 0)
|
|
176
|
+
? SDK_Globals.tmSession?.NewSearchEngine().FindAllReferencesAsync(TID, DID, SDKUI_Globals.userSettings.searchSettings.autoFindReferences) ?? Promise.resolve(undefined)
|
|
177
|
+
: Promise.resolve(undefined)
|
|
178
|
+
];
|
|
179
|
+
const results = await Promise.all(parallelCalls);
|
|
180
|
+
// Destructuring: first three are always the original ones, fourth is references (or undefined)
|
|
181
|
+
const getMetadataResult = results[0];
|
|
182
|
+
const resLayout = results[1];
|
|
183
|
+
const customButtonsLayoutResult = results[2];
|
|
184
|
+
const findRefsResult = results[3];
|
|
185
|
+
// Save references result into state (may be undefined)
|
|
186
|
+
setDcmtReferences(findRefsResult);
|
|
187
|
+
// Imposta il layout e customButtonsLayout immediatamente
|
|
188
|
+
setLayout(resLayout);
|
|
189
|
+
if (layoutMode === LayoutModes.Update && customButtonsLayoutResult) {
|
|
190
|
+
setCustomButtonsLayout(customButtonsLayoutResult);
|
|
191
|
+
}
|
|
192
|
+
// Carica DTD e metadata
|
|
158
193
|
let dtd = await DcmtTypeListCacheService.GetWithNotGrantedAsync(TID, DID, getMetadataResult);
|
|
159
194
|
setFromDTD(dtd);
|
|
160
195
|
if (layoutMode === LayoutModes.Update || (layoutMode === LayoutModes.Ark && DID)) {
|
|
@@ -167,8 +202,6 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
167
202
|
setFormData(structuredClone(metadataList));
|
|
168
203
|
formDataOrigRef.current = structuredClone(metadataList);
|
|
169
204
|
}
|
|
170
|
-
let resLayout = await SDK_Globals.tmSession?.NewDcmtTypeEngine().LayoutRetrieveAsync(TID, layoutMode);
|
|
171
|
-
setLayout(resLayout);
|
|
172
205
|
(layoutMode === LayoutModes.Ark && !inputFile) && handleReset();
|
|
173
206
|
}
|
|
174
207
|
catch (e) {
|
|
@@ -179,7 +212,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
179
212
|
setIsInitialLoading(false);
|
|
180
213
|
setIsNavigating(false);
|
|
181
214
|
}
|
|
182
|
-
}, [TID, DID, layoutMode, inputFile, setMetadataList, handleReset]);
|
|
215
|
+
}, [TID, DID, layoutMode, inputFile, setMetadataList, handleReset, allowButtonsRefs]);
|
|
183
216
|
const createChange = useCallback((mid, metadataType, modifiedValue) => {
|
|
184
217
|
return { mid, metadataType, modifiedValue };
|
|
185
218
|
}, []);
|
|
@@ -211,6 +244,9 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
211
244
|
useEffect(() => {
|
|
212
245
|
fromDTDRef.current = fromDTD;
|
|
213
246
|
}, [fromDTD]);
|
|
247
|
+
useEffect(() => {
|
|
248
|
+
dcmtFileRef.current = dcmtFile;
|
|
249
|
+
}, [dcmtFile]);
|
|
214
250
|
useEffect(() => {
|
|
215
251
|
if (!inputFile || inputFile === null)
|
|
216
252
|
return;
|
|
@@ -271,6 +307,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
271
307
|
if (layoutMode !== LayoutModes.Ark)
|
|
272
308
|
return;
|
|
273
309
|
setFocusedMetadataValue(undefined);
|
|
310
|
+
appliedInputMidsRef.current = null;
|
|
274
311
|
}, [fromDTD, layoutMode]);
|
|
275
312
|
useEffect(() => {
|
|
276
313
|
if (!inputMids || inputMids.length === 0)
|
|
@@ -279,9 +316,13 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
279
316
|
return;
|
|
280
317
|
if (!formData || formData.length === 0)
|
|
281
318
|
return;
|
|
319
|
+
if (!formDataOrig || formDataOrig.length === 0)
|
|
320
|
+
return;
|
|
321
|
+
// Check if formData has actual user metadata (mid > 99), not just system metadata
|
|
322
|
+
if (!formData.some(md => md.mid && md.mid > 99))
|
|
323
|
+
return;
|
|
282
324
|
if (appliedInputMidsRef.current && deepCompare(appliedInputMidsRef.current, inputMids))
|
|
283
325
|
return;
|
|
284
|
-
appliedInputMidsRef.current = inputMids;
|
|
285
326
|
let data = structuredClone(formData);
|
|
286
327
|
for (let md of data) {
|
|
287
328
|
if (!md.mid)
|
|
@@ -312,6 +353,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
312
353
|
}
|
|
313
354
|
});
|
|
314
355
|
setFormData(data);
|
|
356
|
+
appliedInputMidsRef.current = inputMids;
|
|
315
357
|
}, [inputMids, layoutMode, formData, formDataOrig]);
|
|
316
358
|
// Memoizza solo il valore WI_SetID per evitare re-render quando altri metadata cambiano
|
|
317
359
|
const workItemSetIDValue = useMemo(() => formData.find(o => o.md?.name === WorkItemMetadataNames.WI_SetID)?.value, [formData]);
|
|
@@ -396,8 +438,8 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
396
438
|
const outputMids = formData
|
|
397
439
|
.filter(md => md.mid && md.mid > 100 && md.value && md.value.length > 0)
|
|
398
440
|
.map(md => ({ mid: md.mid, value: md.value }));
|
|
399
|
-
passToSearch(outputMids);
|
|
400
|
-
}, [passToSearch, formData]);
|
|
441
|
+
passToSearch(outputMids, TID);
|
|
442
|
+
}, [passToSearch, formData, TID]);
|
|
401
443
|
const isPreviewDisabled = useMemo(() => layoutMode === LayoutModes.Ark && fromDTD?.archiveConstraint === ArchiveConstraints.OnlyMetadata, [layoutMode, fromDTD?.archiveConstraint]);
|
|
402
444
|
const isBoardDisabled = useMemo(() => layoutMode !== LayoutModes.Update || fromDTD?.hasBlog !== 1, [layoutMode, fromDTD?.hasBlog]);
|
|
403
445
|
const isSysMetadataDisabled = useMemo(() => layoutMode !== LayoutModes.Update, [layoutMode]);
|
|
@@ -406,18 +448,41 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
406
448
|
const isWFDisabled = useMemo(() => layoutMode !== LayoutModes.Update || fetchError || workItems.length <= 0, [layoutMode, fetchError, workItems.length]);
|
|
407
449
|
const showToppyForApprove = useMemo(() => layoutMode === LayoutModes.Update && !fetchError && workItems.length > 0 && !isOpenDetails && !isOpenMaster, [layoutMode, fetchError, workItems.length, isOpenDetails, isOpenMaster]);
|
|
408
450
|
const showToppyForCompleteMoreInfo = useMemo(() => layoutMode === LayoutModes.Update && isTaskMoreInfo(taskMoreInfo?.name) && taskMoreInfo?.state !== Task_States.Completed, [layoutMode, taskMoreInfo?.name, taskMoreInfo?.state]);
|
|
451
|
+
const showToppyForReferences = useMemo(() => allowButtonsRefs && layoutMode === LayoutModes.Update && dcmtReferences && dcmtReferences.length > 0 && !isOpenDetails && !isOpenMaster, [allowButtonsRefs, layoutMode, dcmtReferences, isOpenDetails, isOpenMaster]);
|
|
409
452
|
const isMobile = useMemo(() => deviceType === DeviceType.MOBILE, [deviceType]);
|
|
410
453
|
const isApprView = useMemo(() => fromDTD?.templateTID === TemplateTIDs.WF_WIApprView, [fromDTD?.templateTID]);
|
|
411
454
|
const workitemSetID = useMemo(() => workItems.find(o => o.did === Number(DID))?.setID || formData.find(o => o.md?.name === WorkItemMetadataNames.WI_SetID)?.value, [workItems, DID, formData]);
|
|
412
455
|
const approvalVID = useMemo(() => workItems.length > 0 ? Number(workItems[0].tid) : -1, [workItems]);
|
|
413
|
-
const commandsMenuItems = useMemo(() =>
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
456
|
+
const commandsMenuItems = useMemo(() => {
|
|
457
|
+
const items = [
|
|
458
|
+
{ icon: svgToString(_jsx(IconDownload, {})), operationType: 'singleRow', disabled: fromDTD?.perm?.canRetrieveFile !== AccessLevels.Yes, text: "Download file", onClick: async () => await downloadDcmtsAsync(getDcmts(), DownloadTypes.Dcmt, "download") },
|
|
459
|
+
{ icon: svgToString(_jsx(IconDownload, {})), operationType: 'singleRow', disabled: !isXMLFileExt(currentDcmt?.fileExt), text: "Download allegati XML", onClick: async () => await downloadDcmtsAsync(getDcmts(), DownloadTypes.Attachment, "download", undefined, openConfirmAttachmentsDialog) },
|
|
460
|
+
...(allowRelations && currentTIDHasMasterRelations ? [{ icon: svgToString(_jsx(IconDetailDcmts, { transform: 'scale(-1, 1)' })), operationType: 'singleRow', disabled: isMasterDisabled, text: SDKUI_Localizator.DcmtsMaster, onClick: () => { if (!isMasterDisabled)
|
|
461
|
+
setIsOpenMaster(!isOpenMaster); } }] : []),
|
|
462
|
+
...(allowRelations && currentTIDHasDetailRelations ? [{ icon: svgToString(_jsx(IconDetailDcmts, {})), operationType: 'singleRow', disabled: isDetailsDisabled, text: SDKUI_Localizator.DcmtsDetail, onClick: () => { if (!isDetailsDisabled)
|
|
463
|
+
setIsOpenDetails(!isOpenDetails); } }] : []),
|
|
464
|
+
];
|
|
465
|
+
// Aggiungi submenu "Bottoni personalizzati" se esistono customButtons
|
|
466
|
+
if (customButtonsLayout?.customButtons && Array.isArray(customButtonsLayout.customButtons) && customButtonsLayout.customButtons.length > 0) {
|
|
467
|
+
const customButtonsItems = customButtonsLayout.customButtons.map((customButton) => ({
|
|
468
|
+
text: customButton.title || 'Bottone personalizzato',
|
|
469
|
+
onClick: () => {
|
|
470
|
+
// Per ora, visualizziamo le proprietà del bottone in console e alert
|
|
471
|
+
console.log('Custom Button Properties:', customButton);
|
|
472
|
+
TMMessageBoxManager.show({
|
|
473
|
+
message: `Custom Button:\n${JSON.stringify(customButton, null, 2)}`,
|
|
474
|
+
buttons: [ButtonNames.OK],
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
}));
|
|
478
|
+
items.push({
|
|
479
|
+
icon: svgToString(_jsx(IconCheck, {})),
|
|
480
|
+
text: 'Bottoni personalizzati',
|
|
481
|
+
items: customButtonsItems
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
return items;
|
|
485
|
+
}, [fromDTD?.perm?.canRetrieveFile, currentDcmt?.fileExt, allowRelations, currentTIDHasMasterRelations, isMasterDisabled, currentTIDHasDetailRelations, isDetailsDisabled, customButtonsLayout, getDcmts, downloadDcmtsAsync, openConfirmAttachmentsDialog]);
|
|
421
486
|
const isModified = useMemo(() => calcIsModified(formData, formDataOrig), [formData, formDataOrig]);
|
|
422
487
|
const formToolbar = useMemo(() => _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [allowNavigation && canPrev != undefined && _jsx("p", { style: { textAlign: 'center', padding: '1px 4px', display: 'flex' }, children: `${itemIndex}/${count}` }), allowNavigation && canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: isModified, formMode: formMode, canPrev: canPrev, onPrev: onPrev }), allowNavigation && canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: isModified, formMode: formMode, canNext: canNext, onNext: onNext }), layoutMode === LayoutModes.Update && _jsx(IconMenuVertical, { id: `commands-detail-${id}`, color: 'white', cursor: 'pointer' }), layoutMode === LayoutModes.Update && _jsx(ContextMenu, { showEvent: 'click', dataSource: commandsMenuItems, target: `#commands-detail-${id}` }), layoutMode === LayoutModes.Ark &&
|
|
423
488
|
_jsx(TMTooltip, { content: SDKUI_Localizator.PassToSearch, position: 'bottom', children: _jsx(IconSearch, { style: { cursor: 'pointer' }, onClick: handlePassToSearch }) })] }), [allowNavigation, canPrev, canNext, itemIndex, count, isModified, formMode, onPrev, onNext, layoutMode, id, commandsMenuItems, handlePassToSearch]);
|
|
@@ -566,7 +631,13 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
566
631
|
ae.ArchivingFile = file;
|
|
567
632
|
}
|
|
568
633
|
else {
|
|
569
|
-
ae.ArchivingFile =
|
|
634
|
+
ae.ArchivingFile = dcmtFileRef.current;
|
|
635
|
+
}
|
|
636
|
+
if (isSharedDcmt && sharedSourceTID && sharedSourceDID) {
|
|
637
|
+
const sharedDcmt = new TID_DID();
|
|
638
|
+
sharedDcmt.tid = sharedSourceTID;
|
|
639
|
+
sharedDcmt.did = sharedSourceDID;
|
|
640
|
+
ae.SharedDcmt = sharedDcmt;
|
|
570
641
|
}
|
|
571
642
|
let newDID = await ae.ArchiveAsync(abortControllerLocal.signal, (pd) => {
|
|
572
643
|
if (firstBlock) {
|
|
@@ -614,7 +685,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
614
685
|
setShowWaitPanelLocal(false);
|
|
615
686
|
setUseWaitPanelLocalState(false);
|
|
616
687
|
}
|
|
617
|
-
}, [TID,
|
|
688
|
+
}, [TID, connectorFileSave, onSavedAsyncCallback, onSaveRecents, onClose, DID, setMetadataList, handleReset, layoutMode, isSharedDcmt]);
|
|
618
689
|
const handleClearForm = useCallback(() => {
|
|
619
690
|
let data = structuredClone(formData);
|
|
620
691
|
if (!data || data.length === 0)
|
|
@@ -756,9 +827,9 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
756
827
|
]);
|
|
757
828
|
const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { tid: TID, did: DID }), [TID, DID]);
|
|
758
829
|
const tmSysMetadata = useMemo(() => _jsx(TMMetadataValues, { layoutMode: layoutMode, openChooserBySingleClick: !isOpenDistinctValues, TID: TID, isReadOnly: true, deviceType: deviceType, metadataValues: formData.filter(o => (o.mid != undefined && o.mid <= 100)), metadataValuesOrig: formData.filter(o => (o.mid != undefined && o.mid <= 100)), validationItems: [], inputMids: inputMids }), [TID, layoutMode, formData, deviceType, inputMids]);
|
|
759
|
-
const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { currentDcmt: currentDcmt, dcmtFile: dcmtFile ?? inputFile, deviceType: deviceType, fromDTD: fromDTD, layoutMode: layoutMode, onFileUpload: (
|
|
760
|
-
setDcmtFile(
|
|
761
|
-
}, enableDragDropOverlay: enableDragDropOverlay }), [currentDcmt, dcmtFile, deviceType, fromDTD, layoutMode, inputFile, enableDragDropOverlay]);
|
|
830
|
+
const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { currentDcmt: currentDcmt, dcmtFile: dcmtFile ?? inputFile, deviceType: deviceType, fromDTD: fromDTD, layoutMode: layoutMode, onFileUpload: (file) => {
|
|
831
|
+
setDcmtFile(file);
|
|
832
|
+
}, enableDragDropOverlay: enableDragDropOverlay }), [currentDcmt, dcmtFile, deviceType, fromDTD, layoutMode, inputFile, enableDragDropOverlay, setDcmtFile]);
|
|
762
833
|
const tmWF = useMemo(() => {
|
|
763
834
|
if (isWFDataLoading) {
|
|
764
835
|
return (_jsx("div", { style: {
|
|
@@ -824,7 +895,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
824
895
|
showHeader: showHeader,
|
|
825
896
|
title: fromDTD?.nameLoc,
|
|
826
897
|
allowMaximize: !isMobile,
|
|
827
|
-
onBack: (isClosable && deviceType !== DeviceType.MOBILE) ? undefined : handleClose,
|
|
898
|
+
onBack: showBackButton ? (isClosable && deviceType !== DeviceType.MOBILE) ? undefined : handleClose : undefined,
|
|
828
899
|
onClose: isClosable ? () => { } : undefined,
|
|
829
900
|
toolbar: allowNavigation ? formToolbar : _jsx(_Fragment, {})
|
|
830
901
|
},
|
|
@@ -877,7 +948,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
877
948
|
isActive: allInitialPanelVisibility['tmWF']
|
|
878
949
|
}
|
|
879
950
|
},
|
|
880
|
-
], [fromDTD, tmDcmtForm, tmBlog, tmSysMetadata, tmDcmtPreview, tmWF, isPreviewDisabled, isSysMetadataDisabled, isBoardDisabled, isWFDisabled, inputFile, isClosable]);
|
|
951
|
+
], [fromDTD, showBackButton, tmDcmtForm, tmBlog, tmSysMetadata, tmDcmtPreview, tmWF, isPreviewDisabled, isSysMetadataDisabled, isBoardDisabled, isWFDisabled, inputFile, isClosable]);
|
|
881
952
|
// Retrieves the current document form setting based on the normalized TID
|
|
882
953
|
const getCurrentDcmtFormSetting = () => {
|
|
883
954
|
const settings = SDKUI_Globals.userSettings.dcmtFormSettings;
|
|
@@ -959,6 +1030,23 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
959
1030
|
title: SDKUI_Localizator.SignatureAndApprove,
|
|
960
1031
|
});
|
|
961
1032
|
}, [onOpenS4TViewerRequest, TID, DID]);
|
|
1033
|
+
const handleNavigateToReference = useCallback((ref) => {
|
|
1034
|
+
if (onReferenceClick) {
|
|
1035
|
+
try {
|
|
1036
|
+
onReferenceClick(ref);
|
|
1037
|
+
}
|
|
1038
|
+
catch (e) {
|
|
1039
|
+
console.error('onReferenceClick handler failed', e);
|
|
1040
|
+
}
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
}, [onReferenceClick]);
|
|
1044
|
+
// Mapping for objClass specific label/action. Easy to extend for future objClass types.
|
|
1045
|
+
const referenceActionMap = useMemo(() => ({
|
|
1046
|
+
[ObjectClasses.Dossier]: { label: 'Vai a pratica' },
|
|
1047
|
+
[ObjectClasses.WorkingGroup]: { label: 'Vai a gruppo di lavoro' },
|
|
1048
|
+
// add other ObjectClasses here as needed
|
|
1049
|
+
}), []);
|
|
962
1050
|
const renderDcmtForm = () => {
|
|
963
1051
|
// Show flat spinner during initial load (before component is mounted)
|
|
964
1052
|
if (isInitialLoading) {
|
|
@@ -989,12 +1077,22 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
989
1077
|
isEditable: true,
|
|
990
1078
|
value: FormulaHelper.addFormulaTag(newFormula.expression)
|
|
991
1079
|
}));
|
|
992
|
-
} }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, isReject: 0, onClose: () => setShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, isReject: 1, onClose: () => setShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, onClose: () => setShowReAssignPopup(false) }), showMoreInfoPopup && _jsx(WorkFlowMoreInfoPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, onClose: () => setShowMoreInfoPopup(false) }), (isModal && onClose) && _jsx("div", { id: "TMDcmtFormShowConfirmForClose-" + id })] }), showToppyForApprove && (_jsx(ToppyHelpCenter, { deviceType: deviceType, usePortal: false, content: workItems.length === 1 ?
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1080
|
+
} }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, isReject: 0, onClose: () => setShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, isReject: 1, onClose: () => setShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, onClose: () => setShowReAssignPopup(false) }), showMoreInfoPopup && _jsx(WorkFlowMoreInfoPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, onClose: () => setShowMoreInfoPopup(false) }), (isModal && onClose) && _jsx("div", { id: "TMDcmtFormShowConfirmForClose-" + id })] }), (showToppyForApprove || showToppyForCompleteMoreInfo || showToppyForReferences) && (_jsx(ToppyHelpCenter, { deviceType: deviceType, usePortal: false, content: _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: [showToppyForApprove && (workItems.length === 1 ?
|
|
1081
|
+
_jsx(WorkFlowOperationButtons, { deviceType: deviceType, onApprove: () => setShowApprovePopup(true), onSignApprove: handleSignApprove, onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), onMoreInfo: () => setShowMoreInfoPopup(true), dtd: fromDTD })
|
|
1082
|
+
:
|
|
1083
|
+
_jsxs("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: [`Devi approvare ${workItems.length} workitem(s) per questo documento.`, `Vai alla sezione di approvazione.`] })), showToppyForCompleteMoreInfo && (_jsxs(_Fragment, { children: [_jsx("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: `${SDKUI_Localizator.MoreInfoCompleteRequestSentBy} ${taskMoreInfo?.fromName}!` }), _jsx(TMButton, { caption: SDKUI_Localizator.CommentAndComplete, color: 'success', showTooltip: false, onClick: () => {
|
|
1084
|
+
setShowCommentForm(true);
|
|
1085
|
+
} })] })), showToppyForReferences && dcmtReferences && dcmtReferences
|
|
1086
|
+
.filter(ref => ref.objClass === ObjectClasses.Dossier || ref.objClass === ObjectClasses.WorkingGroup) // keep only known objClass types
|
|
1087
|
+
.map((ref, index, arr) => {
|
|
1088
|
+
const mapEntry = referenceActionMap[String(ref.objClass)];
|
|
1089
|
+
const label = mapEntry?.label ?? 'Vai a riferimento';
|
|
1090
|
+
return (_jsxs(React.Fragment, { children: [index === 0 && (showToppyForApprove || showToppyForCompleteMoreInfo) && (_jsx("div", { style: {
|
|
1091
|
+
height: 1,
|
|
1092
|
+
backgroundColor: 'rgba(255,255,255,0.2)',
|
|
1093
|
+
margin: '6px 0'
|
|
1094
|
+
} })), _jsxs(StyledReferenceButton, { onClick: () => handleNavigateToReference(ref), children: [_jsx("span", { children: label }), _jsx("span", { children: ref.objName })] }, `ref-${index}-${ref.objID}`)] }, `ref-frag-${index}-${ref.objID}`));
|
|
1095
|
+
})] }) })), (showCommentForm && TID && DID) &&
|
|
998
1096
|
_jsx(TMBlogCommentForm, { context: { engine: 'SearchEngine', object: { tid: TID, did: DID } }, onClose: () => setShowCommentForm(false), refreshCallback: handleCompleteMoreInfo, participants: [], showAttachmentsSection: false, allArchivedDocumentsFileItems: [] }), isOpenDetails &&
|
|
999
1097
|
_jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMMasterDetailDcmts, { deviceType: deviceType, isForMaster: false, inputDcmts: getSelectionDcmtInfo(), allowNavigation: allowNavigation, canNext: canNext, canPrev: canPrev, onNext: onNext, onPrev: onPrev, onBack: () => setIsOpenDetails(false) }) }), isOpenMaster &&
|
|
1000
1098
|
_jsxs(StyledModalContainer, { style: { backgroundColor: 'white' }, children: [_jsx(TMMasterDetailDcmts, { deviceType: deviceType, inputDcmts: getSelectionDcmtInfo(), isForMaster: true, allowNavigation: allowNavigation, canNext: canNext, canPrev: canPrev, onNext: onNext, onPrev: onPrev, onBack: () => setIsOpenMaster(false), appendMasterDcmts: handleAddItem }), secondaryMasterDcmts.length > 0 && secondaryMasterDcmts.map((dcmt, index) => {
|
|
@@ -1034,7 +1132,7 @@ const applyMetadataFilter = (data, showAll, listMaxItems, TID) => {
|
|
|
1034
1132
|
return showAll ? filteredData : filteredData.slice(0, listMaxItems);
|
|
1035
1133
|
};
|
|
1036
1134
|
//#region Validaion
|
|
1037
|
-
const validateMetadataList = (mvdList = []) => {
|
|
1135
|
+
export const validateMetadataList = (mvdList = []) => {
|
|
1038
1136
|
if (!Array.isArray(mvdList)) {
|
|
1039
1137
|
throw new TypeError("metadataList must be an array of ITMMetadataProps.");
|
|
1040
1138
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import Toppy from '../../../assets/Toppy-generico.png';
|
|
4
|
+
import { SDKUI_Localizator } from "../../../helper";
|
|
4
5
|
const TMDragDropOverlay = (props) => {
|
|
5
6
|
const { handleFile, refocusAfterFileInput } = props;
|
|
6
7
|
const [dragOver, setDragOver] = useState(false);
|
|
@@ -91,6 +92,6 @@ const TMDragDropOverlay = (props) => {
|
|
|
91
92
|
alignItems: 'center',
|
|
92
93
|
gap: 20,
|
|
93
94
|
textAlign: 'center',
|
|
94
|
-
}, children: [_jsx("img", { src: Toppy, alt: "Toppy", style: { width: 80, height: 'auto' } }), _jsx("div", { style: { fontSize: '1.6rem' }, children:
|
|
95
|
+
}, children: [_jsx("img", { src: Toppy, alt: "Toppy", style: { width: 80, height: 'auto' } }), _jsx("div", { style: { fontSize: '1.6rem' }, children: SDKUI_Localizator.DropFileHere })] })] }));
|
|
95
96
|
};
|
|
96
97
|
export default TMDragDropOverlay;
|
|
@@ -279,7 +279,7 @@ const TMRelationViewerWrapper = ({ inputDcmts, isForMaster, showCurrentDcmtIndic
|
|
|
279
279
|
const TMFormOrResultWrapper = ({ deviceType, focusedItem, onTaskCreateRequest }) => {
|
|
280
280
|
const { setPanelVisibilityById } = useTMPanelManagerContext();
|
|
281
281
|
return (_jsx(_Fragment, { children: focusedItem?.isDcmt ?
|
|
282
|
-
_jsx(TMDcmtForm, { groupId: 'tmFormOrResult', TID: focusedItem?.tid, DID: focusedItem.did, isClosable: deviceType !== DeviceType.MOBILE, allowNavigation: false, allowRelations: deviceType !== DeviceType.MOBILE, showDcmtFormSidebar: false, onClose: () => {
|
|
282
|
+
_jsx(TMDcmtForm, { groupId: 'tmFormOrResult', TID: focusedItem?.tid, DID: focusedItem.did, allowButtonsRefs: true, isClosable: deviceType !== DeviceType.MOBILE, allowNavigation: false, allowRelations: deviceType !== DeviceType.MOBILE, showDcmtFormSidebar: false, onClose: () => {
|
|
283
283
|
setPanelVisibilityById('tmTreeView', true);
|
|
284
284
|
} }) :
|
|
285
285
|
_jsx(TMSearchResult, { groupId: 'tmFormOrResult', isClosable: deviceType !== DeviceType.MOBILE, context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, onTaskCreateRequest: onTaskCreateRequest, onClose: () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { DcmtTypeDescriptor, SearchResultDescriptor } from "@topconsultnpm/sdk-ts";
|
|
2
|
+
import { DcmtTypeDescriptor, SearchResultDescriptor, DataColumnDescriptor } from "@topconsultnpm/sdk-ts";
|
|
3
3
|
import { DcmtInfo } from '../../../ts';
|
|
4
4
|
import { ITMTreeItem } from '../../base/TMTreeView';
|
|
5
5
|
/**
|
|
@@ -17,6 +17,7 @@ export interface RelationTreeItem extends ITMTreeItem {
|
|
|
17
17
|
isMaster?: boolean;
|
|
18
18
|
isCorrelated?: boolean;
|
|
19
19
|
isLoaded?: boolean;
|
|
20
|
+
isSeparator?: boolean;
|
|
20
21
|
values?: any;
|
|
21
22
|
searchResult?: SearchResultDescriptor[];
|
|
22
23
|
itemsCount?: number;
|
|
@@ -49,8 +50,24 @@ export interface TMRelationViewerProps {
|
|
|
49
50
|
onSelectedItemsChanged?: (items: RelationTreeItem[]) => void;
|
|
50
51
|
/** Callback when a document is double-clicked */
|
|
51
52
|
onDocumentDoubleClick?: (tid: number, did: number, name?: string) => void;
|
|
52
|
-
/** Custom item renderer */
|
|
53
|
-
customItemRender?: (item: RelationTreeItem | null) => JSX.Element;
|
|
53
|
+
/** Custom item renderer (full control). Return undefined to use default renderer. */
|
|
54
|
+
customItemRender?: (item: RelationTreeItem | null) => JSX.Element | undefined;
|
|
55
|
+
/** Custom document style function */
|
|
56
|
+
customDocumentStyle?: (item: RelationTreeItem) => React.CSSProperties;
|
|
57
|
+
/**
|
|
58
|
+
* Custom content renderer for the main container (when showMainDocument is false).
|
|
59
|
+
* Allows full control over the main container rendering including style and content.
|
|
60
|
+
* This replaces only the main container content, not the detail containers.
|
|
61
|
+
*/
|
|
62
|
+
customMainContainerContent?: (item: RelationTreeItem, defaultContent: JSX.Element) => JSX.Element;
|
|
63
|
+
/** Custom document content renderer (partial control - replaces only metadata display) */
|
|
64
|
+
customDocumentContent?: (item: RelationTreeItem, defaultMetadataContent: JSX.Element) => JSX.Element;
|
|
65
|
+
/**
|
|
66
|
+
* Show metadata names before values (default: false).
|
|
67
|
+
* When true, displays "MetadataName: Value", otherwise just "Value".
|
|
68
|
+
* Value rendering respects DataDomain (uses TMDataListItemViewer for lists, TMUserIdViewer for users, etc.)
|
|
69
|
+
*/
|
|
70
|
+
showMetadataNames?: boolean;
|
|
54
71
|
/** Maximum depth level for recursive loading (default: 2) */
|
|
55
72
|
maxDepthLevel?: number;
|
|
56
73
|
/**
|
|
@@ -58,6 +75,23 @@ export interface TMRelationViewerProps {
|
|
|
58
75
|
* If false, when isForMaster=true shows: master docs → detail docs as children (original navigation)
|
|
59
76
|
*/
|
|
60
77
|
invertMasterNavigation?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Additional static items to append at the end of the tree.
|
|
80
|
+
* These items are not loaded dynamically - they must already contain all data.
|
|
81
|
+
* Useful for showing pre-calculated documents (e.g., additional documents in dossiers).
|
|
82
|
+
* Can include a separator item by marking it with `isSeparator: true`.
|
|
83
|
+
*/
|
|
84
|
+
additionalStaticItems?: RelationTreeItem[];
|
|
85
|
+
/**
|
|
86
|
+
* If false, hides the main document node and shows detail containers directly under the main container.
|
|
87
|
+
* Default: true (show main document as intermediate node)
|
|
88
|
+
*/
|
|
89
|
+
showMainDocument?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Custom label for the main container when showMainDocument is false.
|
|
92
|
+
* If not provided, uses the document type name.
|
|
93
|
+
*/
|
|
94
|
+
labelMainContainer?: string;
|
|
61
95
|
}
|
|
62
96
|
/**
|
|
63
97
|
* Check if document type has detail relations
|
|
@@ -67,5 +101,21 @@ export declare const hasDetailRelations: (mTID: number | undefined) => Promise<b
|
|
|
67
101
|
* Check if document type has master relations
|
|
68
102
|
*/
|
|
69
103
|
export declare const hasMasterRelations: (dTID: number | undefined) => Promise<boolean>;
|
|
104
|
+
/**
|
|
105
|
+
* Get metadata keys excluding system metadata
|
|
106
|
+
*/
|
|
107
|
+
export declare const getMetadataKeys: (obj: any) => string[];
|
|
108
|
+
/**
|
|
109
|
+
* Get display value keys for a document (max 5, prioritize SYS_Abstract)
|
|
110
|
+
*/
|
|
111
|
+
export declare const getDcmtDisplayValue: (obj: any) => string[];
|
|
112
|
+
/**
|
|
113
|
+
* Get display value formatted by column type
|
|
114
|
+
*/
|
|
115
|
+
export declare const getDisplayValueByColumn: (col: DataColumnDescriptor | undefined, value: any) => any;
|
|
116
|
+
/**
|
|
117
|
+
* Convert SearchResultDescriptor to structured data source with metadata
|
|
118
|
+
*/
|
|
119
|
+
export declare const searchResultToDataSource: (searchResult: SearchResultDescriptor | undefined, hideSysMetadata?: boolean) => Promise<any[]>;
|
|
70
120
|
declare const TMRelationViewer: React.FC<TMRelationViewerProps>;
|
|
71
121
|
export default TMRelationViewer;
|