@topconsultnpm/sdkui-react 6.22.0-t1 → 6.22.0-t2

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 (159) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +1 -1
  2. package/lib/components/NewComponents/ContextMenu/styles.d.ts +45 -43
  3. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +1 -1
  4. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +67 -60
  5. package/lib/components/base/Styled.d.ts +92 -76
  6. package/lib/components/base/TMButton.d.ts +13 -0
  7. package/lib/components/base/TMButton.js +137 -5
  8. package/lib/components/base/TMDataGrid.d.ts +2 -0
  9. package/lib/components/base/TMDataGrid.js +260 -8
  10. package/lib/components/base/TMDataGridExportForm.js +39 -30
  11. package/lib/components/base/TMEditorBase.d.ts +2 -0
  12. package/lib/components/base/TMFileManager.js +5 -3
  13. package/lib/components/base/TMFileManagerDataGridView.js +11 -2
  14. package/lib/components/base/TMFileManagerThumbnailItems.js +19 -9
  15. package/lib/components/base/TMFileManagerUtils.d.ts +6 -6
  16. package/lib/components/base/TMFileManagerUtils.js +37 -1
  17. package/lib/components/base/TMModal.d.ts +11 -0
  18. package/lib/components/base/TMModal.js +47 -13
  19. package/lib/components/base/TMPanel.d.ts +6 -0
  20. package/lib/components/base/TMPanel.js +138 -25
  21. package/lib/components/base/TMPopUp.js +3 -0
  22. package/lib/components/base/TMTooltip.d.ts +2 -1
  23. package/lib/components/base/TMTooltip.js +24 -8
  24. package/lib/components/base/TMTreeView.d.ts +13 -7
  25. package/lib/components/base/TMTreeView.js +108 -67
  26. package/lib/components/choosers/TMDcmtTypeChooser.js +4 -3
  27. package/lib/components/choosers/TMDistinctValues.d.ts +9 -7
  28. package/lib/components/choosers/TMDistinctValues.js +149 -142
  29. package/lib/components/choosers/TMMetadataChooser.js +1 -1
  30. package/lib/components/choosers/TMQuickSearchInfo.d.ts +13 -0
  31. package/lib/components/choosers/TMQuickSearchInfo.js +279 -0
  32. package/lib/components/choosers/TMQuickSearchSettingsForm.d.ts +16 -0
  33. package/lib/components/choosers/TMQuickSearchSettingsForm.js +94 -0
  34. package/lib/components/choosers/TMSelectedValuesSummary.d.ts +13 -0
  35. package/lib/components/choosers/TMSelectedValuesSummary.js +91 -0
  36. package/lib/components/editors/TMDateBox.d.ts +16 -1
  37. package/lib/components/editors/TMDateBox.js +90 -22
  38. package/lib/components/editors/TMDropDown.d.ts +3 -0
  39. package/lib/components/editors/TMDropDown.js +197 -5
  40. package/lib/components/editors/TMEditorStyled.d.ts +20 -42
  41. package/lib/components/editors/TMMetadataEditor.d.ts +5 -1
  42. package/lib/components/editors/TMMetadataEditor.js +27 -23
  43. package/lib/components/editors/TMTextArea.d.ts +1 -0
  44. package/lib/components/editors/TMTextArea.js +23 -15
  45. package/lib/components/editors/TMTextBox.d.ts +2 -0
  46. package/lib/components/editors/TMTextBox.js +30 -19
  47. package/lib/components/features/archive/TMArchive.js +17 -3
  48. package/lib/components/features/documents/TMBatchUpdateForm.js +19 -5
  49. package/lib/components/features/documents/TMDcmtBlog.d.ts +3 -0
  50. package/lib/components/features/documents/TMDcmtBlog.js +4 -4
  51. package/lib/components/features/documents/TMDcmtForm.d.ts +7 -0
  52. package/lib/components/features/documents/TMDcmtForm.js +232 -53
  53. package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +11 -0
  54. package/lib/components/features/documents/TMDcmtFormActionButtons.js +77 -7
  55. package/lib/components/features/documents/TMDcmtIcon.js +5 -3
  56. package/lib/components/features/documents/TMDcmtPreview.d.ts +7 -5
  57. package/lib/components/features/documents/TMDcmtPreview.js +10 -6
  58. package/lib/components/features/documents/TMMasterDetailDcmts.js +95 -33
  59. package/lib/components/features/documents/TMMasterInfoFields.d.ts +20 -0
  60. package/lib/components/features/documents/TMMasterInfoFields.js +186 -0
  61. package/lib/components/features/documents/TMMergeToPdfForm.d.ts +1 -2
  62. package/lib/components/features/documents/TMMergeToPdfForm.js +30 -5
  63. package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.d.ts +46 -0
  64. package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.js +323 -0
  65. package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.d.ts +370 -0
  66. package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.js +283 -0
  67. package/lib/components/features/documents/TMRelationViewer.d.ts +14 -1
  68. package/lib/components/features/documents/TMRelationViewer.js +82 -52
  69. package/lib/components/features/search/TMSearch.js +103 -24
  70. package/lib/components/features/search/TMSearchQueryEditor.js +5 -3
  71. package/lib/components/features/search/TMSearchQueryPanel.d.ts +14 -4
  72. package/lib/components/features/search/TMSearchQueryPanel.js +152 -57
  73. package/lib/components/features/search/TMSearchResult.d.ts +16 -0
  74. package/lib/components/features/search/TMSearchResult.js +438 -145
  75. package/lib/components/features/search/TMTreeSelector.js +109 -64
  76. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +10 -0
  77. package/lib/components/features/workflow/TMWorkflowPopup.js +8 -4
  78. package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.d.ts +3 -1
  79. package/lib/components/forms/Login/ChangePasswordInputs.d.ts +3 -1
  80. package/lib/components/grids/TMBlogAttachments.js +13 -2
  81. package/lib/components/grids/TMBlogHeader.js +5 -1
  82. package/lib/components/grids/TMBlogsPost.d.ts +2 -0
  83. package/lib/components/grids/TMBlogsPost.js +31 -4
  84. package/lib/components/grids/TMBlogsPostUtils.d.ts +1 -0
  85. package/lib/components/grids/TMBlogsPostUtils.js +14 -3
  86. package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -0
  87. package/lib/components/layout/panelManager/TMPanelManagerContainer.js +24 -14
  88. package/lib/components/layout/panelManager/TMPanelManagerContext.js +68 -93
  89. package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +4 -5
  90. package/lib/components/layout/panelManager/TMPanelWrapper.js +2 -2
  91. package/lib/components/layout/panelManager/types.d.ts +3 -0
  92. package/lib/components/layout/panelManager/utils.js +13 -11
  93. package/lib/components/query/TMQueryEditor.d.ts +14 -10
  94. package/lib/components/sidebar/TMCommandsPanel.d.ts +4 -4
  95. package/lib/components/sidebar/TMHeader.js +30 -20
  96. package/lib/components/viewers/TMMidViewer.js +5 -2
  97. package/lib/components/viewers/TMTidViewer.js +86 -25
  98. package/lib/css/tm-sdkui.css +1 -1
  99. package/lib/devextreme-license.d.ts +1 -0
  100. package/lib/devextreme-license.js +3 -0
  101. package/lib/helper/Globalization.d.ts +1 -1
  102. package/lib/helper/SDKUI_Globals.d.ts +110 -0
  103. package/lib/helper/SDKUI_Globals.js +151 -0
  104. package/lib/helper/SDKUI_Localizator.d.ts +55 -0
  105. package/lib/helper/SDKUI_Localizator.js +550 -0
  106. package/lib/helper/TMAppUpdatedModal.d.ts +2 -0
  107. package/lib/helper/TMAppUpdatedModal.js +134 -0
  108. package/lib/helper/TMIcons.d.ts +1 -0
  109. package/lib/helper/TMIcons.js +3 -0
  110. package/lib/helper/TMUtils.d.ts +51 -4
  111. package/lib/helper/TMUtils.js +272 -11
  112. package/lib/helper/dataGridSearchHelper.d.ts +28 -0
  113. package/lib/helper/dataGridSearchHelper.js +51 -0
  114. package/lib/helper/dcmtsHelper.d.ts +20 -0
  115. package/lib/helper/dcmtsHelper.js +58 -1
  116. package/lib/helper/helpers.d.ts +23 -1
  117. package/lib/helper/helpers.js +57 -1
  118. package/lib/helper/index.d.ts +2 -0
  119. package/lib/helper/index.js +2 -0
  120. package/lib/helper/queryHelper.d.ts +6 -1
  121. package/lib/helper/queryHelper.js +8 -3
  122. package/lib/hooks/tmDistinctValuesGridHelper.d.ts +16 -0
  123. package/lib/hooks/tmDistinctValuesGridHelper.js +31 -0
  124. package/lib/hooks/useArchiveListForm.d.ts +39 -0
  125. package/lib/hooks/useArchiveListForm.js +46 -0
  126. package/lib/hooks/useCaseFlowApprove.d.ts +56 -0
  127. package/lib/hooks/useCaseFlowApprove.js +157 -0
  128. package/lib/hooks/useDataUserIdItem.d.ts +1 -0
  129. package/lib/hooks/useDataUserIdItem.js +1 -0
  130. package/lib/hooks/useDocumentOperations.d.ts +4 -0
  131. package/lib/hooks/useDocumentOperations.js +52 -10
  132. package/lib/hooks/useMultiMasterDetailDcmts.d.ts +113 -0
  133. package/lib/hooks/useMultiMasterDetailDcmts.js +760 -0
  134. package/lib/hooks/useRelatedDocuments.d.ts +1 -0
  135. package/lib/hooks/useRelatedDocuments.js +22 -27
  136. package/lib/hooks/useShowDossiersV5.d.ts +12 -0
  137. package/lib/hooks/useShowDossiersV5.js +37 -0
  138. package/lib/hooks/useTMDistinctValuesMetadataDisplay.d.ts +18 -0
  139. package/lib/hooks/useTMDistinctValuesMetadataDisplay.js +103 -0
  140. package/lib/hooks/useTMDistinctValuesQuickSearch.d.ts +49 -0
  141. package/lib/hooks/useTMDistinctValuesQuickSearch.js +307 -0
  142. package/lib/hooks/useTMDistinctValuesSelection.d.ts +42 -0
  143. package/lib/hooks/useTMDistinctValuesSelection.js +103 -0
  144. package/lib/hooks/useTMDistinctValuesSource.d.ts +29 -0
  145. package/lib/hooks/useTMDistinctValuesSource.js +105 -0
  146. package/lib/index.d.ts +2 -0
  147. package/lib/index.js +5 -2
  148. package/lib/services/caseflow/CaseFlowService.d.ts +236 -0
  149. package/lib/services/caseflow/CaseFlowService.js +693 -0
  150. package/lib/services/caseflow/CaseFlowTemplateCacheService.d.ts +28 -0
  151. package/lib/services/caseflow/CaseFlowTemplateCacheService.js +121 -0
  152. package/lib/services/caseflow/caseFlowNameCache.d.ts +32 -0
  153. package/lib/services/caseflow/caseFlowNameCache.js +116 -0
  154. package/lib/services/caseflow/caseFlowWorkItemUtils.d.ts +61 -0
  155. package/lib/services/caseflow/caseFlowWorkItemUtils.js +113 -0
  156. package/lib/services/index.d.ts +4 -0
  157. package/lib/services/index.js +4 -0
  158. package/lib/services/platform_services.d.ts +1 -1
  159. package/package.json +9 -5
