@topconsultnpm/sdkui-react 6.19.0-dev1.30 → 6.19.0-dev1.32

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.
@@ -58,7 +58,7 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
58
58
  passToSearch(currentTID, outputMids);
59
59
  } : undefined })
60
60
  :
61
- _jsx(TMPanel, { title: 'Archiviazione', allowMaximize: false, children: _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsx(StyledToppyTextContainer, { children: _jsx(StyledToppyText, { children: SDKUI_Localizator.DcmtTypeSelect }) }), _jsx(StyledToppyImage, { src: Logo, alt: 'Toppy' })] }) }), [currentTID, deviceType, mruTIDs, inputFile, inputMids]);
61
+ _jsx(TMPanel, { title: 'Archiviazione', allowMaximize: false, children: _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsx(StyledToppyTextContainer, { children: _jsx(StyledToppyText, { children: SDKUI_Localizator.DcmtTypeSelect }) }), _jsx(StyledToppyImage, { src: Logo, alt: 'Toppy' })] }) }), [currentTID, deviceType, mruTIDs, inputFile, inputMids, enableDragDropOverlay]);
62
62
  const allInitialPanelVisibility = {
63
63
  'tmTreeSelector': true,
64
64
  'tmRecentsManager': true,
@@ -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: "Rilascia il tuo file qui" })] })] }));
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;
@@ -52,12 +52,14 @@ export interface TMRelationViewerProps {
52
52
  onDocumentDoubleClick?: (tid: number, did: number, name?: string) => void;
53
53
  /** Custom item renderer (full control). Return undefined to use default renderer. */
54
54
  customItemRender?: (item: RelationTreeItem | null) => JSX.Element | undefined;
55
- /** Custom container style function */
56
- customContainerStyle?: (item: RelationTreeItem) => React.CSSProperties;
57
55
  /** Custom document style function */
58
56
  customDocumentStyle?: (item: RelationTreeItem) => React.CSSProperties;
59
- /** Custom container content renderer (partial control - replaces only content, keeps structure) */
60
- customContainerContent?: (item: RelationTreeItem, defaultContent: JSX.Element) => JSX.Element;
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;
61
63
  /** Custom document content renderer (partial control - replaces only metadata display) */
62
64
  customDocumentContent?: (item: RelationTreeItem, defaultMetadataContent: JSX.Element) => JSX.Element;
63
65
  /**
@@ -80,6 +82,16 @@ export interface TMRelationViewerProps {
80
82
  * Can include a separator item by marking it with `isSeparator: true`.
81
83
  */
82
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;
83
95
  }
84
96
  /**
85
97
  * Check if document type has detail relations
@@ -9,9 +9,6 @@ import { TMWaitPanel } from '../../base/TMWaitPanel';
9
9
  import { TMUserIdViewer } from '../../choosers/TMUserChooser';
10
10
  import TMDataListItemViewer from '../../viewers/TMDataListItemViewer';
11
11
  import TMDcmtIcon from './TMDcmtIcon';
12
- // ============================================================================
13
- // UTILITY FUNCTIONS
14
- // ============================================================================
15
12
  /**
16
13
  * Check if document type has detail relations
17
14
  */
@@ -139,7 +136,7 @@ export const searchResultToDataSource = async (searchResult, hideSysMetadata) =>
139
136
  }
140
137
  return output;
141
138
  };
