@topconsultnpm/sdkui-react 6.19.0-dev1.54 → 6.19.0-dev1.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/lib/components/base/TMCustomButton.d.ts +11 -0
  2. package/lib/components/base/TMCustomButton.js +63 -0
  3. package/lib/components/base/TMLayout.d.ts +2 -1
  4. package/lib/components/base/TMLayout.js +2 -2
  5. package/lib/components/features/archive/TMArchive.d.ts +8 -0
  6. package/lib/components/features/archive/TMArchive.js +3 -3
  7. package/lib/components/features/documents/TMDcmtBlog.d.ts +8 -0
  8. package/lib/components/features/documents/TMDcmtBlog.js +3 -3
  9. package/lib/components/features/documents/TMDcmtForm.d.ts +8 -1
  10. package/lib/components/features/documents/TMDcmtForm.js +52 -21
  11. package/lib/components/features/documents/TMDcmtTasks.d.ts +12 -0
  12. package/lib/components/features/documents/TMDcmtTasks.js +24 -0
  13. package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +8 -1
  14. package/lib/components/features/documents/TMMasterDetailDcmts.js +5 -5
  15. package/lib/components/features/search/TMSearch.d.ts +8 -1
  16. package/lib/components/features/search/TMSearch.js +3 -3
  17. package/lib/components/features/search/TMSearchResult.d.ts +8 -1
  18. package/lib/components/features/search/TMSearchResult.js +14 -11
  19. package/lib/components/features/search/TMSearchResultsMenuItems.js +1 -1
  20. package/lib/components/features/tasks/TMTaskForm.d.ts +37 -0
  21. package/lib/components/features/tasks/TMTaskForm.js +291 -0
  22. package/lib/components/features/tasks/TMTasksAgenda.d.ts +17 -0
  23. package/lib/components/features/tasks/TMTasksAgenda.js +107 -0
  24. package/lib/components/features/tasks/TMTasksCalendar.d.ts +21 -0
  25. package/lib/components/features/tasks/TMTasksCalendar.js +240 -0
  26. package/lib/components/features/tasks/TMTasksHeader.d.ts +14 -0
  27. package/lib/components/features/tasks/TMTasksHeader.js +37 -0
  28. package/lib/components/features/tasks/TMTasksPanelContent.d.ts +19 -0
  29. package/lib/components/features/tasks/TMTasksPanelContent.js +64 -0
  30. package/lib/components/features/tasks/TMTasksUtils.d.ts +131 -0
  31. package/lib/components/features/tasks/TMTasksUtils.js +634 -0
  32. package/lib/components/features/tasks/TMTasksUtilsView.d.ts +32 -0
  33. package/lib/components/features/tasks/TMTasksUtilsView.js +107 -0
  34. package/lib/components/features/tasks/TMTasksView.d.ts +39 -0
  35. package/lib/components/features/tasks/TMTasksView.js +554 -0
  36. package/lib/components/features/workflow/TMWorkflowPopup.js +2 -2
  37. package/lib/components/grids/TMBlogAttachments.js +2 -2
  38. package/lib/components/grids/TMBlogsPost.d.ts +8 -5
  39. package/lib/components/grids/TMBlogsPost.js +28 -28
  40. package/lib/components/grids/TMBlogsPostUtils.js +1 -1
  41. package/lib/components/index.d.ts +8 -0
  42. package/lib/components/index.js +9 -0
  43. package/lib/helper/SDKUI_Localizator.d.ts +55 -4
  44. package/lib/helper/SDKUI_Localizator.js +536 -25
  45. package/lib/helper/TMCustomSearchBar.d.ts +8 -0
  46. package/lib/helper/TMCustomSearchBar.js +54 -0
  47. package/lib/helper/TMImageLibrary.d.ts +3 -2
  48. package/lib/helper/TMImageLibrary.js +230 -230
  49. package/lib/helper/TMToppyMessage.js +1 -1
  50. package/lib/helper/TMUtils.d.ts +10 -1
  51. package/lib/helper/TMUtils.js +42 -1
  52. package/lib/helper/dcmtsHelper.d.ts +2 -0
  53. package/lib/helper/dcmtsHelper.js +18 -0
  54. package/lib/stories/TMSDKUI_Localizator.stories.js +1 -1
  55. package/package.json +1 -1
