@topconsultnpm/sdkui-react 6.21.0-dev3.3 → 6.21.0-dev3.30

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 (66) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +22 -1
  2. package/lib/components/NewComponents/ContextMenu/styles.d.ts +19 -43
  3. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +27 -79
  4. package/lib/components/base/Styled.d.ts +40 -76
  5. package/lib/components/base/TMDataGrid.js +12 -2
  6. package/lib/components/base/TMDataGridExportForm.js +19 -8
  7. package/lib/components/base/TMFileManagerDataGridView.js +4 -4
  8. package/lib/components/base/TMFileManagerThumbnailItems.js +3 -3
  9. package/lib/components/base/TMFileManagerUtils.d.ts +9 -6
  10. package/lib/components/base/TMFileManagerUtils.js +14 -1
  11. package/lib/components/base/TMModal.js +2 -2
  12. package/lib/components/base/TMTreeView.d.ts +3 -5
  13. package/lib/components/base/TMTreeView.js +12 -15
  14. package/lib/components/choosers/TMDynDataListItemChooser.js +9 -32
  15. package/lib/components/editors/TMEditorStyled.d.ts +10 -42
  16. package/lib/components/editors/TMFormulaEditor.d.ts +1 -0
  17. package/lib/components/editors/TMFormulaEditor.js +98 -49
  18. package/lib/components/editors/TMMetadataEditor.js +6 -2
  19. package/lib/components/editors/TMMetadataValues.js +11 -3
  20. package/lib/components/features/blog/TMBlogCommentForm.js +5 -2
  21. package/lib/components/features/documents/TMCopyToFolderForm.js +2 -2
  22. package/lib/components/features/documents/TMDcmtIcon.js +1 -1
  23. package/lib/components/features/documents/TMDcmtPreview.d.ts +3 -5
  24. package/lib/components/features/documents/TMMasterDetailDcmts.js +1 -1
  25. package/lib/components/features/documents/TMMergeToPdfForm.js +1 -1
  26. package/lib/components/features/documents/TMRelationViewer.js +8 -3
  27. package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +0 -13
  28. package/lib/components/features/documents/copyAndMergeDcmtsShared.js +1 -39
  29. package/lib/components/features/search/TMMetadataOutputForm.d.ts +17 -0
  30. package/lib/components/features/search/TMMetadataOutputForm.js +225 -0
  31. package/lib/components/features/search/TMMetadataSorterForm.d.ts +17 -0
  32. package/lib/components/features/search/TMMetadataSorterForm.js +243 -0
  33. package/lib/components/features/search/TMSearchQueryEditor.js +14 -8
  34. package/lib/components/features/search/TMSearchQueryPanel.d.ts +3 -3
  35. package/lib/components/features/search/TMSearchQueryPanel.js +249 -58
  36. package/lib/components/features/search/TMSearchResult.d.ts +1 -0
  37. package/lib/components/features/search/TMSearchResult.js +39 -18
  38. package/lib/components/features/search/TMViewHistoryDcmt.js +1 -1
  39. package/lib/components/features/search/metadataFormHelper.d.ts +16 -0
  40. package/lib/components/features/search/metadataFormHelper.js +77 -0
  41. package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.d.ts +1 -1
  42. package/lib/components/forms/Login/ChangePasswordInputs.d.ts +1 -1
  43. package/lib/components/grids/TMBlogAttachments.js +2 -2
  44. package/lib/components/grids/TMBlogsPost.js +5 -3
  45. package/lib/components/grids/TMBlogsPostUtils.d.ts +1 -0
  46. package/lib/components/grids/TMBlogsPostUtils.js +3 -1
  47. package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +2 -5
  48. package/lib/components/query/TMQueryEditor.d.ts +6 -10
  49. package/lib/components/sidebar/TMCommandsPanel.d.ts +2 -4
  50. package/lib/helper/Enum_Localizator.js +1 -0
  51. package/lib/helper/SDKUI_Localizator.d.ts +4 -0
  52. package/lib/helper/SDKUI_Localizator.js +40 -0
  53. package/lib/helper/TMUtils.d.ts +26 -3
  54. package/lib/helper/TMUtils.js +55 -0
  55. package/lib/helper/checkinCheckoutManager.d.ts +4 -3
  56. package/lib/helper/checkinCheckoutManager.js +29 -11
  57. package/lib/hooks/useCheckInOutOperations.d.ts +4 -3
  58. package/lib/hooks/useDataUserIdItem.js +1 -1
  59. package/lib/hooks/useDcmtOperations.d.ts +18 -1
  60. package/lib/hooks/useDcmtOperations.js +235 -24
  61. package/lib/hooks/useDocumentOperations.js +22 -3
  62. package/lib/hooks/useRelatedDocuments.js +4 -4
  63. package/lib/services/platform_services.d.ts +4 -4
  64. package/lib/ts/types.d.ts +2 -1
  65. package/lib/ts/types.js +1 -0
  66. package/package.json +10 -7
