@topconsultnpm/sdkui-react 6.22.0-dev1.2 → 6.22.0-dev1.20

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.
@@ -38,5 +38,7 @@ interface ITMDynDataListItemChooserFormProps extends ITMChooserFormProps<DataLis
38
38
  layoutMode?: LayoutModes;
39
39
  dynDL?: DynamicDataListDescriptor;
40
40
  searchResult?: SearchResultDescriptor;
41
+ /** Se presente, sono i parametri da passare alla query per recuperare il dataSource */
42
+ queryParamsDynDataList?: string[];
41
43
  }
42
44
  export declare const TMDynDataListItemChooserForm: (props: ITMDynDataListItemChooserFormProps) => import("react/jsx-runtime").JSX.Element;
@@ -122,7 +122,7 @@ const TMDynDataListItemChooser = ({ tid, md, width = '100%', titleForm, openChoo
122
122
  updateIsModalOpen?.(true);
123
123
  }
124
124
  }, elementStyle: elementStyle, isModifiedWhen: isModifiedWhen, openEditorOnSummaryClick: openChooserBySingleClick, label: label, template: renderTemplate(), onClearClick: showClearButton ? () => { onValueChanged?.([]); } : undefined, validationItems: validationItems }), showChooser &&
125
- _jsx(TMDynDataListItemChooserForm, { TID: tid, MID: md?.id, dynDL: dynDl, title: titleForm, allowMultipleSelection: allowMultipleSelection, searchResult: dataSource, selectedIDs: values, onClose: () => {
125
+ _jsx(TMDynDataListItemChooserForm, { TID: tid, MID: md?.id, dynDL: dynDl, title: titleForm, allowMultipleSelection: allowMultipleSelection, searchResult: dataSource, selectedIDs: values, queryParamsDynDataList: queryParamsDynDataList, onClose: () => {
126
126
  setShowChooser(false);
127
127
  updateIsModalOpen?.(false);
128
128
  summaryInputRef.current?.focus();
@@ -167,7 +167,7 @@ const TMDynDataListItemChooser = ({ tid, md, width = '100%', titleForm, openChoo
167
167
  export default TMDynDataListItemChooser;
168
168
  const cellRenderIcon = () => _jsx(IconDetails, {});
169
169
  export const TMDynDataListItemChooserForm = (props) => {
170
- const { TID, MID, layoutMode, dynDL, searchResult, selectedIDs, title, width, height, onChoose } = props;
170
+ const { TID, MID, layoutMode, dynDL, searchResult, selectedIDs, title, width, height, onChoose, queryParamsDynDataList } = props;
171
171
  // Generate unique keys for all columns
172
172
  const uniqueKeys = generateUniqueColumnKeys(searchResult?.dtdResult?.columns, searchResult?.fromTID);
173
173
  const dataColumns = searchResult?.dtdResult?.columns?.map((col, index) => {
@@ -184,12 +184,10 @@ export const TMDynDataListItemChooserForm = (props) => {
184
184
  });
185
185
  const keyValue = uniqueKeys[dynDL?.selectItemForValue ?? 0] ?? '';
186
186
  const getItems = async (refreshCache) => {
187
- if (!searchResult)
188
- return [];
189
187
  if (refreshCache)
190
188
  DataListCacheService.RemoveAll();
191
189
  TMSpinner.show({ description: `${SDKUI_Localizator.Loading} - ${SDK_Localizator.DataList} ...` });
192
- let result = await SDK_Globals.tmSession?.NewSearchEngine().GetDynDataListValuesAsync(TID, MID, layoutMode, [])
190
+ let result = await SDK_Globals.tmSession?.NewSearchEngine().GetDynDataListValuesAsync(TID, MID, layoutMode, queryParamsDynDataList ?? [])
193
191
  .catch((err) => { TMSpinner.hide(); TMExceptionBoxManager.show({ exception: err }); });
194
192
  TMSpinner.hide();
195
193
  return result ? searchResultDescriptorToSimpleArray(result) ?? [] : [];
@@ -200,5 +198,5 @@ export const TMDynDataListItemChooserForm = (props) => {
200
198
  titleDataList += `: ${title}`;
201
199
  return titleDataList;
202
200
  };
203
- return (_jsx(TMChooserForm, { title: getTitle(), allowMultipleSelection: props.allowMultipleSelection, width: width, height: height, keyName: keyValue ?? '', showDefaultColumns: false, hasShowId: false, columns: dataColumns, selectedIDs: selectedIDs, cellRenderIcon: cellRenderIcon, dataSource: searchResultDescriptorToSimpleArray(searchResult) ?? [], getItems: getItems, onClose: props.onClose, onChoose: (IDs) => onChoose?.(IDs) }));
201
+ return (_jsx(TMChooserForm, { title: getTitle(), allowMultipleSelection: props.allowMultipleSelection, width: width, height: height, keyName: keyValue ?? '', showDefaultColumns: false, hasShowId: false, columns: dataColumns, selectedIDs: selectedIDs, cellRenderIcon: cellRenderIcon, getItems: getItems, onClose: props.onClose, onChoose: (IDs) => onChoose?.(IDs) }));
204
202
  };
@@ -1425,7 +1425,49 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
1425
1425
  return undefined;
1426
1426
  const settings = getCurrentDcmtFormSetting()?.setting;
1427
1427
  // Return the appropriate layout based on context
1428
- return invocationContext === InvocationContext.Todo ? settings?.layoutToDo : settings?.layout;
1428
+ const persistedState = invocationContext === InvocationContext.Todo ? settings?.layoutToDo : settings?.layout;
1429
+ // tmWF must always start hidden - PanelDisabledStateHandler will restore it
1430
+ // when workflow data becomes available and isWFDisabled becomes false
1431
+ if (persistedState && persistedState['tmWF']?.visible) {
1432
+ // Get tmWF width to redistribute
1433
+ const tmWFWidth = parseFloat(persistedState['tmWF'].width) || 0;
1434
+ // Find other visible panels to redistribute width
1435
+ const otherVisiblePanels = Object.keys(persistedState).filter(key => key !== 'tmWF' && persistedState[key]?.visible);
1436
+ // Calculate extra width per visible panel
1437
+ const extraWidthPerPanel = otherVisiblePanels.length > 0
1438
+ ? tmWFWidth / otherVisiblePanels.length
1439
+ : 0;
1440
+ // Build new state with redistributed widths
1441
+ const newState = {};
1442
+ for (const key of Object.keys(persistedState)) {
1443
+ if (key === 'tmWF') {
1444
+ // Hide tmWF
1445
+ newState[key] = { ...persistedState[key], visible: false };
1446
+ }
1447
+ else if (otherVisiblePanels.includes(key)) {
1448
+ // Add extra width to visible panels
1449
+ const currentWidth = parseFloat(persistedState[key].width) || 0;
1450
+ newState[key] = {
1451
+ ...persistedState[key],
1452
+ width: `${currentWidth + extraWidthPerPanel}%`
1453
+ };
1454
+ }
1455
+ else {
1456
+ // Keep other panels as-is
1457
+ newState[key] = persistedState[key];
1458
+ }
1459
+ }
1460
+ return newState;
1461
+ }
1462
+ return persistedState;
1463
+ };
1464
+ // Returns whether tmWF was visible in persisted state (for restoring after WF data loads)
1465
+ const getPersistedWFVisible = () => {
1466
+ if (isMobile)
1467
+ return false;
1468
+ const settings = getCurrentDcmtFormSetting()?.setting;
1469
+ const persistedState = invocationContext === InvocationContext.Todo ? settings?.layoutToDo : settings?.layout;
1470
+ return persistedState?.['tmWF']?.visible ?? false;
1429
1471
  };
1430
1472
  const onBlogCommentFormCustomSave = useCallback(async (blogPost) => {
1431
1473
  try {
@@ -1514,7 +1556,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
1514
1556
  overflow: 'hidden'
1515
1557
  }, children: [_jsxs("div", { style: { width: '100%', height: '100%', display: isOpenDetails || isOpenMaster ? 'none' : 'flex' }, children: [isNavigating && _jsx(Spinner, { description: SDKUI_Localizator.Loading, flat: false }), (fromDTD) && _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: useWaitPanelLocalState ? showWaitPanelLocal : showWaitPanel, showWaitPanelPrimary: useWaitPanelLocalState ? showPrimaryLocal : showPrimary, showWaitPanelSecondary: useWaitPanelLocalState ? showSecondaryLocal : showSecondary, waitPanelTitle: useWaitPanelLocalState ? waitPanelTitleLocal : waitPanelTitle, waitPanelTextPrimary: useWaitPanelLocalState ? waitPanelTextPrimaryLocal : waitPanelTextPrimary, waitPanelValuePrimary: useWaitPanelLocalState ? waitPanelValuePrimaryLocal : waitPanelValuePrimary, waitPanelMaxValuePrimary: useWaitPanelLocalState ? waitPanelMaxValuePrimaryLocal : waitPanelMaxValuePrimary, waitPanelTextSecondary: useWaitPanelLocalState ? waitPanelTextSecondaryLocal : waitPanelTextSecondary, waitPanelValueSecondary: useWaitPanelLocalState ? waitPanelValueSecondaryLocal : waitPanelValueSecondary, waitPanelMaxValueSecondary: useWaitPanelLocalState ? waitPanelMaxValueSecondaryLocal : waitPanelMaxValueSecondary, isCancelable: useWaitPanelLocalState ? dcmtFile ? dcmtFile.size >= 1000000 : false : true, abortController: useWaitPanelLocalState ? abortControllerLocal : abortController, children: _jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showCicoWaitPanel, showWaitPanelPrimary: showCicoPrimaryProgress, waitPanelTitle: cicoWaitPanelTitle, waitPanelTextPrimary: cicoPrimaryProgressText, waitPanelValuePrimary: cicoPrimaryProgressValue, waitPanelMaxValuePrimary: cicoPrimaryProgressMax, isCancelable: true, abortController: abortControllerLocal, children: [(groupId && groupId.length > 0)
1516
1558
  ? _jsxs(_Fragment, { children: [_jsx(PanelDisabledStateHandler, { isWFDisabled: isWFDisabled, isSysMetadataDisabled: isSysMetadataDisabled, isBoardDisabled: isBoardDisabled, isDcmtTasksDisabled: isDcmtTasksDisabled, isPreviewDisabled: isPreviewDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showDcmtFormSidebar })] })
1517
- : _jsxs(TMPanelManagerWithPersistenceProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: defaultPanelDimensions, initialDimensions: defaultPanelDimensions, initialMobilePanelId: 'tmDcmtForm', isPersistenceEnabled: !isMobile ? hasSavedLayout() : false, persistPanelStates: !isMobile ? (state) => persistPanelStates(state) : undefined, persistedPanelStates: getPersistedPanelStates(), children: [_jsx(PanelDisabledStateHandler, { isWFDisabled: isWFDisabled, isSysMetadataDisabled: isSysMetadataDisabled, isBoardDisabled: isBoardDisabled, isDcmtTasksDisabled: isDcmtTasksDisabled, isPreviewDisabled: isPreviewDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showDcmtFormSidebar })] }), isOpenDistinctValues &&
1559
+ : _jsxs(TMPanelManagerWithPersistenceProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: defaultPanelDimensions, initialDimensions: defaultPanelDimensions, initialMobilePanelId: 'tmDcmtForm', isPersistenceEnabled: !isMobile && layoutMode !== LayoutModes.Ark ? hasSavedLayout() : false, persistPanelStates: !isMobile && layoutMode !== LayoutModes.Ark ? (state) => persistPanelStates(state) : undefined, persistedPanelStates: layoutMode !== LayoutModes.Ark ? getPersistedPanelStates() : undefined, children: [_jsx(PanelDisabledStateHandler, { isWFDisabled: isWFDisabled, isSysMetadataDisabled: isSysMetadataDisabled, isBoardDisabled: isBoardDisabled, isDcmtTasksDisabled: isDcmtTasksDisabled, isPreviewDisabled: isPreviewDisabled, persistedWFVisible: getPersistedWFVisible() }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showDcmtFormSidebar })] }), isOpenDistinctValues &&
1518
1560
  _jsx(TMDistinctValues, { tid: TID, mid: focusedMetadataValue?.mid, isModal: true, showHeader: false, layoutMode: layoutMode, onClosePanelCallback: () => setIsOpenDistinctValues(false), onSelectionChanged: (e) => {
1519
1561
  if (!e)
1520
1562
  return;
@@ -1604,7 +1646,7 @@ const validateMaxLength = (mvd, value, validationItems) => {
1604
1646
  };
1605
1647
  //#endregion Validation
1606
1648
  // Synchronizes panel visibility and toolbar button disabled states when panels become disabled
1607
- const PanelDisabledStateHandler = ({ isWFDisabled, isSysMetadataDisabled, isBoardDisabled, isDcmtTasksDisabled, isPreviewDisabled }) => {
1649
+ const PanelDisabledStateHandler = ({ isWFDisabled, isSysMetadataDisabled, isBoardDisabled, isDcmtTasksDisabled, isPreviewDisabled, persistedWFVisible = false }) => {
1608
1650
  const { setPanelVisibilityById, setToolbarButtonDisabled } = useTMPanelManagerContext();
1609
1651
  useEffect(() => {
1610
1652
  if (isSysMetadataDisabled) {
@@ -1631,8 +1673,12 @@ const PanelDisabledStateHandler = ({ isWFDisabled, isSysMetadataDisabled, isBoar
1631
1673
  }
1632
1674
  else {
1633
1675
  setToolbarButtonDisabled('tmWF', false);
1676
+ // Restore persisted visibility when WF becomes enabled
1677
+ if (persistedWFVisible) {
1678
+ setPanelVisibilityById('tmWF', true);
1679
+ }
1634
1680
  }
1635
- }, [isWFDisabled]);
1681
+ }, [isWFDisabled, persistedWFVisible]);
1636
1682
  useEffect(() => {
1637
1683
  if (isDcmtTasksDisabled) {
1638
1684
  setToolbarButtonDisabled('tmDcmtTasks', true);
@@ -82,7 +82,7 @@ const TMMergeToPdfForm = (props) => {
82
82
  pdfValidationItems.push(new ValidationItem(ResultTypes.ERROR, SDKUI_Localizator.PdfFileName, SDKUI_Localizator.RequiredField));
83
83
  }
84
84
  // ---- Statistiche selezione PDF / convertibili / non-PDF ----
85
- const { convertibleSelectedItems, hasConvertibleSelected, nonPdfSelectedItems, hasNonPdfSelected, metadataOnlySelectedItems, hasMetadataOnlySelected, mergeableSelectedCount, hasEnoughPdfForMerge, } = getMergePdfSelectionStats(selectedDcmtInfos, selectedItemsFull, selectedItemsRelationViewer, showTMRelationViewer);
85
+ const { convertibleSelectedItems, hasConvertibleSelected, nonPdfSelectedItems, hasNonPdfSelected, metadataOnlySelectedItems, hasMetadataOnlySelected, pdfSelectedItems, hasPdfSelected, mergeableSelectedCount, hasEnoughPdfForMerge, } = getMergePdfSelectionStats(selectedDcmtInfos, selectedItemsFull, selectedItemsRelationViewer, showTMRelationViewer);
86
86
  const isFormValid = () => pdfValidationItems.length === 0;
87
87
  // ---- Recupero dei file PDF da unire (condiviso tra Esegui e Anteprima) ----
88
88
  const collectPdfFilesToMerge = async () => {
@@ -285,7 +285,7 @@ const TMMergeToPdfForm = (props) => {
285
285
  width: 'max-content',
286
286
  backgroundColor: TMColors.default_background,
287
287
  zIndex: 1,
288
- }, children: SDKUI_Localizator.Path }), _jsxs("div", { style: { border: `1px solid ${TMColors.border_normal}`, borderRadius: '5px', padding: '4px 10px 4px 13px', display: 'flex', alignItems: 'center', gap: '8px', backgroundColor: '#fafafa' }, children: [_jsx(IconFolderOpen, {}), _jsx("span", { style: { fontSize: '0.9rem', color: '#333' }, children: "Download" })] }), _jsx("span", { style: { fontSize: '0.8rem', color: '#888', fontStyle: 'italic', marginTop: '4px', display: 'block' }, children: SDKUI_Localizator.BrowserDoesNotSupportFolderSelection })] }) })), _jsx("div", { style: { flex: '1.5 1 420px', minWidth: '350px', width: '100%' }, children: _jsx(TMTextBox, { label: SDKUI_Localizator.PdfFileName, value: pdfFileName, validationItems: pdfValidationItems, autoComplete: "one-time-code", onValueChanged: (e) => setPdfFileName(e.target.value) }) })] }), (hasConvertibleSelected || hasMetadataOnlySelected || !hasEnoughPdfForMerge || hasNonPdfSelected) && (_jsxs("div", { style: {
288
+ }, children: SDKUI_Localizator.Path }), _jsxs("div", { style: { border: `1px solid ${TMColors.border_normal}`, borderRadius: '5px', padding: '4px 10px 4px 13px', display: 'flex', alignItems: 'center', gap: '8px', backgroundColor: '#fafafa' }, children: [_jsx(IconFolderOpen, {}), _jsx("span", { style: { fontSize: '0.9rem', color: '#333' }, children: "Download" })] }), _jsx("span", { style: { fontSize: '0.8rem', color: '#888', fontStyle: 'italic', marginTop: '4px', display: 'block' }, children: SDKUI_Localizator.BrowserDoesNotSupportFolderSelection })] }) })), _jsx("div", { style: { flex: '1.5 1 420px', minWidth: '350px', width: '100%' }, children: _jsx(TMTextBox, { label: SDKUI_Localizator.PdfFileName, value: pdfFileName, validationItems: pdfValidationItems, autoComplete: "one-time-code", onValueChanged: (e) => setPdfFileName(e.target.value) }) })] }), (hasConvertibleSelected || hasMetadataOnlySelected || !hasEnoughPdfForMerge || hasNonPdfSelected || hasPdfSelected) && (_jsxs("div", { style: {
289
289
  display: 'flex',
290
290
  flexDirection: 'column',
291
291
  gap: '6px',
@@ -308,17 +308,25 @@ const TMMergeToPdfForm = (props) => {
308
308
  }, children: SDKUI_Localizator.NotesAndWarnings }), _jsxs("ul", { style: { margin: 0, paddingLeft: '18px', display: 'flex', flexDirection: 'column', gap: '4px' }, children: [(hasConvertibleSelected || hasMetadataOnlySelected) && (_jsx("li", { style: { color: '#00527a' }, children: (() => {
309
309
  // Combina convertibili + metadataOnly
310
310
  const allConvertible = [...convertibleSelectedItems, ...metadataOnlySelectedItems];
311
- const extSet = Array.from(new Set([
312
- ...convertibleSelectedItems.map(i => (i.ext ?? '').toString().trim().toLowerCase().replace(/^\./, '')).filter(e => e.length > 0),
313
- ...(hasMetadataOnlySelected ? ['metadati'] : [])
314
- ]));
315
- const extLabel = extSet.length > 0
316
- ? ` (${extSet.map(e => '.' + e).join(', ')})`
317
- : '';
318
- return allConvertible.length === 1
319
- ? SDKUI_Localizator.DocumentWillBeConvertedDuringMerge.replaceParams(extLabel)
320
- : SDKUI_Localizator.DocumentsWillBeConvertedDuringMerge.replaceParams(allConvertible.length.toString(), extLabel);
321
- })() })), !hasEnoughPdfForMerge && (_jsx("li", { style: { color: '#7a5d00' }, children: mergeableSelectedCount === 0
311
+ // Conta le occorrenze per ogni estensione
312
+ const extCounts = new Map();
313
+ convertibleSelectedItems.forEach(i => {
314
+ const ext = (i.ext ?? '').toString().trim().toLowerCase().replace(/^\./, '');
315
+ if (ext.length > 0) {
316
+ extCounts.set(ext, (extCounts.get(ext) || 0) + 1);
317
+ }
318
+ });
319
+ if (hasMetadataOnlySelected) {
320
+ extCounts.set('metadati', metadataOnlySelectedItems.length);
321
+ }
322
+ // Genera label per tooltip: "3 xml, 2 doc, 1 metadati"
323
+ const extLabel = Array.from(extCounts.entries()).map(([ext, count]) => `${count} ${ext}`).join(', ');
324
+ return (_jsxs("span", { style: { display: 'inline-flex', alignItems: 'center', gap: '6px' }, children: [_jsx("span", { children: allConvertible.length === 1
325
+ ? SDKUI_Localizator.DocumentWillBeConvertedDuringMerge
326
+ : SDKUI_Localizator.DocumentsWillBeConvertedDuringMerge.replaceParams(allConvertible.length.toString()) }), extLabel && (_jsx(TMTooltip, { content: _jsxs("div", { style: { minWidth: 180, padding: "10px 12px", borderRadius: 8 }, children: [_jsxs("div", { style: { textAlign: "center", fontWeight: 600, fontSize: 13, marginBottom: 10, paddingBottom: 8, borderBottom: "1px solid rgba(255,255,255,0.15)" }, children: [SDKUI_Localizator.ConversionDetails, " (", Array.from(extCounts.values()).reduce((a, b) => a + b, 0), ")"] }), _jsx("div", { style: { display: "flex", flexDirection: "column", gap: 4, maxHeight: 150, overflowY: "auto" }, children: Array.from(extCounts.entries()).sort((a, b) => a[0].localeCompare(b[0])).map(([ext, count]) => (_jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "4px 8px", background: "rgba(255,255,255,0.08)", borderRadius: 4 }, children: [_jsx("span", { style: { fontSize: 11, fontWeight: 500, textTransform: "uppercase" }, children: ext }), _jsx("span", { style: { display: "inline-flex", alignItems: "center", justifyContent: "center", minWidth: 24, height: 24, padding: "0 6px", background: "transparent", border: "2px solid #4caf50", borderRadius: 12, fontSize: 11, fontWeight: 600, lineHeight: 1 }, children: count > 99 ? '99+' : count })] }, ext))) })] }), children: _jsx("span", { style: { display: 'inline-flex', alignItems: 'center' }, children: _jsx("i", { className: "dx-icon-info", style: { fontSize: '16px', color: '#00527a' } }) }) }))] }));
327
+ })() })), hasPdfSelected && (_jsx("li", { style: { color: '#00527a' }, children: pdfSelectedItems.length === 1
328
+ ? SDKUI_Localizator.DocumentAlreadyInPdfNoConversionNeeded
329
+ : SDKUI_Localizator.DocumentsAlreadyInPdfNoConversionNeeded.replaceParams(pdfSelectedItems.length.toString()) })), !hasEnoughPdfForMerge && (_jsx("li", { style: { color: '#7a5d00' }, children: mergeableSelectedCount === 0
322
330
  ? SDKUI_Localizator.NoPdfOrConvertibleFilesSelected_Param.replaceParams(MIN_PDF_FOR_MERGE.toString())
323
331
  : SDKUI_Localizator.OnlyOnePdfOrConvertibleFileSelected.replaceParams(MIN_PDF_FOR_MERGE.toString()) })), hasNonPdfSelected && (_jsx("li", { style: { color: '#7a5d00' }, children: (() => {
324
332
  const extSet = Array.from(new Set(nonPdfSelectedItems.map(i => (i.ext ?? '').toString().trim().toLowerCase().replace(/^\./, '')).filter(e => e.length > 0)));
@@ -19,6 +19,10 @@ export interface IMergePdfSelectionStats {
19
19
  metadataOnlySelectedItems: Array<ISelectedItemInfo>;
20
20
  /** True se ci sono documenti di soli metadati selezionati */
21
21
  hasMetadataOnlySelected: boolean;
22
+ /** Elementi già in formato PDF (non richiedono conversione) */
23
+ pdfSelectedItems: Array<ISelectedItemInfo>;
24
+ /** True se ci sono elementi già in PDF selezionati */
25
+ hasPdfSelected: boolean;
22
26
  /** Numero totale di file unibili (PDF nativi + convertibili) */
23
27
  mergeableSelectedCount: number;
24
28
  /** True se ci sono abbastanza file per il merge (>= MIN_PDF_FOR_MERGE) */
@@ -65,6 +65,10 @@ export const getMergePdfSelectionStats = (selectedDcmtInfos, selectedItemsFull,
65
65
  const metadataOnlySelectedItems = docs
66
66
  .filter(i => i.isMetadataOnly)
67
67
  .map(i => ({ key: i.key, ext: i.ext }));
68
+ // Elementi già in formato PDF (non richiedono conversione)
69
+ const pdfSelectedItems = docs
70
+ .filter(i => i.isPdf && !i.isMetadataOnly)
71
+ .map(i => ({ key: i.key, ext: i.ext }));
68
72
  // Conteggio file unibili: PDF nativi + convertibili + documenti di soli metadati
69
73
  const mergeableSelectedCount = docs
70
74
  .filter(i => i.isPdf || i.isConvertible || i.isMetadataOnly).length;
@@ -75,6 +79,8 @@ export const getMergePdfSelectionStats = (selectedDcmtInfos, selectedItemsFull,
75
79
  hasNonPdfSelected: nonPdfSelectedItems.length > 0,
76
80
  metadataOnlySelectedItems,
77
81
  hasMetadataOnlySelected: metadataOnlySelectedItems.length > 0,
82
+ pdfSelectedItems,
83
+ hasPdfSelected: pdfSelectedItems.length > 0,
78
84
  mergeableSelectedCount,
79
85
  // Merge possibile se: >= 2 file unibili OPPURE >= 1 file convertibile/metadata-only (verrà trasformato in PDF)
80
86
  hasEnoughPdfForMerge: mergeableSelectedCount >= MIN_PDF_FOR_MERGE ||
@@ -38,6 +38,7 @@ export interface ITMLoginDefaultValues {
38
38
  username?: string;
39
39
  behalfUsername?: string;
40
40
  domain?: string;
41
+ cultureID?: CultureIDs;
41
42
  }
42
43
  interface ITMLoginFormProps {
43
44
  isConnector?: boolean;
@@ -225,6 +225,8 @@ const TMLoginForm = (props) => {
225
225
  setAuthDomain(props.defaultLoginValues.domain);
226
226
  if (props.defaultLoginValues.behalfUsername)
227
227
  setUsernameOnBehalf(props.defaultLoginValues.behalfUsername);
228
+ if (props.defaultLoginValues.cultureID)
229
+ props.onChangeLanguage?.(props.defaultLoginValues.cultureID);
228
230
  }, [props.defaultLoginValues, props.endpoints]);
229
231
  useEffect(() => {
230
232
  if (!hasSingleOption)
@@ -336,6 +338,12 @@ const TMLoginForm = (props) => {
336
338
  const disablePasswordOperations = useMemo(() => {
337
339
  return (username.length === 0 || !dcmtArchive || !endpoint);
338
340
  }, [username, dcmtArchive, endpoint]);
341
+ const loginKey = useMemo(() => {
342
+ const archivePart = dcmtArchive
343
+ ? (dcmtArchive.description?.replace(/ /g, '_') || dcmtArchive.id || '')
344
+ : (manualArchiveID ?? '');
345
+ return `${archivePart}:${username}`;
346
+ }, [dcmtArchive, manualArchiveID, username]);
339
347
  const showLoginBtn = useMemo(() => {
340
348
  if (loginStep === 1)
341
349
  return false;
@@ -714,7 +722,8 @@ const TMLoginForm = (props) => {
714
722
  marginBottom: windowHeight === WindowHeight.SMALL ? '30px' : '25px',
715
723
  width: '100%',
716
724
  minHeight: '15px'
717
- }, children: [_jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.Endpoint, children: _jsx(IconAccessPoint, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: endpoint?.Description ?? '', children: _jsx("p", { children: endpoint?.Description && endpoint.Description.length > 20 ? endpoint.Description.substring(0, 20) + '...' : endpoint?.Description }) })] }), _jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.ArchiveID, children: _jsx(IconArchiveDoc, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: dcmtArchive ? (dcmtArchive.description ?? '') : manualArchiveID, children: _jsx(StyledArchiveText, { children: dcmtArchive ? (dcmtArchive.description ?? '') : manualArchiveID }) })] })] }), _jsxs(StyledStepContainer, { "$windowHeight": windowHeight, "$deviceType": deviceType, children: [_jsx(SelectBox, { value: authMode, options: authModeOptions, onValueChanged: (value) => setAuthMode(value), validationItems: fieldValidations('authenticationMode'), icon: _jsx(IconLogin, {}), label: SDKUI_Localizator.AuthMode }), _jsxs(StyledCredentialWrapper, { children: [authMode === AuthenticationModes.WindowsThroughTopMedia && _jsx(TextBox, { ref: authDomainRef, value: authDomain, onValueChanged: (e) => setAuthDomain(e), validationItems: fieldValidations('authDomain'), type: "text", icon: _jsx(IconWeb, {}), label: SDKUI_Localizator.Domain }), authMode !== AuthenticationModes.MSAzure && _jsx(CeredentialContainer, { isMobile: isMobile, ref: usernameRef, secondaryRef: passwordRef, usernameValidator: fieldValidations('username'), passwordValidator: fieldValidations('password'), authMode: authMode, username: username, password: password, onUsernameChanged: (un) => setUsername(un), onPasswordChanged: (ps) => setPassword(ps) }), authMode === AuthenticationModes.TopMediaOnBehalfOf &&
725
+ }, children: [_jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.Endpoint, children: _jsx(IconAccessPoint, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: endpoint?.Description ?? '', children: _jsx("p", { children: endpoint?.Description && endpoint.Description.length > 20 ? endpoint.Description.substring(0, 20) + '...' : endpoint?.Description }) })] }), _jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.ArchiveID, children: _jsx(IconArchiveDoc, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: dcmtArchive ? (dcmtArchive.description ?? '') : manualArchiveID, children: _jsx(StyledArchiveText, { children: dcmtArchive ? (dcmtArchive.description ?? '') : manualArchiveID }) })] })] }), _jsxs(StyledStepContainer, { "$windowHeight": windowHeight, "$deviceType": deviceType, children: [_jsx(SelectBox, { value: authMode, options: authModeOptions, onValueChanged: (value) => setAuthMode(value), validationItems: fieldValidations('authenticationMode'), icon: _jsx(IconLogin, {}), label: SDKUI_Localizator.AuthMode }), _jsxs(StyledCredentialWrapper, { children: [authMode === AuthenticationModes.WindowsThroughTopMedia && _jsx(TextBox, { ref: authDomainRef, value: authDomain, onValueChanged: (e) => setAuthDomain(e), validationItems: fieldValidations('authDomain'), type: "text", icon: _jsx(IconWeb, {}), label: SDKUI_Localizator.Domain, autoComplete: "off" }), authMode !== AuthenticationModes.MSAzure &&
726
+ _jsxs("form", { onSubmit: (e) => e.preventDefault(), style: { width: '100%' }, children: [_jsx("input", { name: "login_key", autoComplete: "username", readOnly: true, tabIndex: -1, value: loginKey, style: { position: 'absolute', width: 1, height: 1, opacity: 0, overflow: 'hidden', border: 0, padding: 0 } }, loginKey), _jsx(CeredentialContainer, { isMobile: isMobile, ref: usernameRef, secondaryRef: passwordRef, usernameValidator: fieldValidations('username'), passwordValidator: fieldValidations('password'), authMode: authMode, username: username, password: password, onUsernameChanged: (un) => setUsername(un), onPasswordChanged: (ps) => setPassword(ps), usernameAutoComplete: "off", passwordAutoComplete: "current-password" })] }), authMode === AuthenticationModes.TopMediaOnBehalfOf &&
718
727
  _jsxs(StyledCredentialWrapper, { children: [_jsx(TextBox, { value: authDomain, ref: authDomainRef, onValueChanged: (e) => setAuthDomain(e), validationItems: fieldValidations('authDomain'), type: "text", icon: _jsx(IconWeb, {}), label: SDKUI_Localizator.Domain }), _jsx(CeredentialContainer, { isMobile: isMobile, ref: usernameOnBehalfOfRef, secondaryRef: passwordOnBehalfOfRRef, usernameValidator: fieldValidations('usernameOnBehalfOf'), passwordValidator: fieldValidations('passwordOnBehalfOf'), authMode: AuthenticationModes.TopMediaOnBehalfOf, username: usernameOnBehalf, password: passwordOnBehalf, onUsernameChanged: (un) => setUsernameOnBehalf(un), onPasswordChanged: (ps) => setPasswordOnBehalf(ps) })] })] }), authMode !== AuthenticationModes.TopMediaWithMFA &&
719
728
  _jsx(RapidAccessContainer, { isSaveEnable: saveLoginEnable, name: saveLoginName, nameValidationItems: fieldValidations('rapidAccessName'), onEnableSaveChange: () => setSaveLoginEnable(!saveLoginEnable), onNameChange: (name) => setSaveLoginName(name) })] })] }), loginStep === 3 &&