142
- const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndicator = true, allowShowZeroDcmts = true, initialShowZeroDcmts = false, allowedTIDs, allowMultipleSelection = false, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onDocumentDoubleClick, customItemRender, customContainerStyle, customDocumentStyle, customContainerContent, customDocumentContent, showMetadataNames = false, maxDepthLevel = 2, invertMasterNavigation = true, additionalStaticItems = [], }) => {
139
+ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndicator = true, allowShowZeroDcmts = true, initialShowZeroDcmts = false, allowedTIDs, allowMultipleSelection = false, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onDocumentDoubleClick, customItemRender, customDocumentStyle, customMainContainerContent, customDocumentContent, showMetadataNames = false, maxDepthLevel = 2, invertMasterNavigation = true, additionalStaticItems = [], showMainDocument = true, labelMainContainer, }) => {
143
140
  // State
144
141
  const [dcmtTypes, setDcmtTypes] = useState([]);
145
142
  const [treeData, setTreeData] = useState([]);
@@ -395,48 +392,72 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
395
392
  const relatedDocs = isForMaster
396
393
  ? await getMasterDcmtsAsync(dcmt.TID, dcmt.DID, maxDepthLevel)
397
394
  : await getDetailDcmtsAsync(dcmt.TID, dcmt.DID, maxDepthLevel);
398
- // Create document node WITH VALUES
399
- const docNode = {
400
- key: `${isForMaster ? 'detail' : 'master'}-doc-${dcmt.TID}-${dcmt.DID}-${containerGUID}`,
401
- name: docRow?.SYS_Abstract?.value || docRow?.SYS_SUBJECT?.value || `Documento ${isForMaster ? 'Dettaglio' : 'Master'}`,
402
- tid: dcmt.TID,
403
- did: dcmt.DID,
404
- isDcmt: true,
405
- isContainer: false,
406
- expanded: tree.length === 0,
407
- isZero: dcmt.DID === 0,
408
- isMaster: !isForMaster,
409
- isRoot: true,
410
- isLoaded: true,
411
- hidden: false,
412
- values: docRow,
413
- searchResult: result ? [result] : [],
414
- items: relatedDocs,
415
- itemsCount: relatedDocs.length
416
- };
417
- // Create type container with unique key
418
- const typeContainer = {
419
- key: `${isForMaster ? 'detail' : 'master'}-type-${dcmt.TID}-${containerGUID}`,
420
- name: result?.fromName || dtd?.name || `TID: ${dcmt.TID}`,
421
- tid: dcmt.TID,
422
- dtd,
423
- isContainer: true,
424
- isRoot: true,
425
- isLoaded: true,
426
- isZero: false, // Type container is never zero (contains documents)
427
- searchResult: result ? [result] : [],
428
- items: [docNode],
429
- itemsCount: 1,
430
- expanded: tree.length === 0
431
- };
432
- tree.push(typeContainer);
395
+ // Se showMainDocument è false, mostra i container dei dettagli direttamente sotto il container principale
396
+ if (!showMainDocument) {
397
+ // Create type container that contains detail containers directly
398
+ const typeContainer = {
399
+ key: `${isForMaster ? 'detail' : 'master'}-type-${dcmt.TID}-${containerGUID}`,
400
+ name: labelMainContainer || result?.fromName || dtd?.name || `TID: ${dcmt.TID}`,
401
+ tid: dcmt.TID,
402
+ dtd,
403
+ isContainer: true,
404
+ isRoot: true,
405
+ isLoaded: true,
406
+ isZero: false,
407
+ searchResult: result ? [result] : [],
408
+ items: relatedDocs, // Directly show detail containers
409
+ itemsCount: relatedDocs.length,
410
+ expanded: tree.length === 0,
411
+ hidden: false
412
+ };
413
+ tree.push(typeContainer);
414
+ }
415
+ else {
416
+ // MODALITÀ ORIGINALE: mostra il documento master come nodo intermedio
417
+ // Create document node WITH VALUES
418
+ const docNode = {
419
+ key: `${isForMaster ? 'detail' : 'master'}-doc-${dcmt.TID}-${dcmt.DID}-${containerGUID}`,
420
+ name: docRow?.SYS_Abstract?.value || docRow?.SYS_SUBJECT?.value || `Documento ${isForMaster ? 'Dettaglio' : 'Master'}`,
421
+ tid: dcmt.TID,
422
+ did: dcmt.DID,
423
+ isDcmt: true,
424
+ isContainer: false,
425
+ expanded: tree.length === 0,
426
+ isZero: dcmt.DID === 0,
427
+ isMaster: !isForMaster,
428
+ isRoot: true,
429
+ isLoaded: true,
430
+ hidden: false,
431
+ values: docRow,
432
+ searchResult: result ? [result] : [],
433
+ items: relatedDocs,
434
+ itemsCount: relatedDocs.length
435
+ };
436
+ // Create type container with unique key
437
+ const typeContainer = {
438
+ key: `${isForMaster ? 'detail' : 'master'}-type-${dcmt.TID}-${containerGUID}`,
439
+ name: labelMainContainer || result?.fromName || dtd?.name || `TID: ${dcmt.TID}`,
440
+ tid: dcmt.TID,
441
+ dtd,
442
+ isContainer: true,
443
+ isRoot: true,
444
+ isLoaded: true,
445
+ isZero: false, // Type container is never zero (contains documents)
446
+ searchResult: result ? [result] : [],
447
+ items: [docNode],
448
+ itemsCount: 1,
449
+ expanded: tree.length === 0,
450
+ hidden: false
451
+ };
452
+ tree.push(typeContainer);
453
+ }
433
454
  }