@@ -2,22 +2,14 @@ import { ValidationItem } from '@topconsultnpm/sdk-ts';
2
2
  export declare const TMEditorsDefaultBorderRadius = "5px";
3
3
  export declare const TMEditorsDefaultLabelFontSize = "0.9rem";
4
4
  export declare const editorColorManager: (validationItems: ValidationItem[]) => string;
5
- export declare const StyledEditorContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$width"> & {
5
+ export declare const StyledEditorContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Merged<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
6
+ style?: import("react").CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
7
+ }, {
6
8
  $width: string;
7
- }, never> & Partial<Pick<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$width"> & {
8
- $width: string;
9
- }, never>>> & string;
10
- export declare const StyledEditor: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "$width" | "$borderRadius" | "$fontSize" | "$type" | "$disabled" | "$vil" | "$isModified" | "$maxValue" | "$isMobile"> & {
11
- $vil: ValidationItem[];
12
- $width: string;
13
- $type: string;
14
- $isModified: boolean;
15
- $maxValue: number;
16
- $fontSize: string;
17
- $disabled: boolean;
18
- $isMobile?: boolean;
19
- $borderRadius?: string;
20
- }, never> & Partial<Pick<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "$width" | "$borderRadius" | "$fontSize" | "$type" | "$disabled" | "$vil" | "$isModified" | "$maxValue" | "$isMobile"> & {
9
+ }>> & string;
10
+ export declare const StyledEditor: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Merged<Omit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "style"> & {
11
+ style?: import("react").CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
12
+ }, {
21
13
  $vil: ValidationItem[];
22
14
  $width: string;
23
15
  $type: string;
@@ -27,40 +19,26 @@ export declare const StyledEditor: import("styled-components/dist/types").IStyle
27
19
  $disabled: boolean;
28
20
  $isMobile?: boolean;
29
21
  $borderRadius?: string;
30
- }, never>>> & string;
31
- export declare const StyledEditorIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$disabled" | "$vil" | "$isModified"> & {
22
+ }>> & string;
23
+ export declare const StyledEditorIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Merged<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
24
+ style?: import("react").CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
25
+ }, {
32
26
  $vil: ValidationItem[];
33
27
  $disabled: boolean;
34
28
  $isModified: boolean;
35
- }, never> & Partial<Pick<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$disabled" | "$vil" | "$isModified"> & {
36
- $vil: ValidationItem[];
37
- $disabled: boolean;
38
- $isModified: boolean;
39
- }, never>>> & string;
40
- export declare const StyledEditorLabel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$color" | "$fontSize" | "$disabled" | "$isFocused" | "$labelPosition"> & {
29
+ }>> & string;
30
+ export declare const StyledEditorLabel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Merged<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
31
+ style?: import("react").CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
32
+ }, {
41
33
  $isFocused: boolean;
42
34
  $labelPosition: "right" | "left" | "top";
43
35
  $disabled: boolean;
44
36
  $fontSize?: string;
45
37
  $color?: string;
46
- }, never> & Partial<Pick<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$color" | "$fontSize" | "$disabled" | "$isFocused" | "$labelPosition"> & {
47
- $isFocused: boolean;
48
- $labelPosition: "right" | "left" | "top";
49
- $disabled: boolean;
50
- $fontSize?: string;
51
- $color?: string;
52
- }, never>>> & string;
53
- export declare const StyledTextareaEditor: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, "$width" | "$maxHeight" | "$borderRadius" | "$fontSize" | "$disabled" | "$vil" | "$isModified" | "$isMobile" | "$resize"> & {
54
- $vil: ValidationItem[];
55
- $width: string;
56
- $isModified: boolean;
57
- $fontSize: string;
58
- $disabled: boolean;
59
- $isMobile?: boolean;
60
- $maxHeight?: string;
61
- $borderRadius?: string;
62
- $resize?: boolean;
63
- }, never> & Partial<Pick<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, "$width" | "$maxHeight" | "$borderRadius" | "$fontSize" | "$disabled" | "$vil" | "$isModified" | "$isMobile" | "$resize"> & {
38
+ }>> & string;
39
+ export declare const StyledTextareaEditor: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Merged<Omit<import("react").DetailedHTMLProps<import("react").TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, "style"> & {
40
+ style?: import("react").CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
41
+ }, {
64
42
  $vil: ValidationItem[];
65
43
  $width: string;
66
44
  $isModified: boolean;
@@ -70,4 +48,4 @@ export declare const StyledTextareaEditor: import("styled-components/dist/types"
70
48
  $maxHeight?: string;
71
49
  $borderRadius?: string;
72
50
  $resize?: boolean;
73
- }, never>>> & string;
51
+ }>> & string;
@@ -1,9 +1,13 @@
1
1
  import React from 'react';