720
729
  _jsxs(StyledStepThreeContainer, { "$isMobile": isMobile, children: [_jsx(OTPReader, { isMobile: isMobile, digits: otpCode, onChange: handleDigitChange, onFullChange: handleFullChange, text: _jsxs("div", { children: [" ", LOGINLocalizator.EnterOtpInstructions, " "] }), header: '', additionalButtons: [
@@ -723,7 +732,7 @@ const TMLoginForm = (props) => {
723
732
  ] }), _jsx(StyledRapidAccessWrapper, { "$isMobile": isMobile, children: _jsx(RapidAccessContainer, { isSaveEnable: saveLoginEnable, name: saveLoginName, nameValidationItems: fieldValidations('rapidAccessName'), onEnableSaveChange: () => setSaveLoginEnable(!saveLoginEnable), onNameChange: (name) => setSaveLoginName(name) }) })] }), _jsxs(StyledButtonContainer, { "$windowHeight": windowHeight, children: [showContinueBtn && _jsx(TMButton, { fontSize: "1.2rem", onClick: nextStepHandler, showTooltip: false, caption: LOGINLocalizator.Continue, disabled: disableContinueBtn }), showLoginBtn && _jsx(TMButton, { fontSize: "1.2rem", showTooltip: false, onClick: loginHandler, caption: saveLoginEnable ? SDKUI_Localizator.SaveAndLogin : SDKUI_Localizator.Login, disabled: disableLoginBtn })] })] }), showPasswordOperations && _jsx(StyledForgetPassword, { "$isMobile": isMobile, children: _jsx(TMButton, { disabled: disablePasswordOperations, btnStyle: "text", caption: SDKUI_Localizator.ForgetPassword, showTooltip: false, onClick: () => setShowForgetPassword(true) }) }), showBackBtn && _jsx(StyledBackButton, { children: _jsx(TMButton, { onClick: previousStepHandler, btnStyle: "icon", icon: _jsx(IconArrowLeft, { fontSize: 20 }), caption: SDKUI_Localizator.Back }) }), showCultureIDs && _jsx(Menu, { onClose: () => setShowCultureIDs(false), x: 'calc(100% - 250px)', y: 50, visible: showCultureIDs, children: _jsxs(StyledMenuItemContainer, { children: [_jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.It_IT), title: cultureIDsDataSource[0].display, src: it, alt: "it", width: BANNER_DIMENSION, height: BANNER_DIMENSION }), _jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.En_US), title: cultureIDsDataSource[3].display, src: en, alt: "en", width: BANNER_DIMENSION, height: BANNER_DIMENSION }), _jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.Fr_FR), title: cultureIDsDataSource[1].display, src: fr, alt: "fr", width: BANNER_DIMENSION, height: BANNER_DIMENSION }), _jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.Es_ES), title: cultureIDsDataSource[4].display, src: es, alt: "es", width: BANNER_DIMENSION, height: BANNER_DIMENSION }), _jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.Pt_PT), title: cultureIDsDataSource[2].display, src: pt, alt: "pt", width: BANNER_DIMENSION, height: BANNER_DIMENSION }), _jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.De_DE), title: cultureIDsDataSource[5].display, src: de, alt: "de", width: BANNER_DIMENSION, height: BANNER_DIMENSION })] }) }), showChangePassword && _jsx(ChangePassword, { tmSession: changePswTmSession, onClose: () => setShowChangePassword(false) }), showForgetPassword && _jsx(RecoverPasswordFlow, { isMobile: isMobile, tmSession: changePswTmSession, onClose: () => setShowForgetPassword(false), windowHeight: windowHeight }), showRapidAccess && _jsx(RapidAccessLogin, { isMobile: isMobile, onClose: () => setShowRapidAccess(false), onSelect: handleRapidAccessSelection })] })] })] }));