434
455
  // Update progress counter
435
456
  processedCount++;
436
457
  setWaitPanelValuePrimary(processedCount);
437
458
  }
438
459
  setTreeData(updateHiddenProperty(tree));
439
- }, [inputDcmts, dcmtTypes, maxDepthLevel, isForMaster, invertMasterNavigation, getDetailDcmtsAsync, getMasterDcmtsAsync, abortController, updateHiddenProperty]);
460
+ }, [inputDcmts, dcmtTypes, maxDepthLevel, isForMaster, invertMasterNavigation, getDetailDcmtsAsync, getMasterDcmtsAsync, abortController, updateHiddenProperty, showMainDocument, labelMainContainer]);
440
461
  /**
441
462
  * Merge main tree data with additional static items
442
463
  */
@@ -587,19 +608,20 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
587
608
  opacity: item.isZero ? 0.4 : 1,
588
609
  transition: 'opacity 0.2s ease-in-out'
589
610
  };
590
- const containerStyle = customContainerStyle
591
- ? { ...defaultContainerStyle, ...customContainerStyle(item) }
592
- : defaultContainerStyle;
611
+ // Se è il container principale (root) e showMainDocument è false,
612
+ // non mostrare il badge perché conterrebbe il numero di sotto-container, non di documenti
613
+ const shouldShowBadge = !(item.isRoot && !showMainDocument);
593
614
  const defaultContent = (_jsxs(_Fragment, { children: [_jsx("div", { style: { position: 'relative' }, children: _jsx(IconFolder, { color: item.isManyToMany ? '#ff8f44' : TMColors.iconLight, fontSize: 24 }) }), _jsxs(StyledDivHorizontal, { style: { gap: 5, overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }, children: [_jsx("p", { style: {
594
615
  whiteSpace: 'nowrap',
595
616
  textOverflow: 'ellipsis',
596
617
  fontSize: '1rem',
597
618
  color: 'inherit'
598
- }, children: item.name }), _jsx(StyledBadge, { "$backgroundColor": TMColors.info, children: item.items?.length ?? 0 })] })] }));
599
- const content = customContainerContent
600
- ? customContainerContent(item, defaultContent)
619
+ }, children: item.name }), shouldShowBadge && (_jsx(StyledBadge, { "$backgroundColor": TMColors.info, children: item.items?.length ?? 0 }))] })] }));
620
+ // Se è il container principale (root) e abbiamo un custom renderer, usalo
621
+ const content = (item.isRoot && customMainContainerContent)
622
+ ? customMainContainerContent(item, defaultContent)
601
623
  : defaultContent;
602
- return (_jsx("div", { style: containerStyle, children: content }));
624
+ return (_jsx("div", { style: defaultContainerStyle, children: content }));
603
625
  }
604
626
  // Document rendering with full metadata display
605
627
  const defaultDocumentStyle = {
@@ -645,7 +667,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
645
667
  ? customDocumentContent(item, defaultMetadataContent || _jsx(_Fragment, {}))
646
668
  : defaultMetadataContent;
647
669
  return (_jsxs("div", { onDoubleClick: handleDoubleClick, style: documentStyle, children: [item.did && showCurrentDcmtIndicator && item.did === inputDcmts?.[0].DID ? _jsx(IconBackhandIndexPointingRight, { fontSize: 22, overflow: 'visible' }) : _jsx(_Fragment, {}), item.values && (_jsx(TMDcmtIcon, { tid: item.values?.TID?.value, did: item.values?.DID?.value, fileExtension: item.values?.FILEEXT?.value, fileCount: item.values?.FILECOUNT?.value, isLexProt: item.values?.IsLexProt?.value, isMail: item.values?.ISMAIL?.value, isShared: item.values?.ISSHARED?.value, isSigned: item.values?.ISSIGNED?.value, downloadMode: 'openInNewWindow' })), metadataContent] }));
648
- }, [onDocumentDoubleClick, showCurrentDcmtIndicator, inputDcmts, customContainerStyle, customContainerContent, customDocumentStyle, customDocumentContent, showMetadataNames]);
670
+ }, [onDocumentDoubleClick, showCurrentDcmtIndicator, inputDcmts, customMainContainerContent, customDocumentStyle, customDocumentContent, showMetadataNames, showMainDocument]);
649
671
  /**
650
672
  * Wrapper renderer that handles custom rendering if provided
651
673
  */
