@topconsultnpm/sdkui-react-beta 6.16.59 → 6.16.60

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.
@@ -161,7 +161,6 @@ const DiagramItemForm = ({ itemToEdit, wf, onClose, onApply }) => {
161
161
  PlatformObjectValidator.RequiredStringValidator(d.ItemName, DiagramItemProps.ItemName, vil, SDKUI_Localizator.Name);
162
162
  PlatformObjectValidator.RequiredStringValidator(d.Tos, DiagramItemProps.Tos, vil, SDKUI_Localizator.Recipients);
163
163
  PlatformObjectValidator.RequiredStringValidator(d.Severity, DiagramItemProps.Severity, vil, SDKUI_Localizator.Severity);
164
- PlatformObjectValidator.RequiredStringValidator(d.AppType, DiagramItemProps.AppType, vil, SDKUI_Localizator.WorkflowAppType);
165
164
  break;
166
165
  case DiagramItemTypes.RunApp:
167
166
  PlatformObjectValidator.RequiredStringValidator(d.ItemName, DiagramItemProps.ItemName, vil, SDKUI_Localizator.Name);
@@ -1,14 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
3
3
  import { DiagramItemTypes, ArrowSymbol } from './interfaces';
4
- import { parseWfDiagramXml } from './xmlParser';
4
+ import { parseWfDiagramXml, serializeWfDiagramToXml } from './xmlParser';
5
5
  import styled from 'styled-components';
6
6
  import { CultureIDs, SearchEngine, WFAppTypes, WorkItemStatus } from "@topconsultnpm/sdk-ts-beta";
7
7
  import ConnectionComponent from './ConnectionComponent';
8
8
  import DiagramItemComponent from './DiagramItemComponent';
9
9
  import DiagramItemSvgContent from './DiagramItemSvgContent';
10
- import { calculateArrowAngle, getConnectionPoint, isConnectionNonLinear, validateDiagram } from './workflowHelpers';
11
- import { IconFlowChart, IconUndo, IconRestore, IconAdjust, IconCopy, IconCut, IconPaste, IconPin, IconUnpin, IconChevronRight, IconCloseOutline, IconNew, SDKUI_Localizator, generateUUID } from '../../../../helper';
10
+ import { calculateArrowAngle, downloadFile, getConnectionPoint, isConnectionNonLinear, validateDiagram } from './workflowHelpers';
11
+ import { IconFlowChart, IconUndo, IconRestore, IconAdjust, IconCopy, IconCut, IconPaste, IconPin, IconUnpin, IconChevronRight, IconCloseOutline, IconNew, SDKUI_Localizator, generateUUID, IconExport } from '../../../../helper';
12
12
  import { TMExceptionBoxManager } from '../../../base/TMPopUp';
13
13
  import { StyledLoadingContainer, StyledSpinner } from '../../../base/Styled';
14
14
  import DiagramItemForm from './DiagramItemForm';
@@ -589,6 +589,24 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
589
589
  return;
590
590
  }
591
591
  }, [wfDiagram, selectedItems, selectedConnections, handleUndo, handleRedo, handleDelete, updateDiagram, handleCopy, handleCut, handlePaste, readOnly]);
592
+ const handleExportDiagram = useCallback(() => {
593
+ if (!wfDiagram) {
594
+ // Visualizza un errore se il diagramma non è stato caricato o è vuoto
595
+ TMExceptionBoxManager.show({ exception: new Error('Diagram not loaded.') });
596
+ return;
597
+ }
598
+ try {
599
+ // 1. Serializza il diagramma in XML
600
+ const xmlString = serializeWfDiagramToXml(wfDiagram);
601
+ // 2. Determina il nome del file (usa l'ID o un UUID se non disponibile)
602
+ const filename = `WorkflowDiagram_${wfDiagram.Info?.ID || generateUUID()}.xml`;
603
+ // 3. Avvia il download (la cartella è scelta dal browser)
604
+ downloadFile(xmlString, filename, 'application/xml');
605
+ }
606
+ catch (e) {
607
+ TMExceptionBoxManager.show({ exception: e });
608
+ }
609
+ }, [wfDiagram]); // Dipende dallo stato attuale del diagramma
592
610
  const calculateConnectionPath = useCallback((connection, sourceItem, sinkItem) => {
593
611
  const sourcePoint = getConnectionPoint(sourceItem, connection.Source.ConnectorName);
594
612
  const sinkPoint = getConnectionPoint(sinkItem, connection.Sink.ConnectorName);
@@ -1392,7 +1410,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
1392
1410
  isUndoingRedoing.current = false;
1393
1411
  }
1394
1412
  }, [wfDiagram]);