724
733
  };
725
734
  export default TMLoginForm;
726
- const CeredentialContainer = forwardRef(({ isMobile = false, authMode = AuthenticationModes.TopMedia, password = '', username = '', onPasswordChanged, onUsernameChanged, passwordValidator = [], usernameValidator = [], secondaryRef }, ref) => {
735
+ const CeredentialContainer = forwardRef(({ isMobile = false, authMode = AuthenticationModes.TopMedia, password = '', username = '', onPasswordChanged, onUsernameChanged, passwordValidator = [], usernameValidator = [], secondaryRef, usernameAutoComplete = 'off', passwordAutoComplete = 'off' }, ref) => {
727
736
  const passwordRef = useRef(null);
728
737
  useImperativeHandle(ref, () => {
729
738
  return usernameRef.current;
@@ -749,7 +758,7 @@ const CeredentialContainer = forwardRef(({ isMobile = false, authMode = Authenti
749
758
  secondaryRef.current = passwordRef.current;
750
759
  }
751
760
  }, [secondaryRef]);
752
- return (_jsxs(StyledCredentialContainer, { "$isMobile": isMobile, "$authMode": authMode, children: [_jsx(TextBox, { ref: usernameRef, value: username, onValueChanged: (e) => onUsernameChanged(e), validationItems: usernameValidator, type: "text", icon: _jsx(IconUser, {}), label: SDKUI_Localizator.UserName }), _jsx(TextBox, { ref: passwordRef, value: password, onValueChanged: (e) => onPasswordChanged(e), validationItems: passwordValidator, type: "password", icon: authMode !== AuthenticationModes.TopMediaOnBehalfOf ? _jsx(IconPassword, {}) : undefined, label: SDKUI_Localizator.Password })] }));
761
+ return (_jsxs(StyledCredentialContainer, { "$isMobile": isMobile, "$authMode": authMode, children: [_jsx(TextBox, { ref: usernameRef, value: username, onValueChanged: (e) => onUsernameChanged(e), validationItems: usernameValidator, type: "text", icon: _jsx(IconUser, {}), label: SDKUI_Localizator.UserName, autoComplete: usernameAutoComplete }), _jsx(TextBox, { ref: passwordRef, value: password, onValueChanged: (e) => onPasswordChanged(e), validationItems: passwordValidator, type: "password", icon: authMode !== AuthenticationModes.TopMediaOnBehalfOf ? _jsx(IconPassword, {}) : undefined, label: SDKUI_Localizator.Password, autoComplete: passwordAutoComplete })] }));
753
762
  });
754
763
  const RapidAccessContainer = ({ isSaveEnable, name, nameValidationItems, onEnableSaveChange, onNameChange }) => {
755
764
  return (_jsxs(StyledRapidLoginSave, { children: [_jsx(TMCheckBox, { label: LOGINLocalizator.CreateNewQuickAccess, onValueChanged: () => onEnableSaveChange(), value: isSaveEnable, labelColor: "#313131" }), isSaveEnable && _jsx(TextBox, { validationItems: nameValidationItems, disabled: !isSaveEnable, type: "text", value: name, onValueChanged: (value) => onNameChange(value), placeHolder: "Es: Admin risorse umane" })] }));
@@ -19,6 +19,9 @@ interface TextBoxProps {
19
19
  readOnly?: boolean;
20
20
  cursor?: 'default' | 'pointer' | 'text';
21
21
  showSuccess?: boolean;
22
+ name?: string;
23
+ id?: string;
24
+ autoComplete?: string;
22
25
  onClick?: () => void;
23
26
  onValueChanged?: (value: string) => void;
24
27
  onKeyDown?: (event: React.KeyboardEvent) => void;
@@ -71,7 +71,7 @@ const IconButton = styled.div `
71
71
  align-items: center;
72
72
  cursor: ${props => !props.$disabled ? 'pointer' : 'default'};
73
73
  `;
74
- const TextBox = forwardRef(({ label, type, additionalIcons = [], cursor = 'text', disabled, icon, onClick, onKeyDown, onValueChanged, placeHolder, readOnly, showSuccess, validationItems = [], value }, ref) => {
74
+ const TextBox = forwardRef(({ label, type, additionalIcons = [], cursor = 'text', disabled, icon, onClick, onKeyDown, onValueChanged, placeHolder, readOnly, showSuccess, validationItems = [], value, name, id, autoComplete }, ref) => {
75
75
  const [showPassword, setShowPassword] = useState(false);
76
76
  const [isFocused, setIsFocused] = useState(false);
77
77
  const mainValidation = useMemo(() => {
@@ -106,6 +106,6 @@ const TextBox = forwardRef(({ label, type, additionalIcons = [], cursor = 'text'
106
106
  }
107
107
  return color;
108
108
  }, [mainValidation]);
109
- return (_jsxs(Container, { children: [label && _jsx(Label, { "$color": borderColor, children: label }), _jsxs(InputContainer, { "$borderColor": borderColor, "$borderThickness": borderThickness, "$focused": isFocused, "$disabled": disabled, children: [icon && _jsx(IconWrapper, { "$color": validationItems.length > 0 ? borderColor : TMColors.primary, children: icon }), _jsx(Input, { ref: ref, onKeyDown: onKeyDown, onClick: onClick, onFocus: () => setIsFocused(true), onBlur: () => setIsFocused(false), type: type === "password" && showPassword ? "text" : type, value: value, onChange: (e) => onValueChanged?.(e.target.value), placeholder: placeHolder, "$readOnly": readOnly, disabled: disabled, "$color": fontColor, "$cursor": !disabled ? cursor : 'default' }), _jsxs(IconsRow, { children: [additionalIcons.map((iconItem, index) => (iconItem.visible !== false && _jsx(TMTooltip, { content: iconItem.tooltip, children: _jsxs(IconButton, { "$disabled": disabled, "$color": iconItem.color ?? '#313131', onClick: iconItem.onClick, children: [" ", iconItem.icon, " "] }) }, index * 2))), type === "password" && (_jsx(IconButton, { "$disabled": disabled, "$color": '#313131', onClick: () => setShowPassword(!showPassword), children: showPassword ? _jsx(IconShow, {}) : _jsx(IconHide, {}) }))] })] }), _jsx(ValidationMessageContainer, { children: validationMessages.map((val, index) => (_jsx(ValidationMessage, { "$color": val.color, children: val.message }, index * 2))) })] }));
109
+ return (_jsxs(Container, { children: [label && _jsx(Label, { "$color": borderColor, children: label }), _jsxs(InputContainer, { "$borderColor": borderColor, "$borderThickness": borderThickness, "$focused": isFocused, "$disabled": disabled, children: [icon && _jsx(IconWrapper, { "$color": validationItems.length > 0 ? borderColor : TMColors.primary, children: icon }), _jsx(Input, { ref: ref, name: name, id: id, autoComplete: autoComplete, onKeyDown: onKeyDown, onClick: onClick, onFocus: () => setIsFocused(true), onBlur: () => setIsFocused(false), type: type === "password" && showPassword ? "text" : type, value: value, onChange: (e) => onValueChanged?.(e.target.value), placeholder: placeHolder, "$readOnly": readOnly, disabled: disabled, "$color": fontColor, "$cursor": !disabled ? cursor : 'default' }), _jsxs(IconsRow, { children: [additionalIcons.map((iconItem, index) => (iconItem.visible !== false && _jsx(TMTooltip, { content: iconItem.tooltip, children: _jsxs(IconButton, { "$disabled": disabled, "$color": iconItem.color ?? '#313131', onClick: iconItem.onClick, children: [" ", iconItem.icon, " "] }) }, index * 2))), type === "password" && (_jsx(IconButton, { "$disabled": disabled, "$color": '#313131', onClick: () => setShowPassword(!showPassword), children: showPassword ? _jsx(IconShow, {}) : _jsx(IconHide, {}) }))] })] }), _jsx(ValidationMessageContainer, { children: validationMessages.map((val, index) => (_jsx(ValidationMessage, { "$color": val.color, children: val.message }, index * 2))) })] }));
110
110
  });
111
111
  export default TextBox;
@@ -986,7 +986,7 @@ const TMQdWhereItemValue = ({ whereItem, index, queryParamsDynDataList, onlyEdit
986
986
  _jsxs(StyledDivHorizontal, { children: [(editingMode == EditingModes.Chooser) &&
987
987
  _jsxs(_Fragment, { children: [showDataListChooseForm && !isEditableList &&
988
988
  _jsx(TMDataListItemChooserForm, { height: '500px', width: '450px', allowMultipleSelection: whereItem.operator == QueryOperators.In || whereItem.operator == QueryOperators.NotIn, dataListId: md?.dataListID, selectedIDs: whereItem.value1?.split(',').map((item) => !item.startsWith("'") ? item : item.slice(1, -1)) ?? [], onClose: () => setShowDataListChooseForm(false), onChoose: (IDs) => { IDs && normalizeValue(IDs.length == 1 ? IDs[0] : IDs.map((item) => `${item}`).join(","), true); } }), showDynDataListChooseForm && !isEditableList &&
989
- _jsx(TMDynDataListItemChooserForm, { TID: whereItem.tid, MID: md?.id, height: '500px', width: '450px', dynDL: dynDl, allowMultipleSelection: whereItem.operator == QueryOperators.In || whereItem.operator == QueryOperators.NotIn, searchResult: dataSource, selectedIDs: [whereItem.value1], onClose: () => setShowDynDataListChooseForm(false), onChoose: (IDs) => {
989
+ _jsx(TMDynDataListItemChooserForm, { TID: whereItem.tid, MID: md?.id, height: '500px', width: '450px', dynDL: dynDl, allowMultipleSelection: whereItem.operator == QueryOperators.In || whereItem.operator == QueryOperators.NotIn, searchResult: dataSource, selectedIDs: [whereItem.value1], queryParamsDynDataList: queryParamsDynDataList, onClose: () => setShowDynDataListChooseForm(false), onChoose: (IDs) => {
990
990
  IDs && normalizeValue(IDs.length == 1 ? IDs[0] : IDs.map((item) => `${item}`).join(","), true);
991
991
  if (!dynDl)
992
992
  return;
@@ -226,6 +226,9 @@ export declare class SDKUI_Localizator {
226
226
  static get DocumentTypeNameAndCustomMetadata(): string;
227
227
  static get DocumentWillBeConvertedDuringMerge(): string;
228
228
  static get DocumentsWillBeConvertedDuringMerge(): string;
229
+ static get DocumentAlreadyInPdfNoConversionNeeded(): string;
230
+ static get DocumentsAlreadyInPdfNoConversionNeeded(): string;
231
+ static get ConversionDetails(): string;
229
232
  static get Domain(): "Domäne" | "Domain" | "Dominio" | "Domaine";
230
233
  static get DoNotCopy(): string;
231
234
  static get Dossier(): "Übung" | "Dossier" | "Expediente" | "Pratique" | "Prática" | "Pratica";
@@ -2191,22 +2191,52 @@ export class SDKUI_Localizator {
2191
2191
  }
2192
2192
  static get DocumentWillBeConvertedDuringMerge() {
2193
2193
  switch (this._cultureID) {
2194
- case CultureIDs.De_DE: return "Ein Dokument{{0}} wird während der Zusammenführung in PDF konvertiert";
2195
- case CultureIDs.En_US: return "One document{{0}} will be converted to PDF during the merge";
2196
- case CultureIDs.Es_ES: return "Un documento{{0}} se convertirá a PDF durante la unión";
2197
- case CultureIDs.Fr_FR: return "Un document{{0}} sera converti en PDF lors de la fusion";
2198
- case CultureIDs.Pt_PT: return "Um documento{{0}} será convertido em PDF durante a fusão";
2199
- default: return "Un documento{{0}} verrà convertito in PDF durante l'unione";
2194
+ case CultureIDs.De_DE: return "Ein Dokument wird während der Zusammenführung in PDF konvertiert";
2195
+ case CultureIDs.En_US: return "One document will be converted to PDF during the merge";
2196
+ case CultureIDs.Es_ES: return "Un documento se convertirá a PDF durante la unión";
2197
+ case CultureIDs.Fr_FR: return "Un document sera converti en PDF lors de la fusion";
2198
+ case CultureIDs.Pt_PT: return "Um documento será convertido em PDF durante a fusão";
2199
+ default: return "Un documento verrà convertito in PDF durante l'unione";
2200
2200
  }
2201
2201
  }
2202
2202
  static get DocumentsWillBeConvertedDuringMerge() {
2203
2203
  switch (this._cultureID) {
2204
- case CultureIDs.De_DE: return "{{0}} Dokumente{{1}} werden während der Zusammenführung in PDF konvertiert";
2205
- case CultureIDs.En_US: return "{{0}} documents{{1}} will be converted to PDF during the merge";
2206
- case CultureIDs.Es_ES: return "{{0}} documentos{{1}} se convertirán a PDF durante la unión";
2207
- case CultureIDs.Fr_FR: return "{{0}} documents{{1}} seront convertis en PDF lors de la fusion";
2208
- case CultureIDs.Pt_PT: return "{{0}} documentos{{1}} serão convertidos em PDF durante a fusão";
2209
- default: return "{{0}} documenti{{1}} verranno convertiti in PDF durante l'unione";
2204
+ case CultureIDs.De_DE: return "{{0}} Dokumente werden während der Zusammenführung in PDF konvertiert";
2205
+ case CultureIDs.En_US: return "{{0}} documents will be converted to PDF during the merge";
2206
+ case CultureIDs.Es_ES: return "{{0}} documentos se convertirán a PDF durante la unión";
2207
+ case CultureIDs.Fr_FR: return "{{0}} documents seront convertis en PDF lors de la fusion";
2208
+ case CultureIDs.Pt_PT: return "{{0}} documentos serão convertidos em PDF durante a fusão";
2209
+ default: return "{{0}} documenti verranno convertiti in PDF durante l'unione";
2210
+ }
2211
+ }
2212
+ static get DocumentAlreadyInPdfNoConversionNeeded() {
2213
+ switch (this._cultureID) {
2214
+ case CultureIDs.De_DE: return "Ein Dokument ist bereits im PDF-Format und erfordert keine Konvertierung";
2215
+ case CultureIDs.En_US: return "One document is already in PDF format and does not require conversion";
2216
+ case CultureIDs.Es_ES: return "Un documento ya está en formato PDF y no requiere conversión";
2217
+ case CultureIDs.Fr_FR: return "Un document est déjà au format PDF et ne nécessite pas de conversion";
2218
+ case CultureIDs.Pt_PT: return "Um documento já está em formato PDF e não requer conversão";
2219
+ default: return "Un documento è già in formato PDF e non richiede conversione";
2220
+ }
2221
+ }
2222
+ static get DocumentsAlreadyInPdfNoConversionNeeded() {
2223
+ switch (this._cultureID) {
2224
+ case CultureIDs.De_DE: return "{{0}} Dokumente sind bereits im PDF-Format und erfordern keine Konvertierung";
2225
+ case CultureIDs.En_US: return "{{0}} documents are already in PDF format and do not require conversion";
2226
+ case CultureIDs.Es_ES: return "{{0}} documentos ya están en formato PDF y no requieren conversión";
2227
+ case CultureIDs.Fr_FR: return "{{0}} documents sont déjà au format PDF et ne nécessitent pas de conversion";
2228
+ case CultureIDs.Pt_PT: return "{{0}} documentos já estão em formato PDF e não requerem conversão";
2229
+ default: return "{{0}} documenti sono già in formato PDF e non richiedono conversione";
2230
+ }
2231
+ }
2232
+ static get ConversionDetails() {
2233
+ switch (this._cultureID) {
2234
+ case CultureIDs.De_DE: return "Konvertierungsdetails";
2235
+ case CultureIDs.En_US: return "Conversion details";
2236
+ case CultureIDs.Es_ES: return "Detalles de conversión";
2237
+ case CultureIDs.Fr_FR: return "Détails de conversion";
2238
+ case CultureIDs.Pt_PT: return "Detalhes da conversão";
2239
+ default: return "Dettaglio conversioni";
2210
2240
  }
2211
2241
  }
2212
2242
  static get Domain() {
@@ -912,7 +912,7 @@ export const useDocumentOperations = (props) => {
912
912
  name: SDKUI_Localizator.ArchiveDetailDocument,
913
913
  operationType: 'multiRow',
914
914
  disabled: canArchiveDetailRelation !== true,
915
- onClick: async () => await archiveDetailDocuments?.(selectedDcmtInfos?.[0]?.TID)
915
+ onClick: async () => await archiveDetailDocuments(selectedDcmtInfos?.[0]?.TID)
916
916
  },
917
917
  {
918
918
  id: 'rel-mst',
@@ -3,13 +3,24 @@ const usePreventFileDrop = (allowedDropZones) => {
3
3
  useEffect(() => {
4
4
  const isOverAllowedZone = (event) => allowedDropZones.some((ref) => ref.current?.contains(event.target));
5
5
  const handleDragOver = (event) => {
6
- if (!isOverAllowedZone(event)) {
6
+ if (isOverAllowedZone(event)) {
7
+ // Riafferma "copy" ad ogni dragover: altrimenti un "none"
8
+ // impostato mentre si era fuori zona resta e mostra "not-allowed"
9
+ if (event.dataTransfer)
10
+ event.dataTransfer.dropEffect = "copy";
11
+ document.body.style.cursor = "default";
12
+ }
13
+ else {
7
14
  event.preventDefault();
8
- event.dataTransfer.dropEffect = "none";
15
+ if (event.dataTransfer)
16
+ event.dataTransfer.dropEffect = "none";
9
17
  }
10
18
  };
11
19
  const handleDragEnter = (event) => {
12
- if (!isOverAllowedZone(event)) {
20
+ if (isOverAllowedZone(event)) {
21
+ document.body.style.cursor = "default";
22
+ }
23
+ else {
13
24
  document.body.style.cursor = "not-allowed";
14
25
  }
15
26
  };
package/package.json CHANGED
@@ -1,63 +1,63 @@
1
1
  {
2
- "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.22.0-dev1.2",
4
- "description": "",
5
- "scripts": {
6
- "test": "echo \"Error: no test specified\" \u0026\u0026 exit 1",
7
- "clean": "node -e \"const fs=require(\u0027fs\u0027);fs.rmSync(\u0027lib\u0027,{recursive:true,force:true});fs.mkdirSync(\u0027lib\u0027)\"",
8
- "copy-files": "cpx \"src/{assets/*.*,assets/ImageLibrary/*.*,assets/thumbnails/*.*,assets/IconsS4t/*.*,assets/Metadata/*.*,css/tm-sdkui.css}\" lib",
9
- "tm-build": "npm run clean \u0026\u0026 tsc \u0026\u0026 npm run copy-files",
10
- "tm-watch": "tsc -w",
11
- "tm-publish": "npm publish --tag latest",
12
- "tm-publish_wl": "npm publish",
13
- "storybook": "storybook dev -p 6006",
14
- "build-storybook": "storybook build"
15
- },
16
- "author": "TopConsult",
17
- "license": "ISC",
18
- "devDependencies": {
19
- "@chromatic-com/storybook": "^5.1.2",
20
- "@storybook/addon-docs": "^10.3.5",
21
- "@storybook/addon-onboarding": "^10.3.5",
22
- "@storybook/react-vite": "^10.3.5",
23
- "@types/node": "^24.12.2",
24
- "@types/react": "^18.3.3",
25
- "@types/react-dom": "^18.3.3",
26
- "cpx2": "^9.0.0",
27
- "esbuild": "^0.25.0",
28
- "react": "^18.3.1",
29
- "react-dom": "^18.3.1",
30
- "storybook": "^10.3.5",
31
- "typescript": "^5.9.3",
32
- "vite": "^6.1.1"
33
- },
34
- "main": "dist/cjs/index.js",
35
- "types": "./index.d.ts",
36
- "module": "lib/esm/index.js",
37
- "files": [
38
- "dist",
39
- "lib"
40
- ],
41
- "dependencies": {
42
- "react-pdf": "^10.4.1",
43
- "@zip.js/zip.js": "2.8.26",
44
- "pdf-lib": "^1.17.1",
45
- "devextreme-exceljs-fork": "^4.4.10",
46
- "buffer": "^6.0.3",
47
- "@topconsultnpm/sdk-ts": "6.21.0",
48
- "react-window": "^2.2.7",
49
- "devextreme": "^25.2.6",
50
- "htmlparser2": "^10.0.0",
51
- "styled-components": "^6.1.1",
52
- "devextreme-react": "^25.2.6"
53
- },
54
- "overrides": {
55
- "esbuild": "^0.25.0",
56
- "devextreme-exceljs-fork": {
57
- "archiver": "^8.0.0"
58
- },
59
- "quill-delta": {
60
- "lodash.isequal": "npm:fast-deep-equal@^3.1.3"
61
- }
62
- }
2
+ "name": "@topconsultnpm/sdkui-react",
3
+ "version": "6.22.0-dev1.20",
4
+ "description": "",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1",
7
+ "clean": "node -e \"const fs=require('fs');fs.rmSync('lib',{recursive:true,force:true});fs.mkdirSync('lib')\"",
8
+ "copy-files": "cpx \"src/{assets/*.*,assets/ImageLibrary/*.*,assets/thumbnails/*.*,assets/IconsS4t/*.*,assets/Metadata/*.*,css/tm-sdkui.css}\" lib",
9
+ "tm-build": "npm run clean && tsc && npm run copy-files",
10
+ "tm-watch": "tsc -w",
11
+ "tm-publish": "npm publish --tag latest",
12
+ "tm-publish_wl": "npm publish",
13
+ "storybook": "storybook dev -p 6006",
14
+ "build-storybook": "storybook build"
15
+ },
16
+ "author": "TopConsult",
17
+ "license": "ISC",
18
+ "devDependencies": {
19
+ "@chromatic-com/storybook": "^5.1.2",
20
+ "@storybook/addon-docs": "^10.3.5",
21
+ "@storybook/addon-onboarding": "^10.3.5",
22
+ "@storybook/react-vite": "^10.3.5",
23
+ "@types/node": "^24.12.2",
24
+ "@types/react": "^18.3.3",
25
+ "@types/react-dom": "^18.3.3",
26
+ "cpx2": "^9.0.0",
27
+ "esbuild": "^0.25.0",
28
+ "react": "^18.3.1",
29
+ "react-dom": "^18.3.1",
30
+ "storybook": "^10.3.5",
31
+ "typescript": "^5.9.3",
32
+ "vite": "^6.1.1"
33
+ },
34
+ "main": "dist/cjs/index.js",
35
+ "types": "./index.d.ts",
36
+ "module": "lib/esm/index.js",
37
+ "files": [
38
+ "dist",
39
+ "lib"
40
+ ],
41
+ "dependencies": {
42
+ "@topconsultnpm/sdk-ts": "6.22.0-dev1.8",
43
+ "@zip.js/zip.js": "2.8.26",
44
+ "buffer": "^6.0.3",
45
+ "devextreme": "^25.2.6",
46
+ "devextreme-exceljs-fork": "^4.4.10",
47
+ "devextreme-react": "^25.2.6",
48
+ "htmlparser2": "^10.0.0",
49
+ "pdf-lib": "^1.17.1",
50
+ "react-pdf": "^10.4.1",
51
+ "react-window": "^2.2.7",
52
+ "styled-components": "^6.1.1"
53
+ },
54
+ "overrides": {
55
+ "esbuild": "^0.25.0",
56
+ "devextreme-exceljs-fork": {
57
+ "archiver": "^8.0.0"
58
+ },
59
+ "quill-delta": {
60
+ "lodash.isequal": "npm:fast-deep-equal@^3.1.3"
61
+ }
62
+ }
63
63
  }