@@ -0,0 +1,16 @@
1
+ import { DcmtTypeDescriptor, MetadataDescriptor, QueryDescriptor } from "@topconsultnpm/sdk-ts";
2
+ export type MetadataDescriptorWithKey = MetadataDescriptor & {
3
+ uniqueKey: string;
4
+ };
5
+ export declare function removeDuplicatesByTidMid<T extends {
6
+ tid?: number;
7
+ mid?: number;
8
+ }>(items: T[]): T[];
9
+ export declare function loadMetadataFromQd(qd: QueryDescriptor | undefined, filterMetadata?: (value: MetadataDescriptor, index: number, array: MetadataDescriptor[]) => unknown): Promise<{
10
+ metadata: MetadataDescriptorWithKey[];
11
+ dcmtTypes: DcmtTypeDescriptor[];
12
+ }>;
13
+ export declare function areArraysEqual<T extends {
14
+ tid?: number;
15
+ mid?: number;
16
+ }>(arr1: T[], arr2: T[], additionalCompare?: (a: T, b: T) => boolean): boolean;
@@ -0,0 +1,77 @@
1
+ import { DcmtTypeDescriptor, DcmtTypeListCacheService, SDK_Localizator } from "@topconsultnpm/sdk-ts";
2
+ import { getTIDsByQd } from "../../../helper/queryHelper";
3
+ import { SDKUI_Localizator } from "../../../helper";
4
+ import TMSpinner from "../../base/TMSpinner";
5
+ // =============================================================================
6
+ // HELPER: Rimuove duplicati dalla lista (basato su tid + mid)
7
+ // =============================================================================
8
+ export function removeDuplicatesByTidMid(items) {
9
+ const seen = new Set();
10
+ return items.filter(item => {
11
+ const key = `${item.tid}_${item.mid}`;
12
+ if (seen.has(key))
13
+ return false;
14
+ seen.add(key);
15
+ return true;
16
+ });
17
+ }
18
+ // =============================================================================
19
+ // FUNZIONE PRINCIPALE: Estrae i metadati dal QueryDescriptor
20
+ // =============================================================================
21
+ export async function loadMetadataFromQd(qd, filterMetadata) {
22
+ if (!qd)
23
+ return { metadata: [], dcmtTypes: [] };
24
+ const dtdList = [];
25
+ const metadata = [];
26
+ try {
27
+ const tidsFromQd = getTIDsByQd(qd);
28
+ const inputTIDs = tidsFromQd.map((item) => item.tid);
29
+ if (inputTIDs.length === 0)
30
+ return { metadata: [], dcmtTypes: [] };
31
+ TMSpinner.show({ description: `${SDKUI_Localizator.Loading} - ${SDK_Localizator.DcmtType} ...` });
32
+ const dtds = await DcmtTypeListCacheService.GetFromTIDsAsync(inputTIDs, true, undefined, false, false);
33
+ for (let i = 0; i < dtds.length; i++) {
34
+ const dtd = new DcmtTypeDescriptor();
35
+ dtd.init({ ...dtds[i] });
36
+ const alias = tidsFromQd?.[i]?.alias ?? '';
37
+ dtd.customData2 = alias;
38
+ dtd.metadata?.forEach((md) => {
39
+ const mdWithKey = md;
40
+ mdWithKey.customData1 = dtd.id;
41
+ mdWithKey.customData2 = alias;
42
+ mdWithKey.uniqueKey = `${dtd.id}_${md.id}_${alias}`;
43
+ });
44
+ const filteredMetadata = filterMetadata
45
+ ? dtd.metadata?.filter(filterMetadata)
46
+ : dtd.metadata;
47
+ dtdList.push({ ...dtd, metadata: filteredMetadata });
48
+ }
49
+ for (const dtd of dtdList) {
50
+ if (!dtd.metadata)
51
+ continue;
52
+ for (const md of dtd.metadata) {
53
+ metadata.push(md);
54
+ }
55
+ }
56
+ return { metadata, dcmtTypes: dtdList };
57
+ }
58
+ finally {
59
+ TMSpinner.hide();
60
+ }
61
+ }
62
+ // =============================================================================
63
+ // HELPER: Confronta due array per determinare se sono stati modificati
64
+ // =============================================================================
65
+ export function areArraysEqual(arr1, arr2, additionalCompare) {
66
+ if (arr1.length !== arr2.length)
67
+ return false;
68
+ for (let i = 0; i < arr1.length; i++) {
69
+ const a = arr1[i];
70
+ const b = arr2[i];
71
+ if (a.tid !== b.tid || a.mid !== b.mid)
72
+ return false;
73
+ if (additionalCompare && !additionalCompare(a, b))
74
+ return false;
75
+ }
76
+ return true;
77
+ }
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { QueryDescriptor } from '@topconsultnpm/sdk-ts';
3
3
  import { WorkItemActor } from './RecipientList';
