@topconsultnpm/sdkui-react 6.19.0-test2 → 6.20.0-dev1.10

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.
Files changed (38) hide show
  1. package/lib/components/base/TMAccordion.js +2 -2
  2. package/lib/components/choosers/TMDynDataListItemChooser.js +5 -4
  3. package/lib/components/editors/TMHtmlEditor.js +1 -1
  4. package/lib/components/editors/TMMetadataValues.js +34 -12
  5. package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +74 -63
  6. package/lib/components/features/documents/TMDcmtBlog.d.ts +1 -7
  7. package/lib/components/features/documents/TMDcmtBlog.js +29 -2
  8. package/lib/components/features/documents/TMDcmtForm.d.ts +1 -0
  9. package/lib/components/features/documents/TMDcmtForm.js +24 -34
  10. package/lib/components/features/documents/TMDcmtPreview.js +93 -64
  11. package/lib/components/features/search/TMSavedQuerySelector.js +1 -1
  12. package/lib/components/features/search/TMSearchQueryPanel.js +1 -1
  13. package/lib/components/features/search/TMSearchResult.js +249 -58
  14. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +8 -0
  15. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.js +129 -0
  16. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -2
  17. package/lib/components/features/search/TMSearchResultsMenuItems.js +41 -63
  18. package/lib/components/features/search/TMTreeSelector.js +1 -1
  19. package/lib/components/features/search/TMViewHistoryDcmt.d.ts +18 -0
  20. package/lib/components/features/search/TMViewHistoryDcmt.js +285 -0
  21. package/lib/components/grids/TMRecentsManager.js +1 -1
  22. package/lib/helper/SDKUI_Globals.d.ts +3 -7
  23. package/lib/helper/SDKUI_Globals.js +1 -0
  24. package/lib/helper/SDKUI_Localizator.d.ts +16 -0
  25. package/lib/helper/SDKUI_Localizator.js +209 -6
  26. package/lib/helper/TMIcons.d.ts +3 -1
  27. package/lib/helper/TMIcons.js +9 -1
  28. package/lib/helper/TMUtils.d.ts +3 -1
  29. package/lib/helper/TMUtils.js +51 -0
  30. package/lib/helper/checkinCheckoutManager.d.ts +55 -0
  31. package/lib/helper/checkinCheckoutManager.js +266 -0
  32. package/lib/helper/helpers.d.ts +7 -0
  33. package/lib/helper/helpers.js +37 -5
  34. package/lib/helper/index.d.ts +1 -0
  35. package/lib/helper/index.js +1 -0
  36. package/lib/helper/queryHelper.js +13 -1
  37. package/lib/services/platform_services.d.ts +1 -1
  38. package/package.json +52 -52