@@ -1,4 +1,4 @@
1
- import { InvoiceRetrieveFormats, OrderRetrieveFormats } from "@topconsultnpm/sdk-ts";
1
+ import { InvoiceRetrieveFormats, ObjectClasses, OrderRetrieveFormats } from "@topconsultnpm/sdk-ts";
2
2
  export declare const dcmtsFileCacheDownload: Map<string, File>;
3
3
  export declare const dcmtsFileCachePreview: Map<string, File>;
4
4
  export declare const CACHE_SIZE_LIMIT = 10;
@@ -44,6 +44,7 @@ export declare class ThemeSettings {
44
44
  };
45
45
  }
46
46
  export declare class SearchSettings {
47
+ autoFindReferences: ObjectClasses[];
47
48
  invoiceRetrieveFormat: InvoiceRetrieveFormats;
48
49
  orderRetrieveFormat: OrderRetrieveFormats;
49
50
  mruTIDs: number[];
@@ -87,6 +87,7 @@ export class ThemeSettings {
87
87
  }
88
88
  export class SearchSettings {
89
89
  constructor() {
90
+ this.autoFindReferences = [];
90
91
  this.invoiceRetrieveFormat = InvoiceRetrieveFormats.ASW_HTML;
91
92
  this.orderRetrieveFormat = OrderRetrieveFormats.NSO_HTML;
92
93
  this.mruTIDs = [];
@@ -172,6 +172,7 @@ export declare class SDKUI_Localizator {
172
172
  static get DownloadXMLAttachments(): string;
173
173
  static get Draft(): string;
174
174
  static get Drafts(): string;
175
+ static get DropFileHere(): "Ziehen Sie Ihre Datei hierher" | "Drop your file here" | "Suelta tu archivo aquí" | "Déposez votre fichier ici" | "Solte seu arquivo aqui";
175
176
  static get DropFileToShare(): string;
176
177
  static get Duplicate(): "Duplikat" | "Duplicate" | "Duplicar" | "Dupliquer" | "Duplicado" | "Duplica";
177
178
  static get Duplicate_ConfirmFor1(): "Möchten Sie '{{0}}' duplizieren?" | "Are you sure you want to duplicate '{{0}}'?" | "¿Estás seguro de que deseas duplicar '{{0}}'?" | "Êtes-vous sûr de vouloir dupliquer '{{0}}'?" | "Você tem certeza que deseja duplicar '{{0}}'?" | "Sei sicuro di voler duplicare '{{0}}'?";
@@ -1632,6 +1632,16 @@ export class SDKUI_Localizator {
1632
1632
  default: return "Bozze";
1633
1633
  }
1634
1634
  }
1635
+ static get DropFileHere() {
1636
+ switch (this._cultureID) {
1637
+ case CultureIDs.De_DE: return "Ziehen Sie Ihre Datei hierher";
1638
+ case CultureIDs.En_US: return "Drop your file here";
1639
+ case CultureIDs.Es_ES: return "Suelta tu archivo aquí";
1640
+ case CultureIDs.Fr_FR: return "Déposez votre fichier ici";
1641
+ case CultureIDs.Pt_PT: return "Solte seu arquivo aqui";
1642
+ default: return "Drop your file here";
1643
+ }
1644
+ }
1635
1645
  static get DropFileToShare() {
1636
1646
  switch (this._cultureID) {
1637
1647
  case CultureIDs.De_DE: return "Datei zum Teilen hier ablegen";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.19.0-dev1.30",
3
+ "version": "6.19.0-dev1.32",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",