@topconsultnpm/sdkui-react-beta 6.16.16 → 6.16.18

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.
@@ -33,5 +33,5 @@ export const TMGroupIdViewer = (props) => {
33
33
  if (!group) {
34
34
  return _jsx("span", { children: SDKUI_Localizator.NoDataToDisplay });
35
35
  }
36
- return _jsxs("span", { children: [props.showIcon && _jsx(IconUserGroup, { color: '#767676', style: { marginRight: '4px' } }), group.name] });
36
+ return (_jsxs("span", { style: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [props.showIcon && _jsx(IconUserGroup, { color: '#767676' }), _jsx("span", { children: group.name })] }));
37
37
  };
@@ -76,7 +76,14 @@ export const TMUserIdViewer = ({ userId, showIcon = false, noneSelectionText = `
76
76
  return undefined;
77
77
  return ud ? getCompleteUserName(ud.domain, ud.name) : userId.toString() ?? noneSelectionText;
78
78
  };
79
- return (_jsxs(StyledDivHorizontal, { children: [getIcon(), _jsx("p", { style: { textAlign: 'left', marginLeft: showIcon ? '5px' : '', opacity: ud ? 1 : 0.5 }, children: getDescription() })] }));
79
+ return (_jsxs("span", { style: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [getIcon(), _jsx("span", { children: getDescription() })] })
80
+ // <StyledDivHorizontal>
81
+ // {getIcon()}
82
+ // <p style={{ textAlign: 'left', marginLeft: showIcon ? '5px' : '', opacity: ud ? 1 : 0.5 }}>
83
+ // {getDescription()}
84
+ // </p>
85
+ // </StyledDivHorizontal>
86
+ );
80
87
  };
81
88
  export const TMUserIcon = ({ ud }) => {
82
89
  if (!ud)
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { QueryDescriptor } from '@topconsultnpm/sdk-ts-beta';
3
+ export declare enum WorkItemActorTypes {
4
+ None = 0,
5
+ UID = 1,
6
+ GID = 2,
7
+ MID = 3,
8
+ QID = 4,
9
+ FXID = 5,
10
+ STID = 6
11
+ }
12
+ export interface WorkItemActor {
13
+ ActorType: WorkItemActorTypes;
14
+ ActorID: string;
15
+ Or: number;
16
+ }
17
+ interface RecipientListProps {
18
+ recipients: WorkItemActor[];
19
+ title: string;
20
+ tid?: number;
21
+ qd?: QueryDescriptor;
22
+ onQDChange?: (newQd: QueryDescriptor | undefined) => void;
23
+ onAdd: (recipient: WorkItemActor[]) => void;
24
+ onRemove: (recipient: WorkItemActor) => void;
25
+ }
26
+ declare const RecipientList: React.FC<RecipientListProps>;
27
+ export default RecipientList;
@@ -0,0 +1,172 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useState } from 'react';
3
+ import styled from 'styled-components';
4
+ import TMButton from '../../../base/TMButton';
5
+ import { IconAdd, IconDelete, SDKUI_Localizator } from '../../../../helper';
6
+ import { TMUserChooserForm, TMUserIdViewer } from '../../../choosers/TMUserChooser';
7
+ import { TMGroupChooserForm, TMGroupIdViewer } from '../../../choosers/TMGroupChooser';
8
+ import { TMMidViewer } from '../../../viewers/TMMidViewer';
9
+ import { SDK_Globals, SDK_Localizator } from '@topconsultnpm/sdk-ts-beta';
10
+ import { useOutsideClick } from '../../../../hooks/useOutsideClick';
11
+ import { FormModes } from '../../../../ts';
12
+ import { TMMessageBoxManager, ButtonNames } from '../../../base/TMPopUp';
13
+ import TMModal from '../../../base/TMModal';
14
+ import { TMMetadataChooserForm } from '../../../choosers/TMMetadataChooser';
15
+ import TMQueryEditor from '../../../query/TMQueryEditor';
16
+ export var WorkItemActorTypes;
17
+ (function (WorkItemActorTypes) {
18
+ WorkItemActorTypes[WorkItemActorTypes["None"] = 0] = "None";
19
+ WorkItemActorTypes[WorkItemActorTypes["UID"] = 1] = "UID";
20
+ WorkItemActorTypes[WorkItemActorTypes["GID"] = 2] = "GID";
21
+ WorkItemActorTypes[WorkItemActorTypes["MID"] = 3] = "MID";
22
+ WorkItemActorTypes[WorkItemActorTypes["QID"] = 4] = "QID";
23
+ WorkItemActorTypes[WorkItemActorTypes["FXID"] = 5] = "FXID";
24
+ WorkItemActorTypes[WorkItemActorTypes["STID"] = 6] = "STID";
25
+ })(WorkItemActorTypes || (WorkItemActorTypes = {}));
26
+ const RecipientsColumn = styled.div `
27
+ flex: 1;
28
+ border: 1px solid #ccc;
29
+ border-radius: 5px;
30
+ padding: 10px;
31
+ min-width: 300px;
32
+ position: relative;
33
+ `;
34
+ const HeaderContainer = styled.div `
35
+ display: flex;
36
+ justify-content: space-between;
37
+ align-items: center;
38
+ position: relative;
39
+ margin-bottom: 10px;
40
+ `;
41
+ const RecipientItem = styled.div `
42
+ display: flex;
43
+ align-items: center;
44
+ gap: 5px;
45
+ `;
46
+ const FloatingMenu = styled.div `
47
+ position: absolute;
48
+ top: 100%; /* Si apre sotto il bottone */
49
+ right: 0; /* Allinea il bordo destro del menu con quello del genitore */
50
+ background-color: white;
51
+ border: 1px solid #ccc;
52
+ border-radius: 5px;
53
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
54
+ z-index: 10;
55
+ display: flex;
56
+ flex-direction: column; /* Disposizione verticale */
57
+ gap: 5px;
58
+ padding: 5px;
59
+ min-width: 150px;
60
+ transform: translateY(5px);
61
+ align-items: center; /* Centra i pulsanti orizzontalmente */
62
+ `;
63
+ const FloatingMenuButton = styled(TMButton) `
64
+ width: 100%; /* Rende i pulsanti interni larghi quanto il menu */
65
+ `;
66
+ const RecipientList = ({ recipients, title, tid, qd, onAdd, onRemove, onQDChange }) => {
67
+ const [uiState, setUiState] = useState({
68
+ isMenuOpen: false,
69
+ showUserChooser: false,
70
+ showGroupChooser: false,
71
+ showMetadataChooser: false,
72
+ showQdEditor: false,
73
+ });
74
+ const menuRef = useOutsideClick(() => setUiState(prevState => ({ ...prevState, isMenuOpen: false })));
75
+ const handleQdChosen = useCallback((newQd) => {
76
+ if (newQd) {
77
+ const recipientToAdd = {
78
+ ActorType: WorkItemActorTypes.QID,
79
+ ActorID: newQd.id ? newQd.id.toString() : '-1',
80
+ Or: 0,
81
+ };
82
+ onAdd([recipientToAdd]);
83
+ onQDChange?.(newQd);
84
+ }
85
+ setUiState(prevState => ({ ...prevState, showQdEditor: false }));
86
+ }, [onQDChange]);
87
+ const handleUserChosen = useCallback((IDs) => {
88
+ if (IDs && IDs.length > 0) {
89
+ const recipientsToAdd = IDs.map(id => ({
90
+ ActorType: WorkItemActorTypes.UID,
91
+ ActorID: id.toString(),
92
+ Or: 0
93
+ }));
94
+ onAdd(recipientsToAdd);
95
+ }
96
+ setUiState(prevState => ({ ...prevState, showUserChooser: false }));
97
+ }, []);
98
+ const handleGroupChosen = useCallback((IDs) => {
99
+ if (IDs && IDs.length > 0) {
100
+ const recipientsToAdd = IDs.map(id => ({
101
+ ActorType: WorkItemActorTypes.GID,
102
+ ActorID: id.toString(),
103
+ Or: 0
104
+ }));
105
+ onAdd(recipientsToAdd);
106
+ }
107
+ setUiState(prevState => ({ ...prevState, showGroupChooser: false }));
108
+ }, []);
109
+ const handleMetadataChosen = useCallback((IDs) => {
110
+ if (IDs && IDs.length > 0) {
111
+ const recipientsToAdd = IDs.map(item => ({
112
+ ActorType: WorkItemActorTypes.MID,
113
+ ActorID: item.mid ? item.mid.toString() : '0',
114
+ Or: 0
115
+ }));
116
+ onAdd(recipientsToAdd);
117
+ }
118
+ setUiState(prevState => ({ ...prevState, showMetadataChooser: false }));
119
+ }, []);
120
+ const handleAddClick = () => {
121
+ setUiState(prevState => ({ ...prevState, isMenuOpen: !prevState.isMenuOpen }));
122
+ };
123
+ const openChooser = useCallback((chooser) => {
124
+ setUiState(prevState => ({
125
+ ...prevState,
126
+ isAndMenuOpen: false,
127
+ isOrMenuOpen: false,
128
+ [chooser]: true,
129
+ }));
130
+ }, []);
131
+ const openQdEditorFromMenu = useCallback(() => {
132
+ const hasExistingQd = recipients.some(r => r.ActorType === WorkItemActorTypes.QID);
133
+ if (hasExistingQd) {
134
+ TMMessageBoxManager.show({
135
+ buttons: [ButtonNames.OK],
136
+ title: SDK_Globals.appModule,
137
+ message: "Definire solo una query per i destinatari"
138
+ });
139
+ setUiState(prevState => ({ ...prevState, isAndMenuOpen: false, isOrMenuOpen: false }));
140
+ }
141
+ else {
142
+ openChooser('showQdEditor');
143
+ }
144
+ }, [recipients, openChooser]);
145
+ const renderActorViewer = (recipient) => {
146
+ const actorId = parseInt(recipient.ActorID, 10);
147
+ switch (recipient.ActorType) {
148
+ case WorkItemActorTypes.UID:
149
+ return _jsx(TMUserIdViewer, { userId: actorId, showIcon: true });
150
+ case WorkItemActorTypes.GID:
151
+ return _jsx(TMGroupIdViewer, { groupID: actorId, showIcon: true });
152
+ case WorkItemActorTypes.MID:
153
+ return _jsx(TMMidViewer, { tid_mid: { tid: tid, mid: actorId }, showIcon: true });
154
+ case WorkItemActorTypes.QID:
155
+ return (_jsx("span", { onDoubleClick: () => openChooser('showQdEditor'), style: { cursor: 'pointer' }, children: SDKUI_Localizator.WorkflowGetRecipientsFromQuery }));
156
+ default:
157
+ return _jsxs("span", { children: [WorkItemActorTypes[recipient.ActorType], ": ", recipient.ActorID] });
158
+ }
159
+ };
160
+ const renderFloatingMenu = () => {
161
+ const menuItems = [
162
+ { caption: SDK_Localizator.Users, onClick: () => openChooser('showUserChooser') },
163
+ { caption: SDK_Localizator.Groups, onClick: () => openChooser('showGroupChooser') },
164
+ { caption: SDK_Localizator.Metadata, onClick: () => openChooser('showMetadataChooser') },
165
+ { caption: SDK_Localizator.Query, onClick: openQdEditorFromMenu },
166
+ ];
167
+ return (_jsx(FloatingMenu, { ref: menuRef, children: menuItems.map((item, index) => (_jsx(FloatingMenuButton, { btnStyle: 'text', caption: item.caption, onClick: item.onClick }, index))) }));
168
+ };
169
+ return (_jsxs(RecipientsColumn, { children: [_jsxs(HeaderContainer, { children: [_jsx("p", { style: { fontWeight: 600 }, children: title }), _jsx(TMButton, { btnStyle: 'icon', caption: 'Aggiungi destinatario', 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, { children: [_jsx(IconDelete, { color: '#c00', cursor: 'pointer', onClick: () => onRemove(recipient) }), 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 &&
170
+ _jsx(TMModal, { title: SDKUI_Localizator.QueryDefine, onClose: () => setUiState(prevState => ({ ...prevState, showQdEditor: false })), children: _jsx(TMQueryEditor, { inputData: qd, formMode: FormModes.Update, onApplied: handleQdChosen, onClose: () => setUiState(prevState => ({ ...prevState, showQdEditor: false })) }) })] }));
171
+ };
172
+ export default RecipientList;
@@ -1,19 +1,5 @@
1
1
  import React from 'react';
2
2
  import { QueryDescriptor, WorkItemSetRules } from '@topconsultnpm/sdk-ts-beta';
3
- export declare enum WorkItemActorTypes {
4
- None = 0,
5
- UID = 1,
6
- GID = 2,
7
- MID = 3,
8
- QID = 4,
9
- FXID = 5,
10
- STID = 6
11
- }
12
- export interface WorkItemActor {
13
- ActorType: WorkItemActorTypes;
14
- ActorID: string;
15
- Or: number;
16
- }
17
3
  interface WorkitemRecipientsEditorProps {
18
4
  tos: string;
19
5
  setRule: WorkItemSetRules | undefined;
@@ -1,287 +1,103 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useMemo, useState } from 'react';
2
+ import { useCallback, useEffect, useMemo, useState } from 'react';
3
3
  import styled from 'styled-components';
4
- import TMButton from '../../../base/TMButton';
5
- import { IconAdd, IconMetadata, IconSavedQuery, IconUser, IconUserGroup, SDKUI_Localizator } from '../../../../helper'; // Importa anche IconAdd
6
- import { TMUserChooserForm, TMUserIdViewer } from '../../../choosers/TMUserChooser';
7
- import { TMGroupChooserForm, TMGroupIdViewer } from '../../../choosers/TMGroupChooser';
8
- import { SDK_Globals, SDK_Localizator, WorkItemSetRules } from '@topconsultnpm/sdk-ts-beta';
9
- import { TMMetadataChooserForm } from '../../../choosers/TMMetadataChooser';
10
- import { FormModes } from '../../../../ts';
11
4
  import TMDropDown from '../../../editors/TMDropDown';
12
- import { TMMidViewer } from '../../../viewers/TMMidViewer';
13
- import TMQueryEditor from '../../../query/TMQueryEditor';
14
- import TMModal from '../../../base/TMModal';
15
- import { ButtonNames, TMMessageBoxManager } from '../../../base/TMPopUp';
16
- import { useOutsideClick } from '../../../../hooks/useOutsideClick';
17
- export var WorkItemActorTypes;
18
- (function (WorkItemActorTypes) {
19
- WorkItemActorTypes[WorkItemActorTypes["None"] = 0] = "None";
20
- WorkItemActorTypes[WorkItemActorTypes["UID"] = 1] = "UID";
21
- WorkItemActorTypes[WorkItemActorTypes["GID"] = 2] = "GID";
22
- WorkItemActorTypes[WorkItemActorTypes["MID"] = 3] = "MID";
23
- WorkItemActorTypes[WorkItemActorTypes["QID"] = 4] = "QID";
24
- WorkItemActorTypes[WorkItemActorTypes["FXID"] = 5] = "FXID";
25
- WorkItemActorTypes[WorkItemActorTypes["STID"] = 6] = "STID";
26
- })(WorkItemActorTypes || (WorkItemActorTypes = {}));
5
+ import { WorkItemSetRules } from '@topconsultnpm/sdk-ts-beta';
6
+ import RecipientList, { WorkItemActorTypes } from './RecipientList';
7
+ import { SDKUI_Localizator } from '../../../../helper';
27
8
  const RecipientsContainer = styled.div `
28
9
  display: flex;
29
10
  gap: 20px;
30
- /* padding: 10px 0px; */
31
11
  flex-wrap: wrap;
32
12
  `;
33
- const RecipientsColumn = styled.div `
34
- flex: 1;
35
- border: 1px solid #ccc;
36
- border-radius: 5px;
37
- padding: 10px;
38
- min-width: 300px;
39
- position: relative;
40
- `;
41
- const HeaderContainer = styled.div `
42
- display: flex;
43
- justify-content: space-between;
44
- align-items: center;
45
- position: relative;
46
- margin-bottom: 10px;
47
- `;
48
- const RecipientItem = styled.div `
49
- display: flex;
50
- align-items: center;
51
- margin-bottom: 5px;
52
- gap: 5px;
53
- `;
54
- const RecipientRemoveButton = styled.span `
55
- cursor: pointer;
56
- color: #c00;
57
- font-weight: bold;
58
- `;
59
- const FloatingMenu = styled.div `
60
- position: absolute;
61
- top: 100%; /* Si apre sotto il bottone */
62
- right: 0; /* Allinea il bordo destro del menu con quello del genitore */
63
- background-color: white;
64
- border: 1px solid #ccc;
65
- border-radius: 5px;
66
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
67
- z-index: 10;
68
- display: flex;
69
- flex-direction: column; /* Disposizione verticale */
70
- gap: 5px;
71
- padding: 5px;
72
- min-width: 150px;
73
- transform: translateY(5px);
74
- align-items: center; /* Centra i pulsanti orizzontalmente */
75
- `;
76
- const FloatingMenuButton = styled(TMButton) `
77
- width: 100%; /* Rende i pulsanti interni larghi quanto il menu */
78
- `;
79
- const WorkitemRecipientsEditor = ({ tos, setRule, qd, mTID, onTosChange, onQDChange, onSetRuleChange }) => {
80
- const [isAndMenuOpen, setIsAndMenuOpen] = useState(false);
81
- const [isOrMenuOpen, setIsOrMenuOpen] = useState(false);
82
- const [showUserChooser, setShowUserChooser] = useState(false);
83
- const [showGroupChooser, setShowGroupChooser] = useState(false);
84
- // const [showFxChartChooser, setShowFxChartChooser] = useState(false);
85
- const [showMetadataChooser, setShowMetadataChooser] = useState(false);
86
- const [showQdEditor, setShowQdEditor] = useState(false);
87
- const andMenuRef = useOutsideClick(() => {
88
- setIsAndMenuOpen(false);
89
- });
90
- // Applica il custom hook per il menu OR
91
- const orMenuRef = useOutsideClick(() => {
92
- setIsOrMenuOpen(false);
93
- });
94
- // useEffect(() => {
95
- // const handleClickOutside = (event: MouseEvent) => {
96
- // // Controlla il menu AND
97
- // if (isAndMenuOpen && andMenuRef.current && !andMenuRef.current.contains(event.target as Node) && andButtonRef.current && !andButtonRef.current.contains(event.target as Node)) {
98
- // setIsAndMenuOpen(false);
99
- // }
100
- // // Controlla il menu OR
101
- // if (isOrMenuOpen && orMenuRef.current && !orMenuRef.current.contains(event.target as Node) && orButtonRef.current && !orButtonRef.current.contains(event.target as Node)) {
102
- // setIsOrMenuOpen(false);
103
- // }
104
- // };
105
- // // Aggiungi l'event listener se un menu è aperto
106
- // if (isAndMenuOpen || isOrMenuOpen) {
107
- // document.addEventListener('mousedown', handleClickOutside);
108
- // }
109
- // // Pulisci l'event listener
110
- // return () => {
111
- // document.removeEventListener('mousedown', handleClickOutside);
112
- // };
113
- // }, [isAndMenuOpen, isOrMenuOpen]);
114
- // useEffect(() => {
115
- // const handleKeyDown = (event: KeyboardEvent) => {
116
- // if (event.key === 'Escape') {
117
- // if (isAndMenuOpen) {
118
- // setIsAndMenuOpen(false);
119
- // event.stopPropagation(); // Ferma la propagazione per non chiudere anche il modale
120
- // } else if (isOrMenuOpen) {
121
- // setIsOrMenuOpen(false);
122
- // event.stopPropagation(); // Ferma la propagazione per non chiudere anche il modale
123
- // }
124
- // }
125
- // };
126
- // if (isAndMenuOpen || isOrMenuOpen) {
127
- // document.addEventListener('keydown', handleKeyDown);
128
- // }
129
- // return () => {
130
- // document.removeEventListener('keydown', handleKeyDown);
131
- // };
132
- // }, [isAndMenuOpen, isOrMenuOpen]);
133
- const parseTos = (tosString) => {
134
- const andRecipients = [];
135
- const orRecipients = [];
136
- if (!tosString)
137
- return { andRecipients, orRecipients };
138
- const tokens1 = tosString.split(';');
139
- for (const t of tokens1) {
140
- const t1 = t.trim();
141
- if (!t1)
142
- continue;
143
- const tokens2 = t1.split('|');
144
- if (tokens2.length < 2)
145
- continue;
146
- const actorTypeStr = tokens2[0].toUpperCase();
147
- const actorType = WorkItemActorTypes[actorTypeStr];
148
- const actorID = tokens2[1];
149
- const or = tokens2.length === 3 ? parseInt(tokens2[2], 10) : 0;
150
- if (actorType !== undefined) {
151
- const actor = {
152
- ActorType: actorType,
153
- ActorID: actorID,
154
- Or: or,
155
- };
156
- if (or === 0) {
157
- andRecipients.push(actor);
158
- }
159
- else {
160
- orRecipients.push(actor);
161
- }
162
- }
163
- }
13
+ const tosToActors = (tosString) => {
14
+ const andRecipients = [];
15
+ const orRecipients = [];
16
+ if (!tosString)
164
17
  return { andRecipients, orRecipients };
165
- };
166
- const { andRecipients, orRecipients } = useMemo(() => parseTos(tos), [tos]);
167
- const actorsToTos = (actors) => {
168
- return actors.map(actor => `${WorkItemActorTypes[actor.ActorType]}|${actor.ActorID}|${actor.Or}`).join(';');
169
- };
170
- const handleRemoveRecipient = (recipientToRemove) => {
171
- const allRecipients = [...andRecipients, ...orRecipients];
172
- const updatedRecipients = allRecipients.filter(r => r !== recipientToRemove);
173
- const newTos = actorsToTos(updatedRecipients);
174
- onTosChange(newTos);
175
- };
176
- const handleAddRecipients = (newRecipients) => {
177
- const allRecipients = [...andRecipients, ...orRecipients];
178
- const updatedRecipients = [...allRecipients, ...newRecipients]; // Aggiunge tutti i nuovi destinatari
179
- const newTos = actorsToTos(updatedRecipients);
180
- onTosChange(newTos);
181
- setIsAndMenuOpen(false);
182
- setIsOrMenuOpen(false);
183
- setShowUserChooser(false);
184
- setShowQdEditor(false);
185
- };
186
- const handleUserChosen = (IDs, orValue) => {
187
- if (IDs && IDs.length > 0) {
188
- const recipientsToAdd = IDs.map(id => ({
189
- ActorType: WorkItemActorTypes.UID,
190
- ActorID: id.toString(),
191
- Or: orValue
192
- }));
193
- handleAddRecipients(recipientsToAdd);
194
- }
195
- setShowUserChooser(false);
196
- };
197
- const handleGroupChosen = (IDs, orValue) => {
198
- if (IDs && IDs.length > 0) {
199
- const recipientsToAdd = IDs.map(id => ({
200
- ActorType: WorkItemActorTypes.GID,
201
- ActorID: id.toString(),
202
- Or: orValue
203
- }));
204
- handleAddRecipients(recipientsToAdd);
205
- }
206
- setShowGroupChooser(false);
207
- };
208
- const handleMetadataChosen = (IDs, orValue) => {
209
- if (IDs && IDs.length > 0) {
210
- const recipientsToAdd = IDs.map(id => ({
211
- ActorType: WorkItemActorTypes.MID,
212
- ActorID: id.mid ? id.mid.toString() : '0',
213
- Or: orValue
214
- }));
215
- handleAddRecipients(recipientsToAdd);
18
+ const tokens1 = tosString.split(';');
19
+ for (const t of tokens1) {
20
+ const t1 = t.trim();
21
+ if (!t1)
22
+ continue;
23
+ const tokens2 = t1.split('|');
24
+ if (tokens2.length < 2)
25
+ continue;
26
+ const actorTypeStr = tokens2[0].toUpperCase();
27
+ const actorType = WorkItemActorTypes[actorTypeStr];
28
+ const actorID = tokens2[1];
29
+ const or = tokens2.length === 3 ? parseInt(tokens2[2], 10) : 0;
30
+ if (actorType !== undefined) {
31
+ const actor = {
32
+ ActorType: actorType,
33
+ ActorID: actorID,
34
+ Or: or,
35
+ };
36
+ if (or === 0) {
37
+ andRecipients.push(actor);
38
+ }
39
+ else {
40
+ orRecipients.push(actor);
41
+ }
216
42
  }
217
- setShowMetadataChooser(false);
218
- };
219
- const handleQdChosen = (newQd, orValue) => {
220
- if (newQd) {
221
- // 1. Unisci tutti i destinatari e filtra per rimuovere eventuali QID esistenti.
43
+ }
44
+ return { andRecipients, orRecipients };
45
+ };
46
+ const actorsToTos = (actors) => {
47
+ return actors.map(actor => `${WorkItemActorTypes[actor.ActorType]}|${actor.ActorID}|${actor.Or}`).join(';');
48
+ };
49
+ const WorkitemRecipientsEditor = ({ tos, setRule, qd, mTID, onTosChange, onQDChange, onSetRuleChange }) => {
50
+ const [localTos, setLocalTos] = useState(tos);
51
+ useEffect(() => {
52
+ setLocalTos(tos);
53
+ }, [tos]);
54
+ const handleAddRecipients = useCallback((newRecipients, orValue) => {
55
+ setLocalTos(prevTos => {
56
+ const { andRecipients, orRecipients } = tosToActors(prevTos);
57
+ let allRecipients = [...andRecipients, ...orRecipients];
58
+ // 1. Rimuovi qualsiasi QID esistente se il nuovo destinatario è una query
59
+ if (newRecipients.length > 0 && newRecipients[0].ActorType === WorkItemActorTypes.QID) {
60
+ allRecipients = allRecipients.filter(r => r.ActorType !== WorkItemActorTypes.QID);
61
+ }
62
+ const updatedRecipients = [...allRecipients, ...newRecipients.map(r => ({ ...r, Or: orValue }))];
63
+ const newTos = actorsToTos(updatedRecipients);
64
+ onTosChange(newTos);
65
+ return newTos;
66
+ });
67
+ }, [onTosChange, onQDChange]);
68
+ const handleRemoveRecipient = useCallback((recipientToRemove) => {
69
+ setLocalTos(prevTos => {
70
+ const { andRecipients, orRecipients } = tosToActors(prevTos);
222
71
  const allRecipients = [...andRecipients, ...orRecipients];
223
- const updatedRecipients = allRecipients.filter(r => r.ActorType !== WorkItemActorTypes.QID);
224
- // 2. Crea il nuovo destinatario QID
225
- const recipientToAdd = {
226
- ActorType: WorkItemActorTypes.QID,
227
- ActorID: newQd.id ? newQd.id.toString() : '-1',
228
- Or: orValue
229
- };
230
- // 3. Aggiungi il nuovo destinatario alla lista
231
- updatedRecipients.push(recipientToAdd);
232
- // 4. Converte la lista aggiornata in una stringa e aggiorna lo stato.
72
+ const updatedRecipients = allRecipients.filter(r => r.ActorType !== recipientToRemove.ActorType || r.ActorID !== recipientToRemove.ActorID || r.Or !== recipientToRemove.Or);
233
73
  const newTos = actorsToTos(updatedRecipients);
234
74
  onTosChange(newTos);
235
- onQDChange(newQd);
236
- }
237
- setIsAndMenuOpen(false);
238
- setIsOrMenuOpen(false);
239
- setShowQdEditor(false);
240
- };
241
- const renderActorViewer = (recipient) => {
242
- const actorId = parseInt(recipient.ActorID, 10);
243
- switch (recipient.ActorType) {
244
- case WorkItemActorTypes.UID:
245
- return _jsx(TMUserIdViewer, { userId: actorId, showIcon: true });
246
- case WorkItemActorTypes.GID:
247
- return _jsx(TMGroupIdViewer, { groupID: actorId, showIcon: true });
248
- case WorkItemActorTypes.MID:
249
- return _jsx(TMMidViewer, { tid_mid: { tid: mTID, mid: actorId }, showIcon: true });
250
- case WorkItemActorTypes.QID:
251
- return (_jsx("span", { onDoubleClick: openQdEditor, style: { cursor: 'pointer' }, children: SDKUI_Localizator.WorkflowGetRecipientsFromQuery }));
252
- default:
253
- return _jsxs("span", { children: [WorkItemActorTypes[recipient.ActorType], ": ", recipient.ActorID] });
254
- }
255
- };
256
- const openQdEditor = () => {
257
- const filteredRecipients = [...andRecipients, ...orRecipients].filter(r => r.ActorType === WorkItemActorTypes.QID);
258
- if (filteredRecipients.length > 0) {
259
- TMMessageBoxManager.show({
260
- buttons: [ButtonNames.OK],
261
- title: SDK_Globals.appModule,
262
- message: "Definire solo una query per i destinatari"
263
- });
264
- setIsAndMenuOpen(false);
265
- setIsOrMenuOpen(false);
266
- return;
267
- }
268
- setShowQdEditor(true);
269
- };
270
- const renderRecipientList = (recipients, title, orValue) => (_jsxs(RecipientsColumn, { children: [_jsxs(HeaderContainer, { children: [_jsx("p", { style: { fontWeight: 600 }, children: title }), _jsx(TMButton, { btnStyle: 'icon', caption: 'Aggiungi destinatario', icon: _jsx(IconAdd, {}), onClick: () => {
271
- if (orValue === 0) {
272
- setIsAndMenuOpen(prevState => !prevState);
273
- setIsOrMenuOpen(false);
274
- }
275
- else {
276
- setIsOrMenuOpen(prevState => !prevState);
277
- setIsAndMenuOpen(false);
278
- }
279
- } }), (orValue === 0 && isAndMenuOpen) && (_jsxs(FloatingMenu, { ref: andMenuRef, children: [_jsx(FloatingMenuButton, { btnStyle: 'text', icon: _jsx(IconUser, {}), caption: SDK_Localizator.Users, onClick: () => setShowUserChooser(true) }), _jsx(FloatingMenuButton, { btnStyle: 'text', icon: _jsx(IconUserGroup, {}), caption: SDK_Localizator.Groups, onClick: () => setShowGroupChooser(true) }), _jsx(FloatingMenuButton, { btnStyle: 'text', icon: _jsx(IconMetadata, {}), caption: SDK_Localizator.Metadata, onClick: () => setShowMetadataChooser(true) }), _jsx(FloatingMenuButton, { btnStyle: 'text', icon: _jsx(IconSavedQuery, {}), caption: SDK_Localizator.Query, onClick: openQdEditor })] })), (orValue === 1 && isOrMenuOpen) && (_jsxs(FloatingMenu, { ref: orMenuRef, children: [_jsx(FloatingMenuButton, { btnStyle: 'text', icon: _jsx(IconUser, {}), caption: SDK_Localizator.Users, onClick: () => setShowUserChooser(true) }), _jsx(FloatingMenuButton, { btnStyle: 'text', icon: _jsx(IconUserGroup, {}), caption: SDK_Localizator.Groups, onClick: () => setShowGroupChooser(true) }), _jsx(FloatingMenuButton, { btnStyle: 'text', icon: _jsx(IconMetadata, {}), caption: SDK_Localizator.Metadata, onClick: () => setShowMetadataChooser(true) }), _jsx(FloatingMenuButton, { btnStyle: 'text', icon: _jsx(IconSavedQuery, {}), caption: SDK_Localizator.Query, onClick: openQdEditor })] }))] }), _jsx("div", { style: { height: '150px', overflowY: 'auto' }, children: recipients.map((recipient, index) => (_jsxs(RecipientItem, { children: [_jsx(RecipientRemoveButton, { onClick: () => handleRemoveRecipient(recipient), children: "\u274C" }), renderActorViewer(recipient)] }, index))) })] }));
75
+ if (recipientToRemove.ActorType === WorkItemActorTypes.QID) {
76
+ onQDChange(undefined);
77
+ }
78
+ return newTos;
79
+ });
80
+ }, [onTosChange, onQDChange]);
81
+ const { andRecipients, orRecipients } = useMemo(() => {
82
+ return tosToActors(localTos);
83
+ }, [localTos]);
84
+ const handleQDChosen = useCallback((newQd, orValue) => {
85
+ const allRecipients = [...andRecipients, ...orRecipients];
86
+ const updatedRecipients = allRecipients.filter(r => r.ActorType !== WorkItemActorTypes.QID);
87
+ const recipientToAdd = {
88
+ ActorType: WorkItemActorTypes.QID,
89
+ ActorID: newQd.id ? newQd.id.toString() : '-1',
90
+ Or: orValue,
91
+ };
92
+ updatedRecipients.push(recipientToAdd);
93
+ const newTos = actorsToTos(updatedRecipients);
94
+ onTosChange(newTos);
95
+ onQDChange(newQd);
96
+ }, [andRecipients, orRecipients, onTosChange, onQDChange]);
280
97
  const SET_RULE_DATASOURCE = [
281
98
  { value: WorkItemSetRules.Ands_AND_Ors, display: "Ands_AND_Ors" },
282
99
  { value: WorkItemSetRules.Ands_OR_Ors, display: "Ands_OR_Ors" }
283
100
  ];
284
- return (_jsxs("div", { children: [_jsxs(RecipientsContainer, { children: [renderRecipientList(andRecipients, 'Destinatari in AND', 0), renderRecipientList(orRecipients, 'Destinatari in OR', 1)] }), _jsx("div", { style: { display: 'flex', justifyContent: 'center' }, children: _jsx(TMDropDown, { label: SDKUI_Localizator.WorkflowRecipientSetRule, width: '230px', dataSource: SET_RULE_DATASOURCE, value: setRule, onValueChanged: (e) => { onSetRuleChange?.(e.target.value); } }) }), showUserChooser && _jsx(TMUserChooserForm, { allowMultipleSelection: true, allowSorting: true, onClose: () => setShowUserChooser(false), onChoose: (IDs) => handleUserChosen(IDs, isAndMenuOpen ? 0 : 1) }), showGroupChooser && _jsx(TMGroupChooserForm, { allowMultipleSelection: true, allowSorting: true, onClose: () => setShowGroupChooser(false), onChoose: (IDs) => handleGroupChosen(IDs, isAndMenuOpen ? 0 : 1) }), showMetadataChooser && mTID && _jsx(TMMetadataChooserForm, { allowMultipleSelection: true, allowSorting: true, tids: [mTID], onClose: () => setShowMetadataChooser(false), onChoose: (IDs) => handleMetadataChosen(IDs, isAndMenuOpen ? 0 : 1) }), showQdEditor &&
285
- _jsx(TMModal, { title: SDKUI_Localizator.QueryDefine, children: _jsx(TMQueryEditor, { inputData: qd, formMode: FormModes.Update, onApplied: (newQd) => handleQdChosen(newQd, isAndMenuOpen ? 0 : 1), onClose: () => { setShowQdEditor(false); } }) })] }));
101
+ return (_jsxs("div", { children: [_jsxs(RecipientsContainer, { children: [_jsx(RecipientList, { recipients: andRecipients, title: "Destinatari in AND", tid: mTID, qd: qd, onQDChange: (newQd) => newQd && handleQDChosen(newQd, 0), onAdd: (newRecipients) => handleAddRecipients(newRecipients, 0), onRemove: handleRemoveRecipient }), _jsx(RecipientList, { recipients: orRecipients, title: "Destinatari in OR", tid: mTID, qd: qd, onQDChange: (newQd) => newQd && handleQDChosen(newQd, 1), onAdd: (newRecipients) => handleAddRecipients(newRecipients, 1), onRemove: handleRemoveRecipient })] }), _jsx("div", { style: { display: 'flex', justifyContent: 'center' }, children: _jsx(TMDropDown, { label: SDKUI_Localizator.WorkflowRecipientSetRule, width: '230px', dataSource: SET_RULE_DATASOURCE, value: setRule, onValueChanged: (e) => { onSetRuleChange?.(e.target.value); } }) })] }));
286
102
  };
287
103
  export default WorkitemRecipientsEditor;
@@ -86,8 +86,8 @@ const TMChooserForm = ({ children, title, allowMultipleSelection = false, allowA
86
86
  ...summaryItems ?? {}
87
87
  });
88
88
  }, [manageUseLocalizedName, summaryItems]);
89
- return (_jsx(TMModal, { title: renderTitle(), width: width ?? '550px', height: height ?? '600px', toolbar: _jsx(ToolbarButtons, {}), onClose: onClose, children: (children ??
90
- filteredItems.length > 0)
89
+ return (_jsx(TMModal, { title: renderTitle(), width: width ?? '550px', height: height ?? '600px', toolbar: _jsx(ToolbarButtons, {}), onClose: onClose, children: children ??
90
+ filteredItems.length > 0
91
91
  ? _jsx(TMDataGrid, { dataSource: filteredItems, keyExpr: keyName, dataColumns: dataColumns, focusedRowKey: focusedRowKey, selectedRowKeys: selectedRowKeys, searchPanelFocusStarting: true, headerFilter: { visible: true }, selection: { mode: allowMultipleSelection ? 'multiple' : 'single', showCheckBoxesMode: 'always', selectAllMode: 'allPages' }, grouping: allowGrouping ? { autoExpandAll: false, expandMode: 'rowClick' } : undefined, summary: customSummary, onFocusedRowChanged: handleFocusedRowChange, onSelectionChanged: handleSelectionChanged, onRowDblClick: handleRowDoubleClick })
92
92
  : _jsx(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: _jsx(TMLayoutItem, { children: _jsx("p", { style: { height: "100%", color: TMColors.primaryColor, fontSize: "1.5rem", display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: SDKUI_Localizator.NoDataToDisplay }) }) }) }));
93
93
  };
@@ -440,7 +440,7 @@ export declare class SDKUI_Localizator {
440
440
  static get SelectAnOperationBetween(): "Wählen Sie eine Operation zwischen" | "Select an operation between" | "Selecciona una operación entre" | "Sélectionnez une opération entre" | "Selecione uma operação entre" | "Seleziona un'operazione tra";
441
441
  static get SelectArchiveToStart(): "Klicken Sie auf Archivieren, um zu beginnen." | "Click on Archive button to start." | "Haz clic en el botón Archivar para comenzar." | "Cliquez sur le bouton Archiver pour commencer." | "Clique no botão Arquivar para iniciar." | "Clicca sul pulsante Archivia per iniziare.";
442
442
  static get SelectAttachToStart(): "Sie können Dateien zu Ihrer E-Mail hinzufügen, klicken Sie auf Anhängen, um zu beginnen." | "You can attach files to your email, click on Attach button to start." | "Puedes adjuntar archivos a tu correo electrónico, haz clic en el botón Adjuntar para comenzar." | "Vous pouvez joindre des fichiers à votre e-mail, cliquez sur le bouton Joindre pour commencer." | "Você pode anexar arquivos ao seu e-mail, clique no botão Anexar para iniciar." | "Puoi allegare file alla tua email, clicca sul pulsante Allega per iniziare.";
443
- static get SelectedAttachmentFile(): "Ausgewählte Anhangsdatei" | "Selected attachment file" | "Archivo adjunto seleccionado" | "Fichier de pièce jointe sélectionné" | "Arquivo de anexo selecionado" | "File di allegato selezionato";
443
+ static get SelectFromAttachments(): "Aus Anhängen auswählen" | "Select from attachments" | "Seleccionar de archivos adjuntos" | "Sélectionner parmi les pièces jointes" | "Selecionar dos anexos" | "Seleziona dagli allegati";
444
444
  static get SelectSupportAreaMessage(): "Wählen Sie einen Ablagebereich aus" | "Select a support area" | "Seleccione un área de apoyo" | "Sélectionnez une zone de support" | "Selecione uma área de apoio" | "Selezionare un'area di appoggio";
445
445
  static get SelectedSingular(): string;
446
446
  static get Selected(): "Ausgewählt" | "Selected" | "Sélectionné" | "Selecionado" | "Seleccionados" | "Selezionati";
@@ -4364,14 +4364,14 @@ export class SDKUI_Localizator {
4364
4364
  default: return "Puoi allegare file alla tua email, clicca sul pulsante Allega per iniziare.";
4365
4365
  }
4366
4366
  }
4367
- static get SelectedAttachmentFile() {
4368
- switch (this._cultureID) {
4369
- case CultureIDs.De_DE: return "Ausgewählte Anhangsdatei";
4370
- case CultureIDs.En_US: return "Selected attachment file";
4371
- case CultureIDs.Es_ES: return "Archivo adjunto seleccionado";
4372
- case CultureIDs.Fr_FR: return "Fichier de pièce jointe sélectionné";
4373
- case CultureIDs.Pt_PT: return "Arquivo de anexo selecionado";
4374
- default: return "File di allegato selezionato";
4367
+ static get SelectFromAttachments() {
4368
+ switch (this._cultureID) {
4369
+ case CultureIDs.De_DE: return "Aus Anhängen auswählen";
4370
+ case CultureIDs.En_US: return "Select from attachments";
4371
+ case CultureIDs.Es_ES: return "Seleccionar de archivos adjuntos";
4372
+ case CultureIDs.Fr_FR: return "Sélectionner parmi les pièces jointes";
4373
+ case CultureIDs.Pt_PT: return "Selecionar dos anexos";
4374
+ default: return "Seleziona dagli allegati";
4375
4375
  }
4376
4376
  }
4377
4377
  static get SelectSupportAreaMessage() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.16.16",
3
+ "version": "6.16.18",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",