2
- import { ValidationItem, LayoutModes, QueryOperators } from '@topconsultnpm/sdk-ts';
2
+ import { MetadataDescriptor, ValidationItem, LayoutModes, QueryOperators } from '@topconsultnpm/sdk-ts';
3
3
  import { DynDataListsToBeRefreshed, MIDsToBeUpdated } from '../choosers/TMDynDataListItemChooser';
4
4
  interface ITMMetadataEditorProps {
5
5
  tid: number | undefined;
6
6
  mid?: number;
7
+ /** MetadataDescriptor esplicito. Se valorizzato, l'editor lo usa direttamente
8
+ * e salta la risoluzione interna via tid/mid (utile per metadati non legati
9
+ * a un tipo documento, es. copertina CaseFlow). */
10
+ md?: MetadataDescriptor;
7
11
  value: string | undefined;
8
12
  queryParamsDynDataList?: string[];
9
13
  autoFocus?: boolean;
@@ -10,21 +10,10 @@ import TMTextBox from './TMTextBox';
10
10
  import { TMMetadataIcon } from '../viewers/TMMidViewer';
11
11
  import TMTextArea from './TMTextArea';
12
12
  import { DateDisplayTypes } from '../../helper/Globalization';
13
+ import { getCurrencySymbol, getDevExtremeDateDisplayFormat } from '../../helper/TMUtils';
13
14
  const renderMetadataIcon = (tid, md, layoutMode, isMetadataSelected, showLabel) => {
14
15
  return (_jsx(TMMetadataIcon, { isMetadataSelected: isMetadataSelected, layoutMode: layoutMode, md: md, tid: tid, elementStyle: showLabel ? { position: 'relative', top: '4px' } : undefined }));
15
16
  };
16
- const getDateDisplayFormat = (format) => {
17
- format = format ?? MetadataFormats.None;
18
- switch (format) {
19
- case MetadataFormats.LongTime: return "longTime";
20
- case MetadataFormats.ShortTime: return "shortTime";
21
- case MetadataFormats.ShortDateLongTime:
22
- case MetadataFormats.ShortDateShortTime:
23
- case MetadataFormats.LongDateLongTime:
24
- case MetadataFormats.LongDateShortTime: return "shortDateShortTime";
25
- default: return "shortDate";
26
- }
27
- };
28
17
  const getDateDisplayType = (format) => {
29
18
  format = format ?? MetadataFormats.None;
30
19
  switch (format) {
@@ -37,14 +26,26 @@ const getDateDisplayType = (format) => {
37
26
  default: return DateDisplayTypes.Date;
38
27
  }
39
28
  };
40
- const TMMetadataEditor = ({ isSelected = false, customLabel, isReadOnly, isLexProt, layoutMode, queryOperator, isEditable, isModifiedWhen = false, tid, mid, value, queryParamsDynDataList, containerElement, autoFocus, validationItems = [], disabled = false, openChooserBySingleClick = true, onValueChanged, onValueChange, onCascadeRefreshDynDataLists, onCascadeUpdateMIDs, updateIsModalOpen }) => {
41
- const [md, setMd] = useState();
29
+ const getTextTransform = (format) => {
30
+ switch (format) {
31
+ case MetadataFormats.LowerCase: return 'lowercase';
32
+ case MetadataFormats.UpperCase: return 'uppercase';
33
+ default: return undefined;
34
+ }
35
+ };
36
+ const TMMetadataEditor = ({ isSelected = false, customLabel, isReadOnly, isLexProt, layoutMode, queryOperator, isEditable, isModifiedWhen = false, tid, mid, md: mdProp, value, queryParamsDynDataList, containerElement, autoFocus, validationItems = [], disabled = false, openChooserBySingleClick = true, onValueChanged, onValueChange, onCascadeRefreshDynDataLists, onCascadeUpdateMIDs, updateIsModalOpen }) => {
37
+ const [md, setMd] = useState(mdProp);
42
38
  useEffect(() => {
39
+ // Se il descriptor è fornito dall'esterno lo usiamo direttamente (es. metadati di copertina CaseFlow, non legati a un tipo documento).
40
+ if (mdProp) {
41
+ setMd(mdProp);
42
+ return;
43
+ }
43
44
  // Passiamo did = undefined, perché è già in cache
44
45
  DcmtTypeListCacheService.GetWithNotGrantedAsync(tid, undefined).then((dtd) => {
45
46
  setMd(dtd?.metadata?.find(o => o.id == mid));
46
47
  });
47
- }, [tid, mid]);
48
+ }, [tid, mid, mdProp]);
48
49
  const isReadOnlyInternal = () => {
49
50
  if (!md)
50
51
  return false;
@@ -104,23 +105,26 @@ const TMMetadataEditor = ({ isSelected = false, customLabel, isReadOnly, isLexPr
104
105
  else
105
106
  onValueChanged?.(IDs.join(","));
106
107
  }, updateIsModalOpen: updateIsModalOpen });
107
- if (showAsText)
108
- return _jsx(TMTextBox, { placeHolder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', isModifiedWhen: isModifiedWhenInternal(), readOnly: isReadOnlyResult, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, icon: showLabelTop ? icon : undefined, validationItems: validationItems, disabled: disabled, elementStyle: { width: '100%' }, type: 'text', showClearButton: !isReadOnlyResult, maxLength: maxLength, autoFocus: autoFocus, value: value ?? '', onValueChanged: (e) => onValueChange?.(e.target.value), onBlur: (newValue) => onValueChanged?.(newValue) });
109
- if (showAsNumber)
110
- return _jsx(TMTextBox, { placeHolder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', isModifiedWhen: isModifiedWhenInternal(), readOnly: isReadOnlyResult, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, icon: showLabelTop ? icon : undefined, validationItems: validationItems, disabled: disabled, elementStyle: { width: '100%' }, type: 'number', showClearButton: !isReadOnlyResult, precision: md?.length, scale: md?.scale, autoFocus: autoFocus, value: value ?? '', onValueChanged: (e) => onValueChange?.(e.target.value), onBlur: (newValue) => onValueChanged?.(newValue) });
108
+ if (showAsText) {
109
+ return _jsx(TMTextBox, { placeHolder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', isModifiedWhen: isModifiedWhenInternal(), readOnly: isReadOnlyResult, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, icon: showLabelTop ? icon : undefined, validationItems: validationItems, disabled: disabled, elementStyle: { width: '100%' }, type: 'text', showClearButton: !isReadOnlyResult, maxLength: maxLength, autoFocus: autoFocus, value: value ?? '', textTransform: getTextTransform(md?.format?.format), onValueChanged: (e) => onValueChange?.(e.target.value), onBlur: (newValue) => onValueChanged?.(newValue) });
110
+ }
111
+ if (showAsNumber) {
112
+ return _jsx(TMTextBox, { placeHolder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', isModifiedWhen: isModifiedWhenInternal(), readOnly: isReadOnlyResult, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, icon: showLabelTop ? icon : undefined, validationItems: validationItems, disabled: disabled, elementStyle: { width: '100%' }, type: 'number', showClearButton: !isReadOnlyResult, precision: md?.length, scale: md?.scale, autoFocus: autoFocus, value: value ?? '', currencySymbol: getCurrencySymbol(md?.format?.format), onValueChanged: (e) => onValueChange?.(e.target.value), onBlur: (newValue) => onValueChanged?.(newValue) });
113
+ }
111
114
  switch (md?.dataType) {
112
115
  case MetadataDataTypes.DateTime:
113
- return _jsx(TMDateBox, { placeholder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', dateDisplayType: getDateDisplayType(md.format?.format), displayFormat: getDateDisplayFormat(md.format?.format), isModifiedWhen: isModifiedWhenInternal(), readOnly: isReadOnlyResult, icon: showLabelTop ? icon : undefined, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, validationItems: validationItems, disabled: disabled, width: '100%', value: value, showClearButton: !isReadOnlyResult, useDateSerializationFormat: true, containerElement: containerElement, onValueChange: (newValue) => {
116
+ return _jsx(TMDateBox, { placeholder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', dateDisplayType: getDateDisplayType(md.format?.format), displayFormat: getDevExtremeDateDisplayFormat(md.format?.format, md.format?.formatCulture), formatCulture: md.format?.formatCulture, metadataFormat: md.format?.format, isModifiedWhen: isModifiedWhenInternal(), readOnly: isReadOnlyResult, icon: showLabelTop ? icon : undefined, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, validationItems: validationItems, disabled: disabled, width: '100%', value: value, showClearButton: !isReadOnlyResult, useDateSerializationFormat: true, containerElement: containerElement, onValueChange: (newValue) => {
114
117
  onValueChange?.(newValue ? newValue.toString() : undefined);
115
118
  onValueChanged?.(newValue ? newValue.toString() : undefined);
116
119
  } });
117
- case MetadataDataTypes.Number: return _jsx(TMTextBox, { placeHolder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', isModifiedWhen: isModifiedWhenInternal(), readOnly: isReadOnlyResult, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, icon: showLabelTop ? icon : undefined, validationItems: validationItems, disabled: disabled, elementStyle: { width: '100%' }, type: 'number', showClearButton: !isReadOnlyResult, precision: md?.length, scale: md?.scale, autoFocus: autoFocus, value: value ?? '', onValueChanged: (e) => onValueChange?.(e.target.value), onBlur: (newValue) => onValueChanged?.(newValue) });
120
+ case MetadataDataTypes.Number:
121
+ return _jsx(TMTextBox, { placeHolder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', isModifiedWhen: isModifiedWhenInternal(), readOnly: isReadOnlyResult, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, icon: showLabelTop ? icon : undefined, validationItems: validationItems, disabled: disabled, elementStyle: { width: '100%' }, type: 'number', showClearButton: !isReadOnlyResult, precision: md?.length, scale: md?.scale, autoFocus: autoFocus, value: value ?? '', currencySymbol: getCurrencySymbol(md?.format?.format), onValueChanged: (e) => onValueChange?.(e.target.value), onBlur: (newValue) => onValueChanged?.(newValue) });
118
122
  default:
119
123
  if (showByTextarea) {
120
- return _jsx(TMTextArea, { placeHolder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', rows: 1, readOnly: isReadOnlyResult, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, icon: showLabelTop ? icon : undefined, isModifiedWhen: isModifiedWhenInternal(), validationItems: validationItems, disabled: disabled, elementStyle: { width: '100%' }, showClearButton: !isReadOnlyResult, autoFocus: autoFocus, maxLength: maxLength, value: value ?? '', onValueChanged: (e) => onValueChange?.(e.target.value), onBlur: (newValue) => { onValueChanged?.(newValue); }, resize: false });
124
+ return _jsx(TMTextArea, { placeHolder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', rows: 1, readOnly: isReadOnlyResult, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, icon: showLabelTop ? icon : undefined, isModifiedWhen: isModifiedWhenInternal(), validationItems: validationItems, disabled: disabled, elementStyle: { width: '100%' }, showClearButton: !isReadOnlyResult, autoFocus: autoFocus, maxLength: maxLength, value: value ?? '', textTransform: getTextTransform(md?.format?.format), onValueChanged: (e) => onValueChange?.(e.target.value), onBlur: (newValue) => { onValueChanged?.(newValue); }, resize: false });
121
125
  }
122
126
  else {
123
- return _jsx(TMTextBox, { placeHolder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', isModifiedWhen: isModifiedWhenInternal(), readOnly: isReadOnlyResult, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, icon: showLabelTop ? icon : undefined, disabled: disabled, validationItems: validationItems, type: 'text', elementStyle: { width: '100%' }, showClearButton: !isReadOnlyResult, autoFocus: autoFocus, maxLength: maxLength, value: value ?? '', onValueChanged: (e) => onValueChange?.(e.target.value), onBlur: (newValue) => { onValueChanged?.(newValue); } });
127
+ return _jsx(TMTextBox, { placeHolder: layoutMode === LayoutModes.Ark ? md?.defaultValue ?? '' : '', isModifiedWhen: isModifiedWhenInternal(), readOnly: isReadOnlyResult, label: (modulesWithLabelTop || showLabelTop) ? (customLabel ?? md?.nameLoc) : undefined, icon: showLabelTop ? icon : undefined, disabled: disabled, validationItems: validationItems, type: 'text', elementStyle: { width: '100%' }, showClearButton: !isReadOnlyResult, autoFocus: autoFocus, maxLength: maxLength, value: value ?? '', textTransform: getTextTransform(md?.format?.format), onValueChanged: (e) => onValueChange?.(e.target.value), onBlur: (newValue) => { onValueChanged?.(newValue); } });
124
128
  }
125
129
  }
126
130
  };
@@ -16,6 +16,7 @@ interface ITMTextArea extends ITMEditorBase {
16
16
  fillHeight?: boolean;
17
17
  name?: string;
18
18
  id?: string;
19
+ textTransform?: 'lowercase' | 'uppercase';
19
20
  }
20
21
  declare const TMTextArea: React.FunctionComponent<ITMTextArea>;
21
22
  export default TMTextArea;
@@ -28,7 +28,7 @@ const StyledTextAreaEditorButton = styled.div `
28
28
  // Define the TMTextArea component
29
29
  const TMTextArea = (props) => {
30
30
  // Extract properties from the props object
31
- const { label = '', value = '', width = '100%', height = 'auto', autoFocus = false, showClearButton, validationItems = [], disabled = false, isModifiedWhen = false, fontSize = FontSize.defaultFontSize, elementStyle = {}, icon = null, labelPosition = 'left', readOnly = false, onValueChanged, onBlur, placeHolder, formulaItems = [], buttons = [], maxHeight = 'auto', rows, maxLength, resize = true, autoCalculateRows = true, fillHeight = false, name, id } = props;
31
+ const { label = '', value = '', width = '100%', height = 'auto', autoFocus = false, showClearButton, validationItems = [], disabled = false, isModifiedWhen = false, fontSize = FontSize.defaultFontSize, elementStyle = {}, icon = null, labelPosition = 'left', readOnly = false, onValueChanged, onBlur, placeHolder, formulaItems = [], buttons = [], maxHeight = 'auto', rows, maxLength, resize = true, autoCalculateRows = true, fillHeight = false, name, id, textTransform } = props;
32
32
  // Generate a unique id if not provided
33
33
  const autoId = useId();
34
34
  const effectiveId = id ?? autoId;
@@ -151,20 +151,28 @@ const TMTextArea = (props) => {
151
151
  };
152
152
  // Renders the textarea
153
153
  const renderTextArea = () => {
154
- const textareaElement = _jsxs(_Fragment, { children: [_jsx(StyledTextareaEditor, { ref: inputRef, id: effectiveId, ...(name && { name }), autoFocus: autoFocus, readOnly: readOnly, disabled: disabled, value: currentValue, placeholder: placeHolder, rows: fillHeight ? undefined : calculatedRows, maxLength: maxLength, spellCheck: false, onFocus: () => setIsFocused(true), onBlur: (e) => { setIsFocused(false); if (currentValue != value)
155
- onBlur?.(currentValue); }, onChange: (e) => { setCurrentValue(e.target.value); onValueChanged?.(e); }, "$isMobile": deviceType === DeviceType.MOBILE, "$maxHeight": maxHeight, "$disabled": disabled, "$vil": validationItems, "$isModified": isModifiedWhen, "$fontSize": fontSize, "$width": width, "$resize": resize, style: fillHeight ? { flex: 1, height: 0 } : undefined }), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center', position: 'absolute', right: '6px', top: calculatedRows === 1 ? (label.length > 0 ? '20px' : '7px') : (label.length > 0 ? '22px' : '7px'), pointerEvents: disabled ? 'none' : 'auto', opacity: disabled ? 0.4 : 1 }, children: [formulaItems.length > 0 &&
156
- _jsx(StyledTextAreaEditorButton, { onClick: () => {
157
- setShowFormulaItemsChooser(true);
158
- }, children: _jsx(IconDataList, {}) }), showClearButton && currentValue &&
159
- _jsx(StyledTextAreaEditorButton, { onClick: () => {
160
- onValueChanged?.({ target: { value: undefined } });
161
- setCurrentValue('');
162
- if (autoCalculateRows)
163
- setCalculatedRows(1);
164
- onBlur?.(undefined);
165
- }, children: _jsx(IconClearButton, {}) }), buttons.map((buttonItem, index) => {
166
- return (_jsx(StyledTextAreaEditorButton, { onClick: buttonItem.onClick, children: _jsx(TMTooltip, { content: buttonItem.text, children: buttonItem.icon }) }, buttonItem.text));
167
- })] }), openFormulaItemsChooser(), _jsx(TMVilViewer, { vil: validationItems })] });
154
+ const textareaElement = _jsxs(_Fragment, { children: [_jsxs("div", { style: { position: 'relative', ...(fillHeight ? { flex: 1, display: 'flex', flexDirection: 'column' } : {}) }, children: [_jsx(StyledTextareaEditor, { ref: inputRef, id: effectiveId, ...(name && { name }), autoFocus: autoFocus, readOnly: readOnly, disabled: disabled, value: currentValue, placeholder: placeHolder, rows: fillHeight ? undefined : calculatedRows, maxLength: maxLength, spellCheck: false, onFocus: () => setIsFocused(true), onBlur: (e) => { setIsFocused(false); if (currentValue != value)
155
+ onBlur?.(currentValue); }, onChange: (e) => {
156
+ let newValue = e.target.value;
157
+ if (textTransform === 'lowercase')
158
+ newValue = newValue.toLowerCase();
159
+ else if (textTransform === 'uppercase')
160
+ newValue = newValue.toUpperCase();
161
+ setCurrentValue(newValue);
162
+ onValueChanged?.({ ...e, target: { ...e.target, value: newValue } });
163
+ }, "$isMobile": deviceType === DeviceType.MOBILE, "$maxHeight": maxHeight, "$disabled": disabled, "$vil": validationItems, "$isModified": isModifiedWhen, "$fontSize": fontSize, "$width": width, "$resize": resize, style: fillHeight ? { flex: 1, height: 0 } : undefined }), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center', position: 'absolute', right: '6px', top: '50%', transform: 'translateY(-50%)', pointerEvents: disabled ? 'none' : 'auto', opacity: disabled ? 0.4 : 1 }, children: [formulaItems.length > 0 &&
164
+ _jsx(StyledTextAreaEditorButton, { onClick: () => {
165
+ setShowFormulaItemsChooser(true);
166
+ }, children: _jsx(IconDataList, {}) }), showClearButton && currentValue &&
167
+ _jsx(StyledTextAreaEditorButton, { onClick: () => {
168
+ onValueChanged?.({ target: { value: undefined } });
169
+ setCurrentValue('');
170
+ if (autoCalculateRows)
171
+ setCalculatedRows(1);
172
+ onBlur?.(undefined);
173
+ }, children: _jsx(IconClearButton, {}) }), buttons.map((buttonItem, index) => {
174
+ return (_jsx(StyledTextAreaEditorButton, { onClick: buttonItem.onClick, children: _jsx(TMTooltip, { content: buttonItem.text, children: buttonItem.icon }) }, buttonItem.text));
175
+ })] })] }), openFormulaItemsChooser(), _jsx(TMVilViewer, { vil: validationItems })] });
168
176
  // Wrap with context menu if formula items exist
169
177
  if (formulaItems.length > 0) {
170
178
  return (_jsx(TMContextMenu, { items: getFormulaMenuItems(), trigger: "right", children: textareaElement }));
@@ -14,6 +14,8 @@ export interface ITMTextBox extends ITMEditorBase {
14
14
  value?: string | number;
15
15
  fromModal?: boolean;
16
16
  allowedPattern?: RegExp;
17
+ textTransform?: 'lowercase' | 'uppercase';
18
+ currencySymbol?: string;
17
19
  onClick?: () => void;
18
20
  onValueChanged?: (e: React.ChangeEvent<HTMLInputElement>) => void;
19
21
  onBlur?: (value: string | undefined) => void;
@@ -34,7 +34,7 @@ const StyledTextBoxEditorButton = styled.div `
34
34
  border-bottom-color: ${TMColors.primary};
35
35
  }
36
36
  `;
37
- const TMTextBox = ({ autoComplete = 'off', autoFocus, maxLength, labelColor, precision, fromModal = false, scale, showClearButton, validationItems = [], label = '', readOnly = false, formulaItems = [], buttons = [], isModifiedWhen, placeHolder, elementStyle, width = '100%', maxValue, minValue, fontSize = FontSize.defaultFontSize, icon, labelPosition = 'left', value, disabled = false, type = 'text', onClick, onValueChanged, onBlur, onKeyDown, borderRadius, allowedPattern }) => {
37
+ const TMTextBox = ({ autoComplete = 'off', autoFocus, maxLength, labelColor, precision, fromModal = false, scale, showClearButton, validationItems = [], label = '', readOnly = false, formulaItems = [], buttons = [], isModifiedWhen, placeHolder, elementStyle, width = '100%', maxValue, minValue, fontSize = FontSize.defaultFontSize, icon, labelPosition = 'left', value, disabled = false, type = 'text', onClick, onValueChanged, onBlur, onKeyDown, borderRadius, allowedPattern, textTransform, currencySymbol }) => {
38
38
  const [initialType, setInitialType] = useState(type);
39
39
  const [currentType, setCurrentType] = useState(type);
40
40
  const [currentValue, setCurrentValue] = useState(value);
@@ -151,6 +151,13 @@ const TMTextBox = ({ autoComplete = 'off', autoFocus, maxLength, labelColor, pre
151
151
  };
152
152
  const handleInputChange = (e) => {
153
153
  let inputValue = e.target.value;
154
+ // Applica textTransform direttamente durante la digitazione (non per i numeri)
155
+ if (currentType !== 'number') {
156
+ if (textTransform === 'lowercase')
157
+ inputValue = inputValue.toLowerCase();
158
+ else if (textTransform === 'uppercase')
159
+ inputValue = inputValue.toUpperCase();
160
+ }
154
161
  // Validazione generica con RegEx
155
162
  if (allowedPattern) {
156
163
  // Soluzione 1: Confronto diretto (preferibile per un singolo carattere)
@@ -282,24 +289,28 @@ const TMTextBox = ({ autoComplete = 'off', autoFocus, maxLength, labelColor, pre
282
289
  return 6 + (buttonCount * buttonWidth) + 8;
283
290
  }
284
291
  };
285
- return (_jsxs("div", { style: { width: '100%', height: 'fit-content', cursor: onClick ? 'pointer' : undefined }, id: `text-${id}`, onClick: onClick, children: [_jsx(StyledEditor, { ref: inputRef, onContextMenu: (e) => e.stopPropagation(), id: `text-${label}-${id}`, name: label, autoFocus: autoFocus, readOnly: readOnly, type: currentType, disabled: disabled, value: displayedValue, width: width || '100%', placeholder: placeHolder, maxLength: maxLength, autoComplete: autoComplete, spellCheck: false, onFocus: () => setIsFocused(true), onBlur: (e) => { setIsFocused(false); if (currentValue != value)
286
- onBlur?.(currentValue); }, onChange: handleInputChange, onKeyDown: (e) => {
287
- if (currentType === 'number') {
288
- if (!scale && (e.key == "." || e.key == ","))
289
- e.preventDefault();
290
- }
291
- onKeyDown?.(e);
292
- }, "$isMobile": deviceType === DeviceType.MOBILE, "$disabled": disabled, "$vil": validationItems, "$isModified": isModifiedWhen, "$fontSize": fontSize, "$maxValue": maxValue, "$width": width, "$type": currentType, "$borderRadius": borderRadius, style: { paddingRight: `${calculateRightPadding()}px`, cursor: onClick ? 'pointer' : undefined } }), (initialType === 'password' || initialType === 'secureText') && _jsx(StyledShowPasswordIcon, { onClick: toggleShowPassword, "$disabled": disabled, "$vil": validationItems, "$isModified": isModifiedWhen, children: showPasswordIcon() }), (formulaItems.length > 0 || (showClearButton && currentValue) || buttons.length > 0) &&
293
- _jsxs("div", { style: { display: 'flex', flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center', position: 'absolute', right: type === 'number' ? '25px' : (initialType === 'password' ? '34px' : '6px'), top: label.length > 0 ? '20px' : '3px', pointerEvents: disabled ? 'none' : 'auto', opacity: disabled ? 0.4 : 1 }, children: [formulaItems.length > 0 &&
294
- _jsx(StyledTextBoxEditorButton, { onClick: () => {
295
- setShowFormulaItemsChooser(true);
296
- }, children: _jsx(IconDataList, {}) }), showClearButton && currentValue &&
297
- _jsx(StyledTextBoxEditorButton, { onClick: () => {
298
- onValueChanged?.({ target: { value: undefined } });
299
- onBlur?.(undefined);
300
- }, children: _jsx(IconClearButton, {}) }), buttons.map((buttonItem, index) => {
301
- return (_jsx(StyledTextBoxEditorButton, { onClick: buttonItem.onClick, children: _jsx(TMTooltip, { content: buttonItem.text, children: buttonItem.icon }) }, buttonItem.text));
302
- })] }), openFormulaItemsChooser(), formulaItems.length > 0 && (_jsx(TMContextMenu, { items: formulaMenuItems, target: `#text-${id}` })), _jsx(TMVilViewer, { vil: validationItems })] }));
292
+ // Calcola il padding-left per il simbolo della valuta
293
+ const calculateLeftPadding = () => {
294
+ if (!currencySymbol)
295
+ return 6; // Padding di default
296
+ // Stima la larghezza del simbolo (circa 10px per carattere + margine)
297
+ return 6 + (currencySymbol.length * 10) + 4;
298
+ };
299
+ return (_jsx("div", { style: { width: '100%', height: 'fit-content', cursor: onClick ? 'pointer' : undefined, display: 'flex', alignItems: 'center' }, id: `text-${id}`, onClick: onClick, children: _jsxs("div", { style: { flex: 1 }, children: [_jsxs("div", { style: { position: 'relative' }, children: [currencySymbol && initialType !== 'password' && initialType !== 'secureText' && _jsx("span", { style: { position: 'absolute', left: '6px', top: '50%', transform: 'translateY(-50%)', color: disabled ? TMColors.disabled : TMColors.text_normal, fontSize: fontSize, pointerEvents: 'none', zIndex: 1 }, children: currencySymbol }), _jsx(StyledEditor, { ref: inputRef, onContextMenu: (e) => e.stopPropagation(), id: `text-${label}-${id}`, name: label, autoFocus: autoFocus, readOnly: readOnly, type: currentType, disabled: disabled, value: displayedValue, width: width || '100%', placeholder: placeHolder, maxLength: maxLength, autoComplete: autoComplete, spellCheck: false, onFocus: () => setIsFocused(true), onBlur: (e) => { setIsFocused(false); if (currentValue != value)
300
+ onBlur?.(currentValue); }, onChange: handleInputChange, onKeyDown: (e) => {
301
+ if (currentType === 'number') {
302
+ if (!scale && (e.key == "." || e.key == ","))
303
+ e.preventDefault();
304
+ }
305
+ onKeyDown?.(e);
306
+ }, "$isMobile": deviceType === DeviceType.MOBILE, "$disabled": disabled, "$vil": validationItems, "$isModified": isModifiedWhen, "$fontSize": fontSize, "$maxValue": maxValue, "$width": width, "$type": currentType, "$borderRadius": borderRadius, style: { paddingLeft: `${calculateLeftPadding()}px`, paddingRight: `${calculateRightPadding()}px`, cursor: onClick ? 'pointer' : undefined } }), (initialType === 'password' || initialType === 'secureText') && _jsx(StyledShowPasswordIcon, { onClick: toggleShowPassword, "$disabled": disabled, "$vil": validationItems, "$isModified": isModifiedWhen, children: showPasswordIcon() }), (formulaItems.length > 0 || (showClearButton && currentValue) || buttons.length > 0) &&
307
+ _jsxs("div", { style: { display: 'flex', flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center', position: 'absolute', right: type === 'number' ? '25px' : (initialType === 'password' ? '34px' : '6px'), top: '50%', transform: 'translateY(-50%)', pointerEvents: disabled ? 'none' : 'auto', opacity: disabled ? 0.4 : 1 }, children: [formulaItems.length > 0 &&
308
+ _jsx(StyledTextBoxEditorButton, { onClick: () => {
309
+ setShowFormulaItemsChooser(true);
310
+ }, children: _jsx(IconDataList, {}) }), (showClearButton && currentValue) &&
311
+ _jsx(StyledTextBoxEditorButton, { onClick: () => { onValueChanged?.({ target: { value: undefined } }); onBlur?.(undefined); }, children: _jsx(IconClearButton, {}) }), buttons.map((buttonItem, index) => {
312
+ return (_jsx(StyledTextBoxEditorButton, { onClick: buttonItem.onClick, children: _jsx(TMTooltip, { content: buttonItem.text, children: buttonItem.icon }) }, buttonItem.text));
313
+ })] }), openFormulaItemsChooser(), formulaItems.length > 0 && (_jsx(TMContextMenu, { items: formulaMenuItems, target: `#text-${id}` }))] }), _jsx(TMVilViewer, { vil: validationItems })] }) }));
303
314
  };
304
315
  const renderedLeftLabelTextBox = () => {
305
316
  return (_jsxs(TMLayoutContainer, { direction: 'horizontal', children: [icon && _jsx(TMLayoutItem, { width: '20px', children: _jsx(StyledEditorIcon, { "$disabled": disabled, "$vil": validationItems, "$isModified": isModifiedWhen, children: icon }) }), _jsx(TMLayoutItem, { children: _jsxs(StyledEditorContainer, { "$width": width, children: [label && _jsx(StyledEditorLabel, { "$color": labelColor, "$isFocused": isFocused, "$labelPosition": labelPosition, "$disabled": disabled, children: label }), renderInputField()] }) })] }));
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React, { useEffect, useMemo, useState } from 'react';
2
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
3
3
  import Logo from '../../../assets/Toppy-generico.png';
4
4
  import { ArchiveConstraints, DcmtTypeListCacheService, LayoutModes, SDK_Localizator } from '@topconsultnpm/sdk-ts';
5
5
  import { IconTree, SDKUI_Globals, SDKUI_Localizator, IconRecentlyViewed, IconPreview, IconShow, IconBoard, IconDcmtTypeSys, removeMruTid, getMoreInfoTasksForDocument } from '../../../helper';
@@ -56,6 +56,13 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
56
56
  previousTIDRef.current = currentTID;
57
57
  }, [currentTID, onDcmtTypeSelect, isSharedArchive]);
58
58
  const isMobile = deviceType === DeviceType.MOBILE;
59
+ // Scorciatoie: rilegge dal server l'elenco dei tipi documento, così le scorciatoie riflettono
60
+ // quelli aggiunti o rimossi. La nuova identità di mruTIDs fa ricaricare i descrittori a TMRecentsManager.
61
+ const refreshRecentsAsync = useCallback(async () => {
62
+ DcmtTypeListCacheService.RemoveAllWithoutMetadata();
63
+ await DcmtTypeListCacheService.GetAllWithoutMetadataAsync();
64
+ setMruTIDs([...SDKUI_Globals.userSettings.archivingSettings.mruTIDs]);
65
+ }, []);
59
66
  const tmTreeSelectorElement = useMemo(() => _jsx(TMTreeSelectorWrapper, { isMobile: isMobile, isSharedArchive: isSharedArchive, onSelectedTIDChanged: (tid) => {
60
67
  setCurrentTID(tid);
61
68
  if (tid && mruTIDs.includes(tid))
@@ -108,7 +115,14 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
108
115
  {
109
116
  id: 'tmRecentsManager',
110
117
  name: SDKUI_Localizator.Shortcuts,
111
- contentOptions: { component: tmRecentsManagerElement, panelContainer: { title: SDKUI_Localizator.Shortcuts, totalItems: mruTIDs.length } },
118
+ contentOptions: {
119
+ component: tmRecentsManagerElement,
120
+ panelContainer: {
121
+ title: SDKUI_Localizator.Shortcuts,
122
+ totalItems: mruTIDs.length,
123
+ onRefresh: refreshRecentsAsync
124
+ }
125
+ },
112
126
  toolbarOptions: { icon: _jsx(IconRecentlyViewed, { fontSize: 24 }), visible: true, orderNumber: 2, isActive: allInitialPanelVisibility['tmRecentsManager'] }
113
127
  },
114
128
  {
@@ -139,7 +153,7 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
139
153
  }
140
154
  ]
141
155
  },
142
- ], [tmTreeSelectorElement, tmRecentsManagerElement, tmFormElement, currentTID, mruTIDs, isSharedArchive]);
156
+ ], [tmTreeSelectorElement, tmRecentsManagerElement, tmFormElement, currentTID, mruTIDs, isSharedArchive, refreshRecentsAsync]);
143
157
  return (_jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmRecentsManager', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }));
144
158
  };
145
159
  export default TMArchive;
@@ -7,7 +7,7 @@ import { DcmtOperationTypes, FormModes } from '../../../ts';
7
7
  import { StyledToolbarCardContainer, StyledFormButtonsContainer } from '../../base/Styled';
8
8
  import { useDeviceType, DeviceType } from '../../base/TMDeviceProvider';
9
9
  import { TMSplitterLayout } from '../../base/TMLayout';
10
- import { TMExceptionBoxManager } from '../../base/TMPopUp';
10
+ import { TMExceptionBoxManager, TMMessageBoxManager, ButtonNames } from '../../base/TMPopUp';
11
11
  import TMShowAllOrMaxItemsButton from '../../base/TMShowAllOrMaxItemsButton';
12
12
  import TMSpinner from '../../base/TMSpinner';
13
13
  import { TMLayoutWaitingContainer } from '../../base/TMWaitPanel';
@@ -114,10 +114,24 @@ const TMBatchUpdateForm = ({ inputDcmts, TID, DID, isExpertMode = SDKUI_Globals.
114
114
  const totalItems = metadataValues.filter(o => o.mid && o.mid > 100).length;
115
115
  const metadataValuesSource = metadataValues.filter(o => o.mid && o.mid > 100).slice(0, showAll ? metadataValues.filter(o => o.mid && o.mid > 100).length : listMaxItems);
116
116
  const metadataValuesSourceOrig = metadataValuesOrig.filter(o => o.mid && o.mid > 100).slice(0, showAll ? metadataValuesOrig.filter(o => o.mid && o.mid > 100).length : listMaxItems);
117
+ /**
118
+ * Chiusura del form: con modifiche pendenti chiede conferma prima di scartarle.
119
+ * Il TMModal è montato con askClosingConfirm, quindi non si auto-nasconde: la chiusura
120
+ * effettiva avviene solo quando onBack smonta il componente.
121
+ */
122
+ const handleClose = () => {
123
+ if (!isModified) {
124
+ onBack?.();
125
+ return;
126
+ }
127
+ TMMessageBoxManager.show({
128
+ title: SDKUI_Localizator.Cancel, message: SDKUI_Localizator.ConfirmOnCancel, buttons: [ButtonNames.YES, ButtonNames.NO],
129
+ onButtonClick: (e) => { if (e === ButtonNames.YES)
130
+ onBack?.(); }
131
+ });
132
+ };
117
133
  const renderContent = () => {
118
- return (_jsx(TMLayoutWaitingContainer, { showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, isCancelable: true, abortController: abortController, children: _jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: Gutters.getGutters(), separatorColor: 'transparent', separatorActiveColor: 'transparent', showSeparator: showFormulaEditor, start: showFormulaEditor ? ['50%', '50%'] : ['100%', '0%'], min: ['0', '0'], children: [_jsx(TMPanel, { title: isModal ? 'Modifica i metadati' : `${SDKUI_Localizator.BatchUpdate} (${inputDcmts.length} documenti selezionati)`, onBack: deviceType === DeviceType.MOBILE ? onBack : undefined,
119
- // onClose={deviceType !== DeviceType.MOBILE ? onBack : undefined}
120
- allowMaximize: !isModal, showHeader: !isModal, children: _jsxs(StyledToolbarCardContainer, { children: [_jsx(TMMetadataValues, { TID: TID, isExpertMode: isExpertMode, showCheckBoxes: ShowCheckBoxesMode.Always, showNullValueCheckBoxes: true, metadataValues: metadataValuesSource, metadataValuesOrig: metadataValuesSourceOrig, validationItems: validationItems, isOpenDistinctValues: showDistinctValuesPanel, selectedMID: focusedMetadataValue?.mid, onFocusedItemChanged: (item) => { setFocusedMetadataValue(item); }, onValueChanged: (newItems) => {
134
+ return (_jsx(TMLayoutWaitingContainer, { showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, isCancelable: true, abortController: abortController, children: _jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: Gutters.getGutters(), separatorColor: 'transparent', separatorActiveColor: 'transparent', showSeparator: showFormulaEditor, start: showFormulaEditor ? ['50%', '50%'] : ['100%', '0%'], min: ['0', '0'], children: [_jsx(TMPanel, { title: isModal ? 'Modifica i metadati' : `${SDKUI_Localizator.BatchUpdate} (${inputDcmts.length} documenti selezionati)`, onBack: deviceType === DeviceType.MOBILE ? handleClose : undefined, allowMaximize: !isModal, showHeader: !isModal, children: _jsxs(StyledToolbarCardContainer, { children: [_jsx(TMMetadataValues, { TID: TID, isExpertMode: isExpertMode, showCheckBoxes: ShowCheckBoxesMode.Always, showNullValueCheckBoxes: true, metadataValues: metadataValuesSource, metadataValuesOrig: metadataValuesSourceOrig, validationItems: validationItems, isOpenDistinctValues: showDistinctValuesPanel, selectedMID: focusedMetadataValue?.mid, onFocusedItemChanged: (item) => { setFocusedMetadataValue(item); }, onValueChanged: (newItems) => {
121
135
  setMetadataValues((prevItems) => prevItems.map((item) => {
122
136
  const newItem = newItems.find((newItem) => newItem.tid === item.tid && newItem.mid === item.mid);
123
137
  return newItem ? { ...item, ...newItem } : item;
@@ -153,7 +167,7 @@ const TMBatchUpdateForm = ({ inputDcmts, TID, DID, isExpertMode = SDKUI_Globals.
153
167
  } })] }) })] }) }));
154
168
  };
155
169
  return (_jsx(_Fragment, { children: (isModal && onBack)
156
- ? _jsx(TMModal, { title: titleModal, onClose: onBack, width: widthModal ?? '100%', height: heightModal ?? '100%', hidePopup: false, askClosingConfirm: true, children: _jsx("div", { style: { width: "100%", height: "100%", display: 'block', padding: "4px" }, children: renderContent() }) })
170
+ ? _jsx(TMModal, { title: titleModal, onClose: handleClose, width: widthModal ?? '100%', height: heightModal ?? '100%', hidePopup: false, askClosingConfirm: true, children: _jsx("div", { style: { width: "100%", height: "100%", display: 'block', padding: "4px" }, children: renderContent() }) })
157
171
  : renderContent() }));
158
172
  };
159
173
  export default TMBatchUpdateForm;
@@ -3,7 +3,10 @@ import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
3
3
  interface ITMDcmtBlogProps {
4
4
  tid: number | undefined;
5
5
  did: number | undefined;
6
+ /** Il pannello è aperto. La inietta TMPanelWrapper, non va passata dal chiamante */
6
7
  isVisible?: boolean;
8
+ /** La pagina che contiene il pannello è a video: quelle in secondo piano restano montate e non devono caricare */
9
+ isPageVisible?: boolean;
7
10
  fetchBlogDataTrigger?: number;
8
11
  onRefreshBlogDatagrid?: () => Promise<void>;
9
12
  showFloatingCommentButton?: boolean;
@@ -8,7 +8,7 @@ import TMBlogCommentForm from '../blog/TMBlogCommentForm';
8
8
  import TMBlogsPost from '../../grids/TMBlogsPost';
9
9
  import TMSpinner from '../../base/TMSpinner';
10
10
  import { TMExceptionBoxManager } from '../../base/TMPopUp';
11
- const TMDcmtBlog = ({ tid, did, isVisible, fetchBlogDataTrigger, onRefreshBlogDatagrid, showFloatingCommentButton = true, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
11
+ const TMDcmtBlog = ({ tid, did, isVisible, isPageVisible = true, fetchBlogDataTrigger, onRefreshBlogDatagrid, showFloatingCommentButton = true, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
12
12
  const [blogsDatasource, setBlogsDatasource] = useState([]);
13
13
  const [hasLoadedDataOnce, setHasLoadedDataOnce] = useState(false); //traccia se *qualsiasi* dato è stato caricato per la prima volta
14
14
  const [lastLoadedDid, setLastLoadedDid] = useState(undefined); // `lastLoadedDid` tiene traccia dell'ultimo `did` per cui abbiamo caricato i dati
@@ -47,15 +47,15 @@ const TMDcmtBlog = ({ tid, did, isVisible, fetchBlogDataTrigger, onRefreshBlogDa
47
47
  return;
48
48
  }
49
49
  // Condizione per eseguire il fetch:
50
- // 1. Il pannello è visibile
50
+ // 1. Il pannello è visibile in una pagina a video
51
51
  // 2. E (non abbiamo ancora caricato dati o il `did` è cambiato rispetto all'ultima volta)
52
- const shouldFetch = isVisible && (!hasLoadedDataOnce || did !== lastLoadedDid);
52
+ const shouldFetch = isVisible && isPageVisible && (!hasLoadedDataOnce || did !== lastLoadedDid);
53
53
  // Esegui la chiamata API solo se il pannello è visibile E i dati non sono già stati caricati
54
54
  // O, se vuoi ricaricare ogni volta che diventa visibile (ma è meno efficiente per "pesante")
55
55
  if (shouldFetch) {
56
56
  fetchBlogDataAsync(tid, did);
57
57
  }
58
- }, [tid, did, isVisible, hasLoadedDataOnce, lastLoadedDid]);
58
+ }, [tid, did, isVisible, isPageVisible, hasLoadedDataOnce, lastLoadedDid]);
59
59
  const refreshCallback = async () => {
60
60
  await fetchBlogDataAsync(tid, did);
61
61
  await onRefreshBlogDatagrid?.();
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { DcmtTypeDescriptor, HomeBlogPost, LayoutModes, ObjectRef, SearchResultDescriptor, TaskDescriptor, ValidationItem } from '@topconsultnpm/sdk-ts';
3
3
  import { DcmtInfo, FormModes, MetadataValueDescriptorEx, TaskContext, IGraphometricManagerProp } from '../../../ts';
4
4
  import { IntesiCertificateData } from '../../../helper';
5
+ import { ArchiveListMode } from '../../../hooks/useArchiveListForm';
5
6
  /**
6
7
  * Definisce il contesto da cui è stato invocato il TMDcmtForm.
7
8
  * Permette di gestire logiche diverse in base alla provenienza.
@@ -77,6 +78,12 @@ interface ITMDcmtFormProps {
77
78
  mid: number;
78
79
  value: string;
79
80
  }>, tid?: number) => void;
81
+ /**
82
+ * Modalità "aggiungi a elenco" (es. archiviazione dettagli multipli): se valorizzata, in layout di archiviazione
83
+ * il form non archivia ma emette i metadati compilati al chiamante (pulsanti "Aggiungi"/"Modifica" + "Pulisci").
84
+ * Tutta la logica è incapsulata in useArchiveListForm; usata solo da TMMultiMasterDetailDcmts.
85
+ */
86
+ archiveListMode?: ArchiveListMode;
80
87
  fetchRemoteCertificates?: (email: string) => Promise<IntesiCertificateData[]>;
81
88
  datagridUtility?: {
82
89
  onRefreshSearchAsyncDatagrid?: () => Promise<void>;