@@ -0,0 +1,129 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ import TMSaveForm from "../../forms/TMSaveForm";
4
+ import { IconBxInfo, IconFileDots, IconFolder, SDKUI_Globals, SDKUI_Localizator } from "../../../helper";
5
+ import { FormModes } from "../../../ts";
6
+ import { ResultTypes, ValidationItem } from "@topconsultnpm/sdk-ts";
7
+ import { SaveFormOptions, useSaveForm } from "../../../hooks/useForm";
8
+ import { getCicoDownloadFileName, updateCicoCheckoutStorageItem } from "../../../helper/checkinCheckoutManager";
9
+ import { TMColors } from "../../../utils/theme";
10
+ import TMLayoutContainer, { TMLayoutItem } from "../../base/TMLayout";
11
+ import TMTooltip from "../../base/TMTooltip";
12
+ import TMTextBox from "../../editors/TMTextBox";
13
+ import ShowAlert from "../../base/TMAlert";
14
+ import { TMExceptionBoxManager } from "../../base/TMPopUp";
15
+ const TMSearchResultCheckoutInfoForm = (props) => {
16
+ const { dtdName, selectedDcmtOrFocused, onClose } = props;
17
+ const [initialDcmtCheckoutFolder, setInitialDcmtCheckoutFolder] = useState("");
18
+ const [initialDcmtCheckoutName, setInitialDcmtCheckoutName] = useState("");
19
+ const validator = async (params) => {
20
+ const validations = [];
21
+ if (!params.checkoutName?.trim()) {
22
+ validations.push(new ValidationItem(ResultTypes.ERROR, SDKUI_Localizator.Name, SDKUI_Localizator.RequiredField));
23
+ }
24
+ return validations;
25
+ };
26
+ const { formData, setFormData, validationItems, exception } = useSaveForm(FormModes.Create, 0, new SaveFormOptions(), validator);
27
+ const isDisabled = !formData || !formData.checkoutName?.trim() || (formData.checkoutFolder === initialDcmtCheckoutFolder && formData.checkoutName === initialDcmtCheckoutName);
28
+ useEffect(() => {
29
+ if (!selectedDcmtOrFocused.TID || !selectedDcmtOrFocused.DID)
30
+ return;
31
+ const dcmtCheckoutInfoCurrentItems = [...SDKUI_Globals.userSettings.dcmtCheckoutInfo];
32
+ const existingItem = dcmtCheckoutInfoCurrentItems.find((item) => item.TID === selectedDcmtOrFocused.TID.toString() && item.DID === selectedDcmtOrFocused.DID.toString());
33
+ const folder = existingItem?.checkoutFolder ?? "";
34
+ const name = existingItem?.checkoutName ?? getCicoDownloadFileName({ type: 'dcmtInfo', dcmtInfo: selectedDcmtOrFocused, originalFileName: dtdName ?? SDKUI_Localizator.SearchResult }, true, false);
35
+ // Set form data
36
+ setFormData({
37
+ ...formData,
38
+ checkoutFolder: folder,
39
+ checkoutName: name,
40
+ });
41
+ // Save initial values
42
+ setInitialDcmtCheckoutFolder(folder);
43
+ setInitialDcmtCheckoutName(name);
44
+ }, []);
45
+ const calcIsModifiedWrapper = (formData) => {
46
+ if (!formData)
47
+ return false;
48
+ if (formData.checkoutFolder !== initialDcmtCheckoutFolder || formData.checkoutName !== initialDcmtCheckoutName) {
49
+ return true;
50
+ }
51
+ return false;
52
+ };
53
+ const onSaveAsync = () => {
54
+ try {
55
+ if (isDisabled)
56
+ return;
57
+ // Check: formData must exist, selectedDcmtOrFocused.TID and selectedDcmtOrFocused.DID must exist, and at least one of checkoutFolder or checkoutName must be filled
58
+ if (formData && selectedDcmtOrFocused.TID && selectedDcmtOrFocused.DID) {
59
+ // Create a new draft checkout item with TID, DID, and folder/name values
60
+ const newItem = { TID: selectedDcmtOrFocused.TID.toString(), DID: selectedDcmtOrFocused.DID.toString(), checkoutFolder: formData.checkoutFolder ?? "", checkoutName: formData.checkoutName ?? "" };
61
+ updateCicoCheckoutStorageItem(newItem, "dcmtInfo", "addOrUpdate");
62
+ onClose();
63
+ ShowAlert({ mode: 'success', title: SDKUI_Localizator.CheckoutInfo, message: SDKUI_Localizator.OperationSuccess, duration: 3000 });
64
+ }
65
+ }
66
+ catch (error) {
67
+ console.error('Error in onSaveAsync:', error);
68
+ TMExceptionBoxManager.show({ title: SDKUI_Localizator.Error, exception: error });
69
+ }
70
+ };
71
+ return _jsx(TMSaveForm, { title: dtdName + " \u2014 " + SDKUI_Localizator.CheckoutInfo, showTitleFormMode: false, isModal: true, width: "470px", height: "240px", showBackButton: false, showErrorCount: false, showSaveButton: false, showUndoButton: false, showToolbar: false, hasNavigation: false, formMode: FormModes.Create, validationItems: validationItems, exception: exception, isModified: calcIsModifiedWrapper(formData), onClose: onClose, children: _jsx("div", { style: { margin: "0px 10px" }, children: _jsx(TMLayoutContainer, { direction: 'vertical', children: _jsx(TMLayoutContainer, { gap: 5, children: _jsxs(TMLayoutItem, { height: 'max-content', children: [_jsxs("div", { style: { display: "flex", alignItems: "center", gap: "10px", marginTop: "5px", marginBottom: "5px" }, children: [_jsx(TMTooltip, { content: SDKUI_Localizator.CheckInOutSettingsNotice, children: _jsx(IconBxInfo, {}) }), _jsxs("span", { children: [SDKUI_Localizator.DefaultFolder, ":", " ", _jsx("i", { children: SDKUI_Globals.userSettings.defaultCheckInOutFolder !== ""
72
+ ? SDKUI_Globals.userSettings.defaultCheckInOutFolder
73
+ : SDKUI_Localizator.UndefinedText })] })] }), _jsx(TMTextBox, { icon: _jsx(IconFolder, {}), label: SDKUI_Localizator.Folder, value: formData?.checkoutFolder ?? '', isModifiedWhen: formData?.checkoutFolder !== initialDcmtCheckoutFolder, onValueChanged: (e) => {
74
+ const newValue = e.target.value;
75
+ setFormData(prev => ({
76
+ ...prev,
77
+ checkoutFolder: newValue,
78
+ checkoutName: prev?.checkoutName ?? "",
79
+ }));
80
+ }, validationItems: validationItems?.filter(o => o.PropertyName === SDKUI_Localizator.Folder), autoFocus: true, fromModal: true }), _jsx(TMTextBox, { icon: _jsx(IconFileDots, {}), label: SDKUI_Localizator.Name, value: formData?.checkoutName ?? '', isModifiedWhen: formData?.checkoutName !== initialDcmtCheckoutName, onValueChanged: (e) => {
81
+ const newValue = e.target.value;
82
+ setFormData(prev => ({
83
+ ...prev,
84
+ checkoutFolder: prev?.checkoutFolder ?? "",
85
+ checkoutName: newValue,
86
+ }));
87
+ }, validationItems: validationItems?.filter(o => o.PropertyName === SDKUI_Localizator.Name) }), _jsxs("div", { style: {
88
+ width: "100%",
89
+ height: '50px',
90
+ marginTop: "10px",
91
+ display: 'flex',
92
+ justifyContent: 'flex-end',
93
+ alignItems: 'center',
94
+ gap: '10px'
95
+ }, children: [_jsx("button", { onClick: () => onSaveAsync(), disabled: false, style: {
96
+ background: 'none',
97
+ border: 'none',
98
+ color: isDisabled ? '#a0a0a0' : TMColors.primary,
99
+ cursor: isDisabled ? 'not-allowed' : 'pointer',
100
+ padding: '6px 14px',
101
+ borderRadius: '6px',
102
+ transition: 'background-color 0.3s, color 0.3s',
103
+ }, onMouseEnter: e => {
104
+ if (!isDisabled) {
105
+ e.currentTarget.style.backgroundColor = '#e6f0ff';
106
+ e.currentTarget.style.color = '#004a99';
107
+ }
108
+ }, onMouseLeave: e => {
109
+ if (!isDisabled) {
110
+ e.currentTarget.style.backgroundColor = 'transparent';
111
+ e.currentTarget.style.color = TMColors.primary;
112
+ }
113
+ }, children: SDKUI_Localizator.Save }), _jsx("button", { onClick: () => onClose(), style: {
114
+ background: 'none',
115
+ border: 'none',
116
+ color: TMColors.primary,
117
+ cursor: 'pointer',
118
+ padding: '6px 14px',
119
+ borderRadius: '6px',
120
+ transition: 'background-color 0.3s, color 0.3s',
121
+ }, onMouseEnter: e => {
122
+ e.currentTarget.style.backgroundColor = '#e6f0ff';
123
+ e.currentTarget.style.color = '#004a99';
124
+ }, onMouseLeave: e => {
125
+ e.currentTarget.style.backgroundColor = 'transparent';
126
+ e.currentTarget.style.color = TMColors.primary;
127
+ }, children: SDKUI_Localizator.Cancel })] })] }) }) }) }) });
128
+ };
129
+ export default TMSearchResultCheckoutInfoForm;
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
- import { DcmtTypeDescriptor, FileDescriptor, FileFormats, LayoutModes, WorkingGroupDescriptor } from '@topconsultnpm/sdk-ts';
2
+ import { DcmtTypeDescriptor, FileDescriptor, FileFormats, LayoutModes, WorkingGroupDescriptor, UserDescriptor } from '@topconsultnpm/sdk-ts';
3
3
  import { TMDataGridContextMenuItem } from '../../base/TMDataGrid';
4
4
  import { DcmtInfo, DcmtOperationTypes, DownloadModes, DownloadTypes, SearchResultContext } from '../../../ts';
5
5
  export declare const getSelectedDcmtsOrFocused: (selectedItems: Array<any>, focusedItem: any, fileFormat?: FileFormats) => DcmtInfo[];
