@topconsultnpm/sdkui-react 6.19.0-dev2.38 → 6.19.0-dev2.39

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.
@@ -4,7 +4,7 @@ import { useEffect, useRef, useState, useMemo } from 'react';
4
4
  import TMModal from './TMModal';
5
5
  import styled from 'styled-components';
6
6
  import { TMLayoutWaitingContainer } from '../..';
7
- import { processButtonAttributes, processSelectedItems } from '../../helper/dcmtsHelper';
7
+ import { processButtonAttributes } from '../../helper/dcmtsHelper';
8
8
  const IframeContainer = styled.div `
9
9
  display: flex;
10
10
  height: 100%;
@@ -19,8 +19,9 @@ const TMCustomButton = (props) => {
19
19
  const { button, isModal = true, formData, selectedItems, onClose } = props;
20
20
  const { appName: scriptUrl, arguments: args } = button;
21
21
  const iframeRef = useRef(null);
22
- const attributes = useMemo(() => processButtonAttributes(args, formData), [args, formData]);
23
- const selectedItemsProcessed = useMemo(() => processSelectedItems(args, formData, selectedItems), [args, formData, selectedItems]);
22
+ const attributes = useMemo(() => processButtonAttributes(args, formData, selectedItems), [args, formData, selectedItems]);
23
+ const selectedItemsProcessed = []; //da eliminare
24
+ //const selectedItemsProcessed = useMemo(() => processSelectedItems(args, formData, selectedItems), [args, formData, selectedItems]);
24
25
  const RunOnce = button.mode === "RunOnce";
25
26
  const [loading, setLoading] = useState(true);
26
27
  const [error, setError] = useState(false);
@@ -61,10 +62,7 @@ const TMCustomButton = (props) => {
61
62
  const checkIframe = setInterval(() => {
62
63
  if (iframeRef.current?.contentWindow) {
63
64
  clearInterval(checkIframe);
64
- iframeRef.current.contentWindow.postMessage({
65
- "options": item,
66
- "session": SDK_Globals.tmSession
67
- }, targetOrigin);
65
+ iframeRef.current.contentWindow.postMessage({ "options": item }, targetOrigin);
68
66
  // Attendi prima di passare al prossimo
69
67
  setTimeout(() => {
70
68
  setWaitPanelValue(index + 1);
@@ -95,9 +93,8 @@ const TMCustomButton = (props) => {
95
93
  }
96
94
  else if (iframeRef.current?.contentWindow) {
97
95
  // Modalità RunOnce: invia dati all'iframe quando è caricato
98
- const mergedAttributes = { ...attributes, selectedItems: selectedItemsProcessed };
99
96
  iframeRef.current.contentWindow.postMessage({
100
- "options": mergedAttributes,
97
+ "options": attributes,
101
98
  "session": SDK_Globals.tmSession
102
99
  }, targetOrigin);
103
100
  //clearTimeout(timeoutIframe);
@@ -96,6 +96,6 @@ const TMFileManagerDataGridView = (props) => {
96
96
  { dataField: "creationTime", caption: SDKUI_Localizator.CreationTime, dataType: 'datetime', format: 'dd/MM/yyyy HH:mm', cellRender: cellDatetimeRender },
97
97
  ];
98
98
  }, [searchText]);
99
- return _jsx(TMDataGrid, { dataSource: items ?? [], dataColumns: dataColumns, focusedRowKey: focusedRowKey, selectedRowKeys: selectedRowKeys, onFocusedRowChanged: onFocusedRowChanged, onSelectionChanged: onSelectionChanged, onCellDblClick: onCellDblClick, onContextMenuPreparing: onContextMenuPreparing, showSearchPanel: false, noDataText: SDKUI_Localizator.FolderIsEmpty });
99
+ return _jsx(TMDataGrid, { dataSource: items ?? [], dataColumns: dataColumns, focusedRowKey: focusedRowKey, selectedRowKeys: selectedRowKeys, onFocusedRowChanged: onFocusedRowChanged, onSelectionChanged: onSelectionChanged, onCellDblClick: onCellDblClick, onContextMenuPreparing: onContextMenuPreparing, showSearchPanel: false, noDataText: SDKUI_Localizator.FolderIsEmpty }, items.length);
100
100
  };
101
101
  export default TMFileManagerDataGridView;
@@ -8,8 +8,10 @@ interface TMBlogCommentFormProps {
8
8
  showAttachmentsSection?: boolean;
9
9
  selectedAttachments?: Array<FileItem>;
10
10
  selectedAttachmentDid?: Array<number>;
11
+ title?: string;
11
12
  allFileItems?: FileItem;
12
13
  allArchivedDocumentsFileItems?: Array<FileItem>;
14
+ onSavedCallback?: () => void;
13
15
  onFilterCreated?: (predicate: (post: BlogPost) => boolean) => void;
14
16
  refreshCallback?: () => Promise<void>;
15
17
  }
@@ -29,7 +29,7 @@ const getNonDirectoryFiles = (items, exclude) => {
29
29
  };
30
30
  const TMBlogCommentForm = (props) => {
31
31
  const maxLength = 1000;
32
- const { participants, selectedAttachments, selectedAttachmentDid, allFileItems, allArchivedDocumentsFileItems = [], onClose, context, showAttachmentsSection = true, onFilterCreated, refreshCallback } = props;
32
+ const { title = SDKUI_Localizator.AddNewComment, participants, selectedAttachments, selectedAttachmentDid, allFileItems, allArchivedDocumentsFileItems = [], onClose, context, showAttachmentsSection = true, onSavedCallback, onFilterCreated, refreshCallback } = props;
33
33
  // Initialize state with combined array
34
34
  const [dataSource, setDataSource] = useState(() => [...getNonDirectoryFiles(allFileItems?.items || [], []), ...allArchivedDocumentsFileItems]);
35
35
  const [isEditorEnabled, setIsEditorEnabled] = useState(true);
@@ -171,7 +171,10 @@ const TMBlogCommentForm = (props) => {
171
171
  finally {
172
172
  // Hide the loading spinner and close the operation (e.g., close a modal or cleanup)
173
173
  TMSpinner.hide();
174
- onClose();
174
+ if (onSavedCallback)
175
+ onSavedCallback();
176
+ else
177
+ onClose();
175
178
  }
176
179
  };
177
180
  const onCloseCallback = () => {
@@ -216,7 +219,7 @@ const TMBlogCommentForm = (props) => {
216
219
  // Update the state with selected draft items
217
220
  setCurrentDraftAttachments(selectedDraftItems);
218
221
  };
219
- return _jsx(TMSaveForm, { id: 1, title: SDKUI_Localizator.AddNewComment, showTitleFormMode: false, showErrorCount: false, customSaveButton: _jsx("i", { className: 'dx-icon-send' }), customTooltipSaveButton: SDKUI_Localizator.Send, showUndoButton: false, hasNavigation: false, skipIsModifiedCheck: true, isModal: true, width: calcResponsiveSizes(deviceType, '800px', '800px', '95%'), height: '550px', formMode: FormModes.Create, validationItems: validationItems, exception: exception, isModified: calcIsModified(formData, formDataOrig), onSaveAsync: onSaveAsync, onClose: onCloseCallback, customToolbarElements: _jsx("div", { style: { display: 'flex', gap: '2px' }, children: _jsx(TMButton, { btnStyle: "toolbar", icon: isEditorEnabled ? _jsx("i", { className: 'dx-icon-font' }) : _jsx("i", { className: 'dx-icon-background' }), caption: isEditorEnabled ? SDKUI_Localizator.HideFormattingOptions : SDKUI_Localizator.ShowFormattingOptions, onClick: toggleEditorMode }) }), children: _jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx("div", { style: { width: "100%", height: showAttachmentsSection ? "calc(100% - 60px)" : "100%" }, children: _jsx(TMHtmlEditor, { width: '100%', height: '100%', isEditorEnabled: isEditorEnabled, validationItems: validationItems, onValueChanged: onValueChanged, mentionsConfig: mentionsConfig, autoFocus: true, maxLength: maxLength }) }), showAttachmentsSection && _jsxs("div", { style: { display: 'flex', alignItems: 'center', height: '60px', marginTop: '10px' }, children: [_jsx("div", { style: {
222
+ return _jsx(TMSaveForm, { id: 1, title: title, showTitleFormMode: false, showErrorCount: false, customSaveButton: _jsx("i", { className: 'dx-icon-send' }), customTooltipSaveButton: SDKUI_Localizator.Send, showUndoButton: false, hasNavigation: false, skipIsModifiedCheck: true, isModal: true, width: calcResponsiveSizes(deviceType, '800px', '800px', '95%'), height: '550px', formMode: FormModes.Create, validationItems: validationItems, exception: exception, isModified: calcIsModified(formData, formDataOrig), onSaveAsync: onSaveAsync, onClose: onCloseCallback, customToolbarElements: _jsx("div", { style: { display: 'flex', gap: '2px' }, children: _jsx(TMButton, { btnStyle: "toolbar", icon: isEditorEnabled ? _jsx("i", { className: 'dx-icon-font' }) : _jsx("i", { className: 'dx-icon-background' }), caption: isEditorEnabled ? SDKUI_Localizator.HideFormattingOptions : SDKUI_Localizator.ShowFormattingOptions, onClick: toggleEditorMode }) }), children: _jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx("div", { style: { width: "100%", height: showAttachmentsSection ? "calc(100% - 60px)" : "100%" }, children: _jsx(TMHtmlEditor, { width: '100%', height: '100%', isEditorEnabled: isEditorEnabled, validationItems: validationItems, onValueChanged: onValueChanged, mentionsConfig: mentionsConfig, autoFocus: true, maxLength: maxLength }) }), showAttachmentsSection && _jsxs("div", { style: { display: 'flex', alignItems: 'center', height: '60px', marginTop: '10px' }, children: [_jsx("div", { style: {
220
223
  width: 'calc(100% - 60px)',
221
224
  overflowX: 'auto',
222
225
  whiteSpace: 'nowrap',
@@ -4,5 +4,4 @@ export declare const hasDetailRelations: (mTID: number | undefined) => Promise<b
4
4
  /** Check if dcmtType (mTID) has configured Master or Many-to-Many relations */
5
5
  export declare const hasMasterRelations: (mTID: number | undefined) => Promise<boolean>;
6
6
  export declare const isXMLFileExt: (fileExt: string | undefined) => boolean;
7
- export declare const processButtonAttributes: (args: string | undefined, formData: MetadataValueDescriptorEx[] | undefined) => (string | null)[] | undefined;
8
- export declare const processSelectedItems: (args: string | undefined, formData: MetadataValueDescriptorEx[] | undefined, selectedItems: Array<any> | undefined) => any[][];
7
+ export declare const processButtonAttributes: (args: string | undefined, formData: MetadataValueDescriptorEx[] | undefined, selectedItems: Array<any> | undefined) => any[] | Record<string, any> | undefined;
@@ -1,4 +1,4 @@
1
- import { RelationCacheService, RelationTypes } from "@topconsultnpm/sdk-ts";
1
+ import { RelationCacheService, RelationTypes, SDK_Globals } from "@topconsultnpm/sdk-ts";
2
2
  /** Check if dcmtType (mTID) has configured Detail or Many-to-Many relations */
3
3
  export const hasDetailRelations = async (mTID) => {
4
4
  let allRelations = await RelationCacheService.GetAllAsync();
@@ -24,27 +24,70 @@ export const isXMLFileExt = (fileExt) => {
24
24
  }
25
25
  };
26
26
  /*utility functions for TMCustomButton*/
27
- export const processButtonAttributes = (args, formData) => args && formData ? formDataMap(formData, args) : undefined;
28
- export const processSelectedItems = (args, formData, selectedItems) => {
29
- if (!args || !selectedItems)
30
- return [];
31
- const MidList = formData ? formDataMap(formData, args, true) : [];
32
- return selectedItems.map(item =>
33
- //salvo il did come primo elemento dell'array
34
- [item["DID"], ...MidList.map(key => key && item[key])]);
35
- };
36
- const formDataMap = (data, args, returnMid = false) => {
37
- const tokens = args.match(/\{@?[^}]+\}/g) || [];
38
- return tokens.map(token => {
39
- if (token.startsWith('{@')) {
40
- // Campo dinamico: {@campo} -> cerca in formData
41
- const fieldName = token.slice(2, -1);
27
+ export const processButtonAttributes = (args, formData, selectedItems) => args && formData ? formDataMap(formData, args, selectedItems) : undefined;
28
+ const processSelectedItems = (selectedItems) => selectedItems && selectedItems.map(item => item["DID"]) || [];
29
+ const formDataMap = (data, args, selectedItems, returnObject = true) => {
30
+ // Regex per catturare sia chiave={@campo} che {@campo} o {valore}
31
+ const tokens = args.match(/(\w+)=\{@?[^}]+\}|\{@?[^}]+\}/g) || [];
32
+ const session = SDK_Globals.tmSession;
33
+ const sessionDescr = session?.SessionDescr;
34
+ const results = tokens.map(token => {
35
+ let value;
36
+ let fieldName = '';
37
+ // Verifica se ha formato chiave={@campo}
38
+ const keyValueMatch = token.match(/(\w+)=\{@?([^}]+)\}/);
39
+ if (keyValueMatch) {
40
+ // Formato: Test={@Campo}
41
+ fieldName = keyValueMatch[1]; // Test
42
+ const innerField = keyValueMatch[2]; // Campo
43
+ const md = data.find(md => md.md?.name === innerField);
44
+ value = md?.value;
45
+ }
46
+ else if (token.startsWith('{@')) {
47
+ // Formato: {@campo}
48
+ fieldName = token.slice(2, -1);
42
49
  const md = data.find(md => md.md?.name === fieldName);
43
- return returnMid ? (md ? `${md.tid}_${md.mid}` : null) : (md?.value ?? null);
50
+ switch (fieldName) {
51
+ case 'SelectedDIDs':
52
+ value = processSelectedItems(selectedItems);
53
+ break;
54
+ case 'AuthenticationMode':
55
+ value = sessionDescr?.authenticationMode ?? null;
56
+ break;
57
+ case 'ArchiveID':
58
+ value = sessionDescr?.archiveID ?? null;
59
+ break;
60
+ case 'CultureID':
61
+ value = sessionDescr?.cultureID ?? null;
62
+ break;
63
+ case 'Domain':
64
+ value = sessionDescr?.domain ?? null;
65
+ break;
66
+ case 'UserID':
67
+ value = sessionDescr?.userID ?? null;
68
+ break;
69
+ case 'UserName':
70
+ value = sessionDescr?.userName ?? null;
71
+ break;
72
+ case 'Session':
73
+ value = session ?? null;
74
+ break;
75
+ default:
76
+ value = md?.value;
77
+ }
44
78
  }
45
79
  else {
46
- // Campo statico: {valore} -> ritorna il valore o null
47
- return returnMid ? null : token.slice(1, -1);
80
+ // Formato: {valore}
81
+ fieldName = token.slice(1, -1);
82
+ value = fieldName;
48
83
  }
84
+ return { fieldName, value };
49
85
  });
86
+ if (returnObject) {
87
+ return results.reduce((acc, { fieldName, value }) => {
88
+ acc[fieldName] = value;
89
+ return acc;
90
+ }, {});
91
+ }
92
+ return results.map(r => r.value);
50
93
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.19.0-dev2.38",
3
+ "version": "6.19.0-dev2.39",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",