@@ -0,0 +1,554 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from "react";
3
+ import { AssignedTab, checkIfNew, createTasksMenuItems, getHeaderPriorityFilterConfig, getHeaderStatusFilterConfig, getMondayOfCurrentWeek, getNewTaskCount, getStatusLocalizatorValue, isTaskAssignedToAnotherUser, TaskView, TEXT_NOT_SELECTED_COLOR } from "./TMTasksUtils";
4
+ import { TabPanel, Item } from 'devextreme-react/tab-panel';
5
+ import { Priorities, ResultTypes, SDK_Globals, Task_States } from "@topconsultnpm/sdk-ts";
6
+ import { calculateNumberOfDays, renderTaskIcons } from "./TMTasksUtilsView";
7
+ import { getPriorityLocalizatorValue } from "../tasks/TMTasksUtils";
8
+ import ContextMenu from 'devextreme-react/cjs/context-menu';
9
+ import { calcResponsiveSizes, getExceptionMessage, SDKUI_Localizator, StyledTabItem, TMCountBadge } from "../../../helper";
10
+ import { useDeviceType } from "../../base/TMDeviceProvider";
11
+ import { FormModes } from "../../../ts";
12
+ import TMDataGrid from "../../base/TMDataGrid";
13
+ import { TMMessageBoxManager, ButtonNames } from "../../base/TMPopUp";
14
+ import TMTooltip from "../../base/TMTooltip";
15
+ import { TMLayoutWaitingContainer } from "../../base/TMWaitPanel";
16
+ import { TMResultManager } from "../../forms/TMResultDialog";
17
+ import TMTasksCalendar from "./TMTasksCalendar";
18
+ import TMTasksAgenda from "./TMTasksAgenda";
19
+ import TMTaskForm from "./TMTaskForm";
20
+ let abortController = new AbortController();
21
+ const TMTasksView = (props) => {
22
+ const { id, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, visualizedTasks, activeComponent, activeTabIndex, setActiveTabIndex, currentTask, setCurrentTask, assignedToMeCount, assignedByMeCount, allTasksFilteredCount, showId, setShowId, showSearch, setShowSearch, showContextualWG, setShowContextualWG, showContextualDossier, setShowContextualDossier, showContextualDocument, setShowContextualDocument, handleNavigateToWGs, handleNavigateToDossiers, taskContext, usersList, onOpenS4TViewerRequest, s4TViewerDialogComponent } = props;
23
+ // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
24
+ const deviceType = useDeviceType();
25
+ // State to manage show comment form selected file
26
+ const [showTaskForm, setShowTaskForm] = useState(false);
27
+ // State to store form mode (None, Create, Update, Duplicate, ReadOnly)
28
+ const [formMode, setFormMode] = useState(undefined);
29
+ // State to know if there are filters applied
30
+ const [hasFilters, setHasFilters] = useState(false);
31
+ // State to store selected row keys
32
+ const [selectedRowKeys, setSelectedRowKeys] = useState([]);
33
+ // State hook to store the currently focused row key, initially set to undefined
34
+ const [focusedRowKey, setFocusedRowKey] = useState(undefined);
35
+ // State to manage the current agenda date
36
+ const [currentAgendaDate, setCurrentAgendaDate] = useState(getMondayOfCurrentWeek(new Date()));
37
+ // State to manage the current agenda date
38
+ const [currentCalendarDate, setCurrentCalendarDate] = useState(getMondayOfCurrentWeek(new Date()));
39
+ /* State to manage the calendar start date */
40
+ const [calendarStartDate, setCalendarStartDate] = useState(undefined);
41
+ /* State to manage the calendar end date */
42
+ const [calendarEndDate, setCalendarEndDate] = useState(undefined);
43
+ // State variable to control the visibility of the wait panel.
44
+ const [showWaitPanel, setShowWaitPanel] = useState(false);
45
+ // State variable to store the title of the wait panel.
46
+ const [waitPanelTitle, setWaitPanelTitle] = useState('');
47
+ // State variable to control the visibility of the primary section of the wait panel.
48
+ const [showPrimary, setShowPrimary] = useState(false);
49
+ // State variable to store the primary text of the wait panel.
50
+ const [waitPanelTextPrimary, setWaitPanelTextPrimary] = useState('');
51
+ // State variable to track the current value of the primary progress indicator in the wait panel.
52
+ const [waitPanelValuePrimary, setWaitPanelValuePrimary] = useState(0);
53
+ // State variable to define the maximum value for the primary progress indicator in the wait panel.
54
+ const [waitPanelMaxValuePrimary, setWaitPanelMaxValuePrimary] = useState(0);
55
+ // This function open the task form for editing a selected task
56
+ const editTaskAgendaCallback = (rowId) => {
57
+ if (rowId === undefined)
58
+ return;
59
+ const selectedTask = visualizedTasks.find(task => task.id === rowId);
60
+ if (selectedTask) {
61
+ openTaskFormCallback(FormModes.Update, selectedTask);
62
+ }
63
+ else {
64
+ console.error(`Task with ID ${rowId} not found.`);
65
+ }
66
+ };
67
+ const onDuplicateAgendaCallback = (rowId) => {
68
+ if (rowId === undefined)
69
+ return;
70
+ const selectedTask = visualizedTasks.find(task => task.id === rowId);
71
+ if (selectedTask) {
72
+ openTaskFormCallback(FormModes.Duplicate, selectedTask);
73
+ }
74
+ else {
75
+ console.error(`Task with ID ${rowId} not found.`);
76
+ }
77
+ };
78
+ const agendaCalendarItems = useCallback(() => {
79
+ const taskDescriptor = visualizedTasks.find(task => task.id === focusedRowKey);
80
+ return [
81
+ ...createTasksMenuItems(taskDescriptor, showId, setShowId, showSearch, setShowSearch, () => { }, // openTaskForm,
82
+ () => { if (focusedRowKey)
83
+ editTaskAgendaCallback(focusedRowKey); }, () => { if (focusedRowKey)
84
+ onDuplicateAgendaCallback(focusedRowKey); }, () => { if (focusedRowKey)
85
+ onDeleteCallback([focusedRowKey]); }, (rowIds, status) => { if (focusedRowKey)
86
+ markAsStatus([focusedRowKey], status); }, getAllTasks, taskContext?.workingGroup?.id !== undefined, showContextualWG, setShowContextualWG, taskContext?.dossier?.id !== undefined, showContextualDossier, setShowContextualDossier, taskContext?.document?.tid !== undefined && taskContext?.document?.did !== undefined, showContextualDocument, setShowContextualDocument, true, () => { setCurrentCalendarDate(new Date()); setCurrentAgendaDate(new Date()); }, false),
87
+ ];
88
+ }, [visualizedTasks, focusedRowKey, showId, showSearch, showContextualWG, showContextualDossier, taskContext]);
89
+ const [menuItems, setMenuItems] = useState(agendaCalendarItems());
90
+ const newTaskCount = getNewTaskCount(allTasks);
91
+ useEffect(() => {
92
+ setMenuItems(agendaCalendarItems());
93
+ }, [agendaCalendarItems]);
94
+ useEffect(() => {
95
+ if (activeComponent !== TaskView.CALENDAR_TASK) {
96
+ setCalendarStartDate(undefined);
97
+ setCalendarEndDate(undefined);
98
+ }
99
+ }, [activeComponent]);
100
+ // Callback function to close the task form and reset related states
101
+ const closeTaskFormCallback = useCallback(() => {
102
+ setFormMode(undefined);
103
+ setShowTaskForm(false);
104
+ }, []);
105
+ // Callback function to open the task form in a specific mode
106
+ const openTaskFormCallback = useCallback((mode, task) => {
107
+ setFormMode(mode);
108
+ setShowTaskForm(true);
109
+ // If a task is provided, set it as the current task to be processed
110
+ if (task)
111
+ setCurrentTask(task);
112
+ }, []);
113
+ // Updates the active tab index when the selected index changes
114
+ const onSelectedIndexChange = (index) => {
115
+ setActiveTabIndex(index);
116
+ setSelectedRowKeys([]);
117
+ };
118
+ const handleSelectionChange = useCallback((rows) => {
119
+ const selectedKeys = rows.map(row => row.id).filter(id => id !== undefined);
120
+ setSelectedRowKeys([...selectedKeys]);
121
+ }, []);
122
+ // Handles focus change in the data grid
123
+ const handleFocusedRowChange = useCallback((row) => {
124
+ setFocusedRowKey(row?.id ?? undefined);
125
+ }, []);
126
+ // Handles selection change in the data grid
127
+ const onSelectionChanged = useCallback((e) => {
128
+ const selectedKeys = e.component.getSelectedRowKeys() ?? [];
129
+ if (JSON.stringify(selectedKeys) === JSON.stringify(selectedRowKeys))
130
+ return;
131
+ setSelectedRowKeys(selectedKeys);
132
+ }, [selectedRowKeys]);
133
+ // Handles focus change in the data grid
134
+ const onFocusedRowChanged = useCallback((e) => {
135
+ setFocusedRowKey(e.row?.key);
136
+ }, []);
137
+ // Handler for double-click row event
138
+ const onRowDblClick = useCallback((e) => {
139
+ openTaskFormCallback(FormModes.Update, e.data);
140
+ }, [openTaskFormCallback]);
141
+ const onDeleteCallback = useCallback((rowIds) => {
142
+ let msg = "";
143
+ switch (rowIds.length) {
144
+ case 0: return;
145
+ case 1: {
146
+ const selectedTaskId = Number(rowIds[0]);
147
+ const selectedTask = visualizedTasks.find(task => task.id === selectedTaskId);
148
+ if (selectedTask)
149
+ msg = SDKUI_Localizator.Delete_ConfirmFor1.replaceParams(selectedTask.name);
150
+ break;
151
+ }
152
+ default:
153
+ msg = SDKUI_Localizator.Delete_ConfirmForN.replaceParams(rowIds.length);
154
+ break;
155
+ }
156
+ TMMessageBoxManager.show({
157
+ title: SDKUI_Localizator.Delete, message: msg, buttons: [ButtonNames.YES, ButtonNames.NO],
158
+ onButtonClick: async (e) => {
159
+ if (e !== ButtonNames.YES)
160
+ return;
161
+ setWaitPanelTitle(SDKUI_Localizator.Delete);
162
+ setShowWaitPanel(true);
163
+ setShowPrimary(true);
164
+ abortController = new AbortController();
165
+ let result = [];
166
+ let i = 0;
167
+ const deletedTaskIds = [];
168
+ setWaitPanelMaxValuePrimary(rowIds.length);
169
+ for (const key of rowIds) {
170
+ i++;
171
+ const deletedTaskId = Number(key);
172
+ const deletedTask = visualizedTasks.find(task => task.id === deletedTaskId);
173
+ setWaitPanelValuePrimary(i);
174
+ if (abortController.signal.aborted) {
175
+ result.push({ rowIndex: i, id1: deletedTaskId, id2: deletedTaskId, resultType: ResultTypes.WARNING, description: `Operazione interrotta. Elaborate ${i} attività` });
176
+ break;
177
+ }
178
+ else {
179
+ setWaitPanelTextPrimary(SDKUI_Localizator.TaskXofY.replaceParams(i, rowIds.length));
180
+ try {
181
+ const deletionNotAllowed = deletedTask?.fromID !== SDK_Globals.tmSession?.SessionDescr?.userID;
182
+ if (deletionNotAllowed) {
183
+ result.push({ rowIndex: key, id1: key, id2: 0, resultType: ResultTypes.ERROR, description: SDKUI_Localizator.OperationNotAllowed });
184
+ }
185
+ else {
186
+ await SDK_Globals.tmSession?.NewTaskEngine().DeleteAsync(deletedTaskId);
187
+ result.push({ rowIndex: key, id1: key, id2: 0, description: SDKUI_Localizator.DeletionCompletedSuccessfully, resultType: ResultTypes.SUCCESS });
188
+ deletedTaskIds.push(deletedTaskId);
189
+ }
190
+ }
191
+ catch (err) {
192
+ result.push({ rowIndex: key, id1: key, id2: 0, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
193
+ }
194
+ }
195
+ }
196
+ await deleteTaskByIdsCallback(deletedTaskIds);
197
+ handleSelectionChange([]);
198
+ setWaitPanelTextPrimary('');
199
+ setWaitPanelMaxValuePrimary(0);
200
+ setWaitPanelValuePrimary(0);
201
+ setShowWaitPanel(false);
202
+ TMResultManager.show(result, SDKUI_Localizator.Delete, "ID", undefined);
203
+ }
204
+ });
205
+ }, [visualizedTasks]);
206
+ const markAsStatus = useCallback((rowIds, status) => {
207
+ let msg = "";
208
+ switch (rowIds.length) {
209
+ case 0: return;
210
+ case 1: {
211
+ const selectedTaskId = Number(rowIds[0]);
212
+ const selectedTask = visualizedTasks.find(task => task.id === selectedTaskId);
213
+ if (selectedTask)
214
+ msg = SDKUI_Localizator.Edit_ConfirmFor1.replaceParams(selectedTask.name);
215
+ break;
216
+ }
217
+ default:
218
+ msg = SDKUI_Localizator.Edit_ConfirmForN.replaceParams(rowIds.length);
219
+ break;
220
+ }
221
+ TMMessageBoxManager.show({
222
+ title: SDKUI_Localizator.MarkAs, message: msg, buttons: [ButtonNames.YES, ButtonNames.NO],
223
+ onButtonClick: async (e) => {
224
+ if (e !== ButtonNames.YES)
225
+ return;
226
+ setWaitPanelTitle(SDKUI_Localizator.MarkAs);
227
+ setShowWaitPanel(true);
228
+ setShowPrimary(true);
229
+ abortController = new AbortController();
230
+ let result = [];
231
+ let i = 0;
232
+ setWaitPanelMaxValuePrimary(rowIds.length);
233
+ for (const key of rowIds) {
234
+ i++;
235
+ const selectedTask = visualizedTasks.find(task => task.id === key) || undefined;
236
+ if (selectedTask === undefined)
237
+ return;
238
+ selectedTask.state = status;
239
+ setWaitPanelValuePrimary(i);
240
+ if (abortController.signal.aborted) {
241
+ result.push({ rowIndex: i, id1: selectedTask.id, id2: selectedTask.id, resultType: ResultTypes.WARNING, description: `Operazione interrotta. Elaborate ${i} attività` });
242
+ break;
243
+ }
244
+ else {
245
+ setWaitPanelTextPrimary(SDKUI_Localizator.TaskXofY.replaceParams(i, rowIds.length));
246
+ try {
247
+ await SDK_Globals.tmSession?.NewTaskEngine().UpdateAsync(selectedTask);
248
+ result.push({ rowIndex: key, id1: key, id2: 0, description: SDKUI_Localizator.UpdateCompletedSuccessfully, resultType: ResultTypes.SUCCESS });
249
+ }
250
+ catch (err) {
251
+ result.push({ rowIndex: key, id1: key, id2: 0, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
252
+ }
253
+ }
254
+ }
255
+ await getAllTasks().then(() => {
256
+ handleSelectionChange([]);
257
+ setWaitPanelTextPrimary('');
258
+ setWaitPanelMaxValuePrimary(0);
259
+ setWaitPanelValuePrimary(0);
260
+ setShowWaitPanel(false);
261
+ TMResultManager.show(result, SDKUI_Localizator.MarkAs, "ID", undefined);
262
+ });
263
+ }
264
+ });
265
+ }, [visualizedTasks]);
266
+ const onSavedCallback = async (task) => {
267
+ // If task is undefined or has no ID, exit early
268
+ if (task === undefined || task.id === undefined)
269
+ return;
270
+ // Determine the active tab based on task assignment.
271
+ // If assigned to another user, switch to the "Assigned By Me" tab;
272
+ let activeTab = activeTabIndex;
273
+ if (isTaskAssignedToAnotherUser(task))
274
+ activeTab = AssignedTab.AssignedByMe;
275
+ setActiveTabIndex(activeTab);
276
+ // Focus the task row by setting its ID as selected in the list view
277
+ if (task.id) {
278
+ setFocusedRowKey(task.id);
279
+ setCurrentAgendaDate(task.startTime ?? (task.endTime ?? new Date()));
280
+ setCurrentCalendarDate(task.startTime ?? (task.endTime ?? new Date()));
281
+ }
282
+ // Dispatch appropriate action based on form mode (Create or Edit).
283
+ // If in Create mode or in Duplicate mode, add the new task; otherwise, edit the existing task.
284
+ if (formMode === FormModes.Create || formMode === FormModes.Duplicate) {
285
+ await addTaskCallback(task);
286
+ }
287
+ else {
288
+ await editTaskCallback(task);
289
+ }
290
+ setShowTaskForm(false);
291
+ };
292
+ const handleNavigateToDossiersWrapper = useCallback((dossierId) => {
293
+ setShowTaskForm(false);
294
+ handleNavigateToDossiers(dossierId);
295
+ }, []);
296
+ const handleNavigateToWGsWrapper = useCallback((workGroupId) => {
297
+ setShowTaskForm(false);
298
+ handleNavigateToWGs(workGroupId);
299
+ }, []);
300
+ const onContextMenuPreparing = (e) => {
301
+ if (e === undefined)
302
+ return;
303
+ if (e.target === 'content') {
304
+ e.items = e.items || [];
305
+ e.items = createTasksMenuItems(e.row?.data, showId, setShowId, showSearch, setShowSearch, () => { openTaskFormCallback(FormModes.Create); }, () => { openTaskFormCallback(FormModes.Update, e.row?.data); }, () => { openTaskFormCallback(FormModes.Duplicate, e.row?.data); }, onDeleteCallback, markAsStatus, getAllTasks, taskContext?.workingGroup?.id !== undefined, showContextualWG, setShowContextualWG, taskContext?.dossier?.id !== undefined, showContextualDossier, setShowContextualDossier, taskContext?.document?.tid !== undefined && taskContext?.document?.did !== undefined, showContextualDocument, setShowContextualDocument, false);
306
+ }
307
+ };
308
+ const RenderCustomHeader = ({ data }) => { return _jsx("p", { style: { color: TEXT_NOT_SELECTED_COLOR }, children: data.column.caption }); };
309
+ const cellDefaultRender = useCallback((cellData) => {
310
+ const data = cellData.data;
311
+ const { endTime, state, fromID, isNew } = data;
312
+ // Determine styles
313
+ const isCompleted = state === Task_States.Completed;
314
+ const isExpired = endTime && endTime < new Date();
315
+ const isNewTask = checkIfNew(fromID, isNew);
316
+ return _jsx("div", { style: {
317
+ color: isCompleted ? '#000' : (isExpired ? 'red' : '#000'),
318
+ textDecoration: isCompleted ? 'line-through' : 'none',
319
+ fontWeight: isNewTask ? 'bold' : 'normal'
320
+ }, children: cellData.value });
321
+ }, []);
322
+ const cellStateRender = useCallback((cellData) => {
323
+ const data = cellData.data;
324
+ const { startTime, endTime, remTime, pdG, iD1Name, state, fromID, isNew } = data;
325
+ // Determine styles
326
+ const isCompleted = state === Task_States.Completed;
327
+ const isExpired = endTime && endTime < new Date();
328
+ const isNewTask = checkIfNew(fromID, isNew);
329
+ const stateLabel = state || Task_States.None;
330
+ const stateTooltipLabel = getStatusLocalizatorValue(stateLabel);
331
+ const numberOfDays = calculateNumberOfDays(startTime, endTime);
332
+ return _jsx("div", { style: {
333
+ display: 'flex',
334
+ alignItems: 'left',
335
+ justifyContent: 'left',
336
+ gap: 2,
337
+ color: isCompleted ? '#000' : (isExpired ? 'red' : '#000'),
338
+ textDecoration: isCompleted ? 'line-through' : 'none',
339
+ fontWeight: isNewTask ? 'bold' : 'normal'
340
+ }, children: renderTaskIcons({
341
+ stateLabel,
342
+ stateTooltipLabel,
343
+ pdg: pdG ?? undefined,
344
+ ID1Name: iD1Name ?? '',
345
+ endTime,
346
+ remTime,
347
+ isNew: isNewTask,
348
+ numberOfDays
349
+ }) });
350
+ }, []);
351
+ const cellPriorityRender = useCallback((cellData) => {
352
+ const data = cellData.data;
353
+ const { endTime, state, fromID, isNew } = data;
354
+ const priorityLabel = getPriorityLocalizatorValue(cellData.value || Priorities.Low);
355
+ // Determine styles
356
+ const isCompleted = state === Task_States.Completed;
357
+ const isExpired = endTime && endTime < new Date();
358
+ const isNewTask = checkIfNew(fromID, isNew);
359
+ return _jsx("div", { style: {
360
+ color: isCompleted ? '#000' : (isExpired ? 'red' : '#000'),
361
+ textDecoration: isCompleted ? 'line-through' : 'none',
362
+ fontWeight: isNewTask ? 'bold' : 'normal'
363
+ }, children: priorityLabel });
364
+ }, []);
365
+ const cellDatetimeRender = useCallback((cellData) => {
366
+ const data = cellData.data;
367
+ const { endTime, state, fromID, isNew } = data;
368
+ const formattedDate = cellData.value ? new Date(cellData.value).toLocaleString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }) : '';
369
+ // Determine styles
370
+ const isCompleted = state === Task_States.Completed;
371
+ const isExpired = endTime && endTime < new Date();
372
+ const isNewTask = checkIfNew(fromID, isNew);
373
+ return _jsx("div", { style: {
374
+ color: isCompleted ? '#000' : (isExpired ? 'red' : '#000'),
375
+ textDecoration: isCompleted ? 'line-through' : 'none',
376
+ fontWeight: isNewTask ? 'bold' : 'normal'
377
+ }, children: formattedDate });
378
+ }, []);
379
+ const cellFromRender = useCallback((cellData) => {
380
+ const data = cellData.data;
381
+ const { endTime, state, fromID, isNew, fromName } = data;
382
+ // Determine styles
383
+ const isCompleted = state === Task_States.Completed;
384
+ const isExpired = endTime && endTime < new Date();
385
+ const isNewTask = checkIfNew(fromID, isNew);
386
+ // Initial styles setup for default layout
387
+ let style = {
388
+ width: "100%",
389
+ height: "100%",
390
+ display: 'flex',
391
+ justifyContent: 'center',
392
+ alignItems: 'center',
393
+ color: isCompleted ? '#000' : (isExpired ? 'red' : '#000'),
394
+ textDecoration: isCompleted ? 'line-through' : 'none',
395
+ fontWeight: isNewTask ? 'bold' : 'normal'
396
+ };
397
+ return (_jsx("div", { style: { width: '100%', display: 'flex', alignItems: 'left', justifyContent: 'left' }, children: _jsx(TMTooltip, { content: fromName, children: _jsx("div", { style: style, children: _jsxs("div", { children: [fromName, " ", (showId && fromID) && "(" + fromID + ")", " "] }) }) }) }));
398
+ }, []);
399
+ const cellToRender = useCallback((cellData) => {
400
+ const data = cellData.data;
401
+ const { endTime, state, fromID, isNew, toName, toID } = data;
402
+ // Determine styles
403
+ const isCompleted = state === Task_States.Completed;
404
+ const isExpired = endTime && endTime < new Date();
405
+ const isNewTask = checkIfNew(fromID, isNew);
406
+ // Initial styles setup for default layout
407
+ let style = {
408
+ width: "100%",
409
+ height: "100%",
410
+ display: 'flex',
411
+ justifyContent: 'center',
412
+ alignItems: 'center',
413
+ color: isCompleted ? '#000' : (isExpired ? 'red' : '#000'),
414
+ textDecoration: isCompleted ? 'line-through' : 'none',
415
+ fontWeight: isNewTask ? 'bold' : 'normal'
416
+ };
417
+ return (_jsx("div", { style: { width: '100%', display: 'flex', alignItems: 'left', justifyContent: 'left' }, children: _jsx(TMTooltip, { content: toName, children: _jsx("div", { style: style, children: _jsxs("div", { children: [toName, " ", (showId && toID) && "(" + toID + ")", " "] }) }) }) }));
418
+ }, []);
419
+ const getDataColumns = useCallback((fromCell = false, toCell = false) => {
420
+ return [
421
+ {
422
+ dataField: "id",
423
+ caption: "ID",
424
+ dataType: 'string',
425
+ cellRender: cellDefaultRender,
426
+ headerCellRender: (e) => _jsx(RenderCustomHeader, { data: e }),
427
+ visible: showId,
428
+ alignment: "left"
429
+ },
430
+ {
431
+ dataField: "state",
432
+ caption: SDKUI_Localizator.Status,
433
+ dataType: 'string',
434
+ cellRender: cellStateRender,
435
+ headerCellRender: (e) => _jsx(RenderCustomHeader, { data: e }),
436
+ headerFilter: getHeaderStatusFilterConfig(),
437
+ visible: true,
438
+ alignment: "left"
439
+ },
440
+ {
441
+ dataField: "name",
442
+ caption: SDKUI_Localizator.Name,
443
+ dataType: 'string',
444
+ cellRender: cellDefaultRender,
445
+ headerCellRender: (e) => _jsx(RenderCustomHeader, { data: e }),
446
+ visible: true,
447
+ alignment: "left"
448
+ },
449
+ {
450
+ dataField: "priority",
451
+ caption: SDKUI_Localizator.Priority,
452
+ dataType: 'string',
453
+ cellRender: cellPriorityRender,
454
+ headerCellRender: (e) => _jsx(RenderCustomHeader, { data: e }),
455
+ headerFilter: getHeaderPriorityFilterConfig(),
456
+ visible: true,
457
+ alignment: "left"
458
+ },
459
+ {
460
+ dataField: "startTime",
461
+ caption: SDKUI_Localizator.StartDate,
462
+ dataType: 'datetime',
463
+ cellRender: cellDatetimeRender,
464
+ headerCellRender: (e) => _jsx(RenderCustomHeader, { data: e }),
465
+ visible: true,
466
+ alignment: "left",
467
+ format: 'dd/MM/yyyy HH:mm'
468
+ },
469
+ {
470
+ dataField: "endTime",
471
+ caption: SDKUI_Localizator.Expiration,
472
+ dataType: 'datetime',
473
+ cellRender: cellDatetimeRender,
474
+ headerCellRender: (e) => _jsx(RenderCustomHeader, { data: e }),
475
+ visible: true,
476
+ alignment: "left",
477
+ format: 'dd/MM/yyyy HH:mm'
478
+ },
479
+ {
480
+ dataField: "remTime",
481
+ caption: SDKUI_Localizator.Reminder,
482
+ dataType: 'datetime',
483
+ cellRender: cellDatetimeRender,
484
+ headerCellRender: (e) => _jsx(RenderCustomHeader, { data: e }),
485
+ visible: true,
486
+ alignment: "left",
487
+ format: 'dd/MM/yyyy HH:mm'
488
+ },
489
+ {
490
+ dataField: "fromName",
491
+ caption: SDKUI_Localizator.AssignedBy,
492
+ dataType: 'string',
493
+ cellRender: cellFromRender,
494
+ headerCellRender: (e) => _jsx(RenderCustomHeader, { data: e }),
495
+ visible: fromCell,
496
+ alignment: "left"
497
+ },
498
+ {
499
+ dataField: "toName",
500
+ caption: SDKUI_Localizator.AssignedTo,
501
+ dataType: 'string',
502
+ cellRender: cellToRender,
503
+ headerCellRender: (e) => _jsx(RenderCustomHeader, { data: e }),
504
+ visible: toCell,
505
+ alignment: "left"
506
+ },
507
+ ];
508
+ }, [showId]);
509
+ const getFromOrToDatagridElement = (fromOrToDataSource, fromCell = false, toCell = false) => {
510
+ return _jsx(TMDataGrid, { dataSource: fromOrToDataSource, dataColumns: getDataColumns(fromCell, toCell), selection: { mode: 'multiple', showCheckBoxesMode: "always" }, focusedRowKey: focusedRowKey, selectedRowKeys: [...selectedRowKeys], onFocusedRowChanged: onFocusedRowChanged, onSelectionChanged: onSelectionChanged, onRowDblClick: onRowDblClick, onContextMenuPreparing: onContextMenuPreparing, showSearchPanel: showSearch, noDataText: SDKUI_Localizator.TasksEmpty, counterConfig: { show: true }, onHasFiltersChange: (active) => setHasFilters(active) });
511
+ };
512
+ const getFromOrToAgendaElement = (fromOrToDataSource, fromCell = false, toCell = false) => {
513
+ return _jsxs("div", { style: { width: '100%', height: '100%', display: 'flex', flexDirection: 'column', overflow: "auto" }, children: [_jsx(ContextMenu, { dataSource: menuItems, target: `#tasks-agenda-wrapper-${id}` }), _jsx("div", { style: { width: "100%", height: "100%" }, children: _jsx(TMTasksAgenda, { id: id, showId: showId, showSearch: showSearch, visualizedTasks: fromOrToDataSource, fromCell: fromCell, toCell: toCell, currentAgendaDate: currentAgendaDate, setCurrentAgendaDate: setCurrentAgendaDate, openTaskForm: openTaskFormCallback, handleFocusedRowChange: handleFocusedRowChange }) })] });
514
+ };
515
+ const getFromOrToCalendarElement = (fromOrToDataSource, fromCell = false, toCell = false) => {
516
+ return _jsxs("div", { style: { width: '100%', height: '100%', display: 'flex', flexDirection: 'column', overflow: "auto" }, children: [_jsx(ContextMenu, { dataSource: menuItems, target: `#tasks-calendar-wrapper-${id}` }), _jsx("div", { style: { width: "100%", height: "100%" }, children: _jsx(TMTasksCalendar, { id: id, visualizedTasks: fromOrToDataSource, showId: showId, fromCell: fromCell, toCell: toCell, showSearch: showSearch, currentCalendarDate: currentCalendarDate, setCurrentCalendarDate: setCurrentCalendarDate, openTaskForm: openTaskFormCallback, onDeleteCallback: onDeleteCallback, setCalendarStartDate: setCalendarStartDate, setCalendarEndDate: setCalendarEndDate, focusedRowKey: focusedRowKey, handleFocusedRowChange: handleFocusedRowChange }) })] });
517
+ };
518
+ return _jsxs("div", { style: { width: '100%', height: '100%' }, onContextMenu: (e) => e.preventDefault(), children: [_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, isCancelable: true, abortController: abortController, children: _jsxs(TabPanel, { width: "100%", height: "100%", animationEnabled: false, swipeEnabled: false, loop: false, showNavButtons: true, repaintChangesOnly: true, stylingMode: "primary", iconPosition: 'start', tabsPosition: 'top', selectedIndex: activeTabIndex, onSelectedIndexChange: onSelectedIndexChange, id: "task-centered-tab-title", children: [_jsx(Item, { title: SDKUI_Localizator.AssignedToMe, icon: "user", tabRender: (params) => {
519
+ return _jsxs(StyledTabItem, { "$isSelected": activeTabIndex === AssignedTab.AssignedToMe, children: [_jsxs(TMTooltip, { content: SDKUI_Localizator.AssignedToMe, children: [_jsx("i", { className: `dx-icon-${params.icon}` }), "\u00A0", params.title, " ", (assignedToMeCount > 0) ? `(${assignedToMeCount})` : ''] }), newTaskCount > 0 && (_jsx(TMTooltip, { content: SDKUI_Localizator.NewAssignedActivitiesNumber + ": " + newTaskCount, children: _jsx(TMCountBadge, { children: newTaskCount }) }))] });
520
+ }, render: () => activeTabIndex === AssignedTab.AssignedToMe ?
521
+ _jsxs(_Fragment, { children: [activeComponent === TaskView.LIST_TASK && getFromOrToDatagridElement(visualizedTasks, true, false), activeComponent === TaskView.AGENDA_TASK && getFromOrToAgendaElement(visualizedTasks, true, false), activeComponent === TaskView.CALENDAR_TASK && getFromOrToCalendarElement(visualizedTasks, true, false)] }) : '' }), _jsx(Item, { title: SDKUI_Localizator.AssignedByMe, icon: "login", tabRender: (params) => {
522
+ return _jsx(StyledTabItem, { "$isSelected": activeTabIndex === AssignedTab.AssignedByMe, children: _jsxs(TMTooltip, { content: SDKUI_Localizator.AssignedByMe, children: [_jsx("i", { className: `dx-icon-${params.icon}` }), "\u00A0", params.title, " ", (assignedByMeCount > 0) ? `(${assignedByMeCount})` : ''] }) });
523
+ }, render: () => activeTabIndex === AssignedTab.AssignedByMe ?
524
+ _jsxs(_Fragment, { children: [activeComponent === TaskView.CALENDAR_TASK && getFromOrToCalendarElement(visualizedTasks, false, true), activeComponent === TaskView.AGENDA_TASK && getFromOrToAgendaElement(visualizedTasks, false, true), activeComponent === TaskView.LIST_TASK && getFromOrToDatagridElement(visualizedTasks, false, true)] }) : '' }), _jsx(Item, { title: SDKUI_Localizator.AllFemale, icon: "fields", tabRender: (params) => {
525
+ return _jsxs(StyledTabItem, { "$isSelected": activeTabIndex === AssignedTab.All, children: [_jsxs(TMTooltip, { content: SDKUI_Localizator.AllFemale, children: [_jsx("i", { className: `dx-icon-${params.icon}` }), "\u00A0", params.title, " ", (allTasksFilteredCount > 0) ? `(${allTasksFilteredCount})` : ''] }), newTaskCount > 0 && (_jsx(TMTooltip, { content: SDKUI_Localizator.NewAssignedActivitiesNumber + ": " + newTaskCount, children: _jsx(TMCountBadge, { children: newTaskCount }) }))] });
526
+ }, render: () => activeTabIndex === AssignedTab.All ?
527
+ _jsxs(_Fragment, { children: [activeComponent === TaskView.CALENDAR_TASK && getFromOrToCalendarElement(visualizedTasks, true, true), activeComponent === TaskView.AGENDA_TASK && getFromOrToAgendaElement(visualizedTasks, true, true), activeComponent === TaskView.LIST_TASK && getFromOrToDatagridElement(visualizedTasks, true, true)] }) : '' })] }) }), showTaskForm && _jsx(TMTaskForm, { id: currentTask?.id ?? -1, width: calcResponsiveSizes(deviceType, '700px', '700px', '95%'), height: calcResponsiveSizes(deviceType, '670px', '80%', '95%'), title: SDKUI_Localizator.Widget_Activities, isModal: true, formMode: formMode ?? FormModes.Create, visualizedTasks: visualizedTasks, currentTask: currentTask, setCurrentTask: setCurrentTask, selectedRowKeys: selectedRowKeys, handleFocusedRowKeyChange: handleFocusedRowChange, taskContext: taskContext, usersList: usersList, onStatusChanged: () => { }, onClose: closeTaskFormCallback, onCancel: closeTaskFormCallback, showBackButton: false, onSaved: onSavedCallback, startDate: calendarStartDate, endDate: calendarEndDate, onOpenS4TViewerRequest: onOpenS4TViewerRequest, s4TViewerDialogComponent: s4TViewerDialogComponent, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), _jsx("button", { style: {
528
+ position: 'absolute',
529
+ bottom: hasFilters ? '90px' : '18px',
530
+ right: '20px',
531
+ width: '40px',
532
+ height: '40px',
533
+ borderRadius: "50%",
534
+ backgroundColor: "#C2388B",
535
+ color: '#fff',
536
+ border: 'none',
537
+ cursor: 'pointer',
538
+ boxShadow: '0 2px 6px rgba(0,0,0,0.2)',
539
+ zIndex: 1000,
540
+ transition: 'background-color 0.3s ease, transform 0.2s ease',
541
+ display: 'flex',
542
+ justifyContent: 'center',
543
+ alignItems: 'center',
544
+ }, onMouseEnter: (e) => {
545
+ e.currentTarget.style.backgroundColor = '#D94A9F';
546
+ e.currentTarget.style.transform = 'scale(1.1)';
547
+ e.currentTarget.style.boxShadow = '0 4px 12px rgba(37, 89, 165, 0.6)';
548
+ }, onMouseLeave: (e) => {
549
+ e.currentTarget.style.backgroundColor = "#C2388B";
550
+ e.currentTarget.style.transform = 'scale(1)';
551
+ e.currentTarget.style.boxShadow = '0 2px 6px rgba(0,0,0,0.2)';
552
+ }, onClick: () => openTaskFormCallback(FormModes.Create), children: _jsx(TMTooltip, { content: SDKUI_Localizator.Create, children: _jsx("i", { className: "dx-icon-add", style: { fontSize: '25px' } }) }) })] });
553
+ };
554
+ export default TMTasksView;
@@ -265,9 +265,9 @@ export const WorkFlowMoreInfoPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
265
265
  return Object.values(filteredPriorities).map(priority => {
266
266
  switch (priority) {
267
267
  case Priorities.High:
268
- return ({ value: priority, display: SDKUI_Localizator.PriorityHigh });
268
+ return ({ value: priority, display: SDKUI_Localizator.High });
269
269
  default:
270
- return ({ value: priority, display: SDKUI_Localizator.PriorityLow });
270
+ return ({ value: priority, display: SDKUI_Localizator.Low });
271
271
  }
272
272
  });
273
273
  };