1395
- return (_jsxs(CanvasContainer, { children: [!readOnly && (_jsxs(ToolbarContainer, { "$isCollapsed": isToolbarCollapsed, "$isFloating": isToolbarFloating, "$isToolboxVisible": isToolboxVisible, children: [_jsx(ButtonGroup, { "$isFloating": isToolbarFloating, children: _jsxs("button", { onClick: handleToggleToolboxVisibility, title: "Show toolbox", children: [_jsx(IconFlowChart, {}), !isToolbarCollapsed && _jsx("span", { children: "Mostra/nascondi toolbox" })] }) }), _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [_jsxs("button", { onClick: handleUndo, disabled: historyIndex === 0, title: "Undo", children: [_jsx(IconUndo, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Undo" })] }), _jsxs("button", { onClick: handleRedo, disabled: historyIndex === wfDiagramHistory.length - 1, title: "Redo", children: [_jsx(IconUndo, { style: { transform: 'scaleX(-1)' } }), " ", !isToolbarCollapsed && _jsx("span", { children: "Redo" })] }), _jsxs("button", { onClick: handleRestore, title: "Restore", children: [_jsx(IconRestore, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Restore" })] }), _jsxs("button", { onClick: handleNew, title: "New diagram", disabled: readOnly, children: [_jsx(IconNew, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "New" })] })] }), _jsx(ButtonGroup, { "$isFloating": isToolbarFloating, children: _jsxs("button", { onClick: handleAutoAdjust, title: "Auto adjust", children: [_jsx(IconAdjust, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Auto Adjust" })] }) }), _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [_jsxs("button", { onClick: handleCopy, disabled: selectedItems.size === 0, title: "Copy", children: [_jsx(IconCopy, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Copy" })] }), _jsxs("button", { onClick: handleCut, disabled: selectedItems.size === 0, title: "Cut", children: [_jsx(IconCut, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Cut" })] }), _jsxs("button", { onClick: handlePaste, disabled: copiedItems.length === 0 && copiedConnections.length === 0, title: "Paste", children: [_jsx(IconPaste, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Paste" })] })] }), _jsxs("button", { onClick: handleToggleToolbarMode, title: isToolbarFloating ? "Dock Toolbar" : "Float Toolbar", children: [isToolbarFloating ? _jsx(IconPin, {}) : _jsx(IconUnpin, {}), !isToolbarCollapsed && !isToolbarFloating && _jsx("span", { children: "Toggle Mode" })] }), !isToolbarFloating && _jsx(ToolbarToggle, { onClick: () => setIsToolbarCollapsed(!isToolbarCollapsed), title: isToolbarCollapsed ? "Expand Toolbar" : "Collapse Toolbar", children: isToolbarCollapsed ? _jsx(IconChevronRight, {}) : _jsx(IconCloseOutline, {}) })] })), !readOnly && (_jsx(ToolboxContainer, { "$isVisible": isToolboxVisible, children: isToolboxVisible && availableItemTypes.map(type => (_jsxs(ToolboxItem, { draggable: true, onDragStart: (e) => handleToolboxDragStart(e, type), onDragEnd: handleToolboxDragEnd, children: [_jsx(DiagramItemSvgContent, { itemType: type, width: 40, height: 40, isToolboxPreview: true }), _jsx("span", { children: DiagramItemTypes[type] })] }, type))) })), _jsx(SvgScrollContainer, { children: isLoading ?
1413
+ return (_jsxs(CanvasContainer, { children: [!readOnly && (_jsxs(ToolbarContainer, { "$isCollapsed": isToolbarCollapsed, "$isFloating": isToolbarFloating, "$isToolboxVisible": isToolboxVisible, children: [_jsx(ButtonGroup, { "$isFloating": isToolbarFloating, children: _jsxs("button", { onClick: handleToggleToolboxVisibility, title: "Show toolbox", children: [_jsx(IconFlowChart, {}), !isToolbarCollapsed && _jsx("span", { children: "Mostra/nascondi toolbox" })] }) }), _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [_jsxs("button", { onClick: handleUndo, disabled: historyIndex === 0, title: "Undo", children: [_jsx(IconUndo, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Undo" })] }), _jsxs("button", { onClick: handleRedo, disabled: historyIndex === wfDiagramHistory.length - 1, title: "Redo", children: [_jsx(IconUndo, { style: { transform: 'scaleX(-1)' } }), " ", !isToolbarCollapsed && _jsx("span", { children: "Redo" })] }), _jsxs("button", { onClick: handleRestore, title: "Restore", children: [_jsx(IconRestore, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Restore" })] }), _jsxs("button", { onClick: handleNew, title: "New diagram", disabled: readOnly, children: [_jsx(IconNew, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "New" })] }), _jsxs("button", { onClick: handleExportDiagram, disabled: readOnly || !wfDiagram, title: SDKUI_Localizator.Export || 'Export Diagram', children: [_jsx(IconExport, {}), _jsx("span", { children: SDKUI_Localizator.Export || 'Export' })] })] }), _jsx(ButtonGroup, { "$isFloating": isToolbarFloating, children: _jsxs("button", { onClick: handleAutoAdjust, title: "Auto adjust", children: [_jsx(IconAdjust, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Auto Adjust" })] }) }), _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [_jsxs("button", { onClick: handleCopy, disabled: selectedItems.size === 0, title: "Copy", children: [_jsx(IconCopy, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Copy" })] }), _jsxs("button", { onClick: handleCut, disabled: selectedItems.size === 0, title: "Cut", children: [_jsx(IconCut, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Cut" })] }), _jsxs("button", { onClick: handlePaste, disabled: copiedItems.length === 0 && copiedConnections.length === 0, title: "Paste", children: [_jsx(IconPaste, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Paste" })] })] }), _jsxs("button", { onClick: handleToggleToolbarMode, title: isToolbarFloating ? "Dock Toolbar" : "Float Toolbar", children: [isToolbarFloating ? _jsx(IconPin, {}) : _jsx(IconUnpin, {}), !isToolbarCollapsed && !isToolbarFloating && _jsx("span", { children: "Toggle Mode" })] }), !isToolbarFloating && _jsx(ToolbarToggle, { onClick: () => setIsToolbarCollapsed(!isToolbarCollapsed), title: isToolbarCollapsed ? "Expand Toolbar" : "Collapse Toolbar", children: isToolbarCollapsed ? _jsx(IconChevronRight, {}) : _jsx(IconCloseOutline, {}) })] })), !readOnly && (_jsx(ToolboxContainer, { "$isVisible": isToolboxVisible, children: isToolboxVisible && availableItemTypes.map(type => (_jsxs(ToolboxItem, { draggable: true, onDragStart: (e) => handleToolboxDragStart(e, type), onDragEnd: handleToolboxDragEnd, children: [_jsx(DiagramItemSvgContent, { itemType: type, width: 40, height: 40, isToolboxPreview: true }), _jsx("span", { children: DiagramItemTypes[type] })] }, type))) })), _jsx(SvgScrollContainer, { children: isLoading ?
1396
1414
  (_jsxs(StyledLoadingContainer, { children: [_jsx(StyledSpinner, {}), _jsx("span", { children: `${'Caricamento diagramma'}...` })] })) : wfDiagram ? (_jsx(StyledSvg, { ref: svgRef, tabIndex: 0, onKeyDownCapture: handleKeyDown, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseDown: handleMouseDown, onDrop: handleDropOnCanvas, onDragOver: handleDragOver, width: svgWidth, height: svgHeight, children: _jsxs(ScalableGroup, { "$scale": zoomLevel, "$translateX": translateX, "$translateY": translateY, children: [wfDiagram?.DiagramItems.map(item => (_jsx(DiagramItemComponent, { wf: wfDiagram?.Info, readOnly: readOnly, item: item, isSelected: selectedItems.has(item.ID), isCurrent: item.ID === currentSetID, onClick: handleDiagramItemClick, onDrag: handleDrag, onDragEnd: handleDragEnd, onConnectorMouseDown: handleConnectorMouseDown, onConnectorMouseUp: handleConnectorMouseUp, onDimensionsChange: handleItemDimensionsChange, onDoubleClick: handleDoubleClickItem }, item.ID))), calculatedConnections.map(connection => {
1397
1415
  const sourceItem = wfDiagram?.DiagramItems.find(item => item.ID === connection.Source.ParentDiagramItem.ID);
1398
1416
  const sinkItem = wfDiagram?.DiagramItems.find(item => item.ID === connection.Sink.ParentDiagramItem.ID);
@@ -65,3 +65,4 @@ export declare const calculateDiagramItemFullDimensions: (item: DiagramItem, tex
65
65
  /** Helper function to get the color based on connection status */
66
66
  export declare const getConnectionColor: (status: WorkItemStatus) => string;
67
67
  export declare const validateDiagram: (diagram: WfDiagram, newConnection?: Connection) => void;
68
+ export declare const downloadFile: (data: string, filename: string, type: string) => void;
@@ -242,3 +242,14 @@ export const validateDiagram = (diagram, newConnection) => {
242
242
  // In futuro, puoi aggiungere qui la validazione per gli item del diagramma
243
243
  // ...
244
244
  };
245
+ export const downloadFile = (data, filename, type) => {
246
+ const blob = new Blob([data], { type });
247
+ const url = window.URL.createObjectURL(blob);
248
+ const a = document.createElement('a');
249
+ a.href = url;
250
+ a.download = filename;
251
+ document.body.appendChild(a);
252
+ a.click();
253
+ document.body.removeChild(a);
254
+ window.URL.revokeObjectURL(url);
255
+ };
@@ -1,3 +1,10 @@
1
1
  import { WfDiagram } from './interfaces';
2
+ import { CultureIDs, Severities, WFAppTypes, WorkItemSetRules, WorkItemStatus } from '@topconsultnpm/sdk-ts-beta';
3
+ export declare const getCultureIDsNumber: (cultureID: CultureIDs | undefined) => number;
4
+ export declare const getWorkItemStatusNumber: (status: WorkItemStatus | undefined) => number;
5
+ export declare const getSeveritiesNumber: (severity: Severities | undefined) => number;
6
+ export declare const getWorkItemSetRulesNumber: (setRule: WorkItemSetRules | undefined) => number;
7
+ export declare const getWFAppTypesNumber: (appType: WFAppTypes | undefined) => number;
8
+ export declare const mapCultureIDs: (cultureIDValue: number) => CultureIDs;
2
9
  export declare const parseWfDiagramXml: (xmlString: string) => WfDiagram;
3
- export declare function serializeWfDiagramToXml(diagram: WfDiagram): string;
10
+ export declare const serializeWfDiagramToXml: (wfDiagram: WfDiagram | null) => string;
@@ -1,7 +1,116 @@
1
1
  import { ArrowSymbol } from './interfaces';
2
- import { WorkItemStatus } from '@topconsultnpm/sdk-ts-beta';
2
+ import { CultureIDs, Severities, WFAppTypes, WorkItemSetRules, WorkItemStatus } from '@topconsultnpm/sdk-ts-beta';
3
3
  import { parseQueryDescriptorXml } from './queryDescriptorParser'; // Import the new parser
4
4
  import { parseMetadataValuesXml } from './metadataParser';
5
+ // Funzione helper per escapare i caratteri XML speciali (necessaria per i campi stringa)
6
+ const escapeXml = (unsafe) => {
7
+ if (unsafe === undefined || unsafe === null)
8
+ return '';
9
+ const str = String(unsafe);
10
+ return str.replace(/[<>&'"]/g, function (c) {
11
+ switch (c) {
12
+ case '<': return '&lt;';
13
+ case '>': return '&gt;';
14
+ case '&': return '&amp;';
15
+ case "'": return '&apos;';
16
+ case '"': return '&quot;';
17
+ default: return c;
18
+ }
19
+ });
20
+ };
21
+ export const getCultureIDsNumber = (cultureID) => {
22
+ switch (cultureID) {
23
+ case CultureIDs.It_IT:
24
+ return 1;
25
+ case CultureIDs.Fr_FR:
26
+ return 2;
27
+ case CultureIDs.En_US:
28
+ return 3;
29
+ case CultureIDs.Pt_PT:
30
+ return 4;
31
+ case CultureIDs.Es_ES:
32
+ return 5;
33
+ case CultureIDs.De_DE:
34
+ return 6;
35
+ case CultureIDs.None: // 0 è il default
36
+ default:
37
+ return 0;
38
+ }
39
+ };
40
+ export const getWorkItemStatusNumber = (status) => {
41
+ switch (status) {
42
+ case WorkItemStatus.New:
43
+ return 0;
44
+ case WorkItemStatus.Completed:
45
+ return 1;
46
+ case WorkItemStatus.Rejected:
47
+ return -1;
48
+ default:
49
+ return 0;
50
+ }
51
+ };
52
+ export const getSeveritiesNumber = (severity) => {
53
+ switch (severity) {
54
+ case Severities.None:
55
+ return 0;
56
+ case Severities.Critical:
57
+ return 1;
58
+ case Severities.Error:
59
+ return 2;
60
+ case Severities.Warning:
61
+ return 3;
62
+ case Severities.Information:
63
+ return 10;
64
+ default:
65
+ return 0;
66
+ }
67
+ };
68
+ export const getWorkItemSetRulesNumber = (setRule) => {
69
+ switch (setRule) {
70
+ case WorkItemSetRules.Ands_AND_Ors:
71
+ return 0;
72
+ case WorkItemSetRules.Ands_OR_Ors:
73
+ return 1;
74
+ case WorkItemSetRules.Custom:
75
+ return 2;
76
+ default:
77
+ return 0;
78
+ }
79
+ };
80
+ export const getWFAppTypesNumber = (appType) => {
81
+ switch (appType) {
82
+ case WFAppTypes.None:
83
+ return 0;
84
+ case WFAppTypes.EXE:
85
+ return 1;
86
+ case WFAppTypes.SP:
87
+ return 2;
88
+ case WFAppTypes.REST:
89
+ return 3;
90
+ default:
91
+ return 0;
92
+ }
93
+ };
94
+ export const mapCultureIDs = (cultureIDValue) => {
95
+ switch (cultureIDValue) {
96
+ case 1:
97
+ return CultureIDs.It_IT;
98
+ case 2:
99
+ return CultureIDs.Fr_FR;
100
+ case 3:
101
+ return CultureIDs.En_US;
102
+ case 4:
103
+ return CultureIDs.Pt_PT;
104
+ case 5:
105
+ return CultureIDs.Es_ES;
106
+ case 6:
107
+ return CultureIDs.De_DE;
108
+ case 0: // 0 è None
109
+ default:
110
+ console.warn(`Valore CultureID sconosciuto: ${cultureIDValue}. Ritorno CultureIDs.None.`);
111
+ return CultureIDs.None;
112
+ }
113
+ };
5
114
  // Funzione helper per mappare i valori numerici di OutputStatus
6
115
  const mapOutputStatus = (statusValue) => {
7
116
  switch (statusValue) {
@@ -12,11 +121,75 @@ const mapOutputStatus = (statusValue) => {
12
121
  case -1:
13
122
  return WorkItemStatus.Rejected;
14
123
  default:
15
- // Gestisci il caso di un valore sconosciuto, potresti voler lanciare un errore o ritornare un default
16
124
  console.warn(`Valore OutputStatus sconosciuto: ${statusValue}. Ritorno WorkItemStatus.New.`);
17
125
  return WorkItemStatus.New;
18
126
  }
19
127
  };
128
+ // Funzione helper per mappare i valori numerici di Severity (dal precedente problema)
129
+ const mapSeverity = (severityValue) => {
130
+ switch (severityValue) {
131
+ case 0:
132
+ return Severities.None;
133
+ case 1:
134
+ return Severities.Critical;
135
+ case 2:
136
+ return Severities.Error;
137
+ case 3:
138
+ return Severities.Warning;
139
+ case 10: // Mappatura da 10 a Information come nell'enum C#
140
+ return Severities.Information;
141
+ default:
142
+ console.warn(`Valore Severity sconosciuto: ${severityValue}. Ritorno Severities.None.`);
143
+ return Severities.None;
144
+ }
145
+ };
146
+ // Funzione helper per mappare i valori numerici di WorkItemSetRules
147
+ const mapWorkItemSetRules = (ruleValue) => {
148
+ switch (ruleValue) {
149
+ case 0:
150
+ return WorkItemSetRules.Ands_AND_Ors;
151
+ case 1:
152
+ return WorkItemSetRules.Ands_OR_Ors;
153
+ case 2:
154
+ return WorkItemSetRules.Custom;
155
+ default:
156
+ console.warn(`Valore WorkItemSetRules sconosciuto: ${ruleValue}. Ritorno WorkItemSetRules.Ands_AND_Ors.`);
157
+ return WorkItemSetRules.Ands_AND_Ors;
158
+ }
159
+ };
160
+ // Funzione helper per mappare i valori numerici di WFAppTypes
161
+ const mapWFAppTypes = (appTypeValue) => {
162
+ switch (appTypeValue) {
163
+ case 0:
164
+ return WFAppTypes.None;
165
+ case 1:
166
+ return WFAppTypes.EXE;
167
+ case 2:
168
+ return WFAppTypes.SP;
169
+ case 3:
170
+ return WFAppTypes.REST;
171
+ default:
172
+ console.warn(`Valore WFAppTypes sconosciuto: ${appTypeValue}. Ritorno WFAppTypes.None.`);
173
+ return WFAppTypes.None;
174
+ }
175
+ };
176
+ // Placeholder per la serializzazione di QueryDescriptor in XML (DA MODIFICARE CON LA LOGICA REALE)
177
+ const serializeQueryDescriptorXml = (qd) => {
178
+ if (qd) {
179
+ // Logica di serializzazione reale qui, ad esempio:
180
+ // return `<ID>${qd.ID}</ID><Query>${escapeXml(qd.Query)}</Query>...`
181
+ return '[QUERY_DESCRIPTOR_XML_PLACEHOLDER]';
182
+ }
183
+ return '';
184
+ };
185
+ // Placeholder per la serializzazione di MetadataValues in XML (DA MODIFICARE CON LA LOGICA REALE)
186
+ const serializeMetadataValuesXml = (values) => {
187
+ if (!values || values.length === 0)
188
+ return '';
189
+ // Logica di serializzazione reale qui, ad esempio per ogni elemento in values:
190
+ // return values.map(v => `<Value Name="${v.Name}">${v.Value}</Value>`).join('');
191
+ return '[METADATA_VALUES_XML_PLACEHOLDER]';
192
+ };
20
193
  export const parseWfDiagramXml = (xmlString) => {
21
194
  const parser = new DOMParser();
22
195
  const xmlDoc = parser.parseFromString(xmlString, "application/xml");
@@ -78,6 +251,9 @@ export const parseWfDiagramXml = (xmlString) => {
78
251
  const startAfterUpdateMIDsArray = (startAfterUpdateMIDsContent && startAfterUpdateMIDsContent !== '')
79
252
  ? startAfterUpdateMIDsContent.split(';').map(Number)
80
253
  : undefined;
254
+ const xmlSeverity = parseInt(itemXML.querySelector("Severity")?.textContent || "0", 10);
255
+ const xmlSetRule = parseInt(itemXML.querySelector("SetRule")?.textContent || "0", 10);
256
+ const xmlAppType = parseInt(itemXML.querySelector("AppType")?.textContent || "0", 10);
81
257
  const item = {
82
258
  ID: itemXML.querySelector("ID")?.textContent || "",
83
259
  Left: left,
@@ -103,7 +279,7 @@ export const parseWfDiagramXml = (xmlString) => {
103
279
  RegisterPost: itemXML.querySelector("RegisterPost")?.textContent === "true",
104
280
  AllowZeroTos: itemXML.querySelector("AllowZeroTos")?.textContent === "true",
105
281
  Tos: itemXML.querySelector("Tos")?.textContent || undefined,
106
- SetRule: parseInt(itemXML.querySelector("SetRule")?.textContent || "0", 10),
282
+ SetRule: mapWorkItemSetRules(xmlSetRule),
107
283
  StartAfterArchive: parseInt(itemXML.querySelector("StartAfterArchive")?.textContent || "0", 10),
108
284
  StartAfterUpdate: parseInt(itemXML.querySelector("StartAfterUpdate")?.textContent || "0", 10),
109
285
  StartAfterUpdateMIDs: startAfterUpdateMIDsArray,
@@ -113,9 +289,9 @@ export const parseWfDiagramXml = (xmlString) => {
113
289
  QD: parsedQD,
114
290
  SOD: itemXML.querySelector("SOD")?.textContent || undefined,
115
291
  MetadataValues: parsedMetadataValues,
116
- Severity: parseInt(itemXML.querySelector("Severity")?.textContent || "0", 10),
292
+ Severity: mapSeverity(xmlSeverity),
117
293
  RegAsWfInstPart: parseInt(itemXML.querySelector("RegAsWfInstPart")?.textContent || "0", 10),
118
- FormatCultureID: parseInt(itemXML.querySelector("FormatCultureID")?.textContent || "0", 10),
294
+ FormatCultureID: mapCultureIDs(parseInt(itemXML.querySelector("FormatCultureID")?.textContent || "0", 10)),
119
295
  Tos2: itemXML.querySelector("Tos2")?.textContent || undefined,
120
296
  QD2: itemXML.querySelector("QD2")?.textContent || undefined,
121
297
  PlatformObjName: itemXML.querySelector("PlatformObjName")?.textContent || undefined,
@@ -124,7 +300,7 @@ export const parseWfDiagramXml = (xmlString) => {
124
300
  Value2asInt: parseInt(itemXML.querySelector("Value2asInt")?.textContent || "0", 10),
125
301
  Value3asInt: parseInt(itemXML.querySelector("Value3asInt")?.textContent || "0", 10),
126
302
  Value1asString: itemXML.querySelector("Value1asString")?.textContent || undefined,
127
- AppType: parseInt(itemXML.querySelector("AppType")?.textContent || "0", 10),
303
+ AppType: mapWFAppTypes(xmlAppType),
128
304
  AppName: itemXML.querySelector("AppName")?.textContent || undefined,
129
305
  AppArgs: itemXML.querySelector("AppArgs")?.textContent || undefined,
130
306
  Trunc: parseInt(itemXML.querySelector("Trunc")?.textContent || "0", 10),
@@ -161,105 +337,146 @@ export const parseWfDiagramXml = (xmlString) => {
161
337
  return wfDiagram;
162
338
  };
163
339
  // Funzione di serializzazione (inclusa per completezza, se l'avevi)
164
- export function serializeWfDiagramToXml(diagram) {
165
- let xml = `<Root>`;
166
- if (diagram.Info) {
167
- xml += `<Workflow>`;
168
- xml += `<WFID>${diagram.Info.ID}</WFID>`;
169
- xml += `<WFMTID>${diagram.Info.MTID}</WFMTID>`;
170
- xml += `<WFMStatusMID>${diagram.Info.MStatusMID}</WFMStatusMID>`;
171
- xml += `<WFMStatusDLID>${diagram.Info.MStatusDLID}</WFMStatusDLID>`;
172
- // Aggiungi <Type> se esiste in Info
173
- xml += `</Workflow>`;
340
+ export const serializeWfDiagramToXml = (wfDiagram) => {
341
+ if (!wfDiagram) {
342
+ return '<?xml version="1.0" encoding="utf-8"?>\n<Root></Root>';
174
343
  }
175
- xml += `<DiagramItems>`;
176
- diagram.DiagramItems.forEach(item => {
177
- xml += `<DiagramItem>`;
178
- xml += `<ID>${item.ID}</ID>`;
179
- xml += `<L>${item.Left}</L>`;
180
- xml += `<T>${item.Top}</T>`;
181
- xml += `<W>${item.Width}</W>`;
182
- xml += `<H>${item.Height}</H>`;
183
- xml += `<Type>${item.Type}</Type>`;
184
- xml += `<Name>${item.ItemName}</Name>`;
185
- xml += `<Description>${item.Description}</Description>`;
186
- xml += `<StatusValue>${item.StatusValue || ''}</StatusValue>`;
187
- xml += `<RegisterPost>${item.RegisterPost || false}</RegisterPost>`;
188
- xml += `<AllowZeroTos>${item.AllowZeroTos || false}</AllowZeroTos>`;
189
- xml += `<Tos>${item.Tos || ''}</Tos>`;
190
- xml += `<SetRule>${item.SetRule || 0}</SetRule>`;
191
- xml += `<StartAfterArchive>${item.StartAfterArchive || 0}</StartAfterArchive>`;
192
- xml += `<StartAfterUpdate>${item.StartAfterUpdate || 0}</StartAfterUpdate>`;
193
- xml += `<StartAfterUpdateMIDs>${item.StartAfterUpdateMIDs || ''}</StartAfterUpdateMIDs>`;
194
- xml += `<StartManual>${item.StartManual || 0}</StartManual>`;
195
- xml += `<Hist>${item.Hist || 0}</Hist>`;
196
- xml += `<EndWFInstance>${item.EndWFInstance || 0}</EndWFInstance>`;
197
- // Handling serialization of QueryDescriptor:
198
- // This is tricky because DataContractSerializer produces specific XML.
199
- // If you need to serialize it back to the exact DataContract XML format,
200
- // you would ideally have a `serializeQueryDescriptorToXml` function.
201
- // For now, if QD is an object, you cannot simply do `${item.QD || ''}`.
202
- // You would need to re-serialize it. Since the original XML already contained the string,
203
- // and we parsed it, re-serializing it perfectly matches the C# DataContractSerializer
204
- // output can be complex.
205
- // For simple cases, you might stringify it as JSON if the C# side can read it,
206
- // or re-generate the XML structure manually.
207
- // For now, if you are *only* parsing, this is fine. If you also need to serialize,
208
- // you will need a corresponding serialization function for QueryDescriptor that
209
- // matches the C# DataContractSerializer's output precisely.
210
- xml += `<QD>${JSON.stringify(item.QD) || ''}</QD>`; // Placeholder - this won't match C# XML
211
- xml += `<SOD>${item.SOD || ''}</SOD>`;
212
- xml += `<MetadataValues>${item.MetadataValues || ''}</MetadataValues>`;
213
- xml += `<Severity>${item.Severity || 0}</Severity>`;
214
- xml += `<RegAsWfInstPart>${item.RegAsWfInstPart || 0}</RegAsWfInstPart>`;
215
- xml += `<FormatCultureID>${item.FormatCultureID || 0}</FormatCultureID>`;
216
- xml += `<Tos2>${item.Tos2 || ''}</Tos2>`;
217
- xml += `<QD2>${item.QD2 || ''}</QD2>`;
218
- xml += `<PlatformObjName>${item.PlatformObjName || ''}</PlatformObjName>`;
219
- xml += `<PlatformObjDescr>${item.PlatformObjDescr || ''}</PlatformObjDescr>`;
220
- xml += `<Value1asInt>${item.Value1asInt || 0}</Value1asInt>`;
221
- xml += `<Value2asInt>${item.Value2asInt || 0}</Value2asInt>`;
222
- xml += `<Value3asInt>${item.Value3asInt || 0}</Value3asInt>`;
223
- xml += `<Value1asString>${item.Value1asString || ''}</Value1asString>`;
224
- xml += `<AppType>${item.AppType || 0}</AppType>`;
225
- xml += `<AppName>${item.AppName || ''}</AppName>`;
226
- xml += `<AppArgs>${item.AppArgs || ''}</AppArgs>`;
227
- xml += `<Trunc>${item.Trunc || 0}</Trunc>`;
228
- xml += `</DiagramItem>`;
229
- });
230
- xml += `</DiagramItems>`;
231
- xml += `<Connections>`;
232
- diagram.Connections.forEach(conn => {
233
- xml += `<Connection>`;
234
- xml += `<ID>${conn.ID}</ID>`;
235
- xml += `<SourceID>${conn.Source.ParentDiagramItem.ID}</SourceID>`;
236
- // Assicurati che conn.Source.ConnectorName esista e contenga il valore corretto
237
- xml += `<SourceConnectorName>${conn.Source.ConnectorName || ''}</SourceConnectorName>`;
238
- xml += `<SinkID>${conn.Sink.ParentDiagramItem.ID}</SinkID>`;
239
- // Assicurati che conn.Sink.ConnectorName esista e contenga il valore corretto
240
- xml += `<SinkConnectorName>${conn.Sink.ConnectorName || ''}</SinkConnectorName>`;
241
- // Mappa il valore dell'enum WorkItemStatus a un numero per la serializzazione
242
- let outputStatusNumber;
243
- switch (conn.OutputStatus) {
244
- case WorkItemStatus.New:
245
- outputStatusNumber = 0;
246
- break;
247
- case WorkItemStatus.Completed:
248
- outputStatusNumber = 1;
249
- break;
250
- case WorkItemStatus.Rejected:
251
- outputStatusNumber = -1;
252
- break;
253
- default:
254
- outputStatusNumber = 0; // Default per sicurezza
344
+ let xml = '<?xml version="1.0" encoding="utf-8"?>\n';
345
+ xml += '<Root>\n';
346
+ // 1. Serializzazione WfInfo
347
+ if (wfDiagram.Info) {
348
+ xml += ' <Workflow>\n';
349
+ xml += ` <WFID>${escapeXml(wfDiagram.Info.ID)}</WFID>\n`;
350
+ xml += ` <WFMTID>${wfDiagram.Info.MTID}</WFMTID>\n`;
351
+ xml += ` <WFMStatusMID>${wfDiagram.Info.MStatusMID}</WFMStatusMID>\n`;
352
+ xml += ` <WFMStatusDLID>${wfDiagram.Info.MStatusDLID}</WFMStatusDLID>\n`;
353
+ xml += ' </Workflow>\n';
354
+ }
355
+ // 2. Serializzazione DiagramItems
356
+ xml += ' <DiagramItems>\n';
357
+ wfDiagram.DiagramItems.forEach(item => {
358
+ xml += ' <DiagramItem>\n';
359
+ xml += ` <ID>${escapeXml(item.ID)}</ID>\n`;
360
+ xml += ` <L>${item.Left}</L>\n`;
361
+ xml += ` <T>${item.Top}</T>\n`;
362
+ xml += ` <W>${item.Width}</W>\n`;
363
+ xml += ` <H>${item.Height}</H>\n`;
364
+ xml += ` <Type>${item.Type}</Type>\n`;
365
+ xml += ` <Name>${escapeXml(item.ItemName)}</Name>\n`;
366
+ // Nomi localizzati
367
+ if (item.ItemName_IT)
368
+ xml += ` <Name_IT>${escapeXml(item.ItemName_IT)}</Name_IT>\n`;
369
+ if (item.ItemName_EN)
370
+ xml += ` <Name_EN>${escapeXml(item.ItemName_EN)}</Name_EN>\n`;
371
+ if (item.ItemName_FR)
372
+ xml += ` <Name_FR>${escapeXml(item.ItemName_FR)}</Name_FR>\n`;
373
+ if (item.ItemName_PT)
374
+ xml += ` <Name_PT>${escapeXml(item.ItemName_PT)}</Name_PT>\n`;
375
+ if (item.ItemName_ES)
376
+ xml += ` <Name_ES>${escapeXml(item.ItemName_ES)}</Name_ES>\n`;
377
+ if (item.ItemName_DE)
378
+ xml += ` <Name_DE>${escapeXml(item.ItemName_DE)}</Name_DE>\n`;
379
+ xml += ` <Description>${escapeXml(item.Description)}</Description>\n`;
380
+ // Descrizioni localizzate
381
+ if (item.Description_IT)
382
+ xml += ` <Description_IT>${escapeXml(item.Description_IT)}</Description_IT>\n`;
383
+ if (item.Description_EN)
384
+ xml += ` <Description_EN>${escapeXml(item.Description_EN)}</Description_EN>\n`;
385
+ if (item.Description_FR)
386
+ xml += ` <Description_FR>${escapeXml(item.Description_FR)}</Description_FR>\n`;
387
+ if (item.Description_PT)
388
+ xml += ` <Description_PT>${escapeXml(item.Description_PT)}</Description_PT>\n`;
389
+ if (item.Description_ES)
390
+ xml += ` <Description_ES>${escapeXml(item.Description_ES)}</Description_ES>\n`;
391
+ if (item.Description_DE)
392
+ xml += ` <Description_DE>${escapeXml(item.Description_DE)}</Description_DE>\n`;
393
+ if (item.StatusValue)
394
+ xml += ` <StatusValue>${escapeXml(item.StatusValue)}</StatusValue>\n`;
395
+ if (item.RegisterPost !== undefined)
396
+ xml += ` <RegisterPost>${item.RegisterPost ? 'true' : 'false'}</RegisterPost>\n`;
397
+ if (item.AllowZeroTos !== undefined)
398
+ xml += ` <AllowZeroTos>${item.AllowZeroTos ? 'true' : 'false'}</AllowZeroTos>\n`;
399
+ if (item.Tos)
400
+ xml += ` <Tos>${escapeXml(item.Tos)}</Tos>\n`;
401
+ if (item.SetRule !== undefined)
402
+ xml += ` <SetRule>${getWorkItemSetRulesNumber(item.SetRule)}</SetRule>\n`;
403
+ if (item.StartAfterArchive !== undefined)
404
+ xml += ` <StartAfterArchive>${item.StartAfterArchive}</StartAfterArchive>\n`;
405
+ if (item.StartAfterUpdate !== undefined)
406
+ xml += ` <StartAfterUpdate>${item.StartAfterUpdate}</StartAfterUpdate>\n`;
407
+ if (item.StartAfterUpdateMIDs && item.StartAfterUpdateMIDs.length > 0) {
408
+ xml += ` <StartAfterUpdateMIDs>${item.StartAfterUpdateMIDs.join(';')}</StartAfterUpdateMIDs>\n`;
409
+ }
410
+ if (item.StartManual !== undefined)
411
+ xml += ` <StartManual>${item.StartManual}</StartManual>\n`;
412
+ if (item.Hist !== undefined)
413
+ xml += ` <Hist>${item.Hist}</Hist>\n`;
414
+ if (item.EndWFInstance !== undefined)
415
+ xml += ` <EndWFInstance>${item.EndWFInstance}</EndWFInstance>\n`;
416
+ // QueryDescriptor (QD)
417
+ if (item.QD) {
418
+ const qdXmlContent = serializeQueryDescriptorXml(item.QD);
419
+ xml += ` <QD><![CDATA[${qdXmlContent}]]></QD>\n`;
420
+ }
421
+ if (item.SOD)
422
+ xml += ` <SOD>${escapeXml(item.SOD)}</SOD>\n`;
423
+ // MetadataValues
424
+ if (item.MetadataValues) {
425
+ const mvXmlContent = serializeMetadataValuesXml(item.MetadataValues);
426
+ xml += ` <MetadataValues><![CDATA[${mvXmlContent}]]></MetadataValues>\n`;
255
427
  }
256
- xml += `<OutputStatus>${outputStatusNumber}</OutputStatus>`;
257
- xml += `<Description>${conn.Description || ''}</Description>`;
258
- xml += `<SourceArrowSymbol>${conn.SourceArrowSymbol === ArrowSymbol.Arrow ? 'Arrow' : 'None'}</SourceArrowSymbol>`;
259
- xml += `<SinkArrowSymbol>${conn.SinkArrowSymbol === ArrowSymbol.Arrow ? 'Arrow' : 'None'}</SinkArrowSymbol>`;
260
- xml += `</Connection>`;
428
+ if (item.Severity !== undefined)
429
+ xml += ` <Severity>${getSeveritiesNumber(item.Severity)}</Severity>\n`;
430
+ if (item.RegAsWfInstPart !== undefined)
431
+ xml += ` <RegAsWfInstPart>${item.RegAsWfInstPart}</RegAsWfInstPart>\n`;
432
+ if (item.FormatCultureID !== undefined)
433
+ xml += ` <FormatCultureID>${getCultureIDsNumber(item.FormatCultureID)}</FormatCultureID>\n`;
434
+ if (item.Tos2)
435
+ xml += ` <Tos2>${escapeXml(item.Tos2)}</Tos2>\n`;
436
+ if (item.QD2)
437
+ xml += ` <QD2>${escapeXml(item.QD2)}</QD2>\n`;
438
+ if (item.PlatformObjName)
439
+ xml += ` <PlatformObjName>${escapeXml(item.PlatformObjName)}</PlatformObjName>\n`;
440
+ if (item.PlatformObjDescr)
441
+ xml += ` <PlatformObjDescr>${escapeXml(item.PlatformObjDescr)}</PlatformObjDescr>\n`;
442
+ if (item.Value1asInt !== undefined)
443
+ xml += ` <Value1asInt>${item.Value1asInt}</Value1asInt>\n`;
444
+ if (item.Value2asInt !== undefined)
445
+ xml += ` <Value2asInt>${item.Value2asInt}</Value2asInt>\n`;
446
+ if (item.Value3asInt !== undefined)
447
+ xml += ` <Value3asInt>${item.Value3asInt}</Value3asInt>\n`;
448
+ if (item.Value1asString)
449
+ xml += ` <Value1asString>${escapeXml(item.Value1asString)}</Value1asString>\n`;
450
+ if (item.AppType !== undefined)
451
+ xml += ` <AppType>${getWFAppTypesNumber(item.AppType)}</AppType>\n`;
452
+ if (item.AppName)
453
+ xml += ` <AppName>${escapeXml(item.AppName)}</AppName>\n`;
454
+ if (item.AppArgs)
455
+ xml += ` <AppArgs>${escapeXml(item.AppArgs)}</AppArgs>\n`;
456
+ if (item.Trunc !== undefined)
457
+ xml += ` <Trunc>${item.Trunc}</Trunc>\n`;
458
+ xml += ' </DiagramItem>\n';
261
459
  });
262
- xml += `</Connections>`;
263
- xml += `</Root>`;
460
+ xml += ' </DiagramItems>\n';
461
+ // 3. Serializzazione Connections
462
+ xml += ' <Connections>\n';
463
+ wfDiagram.Connections.forEach(conn => {
464
+ xml += ' <Connection>\n';
465
+ xml += ` <ID>${escapeXml(conn.ID)}</ID>\n`;
466
+ xml += ` <SourceID>${escapeXml(conn.Source.ParentDiagramItem.ID)}</SourceID>\n`;
467
+ xml += ` <SourceConnectorName>${escapeXml(conn.Source.ConnectorName || '')}</SourceConnectorName>\n`;
468
+ xml += ` <SinkID>${escapeXml(conn.Sink.ParentDiagramItem.ID)}</SinkID>\n`;
469
+ xml += ` <SinkConnectorName>${escapeXml(conn.Sink.ConnectorName || '')}</SinkConnectorName>\n`;
470
+ const outputStatusNumber = getWorkItemStatusNumber(conn.OutputStatus);
471
+ xml += ` <OutputStatus>${outputStatusNumber}</OutputStatus>\n`;
472
+ xml += ` <Description>${escapeXml(conn.Description || '')}</Description>\n`;
473
+ const sourceArrow = conn.SourceArrowSymbol === ArrowSymbol.Arrow ? 'Arrow' : (conn.SourceArrowSymbol === ArrowSymbol.Diamond ? 'Diamond' : 'None');
474
+ const sinkArrow = conn.SinkArrowSymbol === ArrowSymbol.Arrow ? 'Arrow' : (conn.SinkArrowSymbol === ArrowSymbol.Diamond ? 'Diamond' : 'None');
475
+ xml += ` <SourceArrowSymbol>${sourceArrow}</SourceArrowSymbol>\n`;
476
+ xml += ` <SinkArrowSymbol>${sinkArrow}</SinkArrowSymbol>\n`;
477
+ xml += ' </Connection>\n';
478
+ });
479
+ xml += ' </Connections>\n';
480
+ xml += '</Root>';
264
481
  return xml;
265
- }
482
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.16.59",
3
+ "version": "6.16.60",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",