@topconsultnpm/sdkui-react 6.20.0-test1 → 6.20.0
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.
- package/lib/components/NewComponents/ContextMenu/styles.d.ts +3 -1
- package/lib/components/NewComponents/ContextMenu/styles.js +7 -5
- package/lib/components/base/Styled.d.ts +4 -1
- package/lib/components/base/Styled.js +11 -3
- package/lib/components/base/TMPanel.js +6 -4
- package/lib/components/base/TMPopUp.js +4 -0
- package/lib/components/base/TMTreeView.d.ts +3 -1
- package/lib/components/base/TMTreeView.js +68 -21
- package/lib/components/choosers/TMDataListItemChooser.js +1 -1
- package/lib/components/choosers/TMDataListItemEditor.d.ts +11 -0
- package/lib/components/choosers/TMDataListItemEditor.js +130 -0
- package/lib/components/choosers/TMDataListItemFields.d.ts +11 -0
- package/lib/components/choosers/TMDataListItemFields.js +61 -0
- package/lib/components/choosers/TMDataListItemPicker.d.ts +2 -0
- package/lib/components/choosers/TMDataListItemPicker.js +182 -18
- package/lib/components/choosers/TMDynDataListItemChooser.js +11 -6
- package/lib/components/choosers/TMImageIDChooser.d.ts +16 -0
- package/lib/components/choosers/TMImageIDChooser.js +53 -0
- package/lib/components/choosers/TMMetadataChooser.js +1 -1
- package/lib/components/choosers/TMUserChooser.js +1 -1
- package/lib/components/editors/TMDateBox.js +1 -1
- package/lib/components/editors/TMHtmlEditor.js +1 -1
- package/lib/components/editors/TMLocalizedTextBox.d.ts +1 -0
- package/lib/components/editors/TMLocalizedTextBox.js +3 -3
- package/lib/components/editors/TMMetadataValues.js +203 -41
- package/lib/components/editors/TMTextArea.d.ts +1 -0
- package/lib/components/editors/TMTextArea.js +6 -6
- package/lib/components/editors/TMTextBox.js +9 -10
- package/lib/components/features/archive/TMArchive.d.ts +3 -1
- package/lib/components/features/archive/TMArchive.js +31 -44
- package/lib/components/features/blog/TMBlogCommentForm.d.ts +3 -0
- package/lib/components/features/blog/TMBlogCommentForm.js +42 -36
- package/lib/components/features/documents/TMDcmtForm.d.ts +3 -1
- package/lib/components/features/documents/TMDcmtForm.js +215 -54
- package/lib/components/features/documents/TMDcmtPreview.js +66 -13
- package/lib/components/features/documents/TMDcmtTasks.d.ts +3 -1
- package/lib/components/features/documents/TMDcmtTasks.js +2 -2
- package/lib/components/features/documents/TMFileUploader.d.ts +5 -0
- package/lib/components/features/documents/TMFileUploader.js +28 -6
- package/lib/components/features/documents/TMMasterDetailDcmts.js +31 -85
- package/lib/components/features/documents/TMRelationViewer.d.ts +7 -1
- package/lib/components/features/documents/TMRelationViewer.js +497 -111
- package/lib/components/features/search/TMSearchQueryPanel.js +6 -6
- package/lib/components/features/search/TMSearchResult.d.ts +2 -0
- package/lib/components/features/search/TMSearchResult.js +106 -86
- package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +1 -1
- package/lib/components/features/search/TMSearchResultsMenuItems.js +6 -18
- package/lib/components/features/search/TMSignatureInfoContent.js +10 -6
- package/lib/components/features/search/TMTreeSelector.js +1 -1
- package/lib/components/features/tasks/TMTaskForm.d.ts +1 -0
- package/lib/components/features/tasks/TMTaskForm.js +61 -193
- package/lib/components/features/tasks/TMTaskFormUtils.d.ts +80 -0
- package/lib/components/features/tasks/TMTaskFormUtils.js +559 -0
- package/lib/components/features/tasks/TMTasksUtils.d.ts +3 -1
- package/lib/components/features/tasks/TMTasksUtils.js +46 -16
- package/lib/components/features/tasks/TMTasksUtilsView.d.ts +0 -7
- package/lib/components/features/tasks/TMTasksUtilsView.js +7 -14
- package/lib/components/features/tasks/TMTasksView.js +5 -3
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +20 -3
- package/lib/components/features/workflow/TMWorkflowPopup.js +21 -109
- package/lib/components/features/workflow/diagram/ConnectionComponent.d.ts +1 -0
- package/lib/components/features/workflow/diagram/ConnectionComponent.js +6 -2
- package/lib/components/features/workflow/diagram/DiagramItemForm.d.ts +2 -0
- package/lib/components/features/workflow/diagram/DiagramItemForm.js +32 -25
- package/lib/components/features/workflow/diagram/RecipientList.d.ts +3 -1
- package/lib/components/features/workflow/diagram/RecipientList.js +13 -9
- package/lib/components/features/workflow/diagram/WFDiagram.js +102 -5
- package/lib/components/features/workflow/diagram/workflowHelpers.js +31 -19
- package/lib/components/forms/Login/TMLoginForm.js +1 -1
- package/lib/components/forms/TMSaveForm.js +61 -13
- package/lib/components/grids/TMBlogsPost.js +8 -8
- package/lib/components/grids/TMBlogsPostUtils.js +2 -2
- package/lib/components/grids/TMRecentsManager.js +1 -1
- package/lib/components/index.d.ts +2 -0
- package/lib/components/index.js +2 -0
- package/lib/components/layout/panelManager/TMPanelManagerContainer.js +3 -2
- package/lib/components/pages/TMPage.js +4 -0
- package/lib/components/query/TMQueryEditor.d.ts +1 -0
- package/lib/components/query/TMQueryEditor.js +3 -3
- package/lib/components/viewers/TMMidViewer.js +2 -1
- package/lib/components/viewers/TMTidViewer.js +7 -3
- package/lib/helper/Enum_Localizator.js +5 -0
- package/lib/helper/GlobalStyles.js +3 -0
- package/lib/helper/SDKUI_Globals.d.ts +12 -0
- package/lib/helper/SDKUI_Globals.js +21 -1
- package/lib/helper/SDKUI_Localizator.d.ts +31 -7
- package/lib/helper/SDKUI_Localizator.js +286 -46
- package/lib/helper/TMIcons.d.ts +2 -1
- package/lib/helper/TMIcons.js +4 -1
- package/lib/helper/TMUtils.d.ts +33 -41
- package/lib/helper/TMUtils.js +157 -170
- package/lib/helper/helpers.d.ts +6 -2
- package/lib/helper/helpers.js +24 -8
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/helper/queryHelper.js +1 -1
- package/lib/hooks/useBetaFeatures.d.ts +1 -0
- package/lib/hooks/useBetaFeatures.js +41 -0
- package/lib/hooks/useDataUserIdItem.js +2 -2
- package/lib/hooks/useDcmtOperations.js +14 -2
- package/lib/hooks/useRelatedDocuments.js +64 -42
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/services/platform_services.d.ts +1 -1
- package/lib/services/platform_services.js +4 -0
- package/lib/ts/types.d.ts +3 -0
- package/package.json +2 -2
- package/lib/components/features/search/TMSignSettingsForm.d.ts +0 -9
- package/lib/components/features/search/TMSignSettingsForm.js +0 -621
|
@@ -10,7 +10,7 @@ import TMTextBox from '../../../editors/TMTextBox';
|
|
|
10
10
|
import TMButton from '../../../base/TMButton';
|
|
11
11
|
import styled from 'styled-components';
|
|
12
12
|
import TMQuerySummary from '../../../query/TMQuerySummary';
|
|
13
|
-
import { CultureIDs, DcmtTypeListCacheService, FromItem, MetadataDataDomains, SDK_Globals, SearchEngine, Severities, WFAppTypes, WorkItemSetRules } from '@topconsultnpm/sdk-ts';
|
|
13
|
+
import { CultureIDs, DcmtTypeListCacheService, FromItem, MetadataDataDomains, ResultTypes, SDK_Globals, SearchEngine, Severities, WFAppTypes, WorkItemSetRules } from '@topconsultnpm/sdk-ts';
|
|
14
14
|
import TMLocalizedTextBox from '../../../editors/TMLocalizedTextBox';
|
|
15
15
|
import TMDataListItemPicker from '../../../choosers/TMDataListItemPicker';
|
|
16
16
|
import WorkitemRecipientsEditor, { actorsToTos, RecipientsContainer, tosToActors } from './WorkitemRecipientsEditor';
|
|
@@ -30,9 +30,16 @@ import { DiagramItemProps, wfDiagramItemValidator } from './workflowHelpers';
|
|
|
30
30
|
const FormContainer = styled.div `
|
|
31
31
|
display: flex;
|
|
32
32
|
flex-direction: column;
|
|
33
|
-
|
|
33
|
+
height: 100%;
|
|
34
34
|
padding: 10px;
|
|
35
35
|
`;
|
|
36
|
+
const FieldsContainer = styled.div `
|
|
37
|
+
display: flex;
|
|
38
|
+
flex-direction: column;
|
|
39
|
+
gap: 5px;
|
|
40
|
+
flex: 1;
|
|
41
|
+
overflow-y: auto;
|
|
42
|
+
`;
|
|
36
43
|
const FlexContainer = styled.div `
|
|
37
44
|
display: flex;
|
|
38
45
|
align-items: center;
|
|
@@ -76,7 +83,7 @@ const APP_TYPES_DATASOURCE = [
|
|
|
76
83
|
{ value: WFAppTypes.SP, display: "SP" },
|
|
77
84
|
{ value: WFAppTypes.REST, display: "REST" }
|
|
78
85
|
];
|
|
79
|
-
const DiagramItemForm = ({ itemToEdit, wf, onClose, onApply }) => {
|
|
86
|
+
const DiagramItemForm = ({ itemToEdit, wf, onClose, onApply, onStatusItemEdited }) => {
|
|
80
87
|
const [localItem, setLocalItem] = useState(itemToEdit);
|
|
81
88
|
const [localItemOrig] = useState(structuredClone(itemToEdit));
|
|
82
89
|
const [validationItems, setValidationItems] = useState([]);
|
|
@@ -392,7 +399,7 @@ const DiagramItemForm = ({ itemToEdit, wf, onClose, onApply }) => {
|
|
|
392
399
|
};
|
|
393
400
|
// Function to render Status-specific fields
|
|
394
401
|
const renderStatusFields = () => {
|
|
395
|
-
return (_jsx(TMDataListItemPicker, { dataListID: wf?.MStatusDLID, selectedValue: localItem.StatusValue, onItemSelect: handleStatusChange }));
|
|
402
|
+
return (_jsx(TMDataListItemPicker, { dataListID: wf?.MStatusDLID, selectedValue: localItem.StatusValue, onItemSelect: handleStatusChange, onItemEdited: onStatusItemEdited, allowEdit: true }));
|
|
396
403
|
};
|
|
397
404
|
const renderAppFields = () => {
|
|
398
405
|
return (_jsxs(_Fragment, { children: [_jsx(TMDropDown, { label: SDKUI_Localizator.WorkflowAppType, dataSource: APP_TYPES_DATASOURCE, value: localItem.AppType, isModifiedWhen: localItem.AppType !== localItemOrig.AppType, validationItems: validationItems.filter(v => v.PropertyName === DiagramItemProps.AppType), onValueChanged: (e) => { handleAppTypeChange(e.target.value); } }), localItem.AppType === WFAppTypes.EXE
|
|
@@ -580,38 +587,38 @@ const DiagramItemForm = ({ itemToEdit, wf, onClose, onApply }) => {
|
|
|
580
587
|
setDossierTypes(formattedList);
|
|
581
588
|
});
|
|
582
589
|
}, [localItem.Type]);
|
|
583
|
-
//
|
|
584
|
-
const { andRecipients:
|
|
585
|
-
return tosToActors(localItem.Tos ?? '');
|
|
586
|
-
}, [localItem.Tos]);
|
|
587
|
-
const { andRecipients: tos2Recipients } = useMemo(() => {
|
|
590
|
+
// Owner = Tos2, Participants = Tos
|
|
591
|
+
const { andRecipients: ownerRecipients } = useMemo(() => {
|
|
588
592
|
return tosToActors(localItem.Tos2 ?? '');
|
|
589
593
|
}, [localItem.Tos2]);
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
handleTosChange(newTos);
|
|
595
|
-
}, [localItem.Tos, handleTosChange]);
|
|
596
|
-
const handleRemoveTosRecipient = useCallback((recipientToRemove) => {
|
|
597
|
-
const { andRecipients } = tosToActors(localItem.Tos ?? '');
|
|
598
|
-
const updatedRecipients = andRecipients.filter(r => r.ActorType !== recipientToRemove.ActorType || r.ActorID !== recipientToRemove.ActorID);
|
|
599
|
-
const newTos = actorsToTos(updatedRecipients);
|
|
600
|
-
handleTosChange(newTos);
|
|
601
|
-
}, [localItem.Tos, handleTosChange]);
|
|
602
|
-
const handleAddTos2Recipients = useCallback((newRecipients, orValue) => {
|
|
594
|
+
const { andRecipients: participantRecipients } = useMemo(() => {
|
|
595
|
+
return tosToActors(localItem.Tos ?? '');
|
|
596
|
+
}, [localItem.Tos]);
|
|
597
|
+
const handleAddOwnerRecipients = useCallback((newRecipients, orValue) => {
|
|
603
598
|
const { andRecipients } = tosToActors(localItem.Tos2 ?? '');
|
|
604
599
|
const updatedRecipients = [...andRecipients, ...newRecipients.map(r => ({ ...r, Or: orValue }))];
|
|
605
600
|
const newTos = actorsToTos(updatedRecipients);
|
|
606
601
|
handleTos2Change(newTos);
|
|
607
602
|
}, [localItem.Tos2, handleTos2Change]);
|
|
608
|
-
const
|
|
603
|
+
const handleRemoveOwnerRecipient = useCallback((recipientToRemove) => {
|
|
609
604
|
const { andRecipients } = tosToActors(localItem.Tos2 ?? '');
|
|
610
605
|
const updatedRecipients = andRecipients.filter(r => r.ActorType !== recipientToRemove.ActorType || r.ActorID !== recipientToRemove.ActorID);
|
|
611
606
|
const newTos = actorsToTos(updatedRecipients);
|
|
612
607
|
handleTos2Change(newTos);
|
|
613
608
|
}, [localItem.Tos2, handleTos2Change]);
|
|
614
|
-
|
|
609
|
+
const handleAddParticipantRecipients = useCallback((newRecipients, orValue) => {
|
|
610
|
+
const { andRecipients } = tosToActors(localItem.Tos ?? '');
|
|
611
|
+
const updatedRecipients = [...andRecipients, ...newRecipients.map(r => ({ ...r, Or: orValue }))];
|
|
612
|
+
const newTos = actorsToTos(updatedRecipients);
|
|
613
|
+
handleTosChange(newTos);
|
|
614
|
+
}, [localItem.Tos, handleTosChange]);
|
|
615
|
+
const handleRemoveParticipantRecipient = useCallback((recipientToRemove) => {
|
|
616
|
+
const { andRecipients } = tosToActors(localItem.Tos ?? '');
|
|
617
|
+
const updatedRecipients = andRecipients.filter(r => r.ActorType !== recipientToRemove.ActorType || r.ActorID !== recipientToRemove.ActorID);
|
|
618
|
+
const newTos = actorsToTos(updatedRecipients);
|
|
619
|
+
handleTosChange(newTos);
|
|
620
|
+
}, [localItem.Tos, handleTosChange]);
|
|
621
|
+
return (_jsxs(_Fragment, { children: [_jsx(TMTextExpression, { label: `${SDKUI_Localizator.Name} (${SDKUI_Localizator.Dossier})`, value: localItem.PlatformObjName, valueOrig: localItemOrig.PlatformObjName, tid: wf?.MTID, isModifiedWhen: (localItem.PlatformObjName ?? '') !== (localItemOrig.PlatformObjName ?? ''), onValueChanged: handlePlatformObjNameChange }), _jsx(TMDropDown, { dataSource: dossierTypes, label: SDKUI_Localizator.DossierType, value: localItem.Value3asInt, isModifiedWhen: (localItem.Value3asInt ?? 0) !== (localItemOrig.Value3asInt ?? 0), onValueChanged: (e) => { handleValue3asIntChange(e.target.value); } }), _jsx(TMTextExpression, { label: `${SDKUI_Localizator.Description} (${SDKUI_Localizator.Dossier})`, value: localItem.PlatformObjDescr, valueOrig: localItemOrig.PlatformObjDescr, tid: wf?.MTID, isModifiedWhen: (localItem.PlatformObjDescr ?? '') !== (localItemOrig.PlatformObjDescr ?? ''), onValueChanged: handlePlatformObjDescrChange }), _jsx(TMCultureIDPicker, { label: SDKUI_Localizator.Format, selectedValue: localItem.FormatCultureID, isModifiedWhen: localItem.FormatCultureID !== localItemOrig.FormatCultureID, openChooserBySingleClick: true, onSelectCultureID: handleFormatCultureIDChange }), _jsx(TMTextExpression, { label: `${SDKUI_Localizator.CommentText} (${SDKUI_Localizator.BlogCase})`, placeHolder: 'Inserisci il valore', rows: 2, value: localItem.Value1asString, valueOrig: localItemOrig.Value1asString, tid: wf?.MTID, isModifiedWhen: (localItem.Value1asString ?? '') !== (localItemOrig.Value1asString ?? ''), onValueChanged: handleValue1asStringChange }), _jsx(TMCheckBox, { value: localItem.Value1asInt ?? 0, label: SDKUI_Localizator.WorkflowAddDcmtAsAttachment, isModifiedWhen: localItem.Value1asInt !== localItemOrig.Value1asInt, onValueChanged: handleValue1asIntChange }), _jsx(TMCheckBox, { value: localItem.Value2asInt ?? 0, label: SDKUI_Localizator.WorkflowAddDcmtToDossier, isModifiedWhen: localItem.Value2asInt !== localItemOrig.Value2asInt, onValueChanged: handleValue2asIntChange }), _jsx(TMCheckBox, { value: localItem.Trunc ?? 0, label: SDKUI_Localizator.TruncateString, isModifiedWhen: localItem.Trunc !== localItemOrig.Trunc, onValueChanged: handleTruncChange }), _jsxs(RecipientsContainer, { children: [_jsx(RecipientList, { recipients: ownerRecipients, title: SDKUI_Localizator.OwnerName, tid: wf?.MTID, maxRecipients: 1, validationItems: validationItems.filter(v => v.PropertyName === DiagramItemProps.Tos2), onAdd: (newRecipients) => handleAddOwnerRecipients(newRecipients, 0), onRemove: handleRemoveOwnerRecipient }), _jsx(RecipientList, { recipients: participantRecipients, title: SDKUI_Localizator.Participants, tid: wf?.MTID, onAdd: (newRecipients) => handleAddParticipantRecipients(newRecipients, 0), onRemove: handleRemoveParticipantRecipient })] })] }));
|
|
615
622
|
};
|
|
616
623
|
const renderAddPartsFields = () => {
|
|
617
624
|
const { andRecipients: tosRecipients } = useMemo(() => {
|
|
@@ -679,7 +686,7 @@ const DiagramItemForm = ({ itemToEdit, wf, onClose, onApply }) => {
|
|
|
679
686
|
default:
|
|
680
687
|
specificFields = null;
|
|
681
688
|
}
|
|
682
|
-
return (_jsxs(FormContainer, { children: [renderCommonFields(), specificFields, _jsxs(ButtonsContainer, { children: [_jsx(TMButton, { caption: 'Applica', btnStyle: 'advanced', advancedColor: TMColors.tertiary, icon: _jsx(IconApply, {}), showTooltip: false, disabled: !isModified, onClick: handleSave }), _jsx(TMButton, { caption: 'Annulla', btnStyle: 'toolbar', color: 'primary', icon: _jsx(IconUndo, {}), showTooltip: false, disabled: !isModified, onClick: handleCancel })] })] }));
|
|
689
|
+
return (_jsxs(FormContainer, { children: [_jsxs(FieldsContainer, { children: [renderCommonFields(), specificFields] }), _jsxs(ButtonsContainer, { children: [_jsx(TMButton, { caption: 'Applica', btnStyle: 'advanced', advancedColor: TMColors.tertiary, icon: _jsx(IconApply, {}), showTooltip: false, disabled: !isModified || validationItems.some(v => v.ResultType === ResultTypes.ERROR), onClick: handleSave }), _jsx(TMButton, { caption: 'Annulla', btnStyle: 'toolbar', color: 'primary', icon: _jsx(IconUndo, {}), showTooltip: false, disabled: !isModified, onClick: handleCancel })] })] }));
|
|
683
690
|
};
|
|
684
691
|
return (_jsx(TMModal, { title: LocalizeDiagramItemType(localItem.Type), onClose: onClose, isModal: true, width: calculatedWidth, height: calculatedHeight, children: renderForm() }));
|
|
685
692
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { QueryDescriptor } from '@topconsultnpm/sdk-ts';
|
|
2
|
+
import { QueryDescriptor, ValidationItem } from '@topconsultnpm/sdk-ts';
|
|
3
3
|
export declare enum WorkItemActorTypes {
|
|
4
4
|
None = 0,
|
|
5
5
|
UID = 1,
|
|
@@ -19,6 +19,8 @@ interface RecipientListProps {
|
|
|
19
19
|
title: string;
|
|
20
20
|
tid?: number;
|
|
21
21
|
qd?: QueryDescriptor;
|
|
22
|
+
maxRecipients?: number;
|
|
23
|
+
validationItems?: ValidationItem[];
|
|
22
24
|
onQDChange?: (newQd: QueryDescriptor | undefined) => void;
|
|
23
25
|
onAdd: (recipient: WorkItemActor[]) => void;
|
|
24
26
|
onRemove: (recipient: WorkItemActor) => void;
|
|
@@ -7,6 +7,7 @@ import { TMUserChooserForm } from '../../../choosers/TMUserChooser';
|
|
|
7
7
|
import { TMGroupChooserForm, TMGroupIdViewer } from '../../../choosers/TMGroupChooser';
|
|
8
8
|
import { TMMidViewer } from '../../../viewers/TMMidViewer';
|
|
9
9
|
import { SDK_Globals, SDK_Localizator } from '@topconsultnpm/sdk-ts';
|
|
10
|
+
import TMVilViewer from '../../../base/TMVilViewer';
|
|
10
11
|
import { useOutsideClick } from '../../../../hooks/useOutsideClick';
|
|
11
12
|
import { FormModes } from '../../../../ts';
|
|
12
13
|
import { TMMessageBoxManager, ButtonNames } from '../../../base/TMPopUp';
|
|
@@ -70,7 +71,7 @@ const FloatingMenu = styled.div `
|
|
|
70
71
|
const FloatingMenuButton = (props) => {
|
|
71
72
|
return _jsx(TMButton, { width: "100%", ...props });
|
|
72
73
|
};
|
|
73
|
-
const RecipientList = ({ recipients, title, tid, qd, onAdd, onRemove, onQDChange }) => {
|
|
74
|
+
const RecipientList = ({ recipients, title, tid, qd, maxRecipients, validationItems, onAdd, onRemove, onQDChange }) => {
|
|
74
75
|
const [uiState, setUiState] = useState({
|
|
75
76
|
isMenuOpen: false,
|
|
76
77
|
showUserChooser: false,
|
|
@@ -102,7 +103,7 @@ const RecipientList = ({ recipients, title, tid, qd, onAdd, onRemove, onQDChange
|
|
|
102
103
|
onAdd(recipientsToAdd);
|
|
103
104
|
}
|
|
104
105
|
setUiState(prevState => ({ ...prevState, showUserChooser: false }));
|
|
105
|
-
}, []);
|
|
106
|
+
}, [onAdd]);
|
|
106
107
|
const handleGroupChosen = useCallback((IDs) => {
|
|
107
108
|
if (IDs && IDs.length > 0) {
|
|
108
109
|
const recipientsToAdd = IDs.map(id => ({
|
|
@@ -113,7 +114,7 @@ const RecipientList = ({ recipients, title, tid, qd, onAdd, onRemove, onQDChange
|
|
|
113
114
|
onAdd(recipientsToAdd);
|
|
114
115
|
}
|
|
115
116
|
setUiState(prevState => ({ ...prevState, showGroupChooser: false }));
|
|
116
|
-
}, []);
|
|
117
|
+
}, [onAdd]);
|
|
117
118
|
const handleMetadataChosen = useCallback((IDs) => {
|
|
118
119
|
if (IDs && IDs.length > 0) {
|
|
119
120
|
const recipientsToAdd = IDs.map(item => ({
|
|
@@ -124,8 +125,11 @@ const RecipientList = ({ recipients, title, tid, qd, onAdd, onRemove, onQDChange
|
|
|
124
125
|
onAdd(recipientsToAdd);
|
|
125
126
|
}
|
|
126
127
|
setUiState(prevState => ({ ...prevState, showMetadataChooser: false }));
|
|
127
|
-
}, []);
|
|
128
|
+
}, [onAdd]);
|
|
129
|
+
const isMaxReached = maxRecipients !== undefined && recipients.length >= maxRecipients;
|
|
128
130
|
const handleAddClick = () => {
|
|
131
|
+
if (isMaxReached)
|
|
132
|
+
return;
|
|
129
133
|
setUiState(prevState => ({ ...prevState, isMenuOpen: !prevState.isMenuOpen }));
|
|
130
134
|
};
|
|
131
135
|
const handleRecipientClick = useCallback((index) => {
|
|
@@ -195,11 +199,11 @@ const RecipientList = ({ recipients, title, tid, qd, onAdd, onRemove, onQDChange
|
|
|
195
199
|
document.removeEventListener('keydown', handleKeyPress);
|
|
196
200
|
};
|
|
197
201
|
}, [handleKeyPress]);
|
|
198
|
-
return (_jsxs(RecipientsColumn, { children: [_jsxs(HeaderContainer, { children: [_jsx("p", { style: { fontWeight: 600 }, children: title }), _jsx(TMButton, { btnStyle: 'icon', caption: SDKUI_Localizator.AddRecipient, icon: _jsx(IconAdd, {}), onClick: handleAddClick }), uiState.isMenuOpen && renderFloatingMenu()] }), _jsx("div", { style: { height: '150px', overflowY: 'auto', gap: '5px', display: 'flex', flexDirection: 'column' }, children: recipients.map((recipient, index) => (_jsxs(RecipientItem, { "$isSelected": uiState.selectedRecipientIndex === index, onClick: () => handleRecipientClick(index), tabIndex: 0, children: [_jsx(IconDelete, { color: '#c00', cursor: 'pointer', onClick: (e) => {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
return (_jsxs(RecipientsColumn, { children: [_jsxs(HeaderContainer, { children: [_jsx("p", { style: { fontWeight: 600 }, children: title }), _jsx(TMButton, { btnStyle: 'icon', caption: SDKUI_Localizator.AddRecipient, icon: _jsx(IconAdd, {}), onClick: handleAddClick, disabled: isMaxReached }), uiState.isMenuOpen && !isMaxReached && renderFloatingMenu()] }), _jsx(TMVilViewer, { vil: validationItems }), _jsx("div", { style: { height: '150px', overflowY: 'auto', gap: '5px', display: 'flex', flexDirection: 'column' }, children: recipients.map((recipient, index) => (_jsxs(RecipientItem, { "$isSelected": uiState.selectedRecipientIndex === index, onClick: () => handleRecipientClick(index), tabIndex: 0, children: [_jsx("span", { style: { display: 'flex', alignItems: 'center', flexShrink: 0 }, children: _jsx(IconDelete, { color: '#c00', cursor: 'pointer', onClick: (e) => {
|
|
203
|
+
e.stopPropagation();
|
|
204
|
+
onRemove(recipient);
|
|
205
|
+
setUiState(prevState => ({ ...prevState, selectedRecipientIndex: null }));
|
|
206
|
+
} }) }), _jsx("span", { style: { flex: 1, minWidth: 0, display: 'flex', alignItems: 'center' }, children: renderActorViewer(recipient) })] }, index))) }), uiState.showUserChooser && _jsx(TMUserChooserForm, { allowMultipleSelection: true, allowSorting: true, onClose: () => setUiState(prevState => ({ ...prevState, showUserChooser: false })), onChoose: (IDs) => handleUserChosen(IDs) }), uiState.showGroupChooser && _jsx(TMGroupChooserForm, { allowMultipleSelection: true, allowSorting: true, onClose: () => setUiState(prevState => ({ ...prevState, showGroupChooser: false })), onChoose: (IDs) => handleGroupChosen(IDs) }), uiState.showMetadataChooser && tid && _jsx(TMMetadataChooserForm, { allowMultipleSelection: true, allowSorting: true, tids: [tid], onClose: () => setUiState(prevState => ({ ...prevState, showMetadataChooser: false })), onChoose: (IDs) => handleMetadataChosen(IDs) }), uiState.showQdEditor &&
|
|
203
207
|
_jsx(TMModal, { title: SDKUI_Localizator.QueryDefine, onClose: () => setUiState(prevState => ({ ...prevState, showQdEditor: false })), children: _jsx(TMQueryEditor, { inputData: qd, formMode: FormModes.Update, showDistinct: true, onApplied: handleQdChosen, onClose: () => setUiState(prevState => ({ ...prevState, showQdEditor: false })) }) })] }));
|
|
204
208
|
};
|
|
205
209
|
export default RecipientList;
|
|
@@ -8,13 +8,15 @@ import ConnectionComponent from './ConnectionComponent';
|
|
|
8
8
|
import DiagramItemComponent from './DiagramItemComponent';
|
|
9
9
|
import DiagramItemSvgContent from './DiagramItemSvgContent';
|
|
10
10
|
import { calculateArrowAngle, downloadFile, getConnectionPoint, getNewWfDiagram, isConnectionNonLinear, validateDiagram } from './workflowHelpers';
|
|
11
|
-
import { IconFlowChart, IconUndo, IconRestore, IconAdjust, IconCopy, IconCut, IconPaste, IconPin, IconUnpin, IconChevronRight, IconCloseOutline, IconNew, SDKUI_Localizator, generateUUID, IconExport, IconImport, IconWindowMaximize, IconZoomIn, IconZoomOut, IconPencil, IconLock, LocalizeDiagramItemType, IconWindowMinimize, IconZoomAuto } from '../../../../helper';
|
|
11
|
+
import { IconFlowChart, IconUndo, IconRestore, IconAdjust, IconCopy, IconCut, IconPaste, IconPin, IconUnpin, IconChevronRight, IconCloseOutline, IconNew, SDKUI_Localizator, generateUUID, IconExport, IconImport, IconWindowMaximize, IconZoomIn, IconZoomOut, IconPencil, IconLock, LocalizeDiagramItemType, IconWindowMinimize, IconZoomAuto, IconCloseCircle, IconSuccess } from '../../../../helper';
|
|
12
12
|
import { ButtonNames, TMExceptionBoxManager, TMMessageBoxManager } from '../../../base/TMPopUp';
|
|
13
13
|
import { StyledLoadingContainer, StyledSpinner } from '../../../base/Styled';
|
|
14
14
|
import DiagramItemForm from './DiagramItemForm';
|
|
15
15
|
import ReactDOM from 'react-dom';
|
|
16
16
|
import ConnectionForm from './ConnectionForm';
|
|
17
17
|
import TMFloatingMenuBar from '../../../NewComponents/FloatingMenuBar';
|
|
18
|
+
import TMContextMenu from '../../../NewComponents/ContextMenu/TMContextMenu';
|
|
19
|
+
import { TMColors } from '../../../../utils/theme';
|
|
18
20
|
const ZoomLevelText = styled.span `
|
|
19
21
|
font-size: 0.9em;
|
|
20
22
|
color: #555;
|
|
@@ -331,6 +333,9 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
331
333
|
const [wfDiagram, setWfDiagram] = useState(null);
|
|
332
334
|
const [selectedItems, setSelectedItems] = useState(new Set());
|
|
333
335
|
const [selectedConnections, setSelectedConnections] = useState(new Set());
|
|
336
|
+
// Context menu per le connections
|
|
337
|
+
const [connectionContextMenuPosition, setConnectionContextMenuPosition] = useState({ x: 0, y: 0 });
|
|
338
|
+
const [contextMenuConnectionId, setContextMenuConnectionId] = useState(null);
|
|
334
339
|
const [wfDiagramHistory, setWfDiagramHistory] = useState([]);
|
|
335
340
|
const [historyIndex, setHistoryIndex] = useState(-1);
|
|
336
341
|
const isUndoingRedoing = useRef(false);
|
|
@@ -1311,6 +1316,77 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1311
1316
|
if (!isCtrlPressed)
|
|
1312
1317
|
setSelectedItems(new Set());
|
|
1313
1318
|
}, [isReadOnly]);
|
|
1319
|
+
const handleConnectionContextMenu = useCallback((id, event) => {
|
|
1320
|
+
if (isReadOnly)
|
|
1321
|
+
return;
|
|
1322
|
+
event.preventDefault();
|
|
1323
|
+
event.stopPropagation();
|
|
1324
|
+
// Trova la connection
|
|
1325
|
+
const connection = wfDiagram?.Connections.find(conn => conn.ID === id);
|
|
1326
|
+
if (!connection)
|
|
1327
|
+
return;
|
|
1328
|
+
// Verifica se esce da un DiagramItemTypes.Condition o Approval
|
|
1329
|
+
const sourceItem = wfDiagram?.DiagramItems.find(item => item.ID === connection.Source.ParentDiagramItem.ID);
|
|
1330
|
+
if (!sourceItem || ![DiagramItemTypes.Condition, DiagramItemTypes.Approval].includes(sourceItem.Type))
|
|
1331
|
+
return;
|
|
1332
|
+
// Mostra il context menu
|
|
1333
|
+
setContextMenuConnectionId(id);
|
|
1334
|
+
setConnectionContextMenuPosition({ x: event.clientX, y: event.clientY });
|
|
1335
|
+
}, [isReadOnly, wfDiagram]);
|
|
1336
|
+
const handleChangeConnectionOutputStatus = useCallback((connectionId) => {
|
|
1337
|
+
if (isReadOnly || !wfDiagram)
|
|
1338
|
+
return;
|
|
1339
|
+
const connection = wfDiagram.Connections.find(conn => conn.ID === connectionId);
|
|
1340
|
+
if (!connection)
|
|
1341
|
+
return;
|
|
1342
|
+
// Cambia l'OutputStatus da Completed a Rejected e viceversa
|
|
1343
|
+
const newStatus = connection.OutputStatus === WorkItemStatus.Completed
|
|
1344
|
+
? WorkItemStatus.Rejected
|
|
1345
|
+
: WorkItemStatus.Completed;
|
|
1346
|
+
const oppositeStatus = newStatus === WorkItemStatus.Completed
|
|
1347
|
+
? WorkItemStatus.Rejected
|
|
1348
|
+
: WorkItemStatus.Completed;
|
|
1349
|
+
// Se esiste un'altra connection dallo stesso source con il newStatus,
|
|
1350
|
+
// la si inverte in modo che non esistano mai 2 uscite con lo stesso OutputStatus.
|
|
1351
|
+
const sourceId = connection.Source.ParentDiagramItem.ID;
|
|
1352
|
+
const conflictingConn = wfDiagram.Connections.find(conn => conn.ID !== connectionId &&
|
|
1353
|
+
conn.Source.ParentDiagramItem.ID === sourceId &&
|
|
1354
|
+
conn.OutputStatus === newStatus);
|
|
1355
|
+
const updatedDiagram = {
|
|
1356
|
+
...wfDiagram,
|
|
1357
|
+
Connections: wfDiagram.Connections.map(conn => {
|
|
1358
|
+
if (conn.ID === connectionId)
|
|
1359
|
+
return { ...conn, OutputStatus: newStatus };
|
|
1360
|
+
if (conflictingConn && conn.ID === conflictingConn.ID)
|
|
1361
|
+
return { ...conn, OutputStatus: oppositeStatus };
|
|
1362
|
+
return conn;
|
|
1363
|
+
})
|
|
1364
|
+
};
|
|
1365
|
+
updateDiagram(updatedDiagram);
|
|
1366
|
+
setWfDiagram(updatedDiagram);
|
|
1367
|
+
setContextMenuConnectionId(null);
|
|
1368
|
+
}, [isReadOnly, wfDiagram, updateDiagram]);
|
|
1369
|
+
const closeConnectionContextMenu = useCallback(() => {
|
|
1370
|
+
setContextMenuConnectionId(null);
|
|
1371
|
+
}, []);
|
|
1372
|
+
// Menu items per il context menu delle connections
|
|
1373
|
+
const connectionContextMenuItems = useMemo(() => {
|
|
1374
|
+
if (!contextMenuConnectionId || !wfDiagram)
|
|
1375
|
+
return [];
|
|
1376
|
+
const connection = wfDiagram.Connections.find(conn => conn.ID === contextMenuConnectionId);
|
|
1377
|
+
if (!connection)
|
|
1378
|
+
return [];
|
|
1379
|
+
const targetStatus = connection.OutputStatus === WorkItemStatus.Completed
|
|
1380
|
+
? SDKUI_Localizator.WorkItemStatus_Rejected
|
|
1381
|
+
: SDKUI_Localizator.WorkItemStatus_Completed;
|
|
1382
|
+
return [{
|
|
1383
|
+
icon: connection.OutputStatus === WorkItemStatus.Completed
|
|
1384
|
+
? _jsx(IconCloseCircle, { color: TMColors.error, fontSize: 16 })
|
|
1385
|
+
: _jsx(IconSuccess, { color: TMColors.success, fontSize: 16 }),
|
|
1386
|
+
name: SDKUI_Localizator.ChangeStatusTo.replaceParams(targetStatus),
|
|
1387
|
+
onClick: () => handleChangeConnectionOutputStatus(contextMenuConnectionId)
|
|
1388
|
+
}];
|
|
1389
|
+
}, [contextMenuConnectionId, wfDiagram, handleChangeConnectionOutputStatus]);
|
|
1314
1390
|
const handleDrag = useCallback((id, newX, newY) => {
|
|
1315
1391
|
if (isReadOnly)
|
|
1316
1392
|
return;
|
|
@@ -1393,10 +1469,15 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1393
1469
|
if (sourceItem.Type === DiagramItemTypes.Condition || sourceItem.Type === DiagramItemTypes.Approval) {
|
|
1394
1470
|
const existingConnectionsFromSource = wfDiagram.Connections.filter(conn => conn.Source.ParentDiagramItem.ID === sourceItem.ID);
|
|
1395
1471
|
if (existingConnectionsFromSource.length === 0) {
|
|
1472
|
+
// Prima connessione → Completed
|
|
1396
1473
|
outputStatus = WorkItemStatus.Completed;
|
|
1397
1474
|
}
|
|
1398
1475
|
else if (existingConnectionsFromSource.length === 1) {
|
|
1399
|
-
|
|
1476
|
+
// Seconda connessione → contrario della prima
|
|
1477
|
+
const firstConnection = existingConnectionsFromSource[0];
|
|
1478
|
+
outputStatus = firstConnection.OutputStatus === WorkItemStatus.Completed
|
|
1479
|
+
? WorkItemStatus.Rejected
|
|
1480
|
+
: WorkItemStatus.Completed;
|
|
1400
1481
|
}
|
|
1401
1482
|
}
|
|
1402
1483
|
const newConnection = {
|
|
@@ -1562,6 +1643,18 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1562
1643
|
const newDiagram = { ...wfDiagram, DiagramItems: updatedDiagramItems };
|
|
1563
1644
|
updateDiagram(newDiagram);
|
|
1564
1645
|
}, [wfDiagram, updateDiagram]);
|
|
1646
|
+
const handleStatusItemEdited = useCallback((originalItem, editedItem) => {
|
|
1647
|
+
if (!wfDiagram)
|
|
1648
|
+
return;
|
|
1649
|
+
const updatedDiagramItems = wfDiagram.DiagramItems.map(item => {
|
|
1650
|
+
if (item.Type === DiagramItemTypes.Status && item.StatusValue === originalItem.value) {
|
|
1651
|
+
return { ...item, ItemName: editedItem.name || '', StatusValue: editedItem.value };
|
|
1652
|
+
}
|
|
1653
|
+
return item;
|
|
1654
|
+
});
|
|
1655
|
+
const newDiagram = { ...wfDiagram, DiagramItems: updatedDiagramItems };
|
|
1656
|
+
updateDiagram(newDiagram);
|
|
1657
|
+
}, [wfDiagram, updateDiagram]);
|
|
1565
1658
|
const handleUpdateConnection = useCallback((updatedConnection) => {
|
|
1566
1659
|
setWfDiagram(prevDiagram => {
|
|
1567
1660
|
if (!prevDiagram)
|
|
@@ -1820,7 +1913,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1820
1913
|
fullScreenRef.current.focus();
|
|
1821
1914
|
}
|
|
1822
1915
|
}, [isFullScreen]);
|
|
1823
|
-
const diagramContent = (_jsxs(CanvasContainer, { onDoubleClick: handleCanvasDoubleClick, children: [_jsx("input", { ref: fileInputRef, type: "file", accept: ".xml" // Filtra per file XML
|
|
1916
|
+
const diagramContent = (_jsxs(CanvasContainer, { onDoubleClick: handleCanvasDoubleClick, onContextMenu: (e) => e.preventDefault(), children: [_jsx("input", { ref: fileInputRef, type: "file", accept: ".xml" // Filtra per file XML
|
|
1824
1917
|
, onChange: handleFileChange, style: { display: 'none' } }), SDK_Globals.tmSession?.SessionDescr?.appModuleID === AppModules.SURFER ?
|
|
1825
1918
|
_jsx(TMFloatingMenuBar, { containerRef: diagramRef, defaultPosition: { x: 45, y: 85 }, enableConfigMode: false, fixedItems: [
|
|
1826
1919
|
{ icon: _jsx(IconZoomIn, {}), name: SDKUI_Localizator.ZoomIn, disabled: isAutoZoomEnabled, onClick: () => { handleZoomIn(); }, id: 'zoom-in', isPinned: true },
|
|
@@ -1842,8 +1935,12 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1842
1935
|
const sinkPoint = getConnectionPoint(sinkItem, connection.Sink.ConnectorName);
|
|
1843
1936
|
// Determina se questa è la connessione che stiamo trascinando
|
|
1844
1937
|
const isThisConnectionBeingDragged = isDraggingExistingConnectionEndpoint && draggingConnectionId === connection.ID;
|
|
1845
|
-
return (_jsx(ConnectionComponent, { connection: connection, isSelected: selectedConnections.has(connection.ID), sourcePoint: sourcePoint, sinkPoint: sinkPoint, isTemporary: isThisConnectionBeingDragged, onClick: handleConnectionClick, onDoubleClick: handleDoubleClickConnection, onConnectionEndpointMouseDown: handleConnectionEndpointMouseDown }, connection.ID));
|
|
1846
|
-
}), isDrawingConnection && tempConnectionPathData && (_jsx(TempConnectionPath, { d: tempConnectionPathData })), isDraggingExistingConnectionEndpoint && tempConnectionPathData && (_jsx(TempConnectionPath, { d: tempConnectionPathData })), isDrawingSelectionRect && currentSelectionRect && (_jsx(SelectionRect, { x: currentSelectionRect.x, y: currentSelectionRect.y, width: currentSelectionRect.width, height: currentSelectionRect.height }))] }) })) : (_jsx(DiagramMessage, { children: `${SDKUI_Localizator.WorkflowDiagramMissingOrInvalid} ...` })) }), isModalOpen && itemToEdit && (_jsx(DiagramItemForm, { itemToEdit: itemToEdit, wf: wfDiagram?.Info, onClose: handleCloseModal, onApply: handleUpdateDiagramItem })), isConnectionModalOpen && connectionToEdit && (_jsx(ConnectionForm, { connectionToEdit: connectionToEdit, onClose: () => setIsConnectionModalOpen(false), onApply: handleUpdateConnection }))
|
|
1938
|
+
return (_jsx(ConnectionComponent, { connection: connection, isSelected: selectedConnections.has(connection.ID), sourcePoint: sourcePoint, sinkPoint: sinkPoint, isTemporary: isThisConnectionBeingDragged, onClick: handleConnectionClick, onDoubleClick: handleDoubleClickConnection, onConnectionEndpointMouseDown: handleConnectionEndpointMouseDown, onContextMenu: handleConnectionContextMenu }, connection.ID));
|
|
1939
|
+
}), isDrawingConnection && tempConnectionPathData && (_jsx(TempConnectionPath, { d: tempConnectionPathData })), isDraggingExistingConnectionEndpoint && tempConnectionPathData && (_jsx(TempConnectionPath, { d: tempConnectionPathData })), isDrawingSelectionRect && currentSelectionRect && (_jsx(SelectionRect, { x: currentSelectionRect.x, y: currentSelectionRect.y, width: currentSelectionRect.width, height: currentSelectionRect.height }))] }) })) : (_jsx(DiagramMessage, { children: `${SDKUI_Localizator.WorkflowDiagramMissingOrInvalid} ...` })) }), isModalOpen && itemToEdit && (_jsx(DiagramItemForm, { itemToEdit: itemToEdit, wf: wfDiagram?.Info, onClose: handleCloseModal, onApply: handleUpdateDiagramItem, onStatusItemEdited: handleStatusItemEdited })), isConnectionModalOpen && connectionToEdit && (_jsx(ConnectionForm, { connectionToEdit: connectionToEdit, onClose: () => setIsConnectionModalOpen(false), onApply: handleUpdateConnection })), _jsx(TMContextMenu, { items: connectionContextMenuItems, externalControl: {
|
|
1940
|
+
visible: contextMenuConnectionId !== null,
|
|
1941
|
+
position: connectionContextMenuPosition,
|
|
1942
|
+
onClose: closeConnectionContextMenu
|
|
1943
|
+
} })] }));
|
|
1847
1944
|
return (_jsxs(_Fragment, { children: [!isFullScreen && (_jsx(DiagramWrapper, { ref: diagramRef, children: diagramContent })), isFullScreen && ReactDOM.createPortal(_jsx(FullScreenContainer, { ref: fullScreenRef, tabIndex: 0, onKeyDown: handleFullScreenKeyDown, children: diagramContent }), document.body)] }));
|
|
1848
1945
|
};
|
|
1849
1946
|
export default WFDiagram;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { PlatformObjectValidator, QueryValidatorOptions, ResultTypes,
|
|
1
|
+
import { PlatformObjectValidator, QueryValidatorOptions, ResultTypes, ValidationItem, WorkItemStatus } from '@topconsultnpm/sdk-ts';
|
|
2
2
|
import { DiagramItemTypes, ArrowSymbol } from './interfaces'; // Assicurati che il percorso sia corretto
|
|
3
|
-
import { generateUUID, SDKUI_Localizator } from '../../../../helper';
|
|
3
|
+
import { generateUUID, LocalizeDiagramItemType, SDKUI_Localizator } from '../../../../helper';
|
|
4
|
+
import { tosToActors } from './WorkitemRecipientsEditor';
|
|
4
5
|
/**
|
|
5
6
|
* Calculates the angle in degrees of an arrow based on two points.
|
|
6
7
|
* @param prevPoint The previous point on the trajectory.
|
|
@@ -318,72 +319,73 @@ export const workflowValidator = async (wf) => {
|
|
|
318
319
|
const vil = await wfDiagramItemValidator(item);
|
|
319
320
|
vil.forEach(v => v.PropertyScopes = ['diagramItem']);
|
|
320
321
|
validationItems.push(...vil);
|
|
322
|
+
const itemType = LocalizeDiagramItemType(item.Type);
|
|
321
323
|
switch (item.Type) {
|
|
322
324
|
case DiagramItemTypes.Start:
|
|
323
325
|
if (wf.Connections.filter(c => c.Source.ParentDiagramItem.ID === item.ID).length === 0) {
|
|
324
|
-
validationItems.push(new ValidationItem(ResultTypes.ERROR,
|
|
326
|
+
validationItems.push(new ValidationItem(ResultTypes.ERROR, itemType, SDKUI_Localizator.WorkflowDiagramStartMustHaveOutgoing, ['diagramItem']));
|
|
325
327
|
}
|
|
326
328
|
if (wf.Connections.filter(c => c.Sink.ParentDiagramItem.ID === item.ID).length > 0) {
|
|
327
|
-
validationItems.push(new ValidationItem(ResultTypes.ERROR,
|
|
329
|
+
validationItems.push(new ValidationItem(ResultTypes.ERROR, itemType, SDKUI_Localizator.WorkflowDiagramStartCannotHaveIncoming, ['diagramItem']));
|
|
328
330
|
}
|
|
329
331
|
break;
|
|
330
332
|
case DiagramItemTypes.End:
|
|
331
333
|
case DiagramItemTypes.Exit:
|
|
332
334
|
if (wf.Connections.filter(c => c.Sink.ParentDiagramItem.ID === item.ID).length === 0) {
|
|
333
|
-
validationItems.push(new ValidationItem(ResultTypes.ERROR,
|
|
335
|
+
validationItems.push(new ValidationItem(ResultTypes.ERROR, itemType, SDKUI_Localizator.WorkflowDiagramElementMustHaveIncoming.replaceParams(itemType), ['diagramItem']));
|
|
334
336
|
}
|
|
335
337
|
if (wf.Connections.filter(c => c.Source.ParentDiagramItem.ID === item.ID).length > 0) {
|
|
336
|
-
validationItems.push(new ValidationItem(ResultTypes.ERROR,
|
|
338
|
+
validationItems.push(new ValidationItem(ResultTypes.ERROR, itemType, SDKUI_Localizator.WorkflowDiagramElementCannotHaveOutgoing.replaceParams(itemType), ['diagramItem']));
|
|
337
339
|
}
|
|
338
340
|
break;
|
|
339
341
|
case DiagramItemTypes.Condition:
|
|
340
342
|
if (wf.Connections.filter(c => c.Source.ParentDiagramItem.ID === item.ID).length !== 2) {
|
|
341
|
-
validationItems.push(new ValidationItem(ResultTypes.WARNING,
|
|
343
|
+
validationItems.push(new ValidationItem(ResultTypes.WARNING, itemType, SDKUI_Localizator.WorkflowDiagramConditionTwoOutgoing.replaceParams(item.ItemName), ['diagramItem']));
|
|
342
344
|
}
|
|
343
345
|
if (wf.Connections.filter(c => c.Sink.ParentDiagramItem.ID === item.ID).length === 0) {
|
|
344
|
-
validationItems.push(new ValidationItem(ResultTypes.ERROR,
|
|
346
|
+
validationItems.push(new ValidationItem(ResultTypes.ERROR, itemType, SDKUI_Localizator.WorkflowDiagramConditionMustHaveIncoming.replaceParams(item.ItemName), ['diagramItem']));
|
|
345
347
|
}
|
|
346
348
|
break;
|
|
347
349
|
case DiagramItemTypes.Approval:
|
|
348
350
|
case DiagramItemTypes.ExecTask:
|
|
349
351
|
case DiagramItemTypes.DataEntry:
|
|
350
352
|
if (wf.Connections.filter(c => c.Source.ParentDiagramItem.ID === item.ID).length !== 2) {
|
|
351
|
-
validationItems.push(new ValidationItem(ResultTypes.WARNING,
|
|
353
|
+
validationItems.push(new ValidationItem(ResultTypes.WARNING, itemType, SDKUI_Localizator.WorkflowDiagramElementShouldHaveTwoOutgoing.replaceParams(item.ItemName), ['diagramItem']));
|
|
352
354
|
}
|
|
353
355
|
if (wf.Connections.filter(c => c.Sink.ParentDiagramItem.ID === item.ID).length === 0) {
|
|
354
|
-
validationItems.push(new ValidationItem(ResultTypes.WARNING,
|
|
356
|
+
validationItems.push(new ValidationItem(ResultTypes.WARNING, itemType, SDKUI_Localizator.WorkflowDiagramElementShouldHaveIncoming.replaceParams(item.ItemName), ['diagramItem']));
|
|
355
357
|
}
|
|
356
358
|
break;
|
|
357
359
|
case DiagramItemTypes.Notification:
|
|
358
360
|
if (wf.Connections.filter(c => c.Source.ParentDiagramItem.ID === item.ID).length === 0) {
|
|
359
|
-
validationItems.push(new ValidationItem(ResultTypes.WARNING,
|
|
361
|
+
validationItems.push(new ValidationItem(ResultTypes.WARNING, itemType, SDKUI_Localizator.WorkflowDiagramElementShouldHaveOutgoing.replaceParams(item.ItemName), ['diagramItem']));
|
|
360
362
|
}
|
|
361
363
|
if (wf.Connections.filter(c => c.Sink.ParentDiagramItem.ID === item.ID).length === 0) {
|
|
362
|
-
validationItems.push(new ValidationItem(ResultTypes.WARNING,
|
|
364
|
+
validationItems.push(new ValidationItem(ResultTypes.WARNING, itemType, SDKUI_Localizator.WorkflowDiagramElementShouldHaveIncoming.replaceParams(item.ItemName), ['diagramItem']));
|
|
363
365
|
}
|
|
364
366
|
break;
|
|
365
367
|
case DiagramItemTypes.UpdateDcmt:
|
|
366
368
|
if (wf.Connections.filter(c => c.Source.ParentDiagramItem.ID === item.ID).length !== 1) {
|
|
367
|
-
validationItems.push(new ValidationItem(ResultTypes.WARNING,
|
|
369
|
+
validationItems.push(new ValidationItem(ResultTypes.WARNING, itemType, SDKUI_Localizator.WorkflowDiagramElementShouldHaveOneOutgoing.replaceParams(item.ItemName), ['diagramItem']));
|
|
368
370
|
}
|
|
369
371
|
if (wf.Connections.filter(c => c.Sink.ParentDiagramItem.ID === item.ID).length === 0) {
|
|
370
|
-
validationItems.push(new ValidationItem(ResultTypes.WARNING,
|
|
372
|
+
validationItems.push(new ValidationItem(ResultTypes.WARNING, itemType, SDKUI_Localizator.WorkflowDiagramElementShouldHaveIncoming.replaceParams(item.ItemName), ['diagramItem']));
|
|
371
373
|
}
|
|
372
374
|
break;
|
|
373
375
|
case DiagramItemTypes.Status:
|
|
374
376
|
if (wf.Connections.filter(c => c.Source.ParentDiagramItem.ID === item.ID).length !== 1) {
|
|
375
|
-
validationItems.push(new ValidationItem(ResultTypes.WARNING,
|
|
377
|
+
validationItems.push(new ValidationItem(ResultTypes.WARNING, itemType, SDKUI_Localizator.WorkflowDiagramElementShouldHaveOneOutgoing.replaceParams(item.ItemName), ['diagramItem']));
|
|
376
378
|
}
|
|
377
379
|
if (wf.Connections.filter(c => c.Sink.ParentDiagramItem.ID === item.ID).length === 0) {
|
|
378
|
-
validationItems.push(new ValidationItem(ResultTypes.WARNING,
|
|
380
|
+
validationItems.push(new ValidationItem(ResultTypes.WARNING, itemType, SDKUI_Localizator.WorkflowDiagramElementShouldHaveIncoming.replaceParams(item.ItemName), ['diagramItem']));
|
|
379
381
|
}
|
|
380
382
|
break;
|
|
381
383
|
case DiagramItemTypes.RunApp:
|
|
382
384
|
if (wf.Connections.filter(c => c.Source.ParentDiagramItem.ID === item.ID).length === 0) {
|
|
383
|
-
validationItems.push(new ValidationItem(ResultTypes.WARNING,
|
|
385
|
+
validationItems.push(new ValidationItem(ResultTypes.WARNING, itemType, SDKUI_Localizator.WorkflowDiagramElementShouldHaveOutgoing.replaceParams(item.ItemName), ['diagramItem']));
|
|
384
386
|
}
|
|
385
387
|
if (wf.Connections.filter(c => c.Sink.ParentDiagramItem.ID === item.ID).length === 0) {
|
|
386
|
-
validationItems.push(new ValidationItem(ResultTypes.WARNING,
|
|
388
|
+
validationItems.push(new ValidationItem(ResultTypes.WARNING, itemType, SDKUI_Localizator.WorkflowDiagramElementShouldHaveIncoming.replaceParams(item.ItemName), ['diagramItem']));
|
|
387
389
|
}
|
|
388
390
|
break;
|
|
389
391
|
}
|
|
@@ -480,7 +482,17 @@ export const wfDiagramItemValidator = async (d) => {
|
|
|
480
482
|
qvo.DoOrderByValidation = false;
|
|
481
483
|
await PlatformObjectValidator.QueryValidatorAsync(d.QD, vil, qvo);
|
|
482
484
|
if (d.QD?.where === undefined || d.QD.where.length <= 0) {
|
|
483
|
-
vil.push(new ValidationItem(ResultTypes.ERROR,
|
|
485
|
+
vil.push(new ValidationItem(ResultTypes.ERROR, LocalizeDiagramItemType(d.Type), `La query della condizione '${d.ItemName}' non contiene criteri di selezione`, [DiagramItemProps.QD]));
|
|
486
|
+
}
|
|
487
|
+
break;
|
|
488
|
+
case DiagramItemTypes.CaseFlow_Create:
|
|
489
|
+
PlatformObjectValidator.RequiredStringValidator(d.ItemName, DiagramItemProps.ItemName, vil, SDKUI_Localizator.Name);
|
|
490
|
+
PlatformObjectValidator.RequiredStringValidator(d.Tos2, DiagramItemProps.Tos2, vil, SDKUI_Localizator.OwnerName);
|
|
491
|
+
if (d.Tos2) {
|
|
492
|
+
const { andRecipients } = tosToActors(d.Tos2);
|
|
493
|
+
if (andRecipients.length > 1) {
|
|
494
|
+
vil.push(new ValidationItem(ResultTypes.ERROR, DiagramItemProps.Tos2, SDKUI_Localizator.WorkflowOnlyOneOwnerAllowed));
|
|
495
|
+
}
|
|
484
496
|
}
|
|
485
497
|
break;
|
|
486
498
|
}
|
|
@@ -115,7 +115,7 @@ const TMLoginForm = (props) => {
|
|
|
115
115
|
const [dcmtArchive, setDcmtArchive] = useState();
|
|
116
116
|
const [manualArchiveID, setManualArchiveID] = useState('');
|
|
117
117
|
const [authMode, setAuthMode] = useState(AuthenticationModes.TopMedia);
|
|
118
|
-
const [username, setUsername] = useState('
|
|
118
|
+
const [username, setUsername] = useState('');
|
|
119
119
|
const [password, setPassword] = useState('');
|
|
120
120
|
const [authDomain, setAuthDomain] = useState('');
|
|
121
121
|
const [usernameOnBehalf, setUsernameOnBehalf] = useState('');
|
|
@@ -11,7 +11,7 @@ import { TMColors } from '../../utils/theme';
|
|
|
11
11
|
import TMValidationItemsList from '../grids/TMValidationItemsList';
|
|
12
12
|
import TMModal from '../base/TMModal';
|
|
13
13
|
import { DeviceType, useDeviceType } from '../base/TMDeviceProvider';
|
|
14
|
-
const TMSaveForm = ({ id, formMode = FormModes.Update, showToolbar = true, skipIsModifiedCheck = false, title, children, isModal, exception, customToolbarElements, hasNavigation, showSaveButton = true, customSaveButton, customTooltipSaveButton, showBackButton, showWarningsCount = true, showErrorCount = true, showUndoButton = true, onClose, onSaveAsync, onNext, onPrev, canNext, canPrev, isModified, onShowList, validationItems = [], onUndo, onCancel, width, height, askClosingConfirm = false, showTitleFormMode = true, showCloseButton = true }) => {
|
|
14
|
+
const TMSaveForm = ({ id, formMode = FormModes.Update, showToolbar = true, skipIsModifiedCheck = false, title, children, isModal, exception, customToolbarElements, hasNavigation, showSaveButton = true, customSaveButton, customTooltipSaveButton, showBackButton, showWarningsCount = true, showErrorCount = true, showUndoButton = true, onClose, onSaveAsync, onNext, onPrev, canNext, canPrev, isModified, onShowList, validationItems = [], onUndo, onCancel, width, height, askClosingConfirm = false, showTitleFormMode = true, showCloseButton = true, resizable = true }) => {
|
|
15
15
|
const [showList, setShowList] = useState(true);
|
|
16
16
|
const [showErrorGrid, setShowErrorGrid] = useState(false);
|
|
17
17
|
const deviceType = useDeviceType();
|
|
@@ -65,26 +65,74 @@ const TMSaveForm = ({ id, formMode = FormModes.Update, showToolbar = true, skipI
|
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
67
|
};
|
|
68
|
-
const doClose = () => {
|
|
68
|
+
const doClose = async () => {
|
|
69
|
+
// Se non ci sono modifiche o vogliamo ignorare il controllo delle modifiche
|
|
69
70
|
if (!isModified || skipIsModifiedCheck) {
|
|
70
71
|
onClose?.();
|
|
71
|
-
|
|
72
|
+
// Se il dispositivo è mobile, mostra di nuovo la lista
|
|
73
|
+
if (deviceType === DeviceType.MOBILE) {
|
|
74
|
+
setShowList(true);
|
|
75
|
+
onShowList?.(true);
|
|
76
|
+
}
|
|
72
77
|
return;
|
|
73
78
|
}
|
|
79
|
+
// Determina il messaggio e i pulsanti da mostrare in base alla presenza di errori
|
|
80
|
+
const hasValidationErrors = validationItems.length > 0;
|
|
81
|
+
const message = (isModified && hasValidationErrors) ? SDKUI_Localizator.FormErrorsProceedQuestion : SDKUI_Localizator.SaveQuestion;
|
|
82
|
+
const buttons = hasValidationErrors
|
|
83
|
+
? [ButtonNames.YES, ButtonNames.NO]
|
|
84
|
+
: [ButtonNames.YES, ButtonNames.NO, ButtonNames.CANCEL];
|
|
85
|
+
// Mostra il messaggio di conferma
|
|
74
86
|
TMMessageBoxManager.show({
|
|
75
|
-
parentId: isModal ?
|
|
76
|
-
message
|
|
77
|
-
|
|
87
|
+
parentId: isModal ? `TMSaveFormShowConfirmForClose-${id}` : undefined,
|
|
88
|
+
message,
|
|
89
|
+
buttons,
|
|
90
|
+
onButtonClick: async (buttonClicked) => {
|
|
78
91
|
try {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
92
|
+
// Caso con errori di validazione
|
|
93
|
+
if (hasValidationErrors) {
|
|
94
|
+
if (buttonClicked === ButtonNames.NO)
|
|
95
|
+
return; // Non fare nulla
|
|
96
|
+
if (buttonClicked === ButtonNames.YES) {
|
|
97
|
+
if (deviceType === DeviceType.MOBILE) {
|
|
98
|
+
onUndo();
|
|
99
|
+
setShowList(true);
|
|
100
|
+
onShowList?.(true);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
onUndo();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// Caso senza errori
|
|
109
|
+
switch (buttonClicked) {
|
|
110
|
+
case ButtonNames.CANCEL:
|
|
111
|
+
return; // Non fare nulla
|
|
112
|
+
case ButtonNames.NO:
|
|
113
|
+
if (deviceType === DeviceType.MOBILE) {
|
|
114
|
+
onUndo();
|
|
115
|
+
setShowList(true);
|
|
116
|
+
onShowList?.(true);
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
case ButtonNames.YES:
|
|
120
|
+
if (deviceType === DeviceType.MOBILE) {
|
|
121
|
+
await onSaveAsync?.();
|
|
122
|
+
setShowList(true);
|
|
123
|
+
onShowList?.(true);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
await onSaveAsync?.();
|
|
127
|
+
}
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Chiude il form/modal
|
|
85
132
|
onClose?.();
|
|
86
133
|
}
|
|
87
134
|
catch (ex) {
|
|
135
|
+
// Mostra eventuali eccezioni
|
|
88
136
|
TMExceptionBoxManager.show({ exception: ex });
|
|
89
137
|
}
|
|
90
138
|
}
|
|
@@ -102,7 +150,7 @@ const TMSaveForm = ({ id, formMode = FormModes.Update, showToolbar = true, skipI
|
|
|
102
150
|
_jsx("div", { style: { width: '100%', height: '100%', marginTop: '50px', display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', color: getColor('error') }, children: 'Si è verificato un errore' })
|
|
103
151
|
: _jsx(_Fragment, { children: children }) }), showErrorGrid && validationItems.length > 0 ? _jsx(TMCard, { scrollY: true, padding: false, showBorder: false, children: _jsx(TMValidationItemsList, { validationItems: validationItems }) }) : _jsx(_Fragment, {})] }) }), (isModal && onClose) && _jsx("div", { id: "TMSaveFormShowConfirmForClose-" + id })] }));
|
|
104
152
|
};
|
|
105
|
-
return (_jsx(_Fragment, { children: (isModal && onClose) ? _jsx(_Fragment, { children: _jsx(TMModal, { title: `${title}${showTitleFormMode ? ` - ${LocalizeFormModes(formMode)}` : ''}`, onClose: doClose, width: width ?? '100%', height: height ?? '100%', hidePopup: false, askClosingConfirm: askClosingConfirm, showCloseButton: showCloseButton, children: _jsx("div", { style: { width: "100%", height: "100%", display: 'block' }, children: renderSaveForm() }) }) })
|
|
153
|
+
return (_jsx(_Fragment, { children: (isModal && onClose) ? _jsx(_Fragment, { children: _jsx(TMModal, { title: `${title}${showTitleFormMode ? ` - ${LocalizeFormModes(formMode)}` : ''}`, onClose: doClose, width: width ?? '100%', height: height ?? '100%', hidePopup: false, askClosingConfirm: askClosingConfirm, showCloseButton: showCloseButton, resizable: resizable, children: _jsx("div", { style: { width: "100%", height: "100%", display: 'block' }, children: renderSaveForm() }) }) })
|
|
106
154
|
: renderSaveForm() }));
|
|
107
155
|
};
|
|
108
156
|
export default TMSaveForm;
|