@@ -22,7 +22,7 @@ const TMBlogAttachments = (props) => {
22
22
  const fileName = `${removeFileExtension(name)}_${archiveID}_${blogPostAttachment.tid}_${blogPostAttachment.did}.${fileExt}`;
23
23
  openDcmtForm({ TID: blogPostAttachment.tid, DID: blogPostAttachment.did, fileName });
24
24
  };
25
- return _jsx("div", { style: { width: "100%", marginTop: "5px", overflow: "hidden" }, children: attachments.map((blogPostAttachment) => {
25
+ return _jsx("div", { style: { width: "100%", marginTop: "5px", overflow: "hidden" }, children: attachments.map((blogPostAttachment, index) => {
26
26
  const { name, nameElement, tooltipContent, fileExt, archivedDocumentsExist, draftExist } = getAttachmentInfo(blogPostAttachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText);
27
27
  return _jsx("div", { onDoubleClick: (e) => onDoubleClick(e, blogPostAttachment, name, fileExt), onMouseEnter: (e) => handleMouseEnter(e, blogPostAttachment, name, fileExt), onMouseLeave: (e) => handleMouseLeave(e), style: {
28
28
  display: 'inline-flex',
@@ -37,7 +37,7 @@ const TMBlogAttachments = (props) => {
37
37
  color: isSelected ? "#ffffff" : "#000000",
38
38
  }, children: _jsxs("div", { style: { alignItems: 'center', display: 'flex' }, children: [(!archivedDocumentsExist && !draftExist) ?
39
39
  _jsx(IconAttachment, { style: { marginRight: "5px" } }) :
40
- _jsx("div", { style: { marginRight: "10px" }, children: _jsx(TMDcmtIcon, { tid: blogPostAttachment.tid, did: blogPostAttachment.did, fileExtension: fileExt, downloadMode: 'openInNewWindow', tooltipContent: tooltipContent }) }), _jsx("span", { style: { whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }, children: nameElement })] }) }, blogPostAttachment.did);
40
+ _jsx("div", { style: { marginRight: "10px" }, children: _jsx(TMDcmtIcon, { tid: blogPostAttachment.tid, did: blogPostAttachment.did, fileExtension: fileExt, downloadMode: 'openInNewWindow', tooltipContent: tooltipContent }) }), _jsx("span", { style: { whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }, children: nameElement })] }) }, blogPostAttachment.did + "_" + index);
41
41
  }) });