6
6
  export declare const getAllFieldSelectedDcmtsOrFocused: (selectedItems: Array<any>, focusedItem: any, fileFormat?: FileFormats) => any[];
7
7
  export declare const signatureInformationCallback: (isMobile: boolean, inputDcmts: DcmtInfo[] | undefined) => Promise<void>;
8
- export declare const getCommandsMenuItems: (isMobile: boolean, dtd: DcmtTypeDescriptor | undefined, selectedItems: Array<any>, focusedItem: any, context: SearchResultContext, showFloatingBar: boolean, workingGroupContext: WorkingGroupDescriptor | undefined, showSearch: boolean, setShowFloatingBar: React.Dispatch<React.SetStateAction<boolean>>, openFormHandler: (layoutMode: LayoutModes) => void, openSharedArchiveHandler: () => Promise<void>, showSharedDcmtsHandler: () => Promise<void>, downloadDcmtsAsync: (inputDcmts: DcmtInfo[] | undefined, downloadType: DownloadTypes, downloadMode: DownloadModes, onFileDownloaded?: (dcmtFile: File | undefined) => void, confirmAttachments?: (list: FileDescriptor[]) => Promise<string[] | undefined>, skipConfirmation?: boolean) => Promise<void>, runOperationAsync: (inputDcmts: DcmtInfo[] | undefined, dcmtOperationType: DcmtOperationTypes, actionAfterOperationAsync?: () => Promise<void>) => Promise<void>, onRefreshSearchAsync: (() => Promise<void>) | undefined, onRefreshDataRowsAsync: (() => Promise<void>) | undefined, onRefreshAfterAddDcmtToFavs: (() => void) | undefined, confirmFormat: () => Promise<FileFormats>, confirmAttachments: (list: FileDescriptor[]) => Promise<string[] | undefined>, openTaskFormHandler: () => void, openDetailDcmtsFormHandler: (value: boolean) => void, openMasterDcmtsFormHandler: (value: boolean) => void, openBatchUpdateFormHandler: (value: boolean) => void, openExportForm: () => void, handleToggleSearch: () => void, handleSignApprove: () => void, openSignSettingsForm: () => void, handleCheckOutOperationCallback: (checkout: boolean) => Promise<void>, openWGsCopyMoveForm?: ((mode: "copyToWgDraft" | "copyToWgArchivedDoc", dcmtTypeDescriptor: DcmtTypeDescriptor, documents: Array<DcmtInfo>) => void), openCommentFormCallback?: ((documents: Array<DcmtInfo>) => void), openEditPdf?: ((documents: Array<DcmtInfo>) => void), openAddDocumentForm?: () => void, passToArchiveCallback?: (outputMids: Array<{
8
+ export declare const getCommandsMenuItems: (isMobile: boolean, dtd: DcmtTypeDescriptor | undefined, allUsers: Array<UserDescriptor>, selectedItems: Array<any>, focusedItem: any, context: SearchResultContext, showFloatingBar: boolean, workingGroupContext: WorkingGroupDescriptor | undefined, showSearch: boolean, setShowFloatingBar: React.Dispatch<React.SetStateAction<boolean>>, openFormHandler: (layoutMode: LayoutModes) => void, openSharedArchiveHandler: () => Promise<void>, showSharedDcmtsHandler: () => Promise<void>, downloadDcmtsAsync: (inputDcmts: DcmtInfo[] | undefined, downloadType: DownloadTypes, downloadMode: DownloadModes, onFileDownloaded?: (dcmtFile: File | undefined) => void, confirmAttachments?: (list: FileDescriptor[]) => Promise<string[] | undefined>, skipConfirmation?: boolean) => Promise<void>, runOperationAsync: (inputDcmts: DcmtInfo[] | undefined, dcmtOperationType: DcmtOperationTypes, actionAfterOperationAsync?: () => Promise<void>) => Promise<void>, onRefreshSearchAsync: (() => Promise<void>) | undefined, onRefreshDataRowsAsync: (() => Promise<void>) | undefined, onRefreshAfterAddDcmtToFavs: (() => void) | undefined, confirmFormat: () => Promise<FileFormats>, confirmAttachments: (list: FileDescriptor[]) => Promise<string[] | undefined>, openTaskFormHandler: () => void, openDetailDcmtsFormHandler: (value: boolean) => void, openMasterDcmtsFormHandler: (value: boolean) => void, openBatchUpdateFormHandler: (value: boolean) => void, openExportForm: () => void, handleToggleSearch: () => void, handleSignApprove: () => void, openSignSettingsForm: () => void, handleCheckOutOperationCallback: (checkout: boolean) => Promise<void>, handleCheckInOperationCallback: () => void, showCheckoutInformationFormCallback: () => void, viewHistoryCallback: () => void, infoCheckCopyToClipboard: () => void, openWGsCopyMoveForm?: ((mode: "copyToWgDraft" | "copyToWgArchivedDoc", dcmtTypeDescriptor: DcmtTypeDescriptor, documents: Array<DcmtInfo>) => void), openCommentFormCallback?: ((documents: Array<DcmtInfo>) => void), openEditPdf?: ((documents: Array<DcmtInfo>) => void), openAddDocumentForm?: () => void, passToArchiveCallback?: (outputMids: Array<{
9
9
  mid: number;
10
10
  value: string;
11
11
  }>, tid?: number) => void, archiveMasterDocuments?: (tid: number | undefined) => Promise<void>, archiveDetailDocuments?: (tid: number | undefined) => Promise<void>, hasMasterRelation?: boolean, hasDetailRelation?: boolean, canArchiveMasterRelation?: boolean, canArchiveDetailRelation?: boolean, pairManyToManyDocuments?: (isPairing: boolean) => Promise<void>, hasManyToManyRelation?: boolean) => Array<TMDataGridContextMenuItem>;
@@ -1,75 +1,31 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { AccessLevels, AccessLevelsEx, AppModules, FileFormats, LayoutModes, SDK_Globals, DcmtTypeListCacheService, LicenseModuleStatus, CICO_MetadataNames } from '@topconsultnpm/sdk-ts';
2
+ import { AccessLevels, AccessLevelsEx, AppModules, FileFormats, LayoutModes, SDK_Globals, DcmtTypeListCacheService, LicenseModuleStatus } from '@topconsultnpm/sdk-ts';
3
3
  import { IconActivity, IconArchiveDoc, IconBatchUpdate, IconCheckFile, IconCheckIn, IconCircleInfo, IconCloseCircle, IconConvertFilePdf, IconDelete, IconDotsVerticalCircleOutline, IconDownload, IconEdit, IconExportTo, IconFileDots, IconHide, IconInfo, IconMenuCAArchive, IconPlatform, IconPreview, IconRelation, IconSearch, IconShow, IconStar, IconSubstFile, IconUndo, IconUserGroupOutline, SDKUI_Localizator, svgToString, searchResultToMetadataValues, IconSignaturePencil, IconArchiveMaster, IconArchiveDetail, IconDetailDcmts, isPdfEditorEnabled, IconPair, IconUnpair, IconSharedDcmt, IconShare, IconCopy, IconMoveToFolder } from '../../../helper';
4
4
  import ShowAlert from '../../base/TMAlert';
5
5
  import { TMMessageBoxManager, ButtonNames, TMExceptionBoxManager } from '../../base/TMPopUp';
6
6
  import TMSpinner from '../../base/TMSpinner';
7
7
  import { DcmtOperationTypes, DownloadTypes, SearchResultContext } from '../../../ts';
8
8
  import { isXMLFileExt } from '../../../helper/dcmtsHelper';
9
- const getCicoInfo = (dtd) => {
10
- const cico = {
11
- CICO: 0,
12
- CanCICO: AccessLevels.No,
13
- CanDelChronology: AccessLevels.No,
14
- UserID_MID: 0,
15
- Date_MID: 0,
16
- Ver_MID: 0,
17
- UserID_CanViewOrUpdate: AccessLevels.No,
18
- Date_CanViewOrUpdate: AccessLevels.No,
19
- Ver_CanViewOrUpdate: AccessLevels.No,
20
- };
21
- if (dtd === undefined)
22
- return cico;
23
- cico.CICO = dtd.cico ?? 0;
24
- cico.CanCICO = dtd.perm?.canCICO ?? AccessLevels.No;
25
- cico.CanDelChronology = dtd.perm?.canDelChron ?? AccessLevels.No;
26
- const mdCheckout = dtd.metadata?.find(md => md.name === CICO_MetadataNames.CICO_CheckoutUserID);
27
- if (mdCheckout) {
28
- cico.UserID_MID = mdCheckout.fromMID;
29
- cico.UserID_CanViewOrUpdate = (mdCheckout.perm?.canView == AccessLevels.Yes || mdCheckout.perm?.canUpdate == AccessLevels.Yes) ? AccessLevels.Yes : AccessLevels.No;
30
- }
31
- const mdDate = dtd.metadata?.find(md => md.name === CICO_MetadataNames.CICO_CheckoutDate);
32
- if (mdDate) {
33
- cico.Date_MID = mdDate.fromMID;
34
- cico.Date_CanViewOrUpdate = (mdDate.perm?.canView == AccessLevels.Yes || mdDate.perm?.canUpdate == AccessLevels.Yes) ? AccessLevels.Yes : AccessLevels.No;
35
- }
36
- const mdVer = dtd.metadata?.find(md => md.name === CICO_MetadataNames.CICO_Version);
37
- if (mdVer) {
38
- cico.Ver_MID = mdVer.fromMID;
39
- cico.Ver_CanViewOrUpdate = (mdVer.perm?.canView == AccessLevels.Yes || mdVer.perm?.canUpdate == AccessLevels.Yes) ? AccessLevels.Yes : AccessLevels.No;
40
- }
41
- return cico;
42
- };
43
- const cicoIsEnabled = (dcmt, dtd) => {
44
- const cicoInfo = getCicoInfo(dtd);
45
- let isCheckout = false;
46
- const CICO_CheckoutUserID = dtd?.metadata?.find(md => md.name === CICO_MetadataNames.CICO_CheckoutUserID)?.id;
47
- if (dcmt && CICO_CheckoutUserID) {
48
- const key = dcmt.TID + "_" + CICO_CheckoutUserID;
49
- const value = dcmt[key];
50
- if (value && value > 0) {
51
- isCheckout = true;
52
- }
53
- }
54
- return {
55
- cicoEnabled: cicoInfo.CICO === 1 && cicoInfo.CanCICO === AccessLevels.Yes,
56
- isCheckout: isCheckout
57
- };
58
- };
9
+ import { getDcmtCicoStatus } from '../../../helper/checkinCheckoutManager';
59
10
  const disabledForSingleRow = (selectedItems, focusedItem) => {
60
- return selectedItems.length > 1 || focusedItem === undefined;
11
+ // Disabilita se ci sono più item selezionati o se focusedItem non ha TID/DID validi
12
+ return selectedItems.length > 1 || focusedItem === undefined || focusedItem.TID === undefined || focusedItem.DID === undefined;
61
13
  };
62
14
  const disabledForMultiRow = (selectedItems, focusedItem) => {
63
- return selectedItems.length === 0 && focusedItem === undefined;
15
+ // Disabilita se non ci sono selectedItems e focusedItem non ha TID/DID validi
16
+ return selectedItems.length === 0 && (focusedItem === undefined || focusedItem.TID === undefined || focusedItem.DID === undefined);
64
17
  };
65
18
  const MAX_DCMTS_FOR_SELECTION_REFRESH = 100;
66
19
  export const getSelectedDcmtsOrFocused = (selectedItems, focusedItem, fileFormat) => {
67
20
  if (selectedItems.length <= 0 && !focusedItem)
68
21
  return [];
69
22
  if (selectedItems.length > 0) {
70
- return selectedItems.map((item) => { return { TID: item.TID, DID: item.DID, FILEEXT: item.FILEEXT, ISSIGNED: Number(item.ISSIGNED ?? 0), fileFormat: fileFormat, rowIndex: item.rowIndex }; });
23
+ // Filtra solo gli item che hanno TID e DID validi
24
+ return selectedItems
25
+ .filter((item) => item.TID !== undefined && item.DID !== undefined)
26
+ .map((item) => { return { TID: item.TID, DID: item.DID, FILEEXT: item.FILEEXT, ISSIGNED: Number(item.ISSIGNED ?? 0), fileFormat: fileFormat, rowIndex: item.rowIndex }; });
71
27
  }
72
- else if (focusedItem !== undefined) {
28
+ else if (focusedItem !== undefined && focusedItem.TID !== undefined && focusedItem.DID !== undefined) {
73
29
  return [{ TID: focusedItem.TID, DID: focusedItem.DID, FILEEXT: focusedItem.FILEEXT, ISSIGNED: Number(focusedItem.ISSIGNED ?? 0), fileFormat: fileFormat, rowIndex: focusedItem.rowIndex }];
74
30
  }
75
31
  return [];
@@ -140,7 +96,7 @@ export const signatureInformationCallback = async (isMobile, inputDcmts) => {
140
96
  TMSpinner.hide();
141
97
  }
142
98
  };
143
- export const getCommandsMenuItems = (isMobile, dtd, selectedItems, focusedItem, context, showFloatingBar, workingGroupContext, showSearch, setShowFloatingBar, openFormHandler, openSharedArchiveHandler, showSharedDcmtsHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, onRefreshDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, confirmAttachments, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler, openExportForm, handleToggleSearch, handleSignApprove, openSignSettingsForm, handleCheckOutOperationCallback, openWGsCopyMoveForm, openCommentFormCallback, openEditPdf, openAddDocumentForm, passToArchiveCallback, archiveMasterDocuments, archiveDetailDocuments, hasMasterRelation, hasDetailRelation, canArchiveMasterRelation, canArchiveDetailRelation, pairManyToManyDocuments, hasManyToManyRelation) => {
99
+ export const getCommandsMenuItems = (isMobile, dtd, allUsers, selectedItems, focusedItem, context, showFloatingBar, workingGroupContext, showSearch, setShowFloatingBar, openFormHandler, openSharedArchiveHandler, showSharedDcmtsHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, onRefreshDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, confirmAttachments, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler, openExportForm, handleToggleSearch, handleSignApprove, openSignSettingsForm, handleCheckOutOperationCallback, handleCheckInOperationCallback, showCheckoutInformationFormCallback, viewHistoryCallback, infoCheckCopyToClipboard, openWGsCopyMoveForm, openCommentFormCallback, openEditPdf, openAddDocumentForm, passToArchiveCallback, archiveMasterDocuments, archiveDetailDocuments, hasMasterRelation, hasDetailRelation, canArchiveMasterRelation, canArchiveDetailRelation, pairManyToManyDocuments, hasManyToManyRelation) => {
144
100
  const isPdfEditorLicensed = SDK_Globals?.license?.dcmtArchiveLicenses?.[0]?.siX_60007?.status === LicenseModuleStatus.Licensed;
145
101
  let pdfEditorAvailable = false;
146
102
  if (dtd && dtd.widgets && dtd.widgets.length > 0) {
@@ -372,26 +328,48 @@ export const getCommandsMenuItems = (isMobile, dtd, selectedItems, focusedItem,
372
328
  const selectedDocs = getAllFieldSelectedDcmtsOrFocused(selectedItems, focusedItem);
373
329
  // Take the first document (used for validation checks)
374
330
  const firstDoc = selectedDocs?.[0];
375
- const { cicoEnabled, isCheckout } = cicoIsEnabled(firstDoc, dtd);
331
+ const { cicoEnabled, checkoutStatus } = getDcmtCicoStatus(firstDoc, allUsers, dtd);
376
332
  return {
377
333
  icon: svgToString(_jsx(IconFileDots, {})),
378
334
  text: "Check in/Check out",
379
- disabled: !cicoEnabled || (disabledForSingleRow(selectedItems, focusedItem) && disabledForMultiRow(selectedItems, focusedItem)),
335
+ disabled: firstDoc === undefined || disabledForSingleRow(selectedItems, focusedItem),
380
336
  items: [
381
337
  {
382
338
  icon: "edit",
383
339
  text: 'Check out',
384
- disabled: !cicoEnabled || (disabledForSingleRow(selectedItems, focusedItem) && disabledForMultiRow(selectedItems, focusedItem)),
385
- // disabled: isNotSingleFile || isGroupLocked || isFileCheckedOut,
340
+ disabled: !cicoEnabled || checkoutStatus.isCheckedOut || disabledForSingleRow(selectedItems, focusedItem),
386
341
  onClick: () => handleCheckOutOperationCallback(true),
387
342
  },
343
+ {
344
+ icon: "unlock",
345
+ text: 'Check in',
346
+ onClick: () => handleCheckInOperationCallback(),
347
+ disabled: !cicoEnabled || !checkoutStatus.isCheckedOut || checkoutStatus.mode === 'lockMode' || disabledForSingleRow(selectedItems, focusedItem)
348
+ },
388
349
  {
389
350
  icon: "remove",
390
351
  text: SDKUI_Localizator.CancelCheckOut,
391
- disabled: !cicoEnabled || (disabledForSingleRow(selectedItems, focusedItem) && disabledForMultiRow(selectedItems, focusedItem)),
392
- // disabled: isNotSingleFile || isGroupLocked || isFileNotCheckedOut || isNotCheckedOutByCurrentUser,
352
+ disabled: !cicoEnabled || !checkoutStatus.isCheckedOut || checkoutStatus.mode === 'lockMode' || disabledForSingleRow(selectedItems, focusedItem),
393
353
  onClick: () => handleCheckOutOperationCallback(false),
394
354
  },
355
+ {
356
+ icon: "info",
357
+ text: SDKUI_Localizator.CheckoutInfo,
358
+ onClick: showCheckoutInformationFormCallback,
359
+ disabled: !checkoutStatus.isCheckedOut || disabledForSingleRow(selectedItems, focusedItem)
360
+ },
361
+ {
362
+ icon: "copy",
363
+ text: SDKUI_Localizator.CopyCheckoutPath,
364
+ onClick: infoCheckCopyToClipboard,
365
+ disabled: !checkoutStatus.isCheckedOut || disabledForSingleRow(selectedItems, focusedItem)
366
+ },
367
+ {
368
+ icon: "clock",
369
+ text: SDKUI_Localizator.History,
370
+ disabled: checkoutStatus.version === 1 || disabledForSingleRow(selectedItems, focusedItem),
371
+ onClick: viewHistoryCallback,
372
+ },
395
373
  ]
396
374
  };
397
375
  };
@@ -706,7 +684,7 @@ export const getCommandsMenuItems = (isMobile, dtd, selectedItems, focusedItem,
706
684
  ]
707
685
  },
708
686
  signatureMenuItem(),
709
- // checkinMenuItem(),
687
+ checkinMenuItem(),
710
688
  relationsMenuItem(),
711
689
  sharedDcmtsMenuItem(),
712
690
  // shareMenuItem(),
@@ -178,7 +178,7 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
178
178
  }
179
179
  } }), children: trees.length > 0
180
180
  ?
181
- _jsxs("div", { style: {
181
+ _jsxs("div", { onContextMenu: (e) => e.preventDefault(), style: {
182
182
  display: 'flex',
183
183
  flexDirection: 'column',
184
184
  height: '100%',
@@ -0,0 +1,18 @@
1
+ import { DcmtInfo } from "../../../ts/types";
2
+ import { DeviceType } from "../../base/TMDeviceProvider";
3
+ import { DcmtTypeDescriptor, HomeBlogPost, TaskDescriptor } from "@topconsultnpm/sdk-ts";
4
+ interface TMViewHistoryDcmtProps {
5
+ fromDTD: DcmtTypeDescriptor;
6
+ deviceType: DeviceType | undefined;
7
+ inputDcmt: DcmtInfo;
8
+ onClose: () => void;
9
+ allTasks?: Array<TaskDescriptor>;
10
+ getAllTasks?: () => Promise<void>;
11
+ deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
12
+ addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
13
+ editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
14
+ handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
15
+ handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
16
+ }
17
+ declare const TMViewHistoryDcmt: (props: TMViewHistoryDcmtProps) => import("react/jsx-runtime").JSX.Element;
18
+ export default TMViewHistoryDcmt;
@@ -0,0 +1,285 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useState } from "react";
3
+ import { DownloadTypes, FormModes } from "../../../ts/types";
4
+ import { associateColumnsToRows, calcResponsiveSizes, formatBytes, getExceptionMessage, Globalization, SDKUI_Localizator } from "../../../helper";
5
+ import TMModal from "../../base/TMModal";
6
+ import { DeleteEngine, ResultTypes, SDK_Globals, UpdateEngineByID, UserListCacheService } from "@topconsultnpm/sdk-ts";
7
+ import TMSpinner from "../../base/TMSpinner";
8
+ import { ButtonNames, TMExceptionBoxManager, TMMessageBoxManager } from "../../base/TMPopUp";
9
+ import TMDcmtIcon from "../documents/TMDcmtIcon";
10
+ import TMDataGrid from "../../base/TMDataGrid";
11
+ import TMDcmtForm from "../documents/TMDcmtForm";
12
+ import { useDcmtOperations } from "../../../hooks/useDcmtOperations";
13
+ import { TMLayoutWaitingContainer } from "../../base/TMWaitPanel";
14
+ import { TMResultManager } from "../../forms/TMResultDialog";
15
+ let abortLocalController = new AbortController();
16
+ const TMViewHistoryDcmt = (props) => {
17
+ const { deviceType, inputDcmt, onClose, fromDTD, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers } = props;
18
+ const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
19
+ const [dcmtHistory, setDcmtHistory] = useState([]);
20
+ // showId is a state variable that determines whether an ID-related component or feature should be displayed
21
+ const [showId, setShowId] = useState(false);
22
+ // State to store when show search panel inside datagrid
23
+ const [showSearch, setShowSearch] = useState(true);
24
+ // Memoized configuration for DataGrid selection mode: single selection without checkboxes
25
+ const selection = useMemo(() => {
26
+ return { mode: 'single', showCheckBoxesMode: 'none' };
27
+ }, []);
28
+ // State to store the currently focused row key, initially set to undefined
29
+ const [focusedRowKey, setFocusedRowKey] = useState(undefined);
30
+ // State to store the currently focused row index, initially set to -1
31
+ const [selectedIndex, setSelectedIndex] = useState(-1);
32
+ // State to manage show selected file
33
+ const [showDcmtForm, setShowDcmtForm] = useState(false);
34
+ // Memoized value to get the selected draft based on the focused row key
35
+ const selectedDcmt = useMemo(() => dcmtHistory.find(dcmt => dcmt.id === focusedRowKey), [focusedRowKey, dcmtHistory]);
36
+ // State variable to control the visibility of the wait panel.
37
+ const [showLocalWaitPanel, setShowLocalWaitPanel] = useState(false);
38
+ // State variable to store the title of the wait panel.
39
+ const [waitLocalPanelTitle, setWaitLocalPanelTitle] = useState('');
40
+ // State variable to control the visibility of the primary section of the wait panel.
41
+ const [showLocalPrimary, setShowLocalPrimary] = useState(false);
42
+ // State variable to store the primary text of the wait panel.
43
+ const [waitLocalPanelTextPrimary, setWaitLocalPanelTextPrimary] = useState('');
44
+ // State variable to track the current value of the primary progress indicator in the wait panel.
45
+ const [waitLocalPanelValuePrimary, setWaitLocalPanelValuePrimary] = useState(0);
46
+ // State variable to define the maximum value for the primary progress indicator in the wait panel.
47
+ const [waitLocalPanelMaxValuePrimary, setWaitLocalPanelMaxValuePrimary] = useState(0);
48
+ const getParticipantById = (id, users) => {
49
+ if (users.length === 0)
50
+ return null;
51
+ return users.find(participant => participant.id === id) || null;
52
+ };
53
+ const getHistory = async (users) => {
54
+ try {
55
+ // Show a spinner with a loading message
56
+ TMSpinner.show({ description: SDKUI_Localizator.Loading });
57
+ // Initialize the working group engine
58
+ const ue = new UpdateEngineByID(SDK_Globals.tmSession);
59
+ ue.DID = inputDcmt.DID;
60
+ ue.TID = inputDcmt.TID;
61
+ ue.Metadata_ClearAll();
62
+ const dcmtGetHistory = await ue.GetChronologyAsync();
63
+ if (dcmtGetHistory && dcmtGetHistory.dtdResult) {
64
+ const data = associateColumnsToRows(dcmtGetHistory.dtdResult.columns ?? [], dcmtGetHistory.dtdResult.rows ?? []);
65
+ const historyFileItems = data.map((row) => {
66
+ const updaterID = Number(row.UpdaterID);
67
+ const user = getParticipantById(updaterID, users);
68
+ return {
69
+ id: Number(row.DID),
70
+ TID: row.TID,
71
+ DID: row.DID,
72
+ FileCount: row.FileCount,
73
+ FileExt: row.FileExt,
74
+ FileSize: row.FileSize,
75
+ FileSizeDisplay: formatBytes(Number(row.FileSize) ?? 0),
76
+ UpdaterID: row.UpdaterID,
77
+ UpdaterDisplayName: user?.name ?? updaterID.toString(),
78
+ CreationTime: row.CreationTime,
79
+ LastUpdateTime: row.LastUpdateTime,
80
+ LastUpdateTimeDisplay: row.LastUpdateTime ? Globalization.getDateTimeDisplayValue(new Date(row.LastUpdateTime)) : '-',
81
+ Version: row.Version,
82
+ CheckInTime: row.CheckInTime,
83
+ IsLex: row.IsLex ? row.IsLex.toString() === '1' : false,
84
+ IsLogDel: row.IsLogDel ? row.IsLogDel.toString() === '1' : false,
85
+ IsMail: row.IsMail ? row.IsMail.toString() === '1' : false,
86
+ IsShared: row.IsShared ? row.IsShared.toString() === '1' : false,
87
+ IsSigned: row.IsSigned ? row.IsSigned.toString() === '1' : false,
88
+ };
89
+ });
90
+ return historyFileItems;
91
+ }
92
+ return [];
93
+ }
94
+ catch (error) {
95
+ // Show error if something goes wrong
96
+ TMExceptionBoxManager.show({ exception: error });
97
+ return [];
98
+ }
99
+ finally {
100
+ // Hide spinner when done
101
+ TMSpinner.hide();
102
+ }
103
+ };
104
+ // Define an asynchronous function to fetch draft history
105
+ const fetchDcmtHistory = async (users) => {
106
+ // Await the result of the getHistory() function, which likely retrieves draft history data
107
+ const historyFileItems = await getHistory(users);
108
+ // Update the state with the fetched history data
109
+ setDcmtHistory(historyFileItems);
110
+ };
111
+ // Load users and history data
112
+ const loadData = async () => {
113
+ const users = await UserListCacheService.GetAllAsync();
114
+ await fetchDcmtHistory(users ?? []);
115
+ };
116
+ useEffect(() => {
117
+ loadData();
118
+ }, []);
119
+ // Handles focus change in the data grid
120
+ const onFocusedRowChanged = useCallback((e) => {
121
+ const key = e.row?.key;
122
+ setFocusedRowKey(key);
123
+ if (key !== undefined) {
124
+ const index = dcmtHistory.findIndex(item => item.id === key);
125
+ setSelectedIndex(index);
126
+ }
127
+ else {
128
+ setSelectedIndex(-1);
129
+ }
130
+ }, [dcmtHistory]);
131
+ const downloadFilesCallback = async () => {
132
+ if (focusedRowKey === undefined)
133
+ return;
134
+ const focusedRow = dcmtHistory.find(dcmt => dcmt.id === focusedRowKey);
135
+ const files = [];
136
+ if (focusedRow && focusedRow.TID && focusedRow.DID && focusedRow.FileExt) {
137
+ files.push({ TID: Number(focusedRow.TID), DID: Number(focusedRow.DID), FILEEXT: focusedRow.FileExt });
138
+ }
139
+ if (files.length > 0)
140
+ await downloadDcmtsAsync(files, DownloadTypes.Dcmt, "download");
141
+ };
142
+ const deleteFilesCallback = () => {
143
+ if (!focusedRowKey)
144
+ return;
145
+ const currentDcmt = dcmtHistory.find(dcmt => dcmt.id === focusedRowKey);
146
+ if (currentDcmt && currentDcmt.id) {
147
+ const msg = SDKUI_Localizator.Delete_ConfirmFor1.replaceParams((fromDTD.name ?? SDKUI_Localizator.SearchResult) + " - DID " + currentDcmt.DID + ", " + SDKUI_Localizator.Version + ": " + currentDcmt.Version);
148
+ TMMessageBoxManager.show({
149
+ title: SDKUI_Localizator.Delete, message: msg, buttons: [ButtonNames.YES, ButtonNames.NO],
150
+ onButtonClick: async (e) => {
151
+ if (e !== ButtonNames.YES)
152
+ return;
153
+ setWaitLocalPanelTitle(SDKUI_Localizator.Delete);
154
+ setShowLocalWaitPanel(true);
155
+ setShowLocalPrimary(true);
156
+ abortLocalController = new AbortController();
157
+ let result = [];
158
+ let i = 0;
159
+ setWaitLocalPanelMaxValuePrimary(1);
160
+ if (abortLocalController.signal.aborted) {
161
+ result.push({ rowIndex: i, id1: currentDcmt.id, id2: currentDcmt.id, resultType: ResultTypes.WARNING, description: `Operazione interrotta. Elaborate ${i}` });
162
+ }
163
+ else {
164
+ setWaitLocalPanelTextPrimary(SDKUI_Localizator.Delete);
165
+ const deleteEngine = new DeleteEngine(SDK_Globals.tmSession);
166
+ await deleteEngine.PhysDeleteByIDAsync(Number(currentDcmt.TID), Number(currentDcmt.DID), false)
167
+ .then(async () => {
168
+ result.push({ rowIndex: Number(currentDcmt.TID), id1: Number(currentDcmt.TID), id2: Number(currentDcmt.DID), description: SDKUI_Localizator.DeletionCompletedSuccessfully, resultType: ResultTypes.SUCCESS });
169
+ await loadData();
170
+ })
171
+ .catch((err) => {
172
+ result.push({ rowIndex: Number(currentDcmt.TID), id1: Number(currentDcmt.TID), id2: Number(currentDcmt.DID), resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
173
+ });
174
+ }
175
+ setFocusedRowKey(undefined);
176
+ setWaitLocalPanelTextPrimary('');
177
+ setWaitLocalPanelMaxValuePrimary(0);
178
+ setWaitLocalPanelValuePrimary(0);
179
+ setShowLocalWaitPanel(false);
180
+ TMResultManager.show(result, SDKUI_Localizator.Delete, "ID", undefined);
181
+ }
182
+ });
183
+ }
184
+ };
185
+ const cellExtRender = useCallback((cellData) => {
186
+ const data = cellData.data;
187
+ const tooltipContent = (_jsxs("div", { style: { textAlign: 'left' }, children: [_jsxs("div", { children: [_jsx("span", { style: { fontWeight: 'bold' }, children: "ID:" }), " ", data.id ?? '-'] }), _jsxs("div", { children: [_jsx("span", { style: { fontWeight: 'bold' }, children: "DID:" }), " ", data.DID ?? '-'] }), _jsxs("div", { children: [_jsx("span", { style: { fontWeight: 'bold' }, children: "TID:" }), " ", data.TID ?? '-'] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Author, ":"] }), " ", data.UpdaterDisplayName ?? '-'] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Version, ":"] }), " ", data.Version] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Size, ":"] }), " ", formatBytes(Number(data.FileSize ?? 0))] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.CreationTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(data.CreationTime)] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.LastUpdateTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(data.LastUpdateTime)] })] }));
188
+ return _jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' }, children: _jsx(TMDcmtIcon, { tid: Number(data.TID), did: Number(data.DID), fileExtension: data.FileExt, downloadMode: 'openInNewWindow', tooltipContent: tooltipContent }) });
189
+ }, []);
190
+ const onContextMenuPreparing = (e) => {
191
+ if (e === undefined)
192
+ return;
193
+ if (e.target === 'content') {
194
+ e.items = e.items || [];
195
+ e.items = [
196
+ {
197
+ icon: "datafield",
198
+ text: SDKUI_Localizator.OpenForm,
199
+ disabled: focusedRowKey === undefined,
200
+ onClick: () => setShowDcmtForm(true),
201
+ },
202
+ {
203
+ icon: "download",
204
+ text: 'Download',
205
+ disabled: focusedRowKey === undefined,
206
+ onClick: () => downloadFilesCallback(),
207
+ },
208
+ {
209
+ icon: "trash",
210
+ text: SDKUI_Localizator.Delete,
211
+ disabled: focusedRowKey === undefined,
212
+ onClick: deleteFilesCallback,
213
+ beginGroup: true
214
+ },
215
+ {
216
+ icon: showSearch ? "eyeclose" : "eyeopen",
217
+ onClick: () => setShowSearch(prevShowSearch => !prevShowSearch),
218
+ text: showSearch ? SDKUI_Localizator.HideSearch : SDKUI_Localizator.ShowSearch,
219
+ visible: true,
220
+ disabled: false,
221
+ beginGroup: true
222
+ },
223
+ {
224
+ icon: showId ? 'eyeclose' : 'eyeopen',
225
+ onClick: () => setShowId(prevShowId => !prevShowId),
226
+ text: showId ? SDKUI_Localizator.ID_Hide : SDKUI_Localizator.ID_Show,
227
+ visible: true,
228
+ disabled: false,
229
+ },
230
+ {
231
+ icon: "refresh",
232
+ text: SDKUI_Localizator.Refresh,
233
+ disabled: false,
234
+ onClick: loadData,
235
+ },
236
+ ];
237
+ }
238
+ };
239
+ // Handler for double-click cell event
240
+ const onCellDblClick = useCallback((e) => {
241
+ if (e.column.dataField === "FileExt")
242
+ return;
243
+ setFocusedRowKey(e.data.id);
244
+ setShowDcmtForm(true);
245
+ }, []);
246
+ // Checks if navigation is possible in the given direction
247
+ const canNavigateHandler = (dir) => {
248
+ if (focusedRowKey === undefined)
249
+ return false;
250
+ const index = dcmtHistory.findIndex(item => item.id === focusedRowKey);
251
+ if (index === -1)
252
+ return false;
253
+ return dir === 'next' ? index < dcmtHistory.length - 1 : index > 0;
254
+ };
255
+ // Navigates to the next or previous item in the draft history, if possible.
256
+ const onNavigateHandler = (dir) => {
257
+ if (selectedIndex === -1)
258
+ return;
259
+ let newIndex = selectedIndex;
260
+ if (dir === 'next' && selectedIndex < dcmtHistory.length - 1) {
261
+ newIndex = selectedIndex + 1;
262
+ }
263
+ else if (dir === 'prev' && selectedIndex > 0) {
264
+ newIndex = selectedIndex - 1;
265
+ }
266
+ const newFocusedId = dcmtHistory[newIndex]?.id;
267
+ if (newFocusedId !== undefined) {
268
+ setFocusedRowKey(newFocusedId);
269
+ setSelectedIndex(newIndex);
270
+ }
271
+ };
272
+ const dataColumns = useMemo(() => {
273
+ return ([
274
+ { dataField: "id", caption: "ID", dataType: 'string', visible: showId },
275
+ { dataField: "FileExt", caption: "", cellRender: cellExtRender },
276
+ { dataField: "Version", caption: "V.", dataType: 'number' },
277
+ { dataField: "FileSizeDisplay", caption: SDKUI_Localizator.Size },
278
+ { dataField: "UpdaterDisplayName", caption: SDKUI_Localizator.Author },
279
+ { dataField: "LastUpdateTimeDisplay", caption: SDKUI_Localizator.LastUpdateTime },
280
+ ]);
281
+ }, [showId]);
282
+ return _jsx(TMModal, { title: `${SDKUI_Localizator.SearchResult} \u2014 ${SDKUI_Localizator.History + ": " + (fromDTD.nameLoc ?? SDKUI_Localizator.Document) + " (DID:" + inputDcmt.DID})`, width: calcResponsiveSizes(deviceType, '700px', '700px', '95%'), height: calcResponsiveSizes(deviceType, '80%', '80%', '95%'), onClose: onClose, children: _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showLocalWaitPanel, showWaitPanelPrimary: showLocalPrimary, waitPanelTitle: waitLocalPanelTitle, waitPanelTextPrimary: waitLocalPanelTextPrimary, waitPanelValuePrimary: waitLocalPanelValuePrimary, waitPanelMaxValuePrimary: waitLocalPanelMaxValuePrimary, isCancelable: true, abortController: abortLocalController, children: [_jsx(TMDataGrid, { dataSource: dcmtHistory, dataColumns: dataColumns, focusedRowKey: focusedRowKey, selection: selection, onContextMenuPreparing: onContextMenuPreparing, onFocusedRowChanged: onFocusedRowChanged, onCellDblClick: onCellDblClick, noDataText: SDKUI_Localizator.NoDataToDisplay, showSearchPanel: showSearch }), (showDcmtForm && selectedDcmt !== undefined) &&
283
+ _jsx(TMDcmtForm, { TID: Number(selectedDcmt.TID), DID: Number(selectedDcmt.DID), formMode: FormModes.ReadOnly, isModal: true, widthModal: "95%", heightModal: "95%", titleModal: fromDTD.name ?? SDKUI_Localizator.SearchResult, allowNavigation: dcmtHistory.length > 0, itemIndex: selectedIndex + 1, count: dcmtHistory.length, onClose: () => { setShowDcmtForm(false); }, canNext: canNavigateHandler('next'), canPrev: canNavigateHandler('prev'), onNext: () => onNavigateHandler('next'), onPrev: () => onNavigateHandler('prev'), allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback })] }) }) });
284
+ };
285
+ export default TMViewHistoryDcmt;