4
- export declare const RecipientsContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
4
+ export declare const RecipientsContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
5
5
  export declare const tosToActors: (tosString: string) => {
6
6
  andRecipients: WorkItemActor[];
7
7
  orRecipients: WorkItemActor[];
@@ -11,4 +11,4 @@ interface ChangePasswordInputsProps {
11
11
  }
12
12
  declare const ChangePasswordInputs: React.FC<ChangePasswordInputsProps>;
13
13
  export default ChangePasswordInputs;
14
- export declare const Divider: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
14
+ export declare const Divider: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
@@ -23,7 +23,7 @@ const TMBlogAttachments = (props) => {
23
23
  openDcmtForm({ TID: blogPostAttachment.tid, DID: blogPostAttachment.did, fileName });
24
24
  };
25
25
  return _jsx("div", { style: { width: "100%", marginTop: "5px", overflow: "hidden" }, children: attachments.map((blogPostAttachment, index) => {
26
- const { name, nameElement, tooltipContent, fileExt, archivedDocumentsExist, draftExist } = getAttachmentInfo(blogPostAttachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText);
26
+ const { name, nameElement, tooltipContent, fileExt, archivedDocumentsExist, draftExist, isSigned } = getAttachmentInfo(blogPostAttachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText);
27
27
  return _jsx("div", { onDoubleClick: (e) => !isLoading && onDoubleClick(e, blogPostAttachment, name, fileExt), onMouseEnter: (e) => !isLoading && handleMouseEnter(e, blogPostAttachment, name, fileExt), onMouseLeave: (e) => !isLoading && handleMouseLeave(e), style: {
28
28
  display: layoutMode === "extended" ? "inline-flex" : "flex",
29
29
  padding: '4px 8px',
@@ -63,7 +63,7 @@ const TMBlogAttachments = (props) => {
63
63
  }
64
64
  ` })] })) : (_jsxs(_Fragment, { children: [(!archivedDocumentsExist && !draftExist) ?
65
65
  _jsx(IconAttachment, { style: { marginRight: "5px", flexShrink: 0 } }) :
66
- _jsx("div", { style: { marginRight: "10px", flexShrink: 0 }, children: _jsx(TMDcmtIcon, { tid: blogPostAttachment.tid, did: blogPostAttachment.did, fileExtension: fileExt, downloadMode: 'openInNewWindow', tooltipContent: tooltipContent }) }), _jsx("span", { title: layoutMode === 'compact' ? name + " (DID: " + blogPostAttachment.did + ")" : undefined, style: {
66
+ _jsx("div", { style: { marginRight: "10px", flexShrink: 0, width: isSigned ? "40px" : undefined }, children: _jsx(TMDcmtIcon, { tid: blogPostAttachment.tid, did: blogPostAttachment.did, fileExtension: fileExt, downloadMode: 'openInNewWindow', tooltipContent: tooltipContent, isSigned: isSigned }) }), _jsx("span", { title: layoutMode === 'compact' ? name + " (DID: " + blogPostAttachment.did + ")" : undefined, style: {
67
67
  whiteSpace: 'nowrap',
68
68
  overflow: 'hidden',
69
69
  textOverflow: 'ellipsis',
@@ -510,9 +510,11 @@ const TMBlogsPost = (props) => {
510
510
  icon: _jsx("span", { className: "dx-icon-download" }),
511
511
  name: 'Download',
512
512
  onClick: async () => {
513
- await downloadDcmtsAsync([
514
- { TID: focusedAttachment.TID, DID: focusedAttachment.DID, fileName: focusedAttachment.fileName }
515
- ], DownloadTypes.Dcmt, "download");
513
+ await downloadDcmtsAsync({
514
+ inputDcmts: [{ TID: focusedAttachment.TID, DID: focusedAttachment.DID, fileName: focusedAttachment.fileName }],
515
+ downloadType: DownloadTypes.Dcmt,
516
+ downloadMode: "download"
517
+ });
516
518
  },
517
519
  });
518
520
  }
@@ -82,6 +82,7 @@ export declare const getAttachmentInfo: (attachment: BlogPostAttachment, treeFs:
82
82
  fileExt: string;
83
83
  draftExist: boolean;
84
84
  archivedDocumentsExist: boolean;
85
+ isSigned: number;
85
86
  };
86
87
  export declare const getDcmtTypeDescriptor: (blogPosts: Array<BlogPost>) => Promise<Map<number, DcmtTypeDescriptor>>;
87
88
  export declare const BlogPostHomeHeader: (header: string | undefined, classId: string | undefined, isSelected: boolean, searchText: string, headerClickCallback: () => void) => import("react/jsx-runtime").JSX.Element;
@@ -86,6 +86,7 @@ export const getAttachmentInfo = (attachment, treeFs, draftLatestInfoMap, archiv
86
86
  let archivedDocumentsExist = false;
87
87
  let name = '';
88
88
  let tooltipContent = _jsx(_Fragment, {});
89
+ let isSigned = 0;
89
90
  if (attachment.tid === DRAFT_TYPE_TID && treeFs) {
90
91
  const draftfileItem = findFileItemByDraftID(treeFs, attachment.draftID);
91
92
  if (draftfileItem) {
@@ -94,6 +95,7 @@ export const getAttachmentInfo = (attachment, treeFs, draftLatestInfoMap, archiv
94
95
  draftExist = true;
95
96
  let fileSize = '0';
96
97
  name = draftfileItem.name;
98
+ isSigned = draftfileItem.isSigned ? 1 : 0;
97
99
  if (draftLatestInfoMap && attachment.draftID && attachment.version) {
98
100
  const draftInfo = draftLatestInfoMap.get(attachment.draftID);
99
101
  if (draftInfo) {
@@ -139,7 +141,7 @@ export const getAttachmentInfo = (attachment, treeFs, draftLatestInfoMap, archiv
139
141
  nameElement = (_jsx("span", { children: highlightText(`${name} (DID: ${attachment.did})`, searchText, isSelected) }));
140
142
  }
141
143
  }
142
- return { name, nameElement, tooltipContent, folderId, fileExt, draftExist, archivedDocumentsExist };
144
+ return { name, nameElement, tooltipContent, folderId, fileExt, draftExist, archivedDocumentsExist, isSigned };
143
145
  };
144
146
  export const getDcmtTypeDescriptor = async (blogPosts) => {
145
147
  const dcmtTypeMap = new Map();
@@ -1,12 +1,9 @@
1
1
  import React from 'react';
2
2
  import { TMPanelDefinition } from './types';
3
- export declare const StyledToolbarButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "$isDisabled" | "$isActive"> & {
3
+ export declare const StyledToolbarButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {
4
4
  $isActive?: boolean;
5
5
  $isDisabled?: boolean;
6
- }, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "$isDisabled" | "$isActive"> & {
7
- $isActive?: boolean;
8
- $isDisabled?: boolean;
9
- }, never>>> & string;
6
+ }>> & string;
10
7
  interface TMPanelManagerToolbarProps {
11
8
  panels: Array<TMPanelDefinition>;
12
9
  }
@@ -2,18 +2,14 @@ import React from 'react';
2
2
  import { QueryDescriptor, ValidationItem } from '@topconsultnpm/sdk-ts';
3
3
  import { ITMApplyFormProps, FormModes } from '../../ts';
4
4
  import type { TMContextMenuItemProps } from '../NewComponents/ContextMenu/types';
5
- export declare const StyledRowItem: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
6
- export declare const StyledItemWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$borderRadius"> & {
5
+ export declare const StyledRowItem: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
6
+ export declare const StyledItemWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
7
7
  $borderRadius?: string;
8
- }, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$borderRadius"> & {
9
- $borderRadius?: string;
10
- }, never>>> & string;
11
- export declare const StyledAccordionItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
12
- export declare const StyledAccordionItemContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$disabled"> & {
13
- $disabled?: boolean;
14
- }, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$disabled"> & {
8
+ }>> & string;
9
+ export declare const StyledAccordionItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
10
+ export declare const StyledAccordionItemContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
15
11
  $disabled?: boolean;
16
- }, never>>> & string;
12
+ }>> & string;
17
13
  export declare const colorValue = "rgba(224,224,224,.5)";
18
14
  export declare const colorBrackets = "rgba(209,52,56,.3)";
19
15
  export declare const colorOperator = "rgba(16,124,16,.3)";
@@ -1,9 +1,7 @@
1
1
  import React from 'react';
2
- export declare const StyledCommandsPanel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$isMobile"> & {
2
+ export declare const StyledCommandsPanel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
3
3
  $isMobile?: boolean;
4
- }, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$isMobile"> & {
5
- $isMobile?: boolean;
6
- }, never>>> & string;
4
+ }>> & string;
7
5
  export interface TMCommandItemProps {
8
6
  icon: React.ReactNode;
9
7
  selected?: boolean;
@@ -23,6 +23,7 @@ export function LocalizeDcmtOperationTypes(value) {
23
23
  case DcmtOperationTypes.CheckFile: return SDKUI_Localizator.FileCheck;
24
24
  case DcmtOperationTypes.ConvertFile: return SDKUI_Localizator.FileConversion;
25
25
  case DcmtOperationTypes.VerifySign: return SDKUI_Localizator.VerifySignature;
26
+ case DcmtOperationTypes.CopyCompliant: return SDKUI_Localizator.CopyCompliant;
26
27
  case DcmtOperationTypes.SubstituteFile: return SDKUI_Localizator.AddOrSubstFile;
27
28
  case DcmtOperationTypes.FreeSearchReindex: return SDKUI_Localizator.IndexOrReindex;
28
29
  case DcmtOperationTypes.FreeSearchPurge: return SDKUI_Localizator.IndexingDelete;
@@ -137,6 +137,7 @@ export declare class SDKUI_Localizator {
137
137
  static get CopyAndReplace(): string;
138
138
  static get CopyButRename(): string;
139
139
  static get CopyCheckoutPath(): string;
140
+ static get CopyCompliant(): string;
140
141
  static get CopyToArchived(): string;
141
142
  static get CopyToArchivedDocuments(): string;
142
143
  static get CopyToClipboard(): "Erfolgreich in die Zwischenablage kopiert" | "Copy in clipboard" | "Copiar en portapapeles" | "Copier dans le presse-papier" | "Copiar na área de transferência" | "Copia negli appunti";
@@ -487,6 +488,8 @@ export declare class SDKUI_Localizator {
487
488
  static get NoDataToDisplay(): "Keine Daten zum Anzeigen" | "No data to display" | "No hay datos para mostrar" | "Aucune donnée à afficher" | "Sem dados para exibir" | "Nessun dato da visualizzare";
488
489
  static get NoDcmtFound(): "Kein Dokument gefunden" | "No documents found" | "Ningún documento encontrado" | "Pas de documents trouvés" | "Nenhum documento encontrado" | "Nessun documento trovato";
489
490
  static get NoDcmtSelected(): string;
491
+ static get NoSortingApplied(): string;
492
+ static get NoOutputMetadata(): string;
490
493
  static get NoDetailDocumentFoundForArchiving(): "Kein Detaildokument zur Archivierung gefunden." | "No detail document found for archiving." | "No se encontró ningún documento de detalle para archivar." | "Aucun document détail trouvé pour l'archivage." | "Nenhum documento de detalhe encontrado para arquivamento." | "Nessun documento di dettaglio trovato per l'archiviazione.";
491
494
  static get NoDocumentMatchFound(): "Kein zugeordnetes Dokument gefunden." | "No document match found." | "No se encontró ningún documento emparejado." | "Aucun document associé trouvé." | "Nenhum documento correspondente encontrado." | "Nessun documento abbinato trovato.";
492
495
  static get NoDocumentSelectedForManyToManyMatching(): "Kein Dokument für die Mehrfach-Zuordnung ausgewählt." | "No document selected for many-to-many matching." | "Ningún documento seleccionado para el emparejamiento de muchos a muchos." | "Aucun document sélectionné pour l'association plusieurs à plusieurs." | "Nenhum documento selecionado para correspondência de muitos para muitos." | "Nessun documento selezionato per l'abbinamento molti a molti.";
@@ -738,6 +741,7 @@ export declare class SDKUI_Localizator {
738
741
  static get SignatureType(): string;
739
742
  static get Size(): "Größe" | "Size" | "Dimensión" | "Dimension" | "Tamanho" | "Dimensione";
740
743
  static get SortBy(): "Sortieren nach" | "Sort by" | "Ordenar por" | "Trier par" | "Ordinamento";
744
+ static get SortByPlural(): "Sortierungen" | "Sortings" | "Ordenaciones" | "Tris" | "Ordenações" | "Ordinamenti";
741
745
  static get Source(): "Ursprung" | "Source" | "Origen" | "Origem" | "Origine";
742
746
  static get SpecialOperators(): "Spezielle Operatoren" | "Special operators" | "Operadores especiales" | "Opérateurs spéciaux" | "Os operadores especiais" | "Operatori speciali";
743
747
  static get StandardMode(): "Standardmodus" | "Standard mode" | "Modo estándar" | "Mode standard" | "Modo padrão" | "Modalità standard";
@@ -1356,6 +1356,16 @@ export class SDKUI_Localizator {
1356
1356
  default: return "Copia path di check out";
1357
1357
  }
1358
1358
  }
1359
+ static get CopyCompliant() {
1360
+ switch (this._cultureID) {
1361
+ case CultureIDs.De_DE: return "Elektronisches Duplikat";
1362
+ case CultureIDs.En_US: return "Compliant copy";
1363
+ case CultureIDs.Es_ES: return "Duplicado electrónico";
1364
+ case CultureIDs.Fr_FR: return "Duplicata électronique";
1365
+ case CultureIDs.Pt_PT: return "Duplicado eletrónico";
1366
+ default: return "Duplicato informatico";
1367
+ }
1368
+ }
1359
1369
  static get CopyToArchived() {
1360
1370
  switch (this._cultureID) {
1361
1371
  case CultureIDs.De_DE: return "In Archivierte kopieren";
@@ -4830,6 +4840,26 @@ export class SDKUI_Localizator {
4830
4840
  default: return "Nessun documento selezionato";
4831
4841
  }
4832
4842
  }
4843
+ static get NoSortingApplied() {
4844
+ switch (this._cultureID) {
4845
+ case CultureIDs.De_DE: return "Keine Sortierung angewendet";
4846
+ case CultureIDs.En_US: return "No sorting applied";
4847
+ case CultureIDs.Es_ES: return "Ningún ordenamiento aplicado";
4848
+ case CultureIDs.Fr_FR: return "Aucun tri appliqué";
4849
+ case CultureIDs.Pt_PT: return "Nenhuma ordenação aplicada";
4850
+ default: return "Nessun ordinamento applicato";
4851
+ }
4852
+ }
4853
+ static get NoOutputMetadata() {
4854
+ switch (this._cultureID) {
4855
+ case CultureIDs.De_DE: return "Keine Ausgabemetadaten ausgewählt";
4856
+ case CultureIDs.En_US: return "No output metadata selected";
4857
+ case CultureIDs.Es_ES: return "Ningún metadato de salida seleccionado";
4858
+ case CultureIDs.Fr_FR: return "Aucune métadonnée de sortie sélectionnée";
4859
+ case CultureIDs.Pt_PT: return "Nenhum metadado de saída selecionado";
4860
+ default: return "Nessun metadato di output selezionato";
4861
+ }
4862
+ }
4833
4863
  static get NoDetailDocumentFoundForArchiving() {
4834
4864
  switch (this._cultureID) {
4835
4865
  case CultureIDs.De_DE: return "Kein Detaildokument zur Archivierung gefunden.";
@@ -7360,6 +7390,16 @@ export class SDKUI_Localizator {
7360
7390
  default: return "Ordinamento";
7361
7391
  }
7362
7392
  }
7393
+ static get SortByPlural() {
7394
+ switch (this._cultureID) {
7395
+ case CultureIDs.De_DE: return "Sortierungen";
7396
+ case CultureIDs.En_US: return "Sortings";
7397
+ case CultureIDs.Es_ES: return "Ordenaciones";
7398
+ case CultureIDs.Fr_FR: return "Tris";
7399
+ case CultureIDs.Pt_PT: return "Ordenações";
7400
+ default: return "Ordinamenti";
7401
+ }
7402
+ }
7363
7403
  static get Source() {
7364
7404
  switch (this._cultureID) {
7365
7405
  case CultureIDs.De_DE: return "Ursprung";
@@ -1,6 +1,29 @@
1
1
  import React from 'react';
2
2
  import { FileItem } from '../components';
3
3
  import { AppModules, DataColumnDescriptor, DcmtTypeDescriptor, PdGs, SearchResultDescriptor } from '@topconsultnpm/sdk-ts';
4
+ /**
5
+ * Estensioni di firma/marca temporale note che possono avvolgere altre estensioni.
6
+ * Es: file.pdf.p7m, file.xml.p7m, file.docx.p7m, file.xml.p7m.ts
7
+ */
8
+ export declare const SIGNATURE_EXTENSIONS: Set<string>;
9
+ /**
10
+ * Estrae l'estensione completa da un nome file, gestendo estensioni composite
11
+ * a più livelli come .PDF.P7M, .XML.P7M.TS, etc.
12
+ *
13
+ * Esempi:
14
+ * - "documento.pdf" -> ".pdf"
15
+ * - "DCMT_123.PDF.P7M" -> ".PDF.P7M"
16
+ * - "fattura.xml.p7m" -> ".xml.p7m"
17
+ * - "example.XML.P7M.TS" -> ".XML.P7M.TS"
18
+ * - "file.tar.gz" -> ".gz" (tar.gz non è gestito come firma)
19
+ * - "file" -> ""
20
+ */
21
+ export declare const getFullFileExtension: (fileName: string, depth?: number) => string;
22
+ /**
23
+ * Estrae l'estensione base da un'estensione che può includere firme digitali.
24
+ * Es: pdf.p7m.tsd → pdf, pdf.p7m → pdf, pdf → pdf
25
+ */
26
+ export declare const getBaseExtension: (ext: string) => string;
4
27
  export declare const getFileIcon: (fileExtension: string | undefined, fileCount: number | undefined, tooltipContent?: JSX.Element | string) => import("react/jsx-runtime").JSX.Element;
5
28
  export declare function formatBytes(bytes: number | undefined, decimalPlaces?: number): string;
6
29
  export interface RowData {
@@ -23,9 +46,9 @@ interface TabItemProps {
23
46
  $isSelected: boolean;
24
47
  $activeGradient?: string;
25
48
  }
26
- export declare const StyledTabItem: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof TabItemProps> & TabItemProps, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof TabItemProps> & TabItemProps, never>>> & string;
27
- export declare const StyledTabIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, keyof TabItemProps> & TabItemProps, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, keyof TabItemProps> & TabItemProps, never>>> & string;
28
- export declare const TMCountBadge: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
49
+ export declare const StyledTabItem: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, TabItemProps>> & string;
50
+ export declare const StyledTabIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, TabItemProps>> & string;
51
+ export declare const TMCountBadge: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
29
52
  export declare const PDGS_COLORS: {
30
53
  DOSSIER: string;
31
54
  DOCUMENT: string;
@@ -4,6 +4,61 @@ import { TMTooltip } from '../components';
4
4
  import { IconCADossier, IconKey, IconMenuCAWorkingGroups } from './TMIcons';
5
5
  import { AppModules, DataListCacheService, LicenseModuleStatus, MetadataDataDomains, PdGs, SDK_Globals } from '@topconsultnpm/sdk-ts';
6
6
  import { SDKUI_Localizator } from './SDKUI_Localizator';
7
+ /**
8
+ * Estensioni di firma/marca temporale note che possono avvolgere altre estensioni.
9
+ * Es: file.pdf.p7m, file.xml.p7m, file.docx.p7m, file.xml.p7m.ts
10
+ */
11
+ export const SIGNATURE_EXTENSIONS = new Set(['p7m', 'p7s', 'm7m', 'tsd', 'tsr', 'ts']);
12
+ /** Profondità massima di ricorsione per la ricerca di estensioni composite */
13
+ const MAX_EXTENSION_DEPTH = 5;
14
+ /**
15
+ * Estrae l'estensione completa da un nome file, gestendo estensioni composite
16
+ * a più livelli come .PDF.P7M, .XML.P7M.TS, etc.
17
+ *
18
+ * Esempi:
19
+ * - "documento.pdf" -> ".pdf"
20
+ * - "DCMT_123.PDF.P7M" -> ".PDF.P7M"
21
+ * - "fattura.xml.p7m" -> ".xml.p7m"
22
+ * - "example.XML.P7M.TS" -> ".XML.P7M.TS"
23
+ * - "file.tar.gz" -> ".gz" (tar.gz non è gestito come firma)
24
+ * - "file" -> ""
25
+ */
26
+ export const getFullFileExtension = (fileName, depth = 0) => {
27
+ if (!fileName || depth > MAX_EXTENSION_DEPTH)
28
+ return '';
29
+ const lastDotIndex = fileName.lastIndexOf('.');
30
+ if (lastDotIndex <= 0)
31
+ return '';
32
+ const lastExtension = fileName.substring(lastDotIndex + 1).toLowerCase();
33
+ // Se l'ultima estensione è una firma/marca, cerca ricorsivamente le estensioni precedenti
34
+ if (SIGNATURE_EXTENSIONS.has(lastExtension)) {
35
+ const nameWithoutLastExt = fileName.substring(0, lastDotIndex);
36
+ const innerExtension = getFullFileExtension(nameWithoutLastExt, depth + 1);
37
+ if (innerExtension) {
38
+ // Concatena l'estensione interna con quella corrente
39
+ return innerExtension + fileName.substring(lastDotIndex);
40
+ }
41
+ }
42
+ // Estensione singola (o estensione base dopo le firme)
43
+ return fileName.substring(lastDotIndex);
44
+ };
45
+ /**
46
+ * Estrae l'estensione base da un'estensione che può includere firme digitali.
47
+ * Es: pdf.p7m.tsd → pdf, pdf.p7m → pdf, pdf → pdf
48
+ */
49
+ export const getBaseExtension = (ext) => {
50
+ if (!ext)
51
+ return '';
52
+ const parts = ext.toLowerCase().split('.');
53
+ // Trova la prima parte che non è un'estensione di firma
54
+ for (const part of parts) {
55
+ if (!SIGNATURE_EXTENSIONS.has(part)) {
56
+ return part;
57
+ }
58
+ }
59
+ // Se tutte sono firme, ritorna la prima
60
+ return parts[0] || '';
61
+ };
7
62
  const StyledIconFileContainer = styled.div `
8
63
  height: 22px;
9
64
  width: 18px;
@@ -1,7 +1,8 @@
1
1
  import React from "react";
2
- import { AccessLevels, DcmtTypeDescriptor, FileDescriptor, UserDescriptor } from "@topconsultnpm/sdk-ts";
3
- import { DcmtInfo, DownloadModes, DownloadTypes } from "../ts/types";
2
+ import { AccessLevels, DcmtTypeDescriptor, UserDescriptor } from "@topconsultnpm/sdk-ts";
3
+ import { DcmtInfo } from "../ts/types";
4
4
  import { FileItem } from "../components";
5
+ import { DownloadDcmtsAsyncParams } from "../hooks/useDcmtOperations";
5
6
  /**
6
7
  * Check-in/Check-out Manager
7
8
  * Questo modulo gestisce tutte le operazioni di check-in e check-out
@@ -42,7 +43,7 @@ export type DownloadSource = {
42
43
  originalFileName: string;
43
44
  };
44
45
  export declare const getCicoDownloadFileName: (source: DownloadSource, checkout: boolean, withTimestampAndExt: boolean) => string;
45
- export declare const cicoDownloadFilesCallback: (sources: Array<DownloadSource>, checkout: boolean, downloadDcmtsAsync: (inputDcmts: Array<DcmtInfo> | undefined, downloadType?: DownloadTypes, downloadMode?: DownloadModes, onFileDownloaded?: (dcmtFile: File) => void, confirmAttachments?: (list: FileDescriptor[]) => Promise<string[] | undefined>, skipConfirmation?: boolean) => Promise<void>) => Promise<void>;
46
+ export declare const cicoDownloadFilesCallback: (sources: Array<DownloadSource>, checkout: boolean, downloadDcmtsAsync: (params: DownloadDcmtsAsyncParams) => Promise<void>) => Promise<void>;
46
47
  export declare const updateCicoCheckoutStorageItem: (item: CheckoutInfo, type: "fileItem" | "dcmtInfo", action?: "addOrUpdate" | "remove") => void;
47
48
  export declare const validateCicoFileName: (source: DownloadSource, fileName: string, checkoutDate?: string | null) => FileNameValidation;
48
49
  type ValidationResult = {
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { AccessLevels, CICO_MetadataNames, SDK_Globals, SystemMIDsAsNumber } from "@topconsultnpm/sdk-ts";
3
3
  import TMTooltip from "../components/base/TMTooltip";
4
4
  import { dcmtsFileCachePreview, Globalization, removeDcmtsFileCache, SDKUI_Globals, SDKUI_Localizator } from "./index";
5
+ import { getBaseExtension, getFullFileExtension } from "./TMUtils";
5
6
  import { DownloadTypes } from "../ts/types";
6
7
  const findCheckOutUserName = (users, checkoutUserId) => {
7
8
  let checkOutUser = users.find(user => user.id === checkoutUserId);
@@ -74,7 +75,7 @@ export const cicoDownloadFilesCallback = async (sources, checkout, downloadDcmts
74
75
  }
75
76
  });
76
77
  if (files.length > 0) {
77
- await downloadDcmtsAsync(files, DownloadTypes.Dcmt, "download");
78
+ await downloadDcmtsAsync({ inputDcmts: files, downloadType: DownloadTypes.Dcmt, downloadMode: "download", skipConfirmation: true, useInputFileName: true });
78
79
  }
79
80
  };
80
81
  export const updateCicoCheckoutStorageItem = (item, type, action = "addOrUpdate") => {
@@ -128,13 +129,22 @@ export const validateCicoFileName = (source, fileName, checkoutDate) => {
128
129
  did = DID;
129
130
  ext = FILEEXT;
130
131
  }
131
- // Ensure originalName has the extension
132
- const normalizedExt = ext?.toLowerCase() ?? '';
133
- const name = baseName.toLowerCase().endsWith(`.${normalizedExt}`) ? baseName : `${baseName}.${normalizedExt}`;
132
+ // Ensure originalName has the extension (use base extension for comparison)
133
+ const sourceBaseExt = getBaseExtension(ext ?? '');
134
+ const name = baseName.toLowerCase().endsWith(`.${sourceBaseExt}`) ? baseName : `${baseName}.${sourceBaseExt}`;
134
135
  let fileNameToValidate = fileName;
135
- const fileExtensionCheck = fileNameToValidate.split('.').pop() ?? '';
136
- // Remove extension part
137
- fileNameToValidate = fileNameToValidate.slice(0, -fileExtensionCheck.length - 1);
136
+ // Estrai l'estensione completa (incluse eventuali firme digitali ricorsive es. pdf.p7m.tsd)
137
+ const fullExtension = getFullFileExtension(fileNameToValidate);
138
+ let fileExtensionCheck;
139
+ if (fullExtension) {
140
+ // Rimuovi l'estensione completa dal nome
141
+ fileNameToValidate = fileNameToValidate.slice(0, -fullExtension.length);
142
+ // L'estensione base è la prima parte (es. da ".pdf.p7m.tsd" prendi "pdf")
143
+ fileExtensionCheck = fullExtension.substring(1).split('.')[0];
144
+ }
145
+ else {
146
+ fileExtensionCheck = '';
147
+ }
138
148
  // Check and remove 'checkout~' prefix if present
139
149
  const hasCheckoutPrefix = fileNameToValidate.startsWith('checkout~');
140
150
  if (hasCheckoutPrefix) {
@@ -159,7 +169,7 @@ export const validateCicoFileName = (source, fileName, checkoutDate) => {
159
169
  const isValidDid = didCheck ? did.toString() === parseInt(didCheck, 10).toString() : false;
160
170
  const isValidTid = tidCheck ? tid.toString() === parseInt(tidCheck, 10).toString() : false;
161
171
  const isValidArchive = archiveCheck ? archiveCheck === archiveID : false;
162
- const isValidExt = ext ? ext.toLowerCase() === fileExtensionCheck.toLowerCase() : false;
172
+ const isValidExt = sourceBaseExt ? sourceBaseExt === fileExtensionCheck.toLowerCase() : false;
163
173
  // First phase validation result
164
174
  const isFirstPhaseValid = !!(isValidName && isValidArchive && isValidDid && isValidTid && isValidExt);
165
175
  // Second phase: validate checkoutDate timestamp (only if first phase passed and checkoutDate is a valid string)
@@ -177,11 +187,11 @@ export const validateCicoFileName = (source, fileName, checkoutDate) => {
177
187
  else {
178
188
  const pad = (n) => n.toString().padStart(2, '0');
179
189
  const expectedTimestamp = `${dt.getFullYear()}${pad(dt.getMonth() + 1)}${pad(dt.getDate())}${pad(dt.getHours())}${pad(dt.getMinutes())}${pad(dt.getSeconds())}`;
180
- isSecondPhaseValid = timestampCheck === expectedTimestamp;
181
190
  // Format dates for display: readable date + (raw timestamp)
182
191
  const expectedDisplayDate = Globalization.getDateTimeDisplayValue(dt);
183
192
  // Parse timestampCheck to readable format (YYYYMMDDHHmmss -> Date)
184
193
  let currentDisplayDate = timestampCheck;
194
+ let parsedDate = null;
185
195
  if (timestampCheck && timestampCheck.length === 14) {
186
196
  const year = parseInt(timestampCheck.substring(0, 4), 10);
187
197
  const month = parseInt(timestampCheck.substring(4, 6), 10) - 1;
@@ -189,9 +199,17 @@ export const validateCicoFileName = (source, fileName, checkoutDate) => {
189
199
  const hours = parseInt(timestampCheck.substring(8, 10), 10);
190
200
  const minutes = parseInt(timestampCheck.substring(10, 12), 10);
191
201
  const seconds = parseInt(timestampCheck.substring(12, 14), 10);
192
- const parsedDate = new Date(year, month, day, hours, minutes, seconds);
202
+ parsedDate = new Date(year, month, day, hours, minutes, seconds);
193
203
  currentDisplayDate = Globalization.getDateTimeDisplayValue(parsedDate);
194
204
  }
205
+ // Validate with ±10 seconds tolerance
206
+ if (parsedDate && !isNaN(parsedDate.getTime())) {
207
+ const diffInSeconds = Math.abs((dt.getTime() - parsedDate.getTime()) / 1000);
208
+ isSecondPhaseValid = diffInSeconds <= 10;
209
+ }
210
+ else {
211
+ isSecondPhaseValid = timestampCheck === expectedTimestamp;
212
+ }
195
213
  checkoutDateValidation = {
196
214
  expected: `${expectedDisplayDate} (${expectedTimestamp})`,
197
215
  current: `${currentDisplayDate} (${timestampCheck})`,
@@ -229,7 +247,7 @@ export const validateCicoFileName = (source, fileName, checkoutDate) => {
229
247
  isValid: isValidTid
230
248
  },
231
249
  fileExtension: {
232
- expected: ext?.toLowerCase(),
250
+ expected: sourceBaseExt,
233
251
  current: fileExtensionCheck.toLowerCase(),
234
252
  isValid: isValidExt
235
253
  },
@@ -1,5 +1,6 @@
1
- import { DcmtInfo, DownloadModes, DownloadTypes } from '../ts';
2
- import { FileDescriptor, SearchResultDescriptor } from '@topconsultnpm/sdk-ts';
1
+ import { DcmtInfo } from '../ts';
2
+ import { SearchResultDescriptor } from '@topconsultnpm/sdk-ts';
3
+ import { DownloadDcmtsAsyncParams } from './useDcmtOperations';
3
4
  export interface UseCheckInOutOperationsProps {
4
5
  onRefreshPreview: () => Promise<void>;
5
6
  }
@@ -17,7 +18,7 @@ export interface UseCheckInOutOperationsReturn {
17
18
  };
18
19
  hideCommentFormCallback: () => void;
19
20
  copyCheckoutPathToClipboardCallback: (dcmt: DcmtInfo, filename: string) => void;
20
- handleCheckOutCallback: (dcmt: DcmtInfo, checkout: boolean, filename: string, downloadDcmtsAsync: (inputDcmts: Array<DcmtInfo> | undefined, downloadType?: DownloadTypes, downloadMode?: DownloadModes, onFileDownloaded?: (dcmtFile: File) => void, confirmAttachments?: (list: FileDescriptor[]) => Promise<string[] | undefined>, skipConfirmation?: boolean) => Promise<void>, onRefreshAsync?: (tid: number | undefined, did: number | undefined, refreshUI?: boolean, metadataResult?: SearchResultDescriptor | null) => Promise<void>) => Promise<void>;
21
+ handleCheckOutCallback: (dcmt: DcmtInfo, checkout: boolean, filename: string, downloadDcmtsAsync: (params: DownloadDcmtsAsyncParams) => Promise<void>, onRefreshAsync?: (tid: number | undefined, did: number | undefined, refreshUI?: boolean, metadataResult?: SearchResultDescriptor | null) => Promise<void>) => Promise<void>;
21
22
  handleCheckInCallback: (dcmt: DcmtInfo, checkoutDate?: string | null, onRefreshAsync?: (tid: number | undefined, did: number | undefined, refreshUI?: boolean, metadataResult?: SearchResultDescriptor | null) => Promise<void>) => Promise<void>;
22
23
  showCicoWaitPanel: boolean;
23
24
  cicoWaitPanelTitle: string;
@@ -74,7 +74,7 @@ export const useDataUserIdItem = () => {
74
74
  const getIcon = () => {
75
75
  if (!showIcon)
76
76
  return null;
77
- if (userId === undefined)
77
+ if (userId === undefined || userId === null)
78
78
  return null;
79
79
  return ud ? _jsx(TMUserIcon, { ud: ud }) : _jsx("span", { title: showTitile ? SDKUI_Localizator.ValueNotPresent : undefined, style: { display: 'inline-flex', alignItems: 'center' }, children: _jsx(IconWarning, { color: TMColors.warning }) });
80
80
  };