42
42
  };
43
43
  export default TMBlogAttachments;
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { BlogPost, HomeBlogPost } from "@topconsultnpm/sdk-ts";
2
+ import { BlogPost, HomeBlogPost, TaskDescriptor } from "@topconsultnpm/sdk-ts";
3
3
  import { DcmtInfo } from "../../ts";
4
4
  import { FileItem } from "../base/TMFileManagerUtils";
5
5
  import { TMBlogsPostHeader, TMBlogContextDescriptor } from "./TMBlogsPostUtils";
@@ -68,16 +68,19 @@ interface TMBlogsPostProps {
68
68
  setShowId?: React.Dispatch<React.SetStateAction<boolean>>;
69
69
  /** Refresh Home Page News Callback */
70
70
  refreshHomePageNews?: () => Promise<void>;
71
- /** Optional callback to handle navigation to working groups */
72
- handleNavigateToWGs?: (blogPost: BlogPost | HomeBlogPost) => void;
73
- /** Optional callback to handle navigation to dossiers */
74
- handleNavigateToDossiers?: (blogPost: BlogPost | HomeBlogPost) => void;
75
71
  /** Optional callback to mark blog as read */
76
72
  markBlogAsRead?: (blog: BlogPost | undefined) => Promise<void>;
77
73
  /** Optional blog post to be externally selected */
78
74
  externalBlogPost?: BlogPost;
79
75
  /** Optional function to reset the external blog post */
80
76
  resetExternalBlogPost?: () => void;
77
+ allTasks?: Array<TaskDescriptor>;
78
+ getAllTasks?: () => Promise<void>;
79
+ deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
80
+ addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
81
+ editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
82
+ handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
83
+ handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
81
84
  }
82
85
  declare const TMBlogsPost: (props: TMBlogsPostProps) => import("react/jsx-runtime").JSX.Element;
83
86
  export default TMBlogsPost;