@topconsultnpm/sdkui-react 6.19.0-dev1.53 → 6.19.0-dev1.55
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.
Potentially problematic release.
This version of @topconsultnpm/sdkui-react might be problematic. Click here for more details.
- package/lib/components/base/TMLayout.d.ts +2 -1
- package/lib/components/base/TMLayout.js +2 -2
- package/lib/components/features/documents/TMDcmtBlog.js +1 -1
- package/lib/components/features/search/TMSearch.js +1 -1
- package/lib/components/features/search/TMSearchResult.js +10 -1
- package/lib/components/features/tasks/TMTaskForm.d.ts +33 -0
- package/lib/components/features/tasks/TMTaskForm.js +291 -0
- package/lib/components/features/tasks/TMTasksAgenda.d.ts +17 -0
- package/lib/components/features/tasks/TMTasksAgenda.js +107 -0
- package/lib/components/features/tasks/TMTasksCalendar.d.ts +21 -0
- package/lib/components/features/tasks/TMTasksCalendar.js +240 -0
- package/lib/components/features/tasks/TMTasksHeader.d.ts +14 -0
- package/lib/components/features/tasks/TMTasksHeader.js +37 -0
- package/lib/components/features/tasks/TMTasksPanelContent.d.ts +19 -0
- package/lib/components/features/tasks/TMTasksPanelContent.js +74 -0
- package/lib/components/features/tasks/TMTasksUtils.d.ts +130 -0
- package/lib/components/features/tasks/TMTasksUtils.js +602 -0
- package/lib/components/features/tasks/TMTasksUtilsView.d.ts +32 -0
- package/lib/components/features/tasks/TMTasksUtilsView.js +107 -0
- package/lib/components/features/tasks/TMTasksView.d.ts +37 -0
- package/lib/components/features/tasks/TMTasksView.js +555 -0
- package/lib/components/features/workflow/TMWorkflowPopup.js +2 -2
- package/lib/components/grids/TMBlogsPost.js +27 -27
- package/lib/components/grids/TMBlogsPostUtils.js +1 -1
- package/lib/components/index.d.ts +8 -0
- package/lib/components/index.js +9 -0
- package/lib/helper/SDKUI_Localizator.d.ts +54 -4
- package/lib/helper/SDKUI_Localizator.js +526 -25
- package/lib/helper/TMCustomSearchBar.d.ts +8 -0
- package/lib/helper/TMCustomSearchBar.js +54 -0
- package/lib/helper/TMToppyMessage.js +1 -1
- package/lib/helper/TMUtils.d.ts +10 -1
- package/lib/helper/TMUtils.js +42 -1
- package/lib/stories/TMSDKUI_Localizator.stories.js +1 -1
- package/package.json +1 -1
|
@@ -48,7 +48,8 @@ export interface ITMLayoutContainerProps {
|
|
|
48
48
|
alignItems?: string;
|
|
49
49
|
direction?: 'vertical' | 'horizontal';
|
|
50
50
|
onClick?: () => void;
|
|
51
|
+
onContextMenu?: (e: React.MouseEvent) => void;
|
|
51
52
|
}
|
|
52
|
-
declare const TMLayoutContainer: ({ gap, onClick, justifyContent, alignItems, children, direction }: ITMLayoutContainerProps) => import("react/jsx-runtime").JSX.Element;
|
|
53
|
+
declare const TMLayoutContainer: ({ gap, onClick, justifyContent, alignItems, children, direction, onContextMenu }: ITMLayoutContainerProps) => import("react/jsx-runtime").JSX.Element;
|
|
53
54
|
export { TMCard, TMLayoutItem, TMSplitterLayout };
|
|
54
55
|
export default TMLayoutContainer;
|
|
@@ -193,9 +193,9 @@ const TMSplitterLayout = ({ animation = false, showSeparator = true, separatorCo
|
|
|
193
193
|
const TMLayoutItem = ({ onClick, children, width = '100%', minWidth, maxWidth, maxHeight, height = '100%', minHeight }) => {
|
|
194
194
|
return (_jsx(StyledLayoutItem, { onClick: onClick, "$height": height, "$maxHeight": maxHeight, "$minHeight": minHeight, "$width": width, "$minWidth": minWidth, "$maxWidth": maxWidth, children: children }));
|
|
195
195
|
};
|
|
196
|
-
const TMLayoutContainer = ({ gap = 3, onClick, justifyContent = 'flex-start', alignItems = 'flex-start', children, direction = 'vertical' }) => {
|
|
196
|
+
const TMLayoutContainer = ({ gap = 3, onClick, justifyContent = 'flex-start', alignItems = 'flex-start', children, direction = 'vertical', onContextMenu }) => {
|
|
197
197
|
const renderedEls = () => { return (React.Children.map(children, child => (child))); };
|
|
198
|
-
return (_jsxs(StyledLayoutContainer, { "$alignItems": alignItems, "$justifyContent": justifyContent, onClick: onClick, "$direction": direction, style: { gap: gap }, children: [" ", renderedEls(), " "] }));
|
|
198
|
+
return (_jsxs(StyledLayoutContainer, { "$alignItems": alignItems, "$justifyContent": justifyContent, onClick: onClick, onContextMenu: onContextMenu, "$direction": direction, style: { gap: gap }, children: [" ", renderedEls(), " "] }));
|
|
199
199
|
};
|
|
200
200
|
export { TMCard, TMLayoutItem, TMSplitterLayout };
|
|
201
201
|
export default TMLayoutContainer;
|
|
@@ -83,4 +83,4 @@ const TMDcmtBlog = ({ tid, did, isVisible }) => {
|
|
|
83
83
|
export default TMDcmtBlog;
|
|
84
84
|
const StyledContainer = styled.div ` user-select: none; overflow: hidden; background-color: #ffffff; width: calc(100%); height: calc(100%); display: flex; gap: 10px; `;
|
|
85
85
|
const StyledSectionContainer = styled.div ` width: 100%; height: 100%; display:flex; flex-direction: column; `;
|
|
86
|
-
const StyledBoardContainer = styled.div `width: 100%; height: 100
|
|
86
|
+
const StyledBoardContainer = styled.div `width: 100%; height: 100%;`;
|
|
@@ -177,7 +177,7 @@ const TMSearch = ({ openInOffice, isVisible, inputTID, inputSqdID, inputMids, is
|
|
|
177
177
|
} }), [fromDTD, showSearchResults, setShowSearchResults, currentSQD, isExpertMode, mruTIDs, searchResult, passToArchiveCallback, inputMids]);
|
|
178
178
|
const tmSavedQuerySelectorElement = useMemo(() => _jsxs(TabPanel, { width: "100%", height: "100%", showNavButtons: true, repaintChangesOnly: true, selectedIndex: currentSQDMode, onSelectedIndexChange: (index) => setCurrentSQDMode(index), children: [(currentTID || currentSQD) ? _jsx(Item, { title: fromDTD?.nameLoc, children: _jsx(TMSavedQuerySelectorWrapper, { allowShowSearch: false, items: filteredByTIDSQDs, selectedId: currentSQD?.id, onRefreshData: () => { loadDataSQDsAsync(true); }, onItemClick: (sqd) => {
|
|
179
179
|
onSQDItemClick(sqd, setSQDAsync);
|
|
180
|
-
}, onDeleted: (sqd) => onSQDDeleted(sqd, sqd.id == currentSQD?.id ? filteredByTIDSQDs.find(o => o.id == 1) : currentSQD, setSQDAsync) }) }) : _jsx(_Fragment, {}), _jsx(Item, { title: SDKUI_Localizator.
|
|
180
|
+
}, onDeleted: (sqd) => onSQDDeleted(sqd, sqd.id == currentSQD?.id ? filteredByTIDSQDs.find(o => o.id == 1) : currentSQD, setSQDAsync) }) }) : _jsx(_Fragment, {}), _jsx(Item, { title: SDKUI_Localizator.AllFemale, children: _jsx(TMSavedQuerySelectorWrapper, { allowShowSearch: true, items: allSQDs, manageDefault: false, onItemClick: (sqd) => {
|
|
181
181
|
onSQDItemClick(sqd, setSQDAsync);
|
|
182
182
|
}, onDeleted: (sqd) => onSQDDeleted(sqd, sqd.id == currentSQD?.id ? undefined : currentSQD, setSQDAsync) }) })] }), [currentSQDMode, currentTID, currentSQD, fromDTD, filteredByTIDSQDs, allSQDs]);
|
|
183
183
|
// --- PANEL DEFINITIONS ---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
|
-
import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes, TemplateTIDs, DcmtTypeListCacheService, AccessLevels, SystemMIDsAsNumber, RetrieveFileOptions, DcmtOpers, GeneralRetrieveFormats } from '@topconsultnpm/sdk-ts';
|
|
3
|
+
import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes, TemplateTIDs, DcmtTypeListCacheService, AccessLevels, SystemMIDsAsNumber, RetrieveFileOptions, DcmtOpers, GeneralRetrieveFormats, AccessLevelsEx } from '@topconsultnpm/sdk-ts';
|
|
4
4
|
import styled from 'styled-components';
|
|
5
5
|
import { getCommandsMenuItems, getSelectedDcmtsOrFocused } from './TMSearchResultsMenuItems';
|
|
6
6
|
import { genUniqueId, IconShow, IconBoard, IconDcmtTypeSys, IconDetailDcmts, SDKUI_Localizator, IconDelete, IconRefresh, IconMenuVertical, IconDownload, deepCompare, getDataColumnName, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, IconSearchCheck, TMCommandsContextMenu } from '../../../helper';
|
|
@@ -157,6 +157,15 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
|
|
|
157
157
|
ShowAlert({ message: "Nessun documento selezionato", mode: "warning", title: 'Archivio Condivisa', duration: 3000 });
|
|
158
158
|
return;
|
|
159
159
|
}
|
|
160
|
+
if (fromDTD?.perm?.canArchive !== AccessLevelsEx.Yes && fromDTD?.perm?.canArchive !== AccessLevelsEx.Mixed) {
|
|
161
|
+
ShowAlert({
|
|
162
|
+
message: "Non hai i permessi per archiviare documenti di questo tipo.",
|
|
163
|
+
mode: 'warning',
|
|
164
|
+
title: 'Archivio Condivisa',
|
|
165
|
+
duration: 5000
|
|
166
|
+
});
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
160
169
|
try {
|
|
161
170
|
const rfo = new RetrieveFileOptions();
|
|
162
171
|
rfo.retrieveReason = DcmtOpers.None;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TaskDescriptor, UserDescriptor } from '@topconsultnpm/sdk-ts';
|
|
3
|
+
import { DcmtInfo, FormModes, TaskContext } from '../../../ts';
|
|
4
|
+
export interface TMTaskFormProps {
|
|
5
|
+
id: number;
|
|
6
|
+
title: string;
|
|
7
|
+
isModal: boolean;
|
|
8
|
+
formMode: FormModes;
|
|
9
|
+
visualizedTasks: Array<TaskDescriptor>;
|
|
10
|
+
currentTask: TaskDescriptor | null;
|
|
11
|
+
setCurrentTask?: React.Dispatch<React.SetStateAction<TaskDescriptor | null>>;
|
|
12
|
+
selectedRowKeys: Array<number>;
|
|
13
|
+
handleFocusedRowKeyChange?: (row: TaskDescriptor | undefined) => void;
|
|
14
|
+
onStatusChanged?: () => void;
|
|
15
|
+
onSaved?: (newTask: TaskDescriptor) => void;
|
|
16
|
+
editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
|
|
17
|
+
onClose?: () => void;
|
|
18
|
+
onCancel?: () => void;
|
|
19
|
+
handleNavigateToWGs?: (workGroupId: number) => void;
|
|
20
|
+
handleNavigateToDossiers?: (dossierId: number) => void;
|
|
21
|
+
taskContext?: TaskContext;
|
|
22
|
+
startDate?: Date;
|
|
23
|
+
endDate?: Date;
|
|
24
|
+
showBackButton?: boolean;
|
|
25
|
+
hasNavigation?: boolean;
|
|
26
|
+
width?: string;
|
|
27
|
+
height?: string;
|
|
28
|
+
usersList?: Array<UserDescriptor>;
|
|
29
|
+
onOpenS4TViewerRequest?: (dcmtInfo: Array<DcmtInfo>, onRefreshSearchAsync?: (() => Promise<void>)) => void;
|
|
30
|
+
s4TViewerDialogComponent?: React.ReactNode;
|
|
31
|
+
}
|
|
32
|
+
declare const TMTaskForm: (props: TMTaskFormProps) => import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export default TMTaskForm;
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { ObjectClasses, TaskDescriptor, Priorities, PdGs, SDK_Globals, UserListCacheService, SDK_Localizator } from '@topconsultnpm/sdk-ts';
|
|
4
|
+
import { areDifferentIDs, formatDate, getOriginLabel, getPriorityLocalizatorValue, getPriorityLocalizatorValues, getStatusLocalizatorValues, gotoPDGExtendedLabel, taskValidatorAsync } from './TMTasksUtils';
|
|
5
|
+
import ScrollView from 'devextreme-react/cjs/scroll-view';
|
|
6
|
+
import TMLayoutContainer from '../../base/TMLayout';
|
|
7
|
+
import { FormModes } from '../../../ts';
|
|
8
|
+
import { useWorkflowApprove } from '../../../hooks/useWorkflowApprove';
|
|
9
|
+
import { SaveFormOptions, useSaveForm } from '../../../hooks/useForm';
|
|
10
|
+
import { SDKUI_Localizator, calcIsModified, TMConditionalWrapper, getPdgsIconMap, DateDisplayTypes } from '../../../helper';
|
|
11
|
+
import { TMExceptionBoxManager } from '../../base/TMPopUp';
|
|
12
|
+
import TMSpinner from '../../base/TMSpinner';
|
|
13
|
+
import TMTooltip from '../../base/TMTooltip';
|
|
14
|
+
import TMUserChooser from '../../choosers/TMUserChooser';
|
|
15
|
+
import TMDateBox from '../../editors/TMDateBox';
|
|
16
|
+
import TMDropDown from '../../editors/TMDropDown';
|
|
17
|
+
import TMTextArea from '../../editors/TMTextArea';
|
|
18
|
+
import TMTextBox from '../../editors/TMTextBox';
|
|
19
|
+
import TMSaveForm from '../../forms/TMSaveForm';
|
|
20
|
+
import TMDcmtForm from '../documents/TMDcmtForm';
|
|
21
|
+
const TMTaskForm = (props) => {
|
|
22
|
+
// Custom hook to manage workflow approval data
|
|
23
|
+
const { refreshWorkflowApprove } = useWorkflowApprove();
|
|
24
|
+
const validator = async (taskDescriptor) => { return await taskValidatorAsync(taskDescriptor); };
|
|
25
|
+
// Destructure the props object to extract individual properties
|
|
26
|
+
const { id, title, isModal, formMode, visualizedTasks, editTaskCallback, currentTask, setCurrentTask, selectedRowKeys, handleFocusedRowKeyChange, onStatusChanged, onSaved, onClose, onCancel, handleNavigateToWGs, handleNavigateToDossiers, taskContext, startDate, endDate, showBackButton = true, hasNavigation = true, width = "100%", height = "100%", usersList, onOpenS4TViewerRequest, s4TViewerDialogComponent } = props;
|
|
27
|
+
const sfo = new SaveFormOptions();
|
|
28
|
+
sfo.objClass = ObjectClasses.Task;
|
|
29
|
+
const customizeFormData = (task) => {
|
|
30
|
+
if (taskContext?.document && formMode === FormModes.Create) {
|
|
31
|
+
task.pdG = PdGs.DT;
|
|
32
|
+
task.iD1 = taskContext.document.tid;
|
|
33
|
+
task.iD2 = taskContext.document.did;
|
|
34
|
+
}
|
|
35
|
+
else if (taskContext?.workingGroup && formMode === FormModes.Create) {
|
|
36
|
+
task.pdG = PdGs.WG;
|
|
37
|
+
task.iD1 = taskContext.workingGroup.id;
|
|
38
|
+
}
|
|
39
|
+
else if (taskContext?.dossier && formMode === FormModes.Create) {
|
|
40
|
+
task.pdG = PdGs.CF;
|
|
41
|
+
task.iD1 = taskContext.dossier.id;
|
|
42
|
+
if (currentTask)
|
|
43
|
+
task.name = currentTask.name;
|
|
44
|
+
}
|
|
45
|
+
else if (taskContext?.workItem && formMode === FormModes.Create) {
|
|
46
|
+
task.pdG = PdGs.DT;
|
|
47
|
+
task.iD1 = taskContext.workItem.tid;
|
|
48
|
+
task.iD2 = taskContext.workItem.did;
|
|
49
|
+
task.toID = 0;
|
|
50
|
+
}
|
|
51
|
+
return task;
|
|
52
|
+
};
|
|
53
|
+
const { formData, setFormData, formDataOrig, validationItems, exception, saveDataAsync } = useSaveForm(formMode, id, sfo, validator, onSaved, onStatusChanged, customizeFormData);
|
|
54
|
+
const containerRef = useRef(null);
|
|
55
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
56
|
+
const [showDcmtForm, setShowDcmtForm] = useState(false);
|
|
57
|
+
const mobileBreakpoint = 768;
|
|
58
|
+
const [users, setUsers] = useState([]); // State to store the users
|
|
59
|
+
// Initial state for the fields' editability (readonly)
|
|
60
|
+
const [fieldsReadOnly, setFieldsReadOnly] = useState({
|
|
61
|
+
name: false,
|
|
62
|
+
description: false,
|
|
63
|
+
fromID: false,
|
|
64
|
+
assignedTO: false,
|
|
65
|
+
status: false,
|
|
66
|
+
priority: false,
|
|
67
|
+
startDate: false,
|
|
68
|
+
endDate: false,
|
|
69
|
+
remTime: false
|
|
70
|
+
});
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const fetchUsers = async () => {
|
|
73
|
+
try {
|
|
74
|
+
// Show spinner while loading
|
|
75
|
+
TMSpinner.show({ description: `${SDKUI_Localizator.Loading} - ${SDK_Localizator.Users} ...` });
|
|
76
|
+
const userList = await UserListCacheService.GetAllAsync();
|
|
77
|
+
setUsers(userList); // Update state with the fetched users
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
TMExceptionBoxManager.show({ exception: err });
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
TMSpinner.hide();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
fetchUsers();
|
|
87
|
+
}, []);
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (isModal)
|
|
90
|
+
setIsMobile(true);
|
|
91
|
+
}, [isModal]);
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (formDataOrig && formMode === FormModes.Update) {
|
|
94
|
+
const isTaskAssignedByDifferentUser = areDifferentIDs(formDataOrig.fromID, SDK_Globals.tmSession?.SessionDescr?.userID);
|
|
95
|
+
setFieldsReadOnly({
|
|
96
|
+
name: isTaskAssignedByDifferentUser,
|
|
97
|
+
description: isTaskAssignedByDifferentUser,
|
|
98
|
+
fromID: isTaskAssignedByDifferentUser,
|
|
99
|
+
assignedTO: isTaskAssignedByDifferentUser,
|
|
100
|
+
status: false,
|
|
101
|
+
priority: isTaskAssignedByDifferentUser,
|
|
102
|
+
startDate: isTaskAssignedByDifferentUser,
|
|
103
|
+
endDate: isTaskAssignedByDifferentUser,
|
|
104
|
+
remTime: false
|
|
105
|
+
});
|
|
106
|
+
const newTaskDescriptor = new TaskDescriptor();
|
|
107
|
+
Object.assign(newTaskDescriptor, formDataOrig);
|
|
108
|
+
newTaskDescriptor.isNew = 0;
|
|
109
|
+
editTaskCallback?.(newTaskDescriptor);
|
|
110
|
+
}
|
|
111
|
+
else if (formDataOrig && formMode === FormModes.Create && taskContext?.dossier && currentTask) {
|
|
112
|
+
setFieldsReadOnly({
|
|
113
|
+
name: true,
|
|
114
|
+
description: false,
|
|
115
|
+
fromID: false,
|
|
116
|
+
assignedTO: false,
|
|
117
|
+
status: false,
|
|
118
|
+
priority: false,
|
|
119
|
+
startDate: false,
|
|
120
|
+
endDate: false,
|
|
121
|
+
remTime: false
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}, [formDataOrig, formMode]);
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
if (!isModal) {
|
|
127
|
+
// Function to handle resize events and update the mobile state based on container width.
|
|
128
|
+
const updateDimensions = (entries) => {
|
|
129
|
+
for (let entry of entries) {
|
|
130
|
+
const { width } = entry.contentRect;
|
|
131
|
+
setIsMobile(width <= mobileBreakpoint);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
// Create a ResizeObserver to observe container size changes
|
|
135
|
+
const resizeObserver = new ResizeObserver(updateDimensions);
|
|
136
|
+
if (containerRef.current) {
|
|
137
|
+
resizeObserver.observe(containerRef.current);
|
|
138
|
+
}
|
|
139
|
+
// Cleanup: Stop observing when the component unmounts or the dependency changes.
|
|
140
|
+
return () => {
|
|
141
|
+
if (containerRef.current) {
|
|
142
|
+
resizeObserver.unobserve(containerRef.current);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return undefined;
|
|
147
|
+
}, [containerRef, isModal]); // Dependency array ensures this effect runs when containerRef changes.
|
|
148
|
+
// Function to handle changes in the status value of a TM Drop Down
|
|
149
|
+
const onStatusValueChange = (e) => {
|
|
150
|
+
if (!e?.target?.value)
|
|
151
|
+
return;
|
|
152
|
+
setFormData({ ...formData ?? {}, state: e?.target?.value });
|
|
153
|
+
};
|
|
154
|
+
// Function to handle changes in the priority value of a TM Drop Down
|
|
155
|
+
const onPriorityValueChange = (e) => {
|
|
156
|
+
if (!e?.target?.value)
|
|
157
|
+
return;
|
|
158
|
+
setFormData({ ...formData ?? {}, priority: e?.target?.value });
|
|
159
|
+
};
|
|
160
|
+
// Function to handle the undo action
|
|
161
|
+
const onUndoCallback = () => {
|
|
162
|
+
setFormData(formDataOrig);
|
|
163
|
+
};
|
|
164
|
+
const canNext = () => {
|
|
165
|
+
if (currentTask === null)
|
|
166
|
+
return false;
|
|
167
|
+
if (visualizedTasks.length === 1)
|
|
168
|
+
return false;
|
|
169
|
+
let index = visualizedTasks.findIndex(item => item.id === currentTask.id);
|
|
170
|
+
if (index < visualizedTasks.length - 1) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
const canPrev = () => {
|
|
178
|
+
if (currentTask === null)
|
|
179
|
+
return false;
|
|
180
|
+
if (visualizedTasks.length === 1)
|
|
181
|
+
return false;
|
|
182
|
+
let index = visualizedTasks.findIndex(item => item.id === currentTask.id);
|
|
183
|
+
if (index > 0) {
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
const onNextCallback = () => {
|
|
191
|
+
if (currentTask === null)
|
|
192
|
+
return;
|
|
193
|
+
if (visualizedTasks.length === 0)
|
|
194
|
+
return;
|
|
195
|
+
let index = visualizedTasks.findIndex(item => item.id === currentTask.id);
|
|
196
|
+
const nextTask = visualizedTasks[index + 1];
|
|
197
|
+
if (nextTask) {
|
|
198
|
+
setCurrentTask?.(nextTask);
|
|
199
|
+
if (nextTask.id)
|
|
200
|
+
handleFocusedRowKeyChange?.(nextTask);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
const onPrevCallback = () => {
|
|
204
|
+
if (currentTask === null)
|
|
205
|
+
return;
|
|
206
|
+
if (visualizedTasks.length === 0)
|
|
207
|
+
return;
|
|
208
|
+
let index = visualizedTasks.findIndex(item => item.id === currentTask.id);
|
|
209
|
+
const prevTask = visualizedTasks[index - 1];
|
|
210
|
+
if (prevTask) {
|
|
211
|
+
setCurrentTask?.(prevTask);
|
|
212
|
+
if (prevTask.id)
|
|
213
|
+
handleFocusedRowKeyChange?.(prevTask);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
const gotoPDGExtendedLabelClickCallback = () => {
|
|
217
|
+
// Return early if formData is not defined
|
|
218
|
+
if (!formData)
|
|
219
|
+
return;
|
|
220
|
+
// Destructure needed properties from formData
|
|
221
|
+
const { pdG = PdGs.None, iD1, iD2, iD1Name } = formData;
|
|
222
|
+
// Check if pdG is None
|
|
223
|
+
if (pdG === PdGs.None)
|
|
224
|
+
return;
|
|
225
|
+
// If both id1 and id2 are present and pdg is of type DT, show the document form
|
|
226
|
+
if (iD1 && iD2 && pdG === PdGs.DT) {
|
|
227
|
+
setShowDcmtForm(true);
|
|
228
|
+
return; // Exit the function after showing the form
|
|
229
|
+
}
|
|
230
|
+
if (iD1 && pdG === PdGs.WG) {
|
|
231
|
+
// Working Group navigation
|
|
232
|
+
if (handleNavigateToWGs) {
|
|
233
|
+
handleNavigateToWGs(iD1);
|
|
234
|
+
}
|
|
235
|
+
return; // Exit the function after navigation
|
|
236
|
+
}
|
|
237
|
+
if (iD1 && pdG === PdGs.CF) {
|
|
238
|
+
// Dossier navigation
|
|
239
|
+
if (handleNavigateToDossiers) {
|
|
240
|
+
handleNavigateToDossiers(iD1);
|
|
241
|
+
}
|
|
242
|
+
return; // Exit the function after navigation
|
|
243
|
+
}
|
|
244
|
+
// Otherwise, alert the user with the provided information
|
|
245
|
+
alert(gotoPDGExtendedLabel(false, pdG, iD1Name));
|
|
246
|
+
};
|
|
247
|
+
const handleStartTimeContentReady = () => {
|
|
248
|
+
setTimeout(() => { if (startDate && !formData?.startTime && formMode === FormModes.Create) {
|
|
249
|
+
setFormData(prev => ({ ...prev, startTime: startDate }));
|
|
250
|
+
} }, 100);
|
|
251
|
+
};
|
|
252
|
+
const handleEndTimeContentReady = () => {
|
|
253
|
+
setTimeout(() => { if (endDate && !formData?.endTime && formMode === FormModes.Create) {
|
|
254
|
+
setFormData(prev => ({ ...prev, endTime: endDate }));
|
|
255
|
+
} }, 200);
|
|
256
|
+
};
|
|
257
|
+
const onCloseCallback = () => {
|
|
258
|
+
if (formData && formData.id) {
|
|
259
|
+
if (!selectedRowKeys.includes(formData.id)) {
|
|
260
|
+
handleFocusedRowKeyChange?.(formData);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
onClose?.();
|
|
264
|
+
};
|
|
265
|
+
const onTaskCompleted = async (task) => {
|
|
266
|
+
await editTaskCallback?.(task);
|
|
267
|
+
onClose?.();
|
|
268
|
+
};
|
|
269
|
+
return (_jsx("div", { style: { width: "100%", height: "100%", overflow: "auto" }, ref: containerRef, children: _jsx(TMSaveForm, { width: width, height: height, id: id, title: title, isModal: isModal, formMode: formMode, onSaveAsync: saveDataAsync, onClose: onCloseCallback, onUndo: onUndoCallback, exception: exception, isModified: calcIsModified(formData, formDataOrig), validationItems: validationItems, showBackButton: showBackButton, hasNavigation: (hasNavigation && formMode !== FormModes.Create), canNext: canNext(), onNext: onNextCallback, canPrev: canPrev(), onPrev: onPrevCallback, showToolbar: !(showDcmtForm && formData?.iD1 && formData?.iD2), children: _jsxs(_Fragment, { children: [_jsx(ScrollView, { direction: "vertical", useNative: true, height: "calc(100% - 35px)", children: _jsx("div", { style: { marginRight: "5px" }, children: _jsxs(TMLayoutContainer, { direction: 'vertical', gap: 2, children: [(formMode === FormModes.Update && areDifferentIDs(formDataOrig?.fromID, SDK_Globals.tmSession?.SessionDescr?.userID)) && _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsxs("div", { style: { width: '100%', display: 'flex', alignItems: 'center', color: "#E29000" }, children: [_jsx("i", { className: "dx-icon-info", style: { fontSize: 20 } }), "\u00A0", _jsx("span", { children: SDKUI_Localizator.TaskAssignedMessage.replaceParams(formDataOrig?.fromName ?? '') })] }) }), taskContext?.workItem === undefined && (!areDifferentIDs(formData?.fromID, SDK_Globals.tmSession?.SessionDescr?.userID)
|
|
270
|
+
&& !areDifferentIDs(formData?.toID, SDK_Globals.tmSession?.SessionDescr?.userID))
|
|
271
|
+
&& _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsxs("div", { style: { width: '100%', display: 'flex', alignItems: 'center', color: "#2559A5" }, children: [_jsx("i", { className: "dx-icon-info", style: { fontSize: 20 } }), "\u00A0", _jsx("span", { children: SDKUI_Localizator.PersonalTaskAssignmentMessage })] }) }), (!areDifferentIDs(formData?.fromID, SDK_Globals.tmSession?.SessionDescr?.userID)
|
|
272
|
+
&& areDifferentIDs(formData?.toID, SDK_Globals.tmSession?.SessionDescr?.userID))
|
|
273
|
+
&& _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsxs("div", { style: { width: '100%', display: 'flex', alignItems: 'center', color: "#2559A5" }, children: [_jsx("i", { className: "dx-icon-info", style: { fontSize: 20 } }), "\u00A0", _jsx("span", { children: SDKUI_Localizator.TaskAssignedToUserMessage.replaceParams(users.find(user => user.id === formData?.toID)?.name ?? '-') })] }) }), (formMode === FormModes.Create && taskContext && taskContext.workingGroup && taskContext.workingGroup.id) && _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsx("div", { style: { width: isMobile ? '100%' : '50%', display: 'flex', alignItems: 'center', color: "#000", marginTop: 10 }, children: _jsxs(TMTooltip, { content: getOriginLabel(PdGs.WG, taskContext.workingGroup.name), children: [_jsx("span", { children: getPdgsIconMap().get(PdGs.WG) }), "\u00A0", _jsx("span", { children: getOriginLabel(PdGs.WG, taskContext.workingGroup.name) })] }) }) }), (formMode === FormModes.Create && taskContext && taskContext.dossier && taskContext.dossier.id) && _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsx("div", { style: { width: isMobile ? '100%' : '50%', display: 'flex', alignItems: 'center', color: "#000", marginTop: 10 }, children: _jsxs(TMTooltip, { content: getOriginLabel(PdGs.CF, taskContext.dossier.name), children: [_jsx("span", { children: getPdgsIconMap().get(PdGs.CF) }), "\u00A0", _jsx("span", { children: getOriginLabel(PdGs.CF, taskContext.dossier.name) })] }) }) }), (formMode === FormModes.Create && taskContext && taskContext.document && taskContext.document.tid && taskContext.document.did && taskContext.document.name) && _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsx("div", { style: { width: isMobile ? '100%' : '50%', display: 'flex', alignItems: 'center', color: "#000", marginTop: 10 }, children: _jsxs(TMTooltip, { content: getOriginLabel(PdGs.DT, taskContext.document.name), children: [_jsx("span", { children: getPdgsIconMap().get(PdGs.DT) }), "\u00A0", _jsx("span", { children: getOriginLabel(PdGs.DT, taskContext.document.name) })] }) }) }), (formMode === FormModes.Create && taskContext && taskContext.workItem && taskContext.workItem.tid && taskContext.workItem.did && taskContext.workItem.name) && _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsx("div", { style: { width: isMobile ? '100%' : '50%', display: 'flex', alignItems: 'center', color: "#000", marginTop: 10 }, children: _jsxs(TMTooltip, { content: getOriginLabel(PdGs.DT, taskContext.workItem.name), children: [_jsx("span", { children: getPdgsIconMap().get(PdGs.DT) }), "\u00A0", _jsx("span", { children: getOriginLabel(PdGs.DT, taskContext.workItem.name) })] }) }) }), (formMode === FormModes.Update && formData?.pdG && formData?.iD1Name) && _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsx("div", { style: { width: isMobile ? '100%' : '50%' }, children: _jsx("div", { style: { display: 'flex', alignItems: 'center', marginTop: 10 }, children: _jsx(TMTooltip, { content: formData?.pdG && formData?.pdG !== PdGs.None ? gotoPDGExtendedLabel(true, formData?.pdG, formData?.iD1Name) : '', children: _jsxs("span", { onClick: () => formData?.pdG && formData?.pdG !== PdGs.None ? gotoPDGExtendedLabelClickCallback() : null, style: {
|
|
274
|
+
display: 'flex',
|
|
275
|
+
alignItems: 'center',
|
|
276
|
+
color: formData?.pdG && formData?.pdG !== PdGs.None ? '#1a0dab' : '#000',
|
|
277
|
+
cursor: formData?.pdG && formData?.pdG !== PdGs.None ? 'pointer' : 'default',
|
|
278
|
+
textDecoration: formData?.pdG && formData?.pdG !== PdGs.None ? 'underline' : 'none',
|
|
279
|
+
fontWeight: 'bold',
|
|
280
|
+
transition: 'color 0.2s ease-in-out'
|
|
281
|
+
}, children: [_jsx("span", { children: getPdgsIconMap().get(formData?.pdG) }), "\u00A0", _jsx("span", { children: getOriginLabel(formData?.pdG, formData?.iD1Name) })] }) }) }) }) }), _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsx("div", { style: { width: isMobile ? '100%' : '50%' }, children: _jsx(TMTextBox, { label: SDKUI_Localizator.Name, value: formData?.name ?? '', readOnly: fieldsReadOnly.name, autoFocus: true, maxLength: 100, isModifiedWhen: formData?.name !== formDataOrig?.name, onValueChanged: (e) => { setFormData({ ...formData ?? {}, name: e.target.value }); }, validationItems: validationItems?.filter(o => o.PropertyName === SDKUI_Localizator.Name) }) }) }), _jsx("div", { style: { width: '100%' }, children: _jsx(TMTextArea, { label: SDKUI_Localizator.Description, value: formData?.description ?? '', maxLength: 200, readOnly: fieldsReadOnly.description, isModifiedWhen: formData?.description !== formDataOrig?.description, onValueChanged: (e) => { setFormData({ ...formData ?? {}, description: e.target.value }); }, validationItems: validationItems?.filter(o => o.PropertyName === SDKUI_Localizator.Description), resize: false }) }), _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: (formMode === FormModes.Create || !areDifferentIDs(formDataOrig?.fromID, SDK_Globals.tmSession?.SessionDescr?.userID)) ?
|
|
282
|
+
_jsx("div", { id: "assignedToAnotherUserField", style: { width: isMobile ? '100%' : '50%' }, children: _jsx(TMUserChooser, { dataSource: usersList ?? undefined, allowMultipleSelection: false, label: SDKUI_Localizator.AssignedTo, readOnly: fieldsReadOnly.assignedTO, values: formData?.toID ? [formData?.toID] : [], isModifiedWhen: formData?.toID !== formDataOrig?.toID, validationItems: validationItems?.filter(o => o.PropertyName === SDKUI_Localizator.AssignedTo), onValueChanged: (newValue) => {
|
|
283
|
+
if (newValue === undefined)
|
|
284
|
+
return;
|
|
285
|
+
setFormData({ ...formData ?? {}, toID: newValue[0] });
|
|
286
|
+
} }) })
|
|
287
|
+
: formMode === FormModes.Update && _jsxs(_Fragment, { children: [areDifferentIDs(formDataOrig?.fromID, SDK_Globals.tmSession?.SessionDescr?.userID) && _jsx("div", { style: { width: isMobile ? '100%' : '50%' }, children: _jsx(TMTextBox, { label: SDKUI_Localizator.AssignedBy, value: formData?.fromName ?? '', readOnly: true }) }), areDifferentIDs(formDataOrig?.toID, SDK_Globals.tmSession?.SessionDescr?.userID) && _jsx("div", { style: { width: isMobile ? '100%' : '50%' }, children: _jsx(TMTextBox, { label: SDKUI_Localizator.AssignedTo, value: formData?.toName ?? '', readOnly: true }) })] }) }), _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsxs(_Fragment, { children: [_jsx("div", { style: { width: isMobile ? '100%' : '50%' }, children: _jsx(TMDropDown, { label: SDKUI_Localizator.Status, value: formData?.state, dataSource: getStatusLocalizatorValues(), isModifiedWhen: formData?.state !== formDataOrig?.state, onValueChanged: onStatusValueChange, readOnly: fieldsReadOnly.status }) }), _jsx("div", { style: { width: isMobile ? '100%' : '50%' }, children: !fieldsReadOnly.priority ? _jsx(TMDropDown, { label: SDKUI_Localizator.Priority, value: formData?.priority, dataSource: getPriorityLocalizatorValues(), isModifiedWhen: formData?.priority !== formDataOrig?.priority, onValueChanged: onPriorityValueChange })
|
|
288
|
+
: _jsx(TMTextBox, { label: SDKUI_Localizator.Priority, value: getPriorityLocalizatorValue(formData?.priority ?? Priorities.Low), readOnly: true }) })] }) }), _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsxs(_Fragment, { children: [_jsx("div", { style: { width: isMobile ? '100%' : '50%', marginTop: 10 }, children: !fieldsReadOnly.startDate ? _jsx(TMDateBox, { id: "start-date", resetTimeToZeroOnKeyPress: false, label: SDKUI_Localizator.StartDate, dateDisplayType: DateDisplayTypes.DateTime, value: formData?.startTime, isModifiedWhen: formData?.startTime !== formDataOrig?.startTime, validationItems: validationItems?.filter(o => o.PropertyName === SDKUI_Localizator.ErrorStartEndDate), onContentReady: handleStartTimeContentReady, onValueChange: (value) => { setFormData({ ...formData ?? {}, startTime: value }); }, showClearButton: true }) : _jsx(TMTextBox, { label: SDKUI_Localizator.StartDate, value: formData?.startTime ? formatDate(formData?.startTime) : '', readOnly: true }) }), _jsx("div", { style: { width: isMobile ? '100%' : '50%', marginTop: 10 }, children: !fieldsReadOnly.startDate ? _jsx(TMDateBox, { id: "end-date", resetTimeToZeroOnKeyPress: false, label: SDKUI_Localizator.Expiration, dateDisplayType: DateDisplayTypes.DateTime, value: formData?.endTime, isModifiedWhen: formData?.endTime !== formDataOrig?.endTime, validationItems: validationItems?.filter(o => o.PropertyName === SDKUI_Localizator.ErrorStartEndDate || o.PropertyName === SDKUI_Localizator.ErrorEndRemDate), onContentReady: handleEndTimeContentReady, onValueChange: (value) => { setFormData({ ...formData ?? {}, endTime: value }); }, showClearButton: true, readOnly: fieldsReadOnly.endDate }) : _jsx(TMTextBox, { label: SDKUI_Localizator.Expiration, value: formData?.endTime ? formatDate(formData?.endTime) : '', readOnly: true }) })] }) }), _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 3 }, children: children }), children: _jsx("div", { style: { width: isMobile ? '100%' : '50%', marginTop: 10 }, children: _jsx(TMDateBox, { id: "alert-time", resetTimeToZeroOnKeyPress: false, label: SDKUI_Localizator.Reminder, dateDisplayType: DateDisplayTypes.DateTime, value: formData?.remTime ?? undefined, isModifiedWhen: formData?.remTime !== formDataOrig?.remTime, validationItems: validationItems?.filter(o => o.PropertyName === SDKUI_Localizator.ErrorEndRemDate), onValueChange: (value) => { setFormData({ ...formData ?? {}, remTime: value }); }, showClearButton: true, readOnly: fieldsReadOnly.remTime }) }) })] }) }) }), (showDcmtForm && formData?.iD1 && formData?.iD2) &&
|
|
289
|
+
_jsx(TMDcmtForm, { titleModal: formData.iD1Name ?? '-', isModal: true, TID: formData.iD1, DID: formData.iD2, allowButtonsRefs: true, taskMoreInfo: formData, onWFOperationCompleted: refreshWorkflowApprove, onTaskCompleted: onTaskCompleted, onClose: () => { setShowDcmtForm(false); }, onOpenS4TViewerRequest: onOpenS4TViewerRequest, s4TViewerDialogComponent: s4TViewerDialogComponent })] }) }) }));
|
|
290
|
+
};
|
|
291
|
+
export default TMTaskForm;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { TaskDescriptor } from "@topconsultnpm/sdk-ts";
|
|
3
|
+
import { FormModes } from "../../../ts";
|
|
4
|
+
interface TMTasksAgendaProps {
|
|
5
|
+
id: string;
|
|
6
|
+
showId: boolean;
|
|
7
|
+
showSearch: boolean;
|
|
8
|
+
visualizedTasks: Array<TaskDescriptor>;
|
|
9
|
+
fromCell: boolean;
|
|
10
|
+
toCell: boolean;
|
|
11
|
+
currentAgendaDate: Date;
|
|
12
|
+
setCurrentAgendaDate: React.Dispatch<React.SetStateAction<Date>>;
|
|
13
|
+
openTaskForm: (formMode: FormModes, task?: TaskDescriptor) => void;
|
|
14
|
+
handleFocusedRowChange: (row: TaskDescriptor | undefined) => void;
|
|
15
|
+
}
|
|
16
|
+
declare const TMTasksAgenda: React.MemoExoticComponent<(props: TMTasksAgendaProps) => import("react/jsx-runtime").JSX.Element>;
|
|
17
|
+
export default TMTasksAgenda;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import ArrayStore from "devextreme/data/array_store";
|
|
4
|
+
import Scheduler from "devextreme-react/cjs/scheduler";
|
|
5
|
+
import { calculateNumberOfDays, highlightTaskText, priorityLegend, renderTaskIcons } from "./TMTasksUtilsView";
|
|
6
|
+
import { Priorities, Task_States } from "@topconsultnpm/sdk-ts";
|
|
7
|
+
import { checkIfNew, convertToSchedulerAppointments, findTasksBySearch, formatDate, getPriorityColor, getStatusLocalizatorValue } from "./TMTasksUtils";
|
|
8
|
+
import ScrollView from "devextreme-react/cjs/scroll-view";
|
|
9
|
+
import LoadIndicator from "devextreme-react/cjs/load-indicator";
|
|
10
|
+
import { FormModes } from "../../../ts";
|
|
11
|
+
import { SDKUI_Localizator } from "../../../helper";
|
|
12
|
+
import TMCustomSearchBar from "../../../helper/TMCustomSearchBar";
|
|
13
|
+
import TMTooltip from "../../base/TMTooltip";
|
|
14
|
+
const TMTasksAgenda = React.memo((props) => {
|
|
15
|
+
const views = ['agenda'];
|
|
16
|
+
const { id, showId, showSearch, visualizedTasks, fromCell, toCell, currentAgendaDate, setCurrentAgendaDate, openTaskForm, handleFocusedRowChange } = props;
|
|
17
|
+
const [schedulerData, setSchedulerData] = useState([]);
|
|
18
|
+
const [loading, setLoading] = useState(false);
|
|
19
|
+
const [searchText, setSearchText] = useState('');
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
setSchedulerData(convertToSchedulerAppointments(visualizedTasks));
|
|
22
|
+
}, [visualizedTasks]);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
let timeoutId;
|
|
25
|
+
if (searchText.length > 0) {
|
|
26
|
+
setLoading(true);
|
|
27
|
+
timeoutId = setTimeout(() => {
|
|
28
|
+
const filteredTasks = findTasksBySearch(visualizedTasks, searchText);
|
|
29
|
+
setSchedulerData(convertToSchedulerAppointments(filteredTasks));
|
|
30
|
+
setLoading(false);
|
|
31
|
+
}, 300);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
setSchedulerData(convertToSchedulerAppointments(visualizedTasks));
|
|
35
|
+
setLoading(false);
|
|
36
|
+
}
|
|
37
|
+
return () => {
|
|
38
|
+
clearTimeout(timeoutId);
|
|
39
|
+
};
|
|
40
|
+
}, [searchText]);
|
|
41
|
+
const appointmentRender = useCallback((params) => {
|
|
42
|
+
const currentTask = visualizedTasks.find(task => task.id !== undefined && task.id === params.appointmentData.id);
|
|
43
|
+
if (currentTask === undefined || currentTask.id === undefined)
|
|
44
|
+
return;
|
|
45
|
+
const startTime = currentTask.startTime;
|
|
46
|
+
const endTime = currentTask.endTime;
|
|
47
|
+
const remTime = currentTask.remTime;
|
|
48
|
+
const stateLabel = currentTask.state ?? Task_States.None;
|
|
49
|
+
const stateTooltipLabel = getStatusLocalizatorValue(stateLabel);
|
|
50
|
+
const pdg = currentTask.pdG ?? undefined;
|
|
51
|
+
const ID1Name = currentTask.iD1Name ?? '';
|
|
52
|
+
const isNew = checkIfNew(currentTask.fromID, currentTask.isNew);
|
|
53
|
+
const numberOfDays = calculateNumberOfDays(startTime, endTime);
|
|
54
|
+
const priority = currentTask.priority ?? Priorities.None;
|
|
55
|
+
let bgColor = 'transparent';
|
|
56
|
+
if (priority)
|
|
57
|
+
bgColor = getPriorityColor(priority);
|
|
58
|
+
return _jsx("div", { style: { width: "100%", height: "100%", display: 'flex', flexDirection: 'column', justifyContent: 'flex-start', alignItems: 'flex-end', backgroundColor: bgColor }, children: _jsx(ScrollView, { width: "100%", height: "100%", direction: "both", useNative: true, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', width: '100%', fontWeight: isNew ? 'bold' : 'normal' }, children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [showId && _jsxs("span", { children: [highlightTaskText(currentTask.id.toString(), searchText, currentTask.id), " - "] }), renderTaskIcons({ stateLabel, stateTooltipLabel, pdg, ID1Name, endTime, remTime, isNew, numberOfDays }), "\u00A0", _jsx("span", { style: { fontWeight: "bold" }, children: highlightTaskText(currentTask.name ?? '', searchText, currentTask.id) })] }), _jsxs("div", { children: [startTime !== undefined && (_jsxs("span", { children: [SDKUI_Localizator.StartDate, ": ", formatDate(startTime), " - \u00A0"] })), endTime !== undefined && (_jsxs("span", { children: [SDKUI_Localizator.Expiration, ": ", formatDate(endTime)] }))] })] }), fromCell && _jsxs("div", { style: { display: 'flex', alignItems: 'center', alignSelf: 'flex-end' }, children: [_jsxs("span", { children: [SDKUI_Localizator.AssignedBy, ":"] }), "\u00A0", _jsxs("div", { children: [highlightTaskText(currentTask.fromName ?? '', searchText, currentTask.id), (showId && currentTask.fromID) && _jsxs("span", { children: ["(", currentTask.fromID, ")"] })] })] }), toCell && _jsxs("div", { style: { display: 'flex', alignItems: 'center', alignSelf: 'flex-end' }, children: [_jsxs("span", { children: [SDKUI_Localizator.AssignedTo, ":"] }), "\u00A0", _jsxs("div", { children: [highlightTaskText(currentTask.toName ?? '', searchText, currentTask.id), (showId && currentTask.toID) && _jsxs("span", { children: ["(", currentTask.toID, ")"] })] })] })] }) }) });
|
|
59
|
+
}, [visualizedTasks, searchText]);
|
|
60
|
+
// handle appointment click handler
|
|
61
|
+
const handleAppointmentClick = useCallback((e) => {
|
|
62
|
+
if (e === undefined || e.event === undefined || e.appointmentData.id === undefined)
|
|
63
|
+
return;
|
|
64
|
+
e.event.preventDefault();
|
|
65
|
+
e.cancel = true;
|
|
66
|
+
const { id } = e.appointmentData;
|
|
67
|
+
// Update the state with the new set of selected appointments
|
|
68
|
+
const task = visualizedTasks.find(task => task.id === id);
|
|
69
|
+
if (task) {
|
|
70
|
+
handleFocusedRowChange(task);
|
|
71
|
+
}
|
|
72
|
+
}, [visualizedTasks]);
|
|
73
|
+
const onAppointmentContextMenu = useCallback((e) => {
|
|
74
|
+
if (e === undefined || e.event === undefined || e.appointmentData.id === undefined)
|
|
75
|
+
return;
|
|
76
|
+
e.event.preventDefault();
|
|
77
|
+
const { id } = e.appointmentData;
|
|
78
|
+
// Update the state with the new set of selected appointments
|
|
79
|
+
const task = visualizedTasks.find(task => task.id === id);
|
|
80
|
+
if (task) {
|
|
81
|
+
handleFocusedRowChange(task);
|
|
82
|
+
}
|
|
83
|
+
}, []);
|
|
84
|
+
const onCurrentDateChange = useCallback((value) => {
|
|
85
|
+
// Exit early if it's not a valid Date
|
|
86
|
+
if (!(value instanceof Date) || isNaN(value.getTime())) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
setCurrentAgendaDate(value);
|
|
90
|
+
setSearchText('');
|
|
91
|
+
}, []);
|
|
92
|
+
// Double-click appointment handler
|
|
93
|
+
const handleAppointmentDblClick = useCallback((e) => {
|
|
94
|
+
if (e === undefined || e.event === undefined || e.appointmentData.id === undefined)
|
|
95
|
+
return;
|
|
96
|
+
e.event.preventDefault();
|
|
97
|
+
e.cancel = true;
|
|
98
|
+
const task = visualizedTasks.find(task => task.id === e.appointmentData.id);
|
|
99
|
+
if (task) {
|
|
100
|
+
handleFocusedRowChange(task);
|
|
101
|
+
openTaskForm(FormModes.Update, task);
|
|
102
|
+
}
|
|
103
|
+
}, [visualizedTasks]);
|
|
104
|
+
return _jsxs("div", { style: { height: "100%", width: "100%" }, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%', height: "48px" }, children: [_jsx("div", { style: { width: showSearch ? "160px" : "0", marginLeft: '10px' }, children: showSearch && (_jsx(TMCustomSearchBar, { initialValue: searchText, onSearchChange: (value) => setSearchText(value) })) }), _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: "default" }, children: _jsxs(TMTooltip, { content: priorityLegend(), children: [" ", SDKUI_Localizator.PriorityLegend] }) })] }), _jsx("div", { style: { height: "calc(100% - 48px)", width: "100%" }, children: loading ? _jsx("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", width: "100%" }, children: _jsx(LoadIndicator, {}) })
|
|
105
|
+
: _jsx("div", { id: `tasks-agenda-wrapper-${id}`, style: { width: "100%", height: "100%" }, onContextMenu: () => { handleFocusedRowChange(undefined); }, onClick: () => { handleFocusedRowChange(undefined); }, children: _jsx(Scheduler, { id: "tasks-agenda", defaultCurrentView: "agenda", dataSource: new ArrayStore({ key: `tasks-agenda-data`, data: schedulerData }), width: "100%", height: "100%", editing: false, views: views, currentDate: currentAgendaDate, appointmentRender: appointmentRender, onAppointmentDblClick: handleAppointmentDblClick, onCurrentDateChange: onCurrentDateChange, onAppointmentContextMenu: onAppointmentContextMenu, onAppointmentClick: handleAppointmentClick }) }) })] });
|
|
106
|
+
});
|
|
107
|
+
export default TMTasksAgenda;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TaskDescriptor } from "@topconsultnpm/sdk-ts";
|
|
3
|
+
import { FormModes } from '../../../ts';
|
|
4
|
+
interface TMTasksCalendarProps {
|
|
5
|
+
id: string;
|
|
6
|
+
visualizedTasks: Array<TaskDescriptor>;
|
|
7
|
+
showId: boolean;
|
|
8
|
+
showSearch: boolean;
|
|
9
|
+
fromCell: boolean;
|
|
10
|
+
toCell: boolean;
|
|
11
|
+
openTaskForm: (formMode: FormModes, task?: TaskDescriptor) => void;
|
|
12
|
+
onDeleteCallback: (rowIds: Array<number>) => void;
|
|
13
|
+
currentCalendarDate: Date;
|
|
14
|
+
setCurrentCalendarDate: React.Dispatch<React.SetStateAction<Date>>;
|
|
15
|
+
setCalendarStartDate: React.Dispatch<React.SetStateAction<Date | undefined>>;
|
|
16
|
+
setCalendarEndDate: React.Dispatch<React.SetStateAction<Date | undefined>>;
|
|
17
|
+
focusedRowKey: number | undefined;
|
|
18
|
+
handleFocusedRowChange: (row: TaskDescriptor | undefined) => void;
|
|
19
|
+
}
|
|
20
|
+
declare const TMTasksCalendar: (props: TMTasksCalendarProps) => import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export default TMTasksCalendar;
|