@zeniai/client-epic-state 5.1.42-betaDI4 → 5.1.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +1 -1
- package/lib/entity/task/taskPayload.d.ts +1 -2
- package/lib/entity/task/taskPayload.js +1 -8
- package/lib/entity/task/taskReducer.d.ts +1 -8
- package/lib/entity/task/taskReducer.js +4 -29
- package/lib/entity/task/taskState.d.ts +0 -1
- package/lib/entity/tenant/epic/saveExternalConnectionEpic.js +15 -11
- package/lib/epic.d.ts +3 -5
- package/lib/epic.js +3 -5
- package/lib/esm/entity/snackbar/snackbarTypes.js +1 -1
- package/lib/esm/entity/task/taskPayload.js +1 -8
- package/lib/esm/entity/task/taskReducer.js +3 -28
- package/lib/esm/entity/tenant/epic/saveExternalConnectionEpic.js +15 -11
- package/lib/esm/epic.js +3 -5
- package/lib/esm/index.js +7 -7
- package/lib/esm/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +0 -3
- package/lib/esm/view/companyTaskManagerView/epics/fetchTaskManagerMetricsEpic.js +1 -7
- package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +7 -0
- package/lib/esm/view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic.js +0 -1
- package/lib/esm/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +9 -70
- package/lib/esm/view/taskManager/taskDetailView/taskDetailReducer.js +2 -56
- package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +9 -32
- package/lib/esm/view/taskManager/taskListView/epics/fetchTaskListEpic.js +1 -3
- package/lib/esm/view/taskManager/taskListView/taskList.js +0 -1
- package/lib/esm/view/taskManager/taskListView/taskListReducer.js +12 -240
- package/lib/esm/view/taskManager/taskListView/taskListSelector.js +0 -1
- package/lib/esm/view/taskManager/taskListView/taskListViewHelpers.js +0 -58
- package/lib/esm/view/transactionDetail/epics/saveTransactionHelper.js +22 -0
- package/lib/esm/view/transactionDetail/epics/updateTransactionDetailEpic.js +75 -3
- package/lib/esm/view/transactionDetail/journalEntryLinesViewModel.js +58 -0
- package/lib/esm/view/transactionDetail/transactionDetailLocalDataHelper.js +10 -8
- package/lib/esm/view/transactionDetail/transactionDetailReducer.js +66 -1
- package/lib/index.d.ts +10 -10
- package/lib/index.js +25 -25
- package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +0 -3
- package/lib/view/companyTaskManagerView/epics/fetchTaskManagerMetricsEpic.js +1 -7
- package/lib/view/companyView/types/cockpitTypes.d.ts +0 -3
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +7 -0
- package/lib/view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic.js +0 -1
- package/lib/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.d.ts +2 -2
- package/lib/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +8 -69
- package/lib/view/taskManager/taskDetailView/taskDetail.d.ts +0 -15
- package/lib/view/taskManager/taskDetailView/taskDetailReducer.d.ts +2 -14
- package/lib/view/taskManager/taskDetailView/taskDetailReducer.js +3 -57
- package/lib/view/taskManager/taskDetailView/taskDetailSelector.d.ts +1 -2
- package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +7 -30
- package/lib/view/taskManager/taskListView/epics/fetchTaskListEpic.js +1 -3
- package/lib/view/taskManager/taskListView/taskList.d.ts +1 -1
- package/lib/view/taskManager/taskListView/taskList.js +0 -1
- package/lib/view/taskManager/taskListView/taskListPayload.d.ts +0 -4
- package/lib/view/taskManager/taskListView/taskListReducer.d.ts +2 -6
- package/lib/view/taskManager/taskListView/taskListReducer.js +13 -241
- package/lib/view/taskManager/taskListView/taskListSelector.js +0 -1
- package/lib/view/taskManager/taskListView/taskListViewHelpers.d.ts +0 -11
- package/lib/view/taskManager/taskListView/taskListViewHelpers.js +1 -60
- package/lib/view/transactionDetail/epics/saveTransactionHelper.js +22 -0
- package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.d.ts +5 -1
- package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.js +77 -4
- package/lib/view/transactionDetail/journalEntryLinesViewModel.d.ts +27 -0
- package/lib/view/transactionDetail/journalEntryLinesViewModel.js +61 -1
- package/lib/view/transactionDetail/transactionDetailLocalDataHelper.js +10 -8
- package/lib/view/transactionDetail/transactionDetailReducer.d.ts +11 -2
- package/lib/view/transactionDetail/transactionDetailReducer.js +67 -2
- package/lib/view/transactionDetail/transactionDetailState.d.ts +8 -1
- package/lib/view/transactionDetail/transactionDetailTypes.d.ts +2 -0
- package/package.json +1 -1
- package/lib/esm/view/taskManager/taskDetailView/epics/createSubTaskEpic.js +0 -96
- package/lib/esm/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.js +0 -53
- package/lib/view/taskManager/taskDetailView/epics/createSubTaskEpic.d.ts +0 -9
- package/lib/view/taskManager/taskDetailView/epics/createSubTaskEpic.js +0 -100
- package/lib/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.d.ts +0 -8
- package/lib/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.js +0 -57
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
var _a;
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.updateDeletedTagToLocalStore = exports.updateCreatedTagToLocalStore = exports.clearTaskDetail = exports.updateTaskHistoryFetchStatus = exports.updateTaskHistory = exports.fetchTaskHistory = exports.unsnoozeTask = exports.snoozeTaskSuccessOrFailure = exports.snoozeTask = exports.deleteTaskSuccessOrFailure = exports.removeTaskDetail = exports.deleteTask = exports.
|
|
7
|
+
exports.updateDeletedTagToLocalStore = exports.updateCreatedTagToLocalStore = exports.clearTaskDetail = exports.updateTaskHistoryFetchStatus = exports.updateTaskHistory = exports.fetchTaskHistory = exports.unsnoozeTask = exports.snoozeTaskSuccessOrFailure = exports.snoozeTask = exports.deleteTaskSuccessOrFailure = exports.removeTaskDetail = exports.deleteTask = exports.saveTaskSuccessOrFailure = exports.archiveTaskSuccessOrFailure = exports.archiveTask = exports.saveTaskDetail = exports.discardTaskUpdatesInLocalStore = exports.saveTaskUpdatesToLocalStore = exports.updateEditTaskFetchStatus = exports.initializeTaskToLocalStore = exports.fetchTaskDetail = exports.fetchTaskDetailPage = exports.initialState = void 0;
|
|
8
8
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
9
9
|
const get_1 = __importDefault(require("lodash/get"));
|
|
10
10
|
const commonHistory_1 = require("../../spendManagement/commonHistoryView/commonHistory");
|
|
@@ -13,11 +13,6 @@ const taskDetail_1 = require("./taskDetail");
|
|
|
13
13
|
exports.initialState = {
|
|
14
14
|
newTaskState: taskDetail_1.initialTaskDetail,
|
|
15
15
|
editTaskStateById: {},
|
|
16
|
-
subTaskCreateStatus: {
|
|
17
|
-
fetchState: 'Not-Started',
|
|
18
|
-
error: undefined,
|
|
19
|
-
},
|
|
20
|
-
subTaskListFetchStatusByParentId: {},
|
|
21
16
|
taskHistoryById: {},
|
|
22
17
|
};
|
|
23
18
|
const taskDetailView = (0, toolkit_1.createSlice)({
|
|
@@ -62,7 +57,7 @@ const taskDetailView = (0, toolkit_1.createSlice)({
|
|
|
62
57
|
updateEditTaskFetchStatus(draft, action) {
|
|
63
58
|
const { taskId, fetchState, error } = action.payload;
|
|
64
59
|
draft.editTaskStateById[taskId] = {
|
|
65
|
-
...
|
|
60
|
+
...draft.editTaskStateById[taskId],
|
|
66
61
|
fetchTaskStatus: {
|
|
67
62
|
fetchState,
|
|
68
63
|
error: fetchState === 'Error' ? error : undefined,
|
|
@@ -330,59 +325,10 @@ const taskDetailView = (0, toolkit_1.createSlice)({
|
|
|
330
325
|
error,
|
|
331
326
|
};
|
|
332
327
|
},
|
|
333
|
-
createSubTask: {
|
|
334
|
-
reducer(draft) {
|
|
335
|
-
draft.subTaskCreateStatus = {
|
|
336
|
-
fetchState: 'In-Progress',
|
|
337
|
-
error: undefined,
|
|
338
|
-
};
|
|
339
|
-
},
|
|
340
|
-
prepare(payload) {
|
|
341
|
-
return { payload };
|
|
342
|
-
},
|
|
343
|
-
},
|
|
344
|
-
createSubTaskSuccessOrFailure(draft, action) {
|
|
345
|
-
const { fetchState, error } = action.payload;
|
|
346
|
-
draft.subTaskCreateStatus = {
|
|
347
|
-
fetchState,
|
|
348
|
-
error,
|
|
349
|
-
};
|
|
350
|
-
},
|
|
351
|
-
resetSubTaskCreateStatus(draft) {
|
|
352
|
-
draft.subTaskCreateStatus = {
|
|
353
|
-
...exports.initialState.subTaskCreateStatus,
|
|
354
|
-
};
|
|
355
|
-
},
|
|
356
|
-
fetchSubTasks: {
|
|
357
|
-
reducer(draft, action) {
|
|
358
|
-
const { parentTaskId } = action.payload;
|
|
359
|
-
draft.subTaskListFetchStatusByParentId[parentTaskId] = {
|
|
360
|
-
fetchState: 'In-Progress',
|
|
361
|
-
error: undefined,
|
|
362
|
-
};
|
|
363
|
-
},
|
|
364
|
-
prepare(parentTaskId) {
|
|
365
|
-
return { payload: { parentTaskId } };
|
|
366
|
-
},
|
|
367
|
-
},
|
|
368
|
-
updateSubTasks(draft, action) {
|
|
369
|
-
const { parentTaskId } = action.payload;
|
|
370
|
-
draft.subTaskListFetchStatusByParentId[parentTaskId] = {
|
|
371
|
-
fetchState: 'Completed',
|
|
372
|
-
error: undefined,
|
|
373
|
-
};
|
|
374
|
-
},
|
|
375
|
-
updateSubTasksFetchStatus(draft, action) {
|
|
376
|
-
const { parentTaskId, fetchState, error } = action.payload;
|
|
377
|
-
draft.subTaskListFetchStatusByParentId[parentTaskId] = {
|
|
378
|
-
fetchState,
|
|
379
|
-
error,
|
|
380
|
-
};
|
|
381
|
-
},
|
|
382
328
|
clearTaskDetail(draft) {
|
|
383
329
|
Object.assign(draft, exports.initialState);
|
|
384
330
|
},
|
|
385
331
|
},
|
|
386
332
|
});
|
|
387
|
-
_a = taskDetailView.actions, exports.fetchTaskDetailPage = _a.fetchTaskDetailPage, exports.fetchTaskDetail = _a.fetchTaskDetail, exports.initializeTaskToLocalStore = _a.initializeTaskToLocalStore, exports.updateEditTaskFetchStatus = _a.updateEditTaskFetchStatus, exports.saveTaskUpdatesToLocalStore = _a.saveTaskUpdatesToLocalStore, exports.discardTaskUpdatesInLocalStore = _a.discardTaskUpdatesInLocalStore, exports.saveTaskDetail = _a.saveTaskDetail, exports.archiveTask = _a.archiveTask, exports.archiveTaskSuccessOrFailure = _a.archiveTaskSuccessOrFailure, exports.saveTaskSuccessOrFailure = _a.saveTaskSuccessOrFailure, exports.
|
|
333
|
+
_a = taskDetailView.actions, exports.fetchTaskDetailPage = _a.fetchTaskDetailPage, exports.fetchTaskDetail = _a.fetchTaskDetail, exports.initializeTaskToLocalStore = _a.initializeTaskToLocalStore, exports.updateEditTaskFetchStatus = _a.updateEditTaskFetchStatus, exports.saveTaskUpdatesToLocalStore = _a.saveTaskUpdatesToLocalStore, exports.discardTaskUpdatesInLocalStore = _a.discardTaskUpdatesInLocalStore, exports.saveTaskDetail = _a.saveTaskDetail, exports.archiveTask = _a.archiveTask, exports.archiveTaskSuccessOrFailure = _a.archiveTaskSuccessOrFailure, exports.saveTaskSuccessOrFailure = _a.saveTaskSuccessOrFailure, exports.deleteTask = _a.deleteTask, exports.removeTaskDetail = _a.removeTaskDetail, exports.deleteTaskSuccessOrFailure = _a.deleteTaskSuccessOrFailure, exports.snoozeTask = _a.snoozeTask, exports.snoozeTaskSuccessOrFailure = _a.snoozeTaskSuccessOrFailure, exports.unsnoozeTask = _a.unsnoozeTask, exports.fetchTaskHistory = _a.fetchTaskHistory, exports.updateTaskHistory = _a.updateTaskHistory, exports.updateTaskHistoryFetchStatus = _a.updateTaskHistoryFetchStatus, exports.clearTaskDetail = _a.clearTaskDetail, exports.updateCreatedTagToLocalStore = _a.updateCreatedTagToLocalStore, exports.updateDeletedTagToLocalStore = _a.updateDeletedTagToLocalStore;
|
|
388
334
|
exports.default = taskDetailView.reducer;
|
|
@@ -2,7 +2,7 @@ import { FetchStateAndError, ID } from '../../../commonStateTypes/common';
|
|
|
2
2
|
import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndReport';
|
|
3
3
|
import { Class } from '../../../entity/class/classState';
|
|
4
4
|
import { File } from '../../../entity/file/fileState';
|
|
5
|
-
import {
|
|
5
|
+
import { TaskPriority, TaskStatus } from '../../../entity/task/taskState';
|
|
6
6
|
import { RootState } from '../../../reducer';
|
|
7
7
|
import { ZeniDate } from '../../../zeniDayJS';
|
|
8
8
|
import { UserAndRole } from '../../companyView/types/userAndRole';
|
|
@@ -14,7 +14,6 @@ export interface TaskDetailSelectorView extends SelectorView {
|
|
|
14
14
|
deleteFileStatusById: Record<ID, FetchStateAndError | undefined>;
|
|
15
15
|
files: File[];
|
|
16
16
|
showTaskDetailFormFooter: boolean;
|
|
17
|
-
subtasks: Task[];
|
|
18
17
|
taskDetailView: EditTaskDetail;
|
|
19
18
|
taskHistory: HistoricEvent[];
|
|
20
19
|
updateFileStatusById: Record<ID, FetchStateAndError | undefined>;
|
|
@@ -33,13 +33,8 @@ const getTaskDetail = (state, taskId) => {
|
|
|
33
33
|
let recurringSourceTaskId = undefined;
|
|
34
34
|
let snoozedUntil = undefined;
|
|
35
35
|
let taskGroupId = undefined;
|
|
36
|
-
let subtasks = [];
|
|
37
36
|
if (taskId != null && sourceTaskDetail != null) {
|
|
38
37
|
const taskEntity = (0, taskSelector_1.getTaskById)(taskState, taskId);
|
|
39
|
-
subtasks =
|
|
40
|
-
taskEntity != null
|
|
41
|
-
? (0, taskSelector_1.getTasksByIds)(taskState, taskEntity.subTasksIds)
|
|
42
|
-
: [];
|
|
43
38
|
const fileIdsInEntity = taskEntity?.fileIds ?? [];
|
|
44
39
|
if (taskEntity != null) {
|
|
45
40
|
createdByUser = (0, userAndRole_1.getUserAndUserRole)(userState, userRoleState, addressState, taskEntity.createdBy);
|
|
@@ -49,37 +44,26 @@ const getTaskDetail = (state, taskId) => {
|
|
|
49
44
|
snoozedUntil = taskEntity.snoozedUntil;
|
|
50
45
|
taskGroupId = taskEntity.taskGroupIds[0];
|
|
51
46
|
}
|
|
52
|
-
// Treat "no entry" as Completed so it doesn't block the combined
|
|
53
|
-
// fetch state. The Not-Started default would pin the detail page
|
|
54
|
-
// below Completed forever before the first fetchSubTasks dispatches.
|
|
55
|
-
const completedSubTaskStatus = {
|
|
56
|
-
fetchState: 'Completed',
|
|
57
|
-
error: undefined,
|
|
58
|
-
};
|
|
59
|
-
const subTaskStatus = taskDetailState.subTaskListFetchStatusByParentId[taskId] ??
|
|
60
|
-
completedSubTaskStatus;
|
|
61
47
|
if (fileIdsInEntity.length > 0) {
|
|
62
|
-
fetchStatus = (0, reduceFetchState_1.
|
|
48
|
+
fetchStatus = (0, reduceFetchState_1.reduceFetchState)([
|
|
63
49
|
fileViewState.fetchFilesStatus,
|
|
64
50
|
sourceTaskDetail.fetchTaskStatus,
|
|
65
51
|
userList,
|
|
66
52
|
classListState,
|
|
67
|
-
subTaskStatus,
|
|
68
53
|
]);
|
|
69
54
|
}
|
|
70
55
|
else {
|
|
71
|
-
fetchStatus = (0, reduceFetchState_1.
|
|
56
|
+
fetchStatus = (0, reduceFetchState_1.reduceFetchState)([
|
|
72
57
|
sourceTaskDetail.fetchTaskStatus,
|
|
73
58
|
userList,
|
|
74
59
|
classListState,
|
|
75
|
-
subTaskStatus,
|
|
76
60
|
]);
|
|
77
61
|
}
|
|
78
62
|
showTaskDetailFormFooter = showFormFooter(sourceTaskDetail.taskDetailLocalData, taskEntity);
|
|
79
63
|
taskHistory = taskDetailState.taskHistoryById[taskId]?.historicEvents ?? [];
|
|
80
64
|
}
|
|
81
65
|
else if (taskId == null) {
|
|
82
|
-
fetchStatus = (0, reduceFetchState_1.
|
|
66
|
+
fetchStatus = (0, reduceFetchState_1.reduceFetchState)([userList, classListState]);
|
|
83
67
|
}
|
|
84
68
|
const { classIds } = classListState;
|
|
85
69
|
const allAccountingClasses = (0, classSelector_1.getClassesByIds)(classState, {
|
|
@@ -112,7 +96,6 @@ const getTaskDetail = (state, taskId) => {
|
|
|
112
96
|
showTaskDetailFormFooter,
|
|
113
97
|
snoozedUntil,
|
|
114
98
|
taskGroupId,
|
|
115
|
-
subtasks,
|
|
116
99
|
};
|
|
117
100
|
};
|
|
118
101
|
exports.getTaskDetail = getTaskDetail;
|
|
@@ -161,16 +144,13 @@ exports.allTaskPriority = [
|
|
|
161
144
|
},
|
|
162
145
|
];
|
|
163
146
|
const showFormFooter = (taskDetailLocalData, taskDetailInStore) => {
|
|
164
|
-
if (
|
|
165
|
-
return false;
|
|
166
|
-
}
|
|
167
|
-
if (taskDetailLocalData.name !== taskDetailInStore.name ||
|
|
147
|
+
if (taskDetailLocalData.name !== taskDetailInStore?.name ||
|
|
168
148
|
taskDetailLocalData.description !== taskDetailInStore.description ||
|
|
169
149
|
taskDetailLocalData.priority !== taskDetailInStore.priority.code ||
|
|
170
150
|
taskDetailLocalData.status !== taskDetailInStore.status.code ||
|
|
171
151
|
!(0, isEqual_1.default)(taskDetailInStore.tagIds, taskDetailLocalData.tagIds) ||
|
|
172
|
-
!(0, isEqual_1.default)(taskDetailLocalData.assignee, taskDetailInStore
|
|
173
|
-
!(0, isEqual_1.default)(taskDetailLocalData.groupAssignees, taskDetailInStore
|
|
152
|
+
!(0, isEqual_1.default)(taskDetailLocalData.assignee, taskDetailInStore?.assignees ?? []) ||
|
|
153
|
+
!(0, isEqual_1.default)(taskDetailLocalData.groupAssignees, taskDetailInStore?.groupAssignees ?? []) ||
|
|
174
154
|
!(0, isEqual_1.default)(taskDetailLocalData.fileIds, taskDetailInStore.fileIds ?? []) ||
|
|
175
155
|
!(0, isEqual_1.default)(taskDetailLocalData.dueDate, taskDetailInStore.dueDate) ||
|
|
176
156
|
!(0, isEqual_1.default)(taskDetailLocalData.type, taskDetailInStore.type) ||
|
|
@@ -178,10 +158,7 @@ const showFormFooter = (taskDetailLocalData, taskDetailInStore) => {
|
|
|
178
158
|
!(0, isEqual_1.default)(taskDetailLocalData.recurringFrequency, taskDetailInStore.recurringFrequency) ||
|
|
179
159
|
!(0, isEqual_1.default)(taskDetailLocalData.recurringDaysOfWeek, taskDetailInStore.recurringDaysOfWeek) ||
|
|
180
160
|
!(0, isEqual_1.default)(taskDetailLocalData.recurringStartDate, taskDetailInStore.recurringStartDate) ||
|
|
181
|
-
!(0, isEqual_1.default)(taskDetailLocalData.timeSpent, taskDetailInStore.timeSpent)
|
|
182
|
-
!(0, isEqual_1.default)(taskDetailLocalData.taskGroupId, taskDetailInStore.taskGroupIds.length > 0
|
|
183
|
-
? taskDetailInStore.taskGroupIds[0]
|
|
184
|
-
: undefined)) {
|
|
161
|
+
!(0, isEqual_1.default)(taskDetailLocalData.timeSpent, taskDetailInStore.timeSpent)) {
|
|
185
162
|
return true;
|
|
186
163
|
}
|
|
187
164
|
return false;
|
|
@@ -12,17 +12,15 @@ const fetchTaskListEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, oper
|
|
|
12
12
|
.getJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/tasks?query=${encodeURIComponent(`{"task_type": "all"}`)}`)
|
|
13
13
|
.pipe((0, operators_1.mergeMap)((response) => {
|
|
14
14
|
if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
|
|
15
|
-
const { tasks, deleted, archived, snoozed
|
|
15
|
+
const { tasks, deleted, archived, snoozed } = response.data;
|
|
16
16
|
const allTasks = [
|
|
17
17
|
...tasks,
|
|
18
|
-
...(completed ?? []),
|
|
19
18
|
...(deleted ?? []),
|
|
20
19
|
...(archived ?? []),
|
|
21
20
|
...(snoozed ?? []),
|
|
22
21
|
];
|
|
23
22
|
return (0, rxjs_1.of)((0, taskReducer_1.updateTasks)(allTasks), (0, taskListReducer_1.updateTaskList)({
|
|
24
23
|
data: tasks,
|
|
25
|
-
completed: completed ?? [],
|
|
26
24
|
deleted: deleted ?? [],
|
|
27
25
|
archived: archived ?? [],
|
|
28
26
|
snoozed: snoozed ?? [],
|
|
@@ -3,7 +3,7 @@ import { PriorityCodeType, TaskStatusCodeType } from '../../../entity/task/taskS
|
|
|
3
3
|
import { ZeniDate } from '../../../zeniDayJS';
|
|
4
4
|
import { SpendManagementUIState } from '../../spendManagement/billPay/billList/billListState';
|
|
5
5
|
import { CategoryCombinationOperator, FilterCategoryType } from '../../spendManagement/spendManagementFilterHelpers';
|
|
6
|
-
export declare const ALL_TASK_LIST_TABS: readonly ["live", "
|
|
6
|
+
export declare const ALL_TASK_LIST_TABS: readonly ["live", "archived", "deleted", "snoozed"];
|
|
7
7
|
export type TaskListTab = (typeof ALL_TASK_LIST_TABS)[number];
|
|
8
8
|
export interface TaskListTabData {
|
|
9
9
|
taskIds: ID[];
|
|
@@ -3,10 +3,6 @@ import { ZeniAPIResponse } from '../../../responsePayload';
|
|
|
3
3
|
interface FetchTaskListPayload {
|
|
4
4
|
tasks: TaskPayload[];
|
|
5
5
|
archived?: TaskPayload[];
|
|
6
|
-
/** Tasks whose status is "done" or "resolved". Returned as a separate
|
|
7
|
-
* bucket so the "Completed" tab can show them without duplicating
|
|
8
|
-
* them under Active. */
|
|
9
|
-
completed?: TaskPayload[];
|
|
10
6
|
deleted?: TaskPayload[];
|
|
11
7
|
snoozed?: TaskPayload[];
|
|
12
8
|
}
|
|
@@ -12,10 +12,9 @@ export declare const fetchTaskListPage: import("@reduxjs/toolkit").ActionCreator
|
|
|
12
12
|
}, "taskList/fetchTaskListPage", never, never>, fetchTaskList: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"taskList/fetchTaskList">, updateTaskList: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
13
13
|
data: TaskPayload[];
|
|
14
14
|
archived?: TaskPayload[];
|
|
15
|
-
completed?: TaskPayload[];
|
|
16
15
|
deleted?: TaskPayload[];
|
|
17
16
|
snoozed?: TaskPayload[];
|
|
18
|
-
}, "taskList/updateTaskList">, updateTaskListTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<"
|
|
17
|
+
}, "taskList/updateTaskList">, updateTaskListTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<"deleted" | "archived" | "live" | "snoozed", "taskList/updateTaskListTab">, updateTaskListFetchStatus: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
19
18
|
fetchState: FetchState;
|
|
20
19
|
error?: ZeniAPIStatus;
|
|
21
20
|
}, "taskList/updateTaskListFetchStatus">, updateTaskListSearchText: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
@@ -59,9 +58,6 @@ export declare const fetchTaskListPage: import("@reduxjs/toolkit").ActionCreator
|
|
|
59
58
|
error: ZeniAPIStatus;
|
|
60
59
|
}, "taskList/updateTasksListOnUpdateTaskFailure">, updateTaskListOnCreateTaskFromTemplateSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
61
60
|
tasks: TaskPayload[];
|
|
62
|
-
}, "taskList/updateTaskListOnCreateTaskFromTemplateSuccess">, removeTaskFromList: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "taskList/removeTaskFromList">,
|
|
63
|
-
taskGroupId: ID;
|
|
64
|
-
taskId: ID;
|
|
65
|
-
}, "taskList/removeTaskFromGroupBucket">, clearTaskList: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"taskList/clearTaskList">;
|
|
61
|
+
}, "taskList/updateTaskListOnCreateTaskFromTemplateSuccess">, removeTaskFromList: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "taskList/removeTaskFromList">, clearTaskList: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"taskList/clearTaskList">;
|
|
66
62
|
declare const _default: import("redux").Reducer<TaskListState>;
|
|
67
63
|
export default _default;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.clearTaskList = exports.
|
|
4
|
+
exports.clearTaskList = exports.removeTaskFromList = exports.updateTaskListOnCreateTaskFromTemplateSuccess = exports.updateTasksListOnUpdateTaskFailure = exports.updateTasksListOnUpdateTaskSuccess = exports.updateTaskFromListView = exports.updateTaskListOnTaskGroupNameUpdate = exports.updateTaskListOnNewTaskCreationSuccess = exports.dragNDropTasks = exports.updateTaskListOnTaskGroupDeletion = exports.updateTaskListLocalData = exports.initiateTaskListLocalData = exports.updateTasksListOnBulkUpdateTasksFailure = exports.updateTasksListOnBulkUpdateTasksSuccess = exports.bulkUpdateTaskList = exports.updateTaskListOnNewGroupCreationSuccess = exports.updateTaskFilters = exports.updateTaskListUIState = exports.updateTaskListSearchText = exports.updateTaskListFetchStatus = exports.updateTaskListTab = exports.updateTaskList = exports.fetchTaskList = exports.fetchTaskListPage = exports.initialState = void 0;
|
|
5
5
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
|
-
const taskReducer_1 = require("../../../entity/task/taskReducer");
|
|
7
6
|
const taskState_1 = require("../../../entity/task/taskState");
|
|
8
7
|
const zeniDayJS_1 = require("../../../zeniDayJS");
|
|
9
8
|
const taskList_1 = require("./taskList");
|
|
@@ -47,7 +46,6 @@ exports.initialState = {
|
|
|
47
46
|
currentTab: 'live',
|
|
48
47
|
byTab: {
|
|
49
48
|
live: { ...initialTabData },
|
|
50
|
-
completed: { ...initialTabData },
|
|
51
49
|
archived: { ...initialTabData },
|
|
52
50
|
deleted: { ...initialTabData },
|
|
53
51
|
snoozed: { ...initialTabData },
|
|
@@ -69,12 +67,14 @@ exports.initialState = {
|
|
|
69
67
|
},
|
|
70
68
|
filters: {
|
|
71
69
|
categoryCombinationOperator: 'AND',
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
categories: [
|
|
71
|
+
{
|
|
72
|
+
field: 'status',
|
|
73
|
+
matchingOperator: 'not_equal',
|
|
74
|
+
values: ['resolved'],
|
|
75
|
+
valuesCombinationOperator: 'ANY',
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
78
|
},
|
|
79
79
|
hasValidState() {
|
|
80
80
|
return this.fetchState == 'Completed';
|
|
@@ -106,16 +106,13 @@ const taskList = (0, toolkit_1.createSlice)({
|
|
|
106
106
|
draft.error = undefined;
|
|
107
107
|
},
|
|
108
108
|
updateTaskList(draft, action) {
|
|
109
|
-
const { data, archived,
|
|
109
|
+
const { data, archived, deleted, snoozed } = action.payload;
|
|
110
110
|
draft.fetchState = 'Completed';
|
|
111
111
|
draft.error = undefined;
|
|
112
112
|
// Group live tasks
|
|
113
113
|
const liveGrouped = getGroupedTaskIds(data);
|
|
114
114
|
draft.byTab.live = toTabData(liveGrouped);
|
|
115
115
|
// Group other tabs if provided
|
|
116
|
-
if (completed != null) {
|
|
117
|
-
draft.byTab.completed = toTabData(getGroupedTaskIds(completed));
|
|
118
|
-
}
|
|
119
116
|
if (archived != null) {
|
|
120
117
|
draft.byTab.archived = toTabData(getGroupedTaskIds(archived));
|
|
121
118
|
}
|
|
@@ -361,26 +358,9 @@ const taskList = (0, toolkit_1.createSlice)({
|
|
|
361
358
|
draft.taskIdsByAssignees[assigneeKey] = draft.taskIdsByAssignees[assigneeKey].filter((taskId) => taskId !== currentTaskState.id);
|
|
362
359
|
draft.taskIdsByTags[tagsKey] = draft.taskIdsByTags[tagsKey].filter((taskId) => taskId !== currentTaskState.id);
|
|
363
360
|
draft.taskIdsByDueDate[dueDateKey] = draft.taskIdsByDueDate[dueDateKey].filter((taskId) => taskId !== currentTaskState.id);
|
|
364
|
-
|
|
365
|
-
// just the destination bucket. Otherwise a detail-page save that
|
|
366
|
-
// moves a task from group A to group B leaves the row listed
|
|
367
|
-
// under both A and B until refetch.
|
|
368
|
-
const previousGroupIds = currentTaskState.taskGroupIds ?? [];
|
|
369
|
-
const allGroupIdsToClean = new Set([
|
|
370
|
-
...previousGroupIds,
|
|
371
|
-
taskGroupId,
|
|
372
|
-
]);
|
|
373
|
-
allGroupIdsToClean.forEach((gid) => {
|
|
374
|
-
if (draft.taskIdsByGroupsIds[gid] != null) {
|
|
375
|
-
draft.taskIdsByGroupsIds[gid] = draft.taskIdsByGroupsIds[gid].filter((id) => id !== currentTaskState.id);
|
|
376
|
-
}
|
|
377
|
-
});
|
|
361
|
+
draft.taskIdsByGroupsIds[taskGroupId] = draft.taskIdsByGroupsIds[taskGroupId].filter((taskId) => taskId !== currentTaskState.id);
|
|
378
362
|
}
|
|
379
363
|
doUpdateTaskList(draft, task, taskGroupId);
|
|
380
|
-
// Mirror top-level grouping into the active tab's byTab snapshot,
|
|
381
|
-
// otherwise the next updateTaskListTab call copies stale byTab data
|
|
382
|
-
// back over this optimistic update.
|
|
383
|
-
syncTopLevelToActiveTab(draft);
|
|
384
364
|
},
|
|
385
365
|
updateTaskListOnCreateTaskFromTemplateSuccess(draft, action) {
|
|
386
366
|
const { tasks } = action.payload;
|
|
@@ -404,7 +384,6 @@ const taskList = (0, toolkit_1.createSlice)({
|
|
|
404
384
|
const taskId = task.id;
|
|
405
385
|
draft.updateTasksFetchState.fetchState = 'In-Progress';
|
|
406
386
|
draft.updateTasksFetchState.error = undefined;
|
|
407
|
-
let didMigrateTab = false;
|
|
408
387
|
if (updates.priority != null) {
|
|
409
388
|
const prevPriorityCode = (0, taskState_1.toPriorityCodeType)(task.priority.code);
|
|
410
389
|
draft.taskIdsByPriority[prevPriorityCode] = draft.taskIdsByPriority[prevPriorityCode].filter((id) => id != taskId);
|
|
@@ -416,25 +395,6 @@ const taskList = (0, toolkit_1.createSlice)({
|
|
|
416
395
|
draft.taskIdsByStatus[prevStatusCode] = draft.taskIdsByStatus[prevStatusCode].filter((id) => id != taskId);
|
|
417
396
|
const newStatusCode = (0, taskState_1.toTaskStatusCodeType)(updates.status.code);
|
|
418
397
|
draft.taskIdsByStatus[newStatusCode].push(taskId);
|
|
419
|
-
// Optimistically re-bucket between the live and completed tabs
|
|
420
|
-
// when status transitions in/out of "resolved", so the task
|
|
421
|
-
// moves to the Completed tab without waiting for the next
|
|
422
|
-
// fetch. Mirrors backend split in task_handler.py: only
|
|
423
|
-
// `resolved` counts as completed; `done` stays Active.
|
|
424
|
-
//
|
|
425
|
-
// Subtasks travel with their parent — they appear nested under
|
|
426
|
-
// the parent row, not as standalone entries in byTab.taskIds.
|
|
427
|
-
// So we only rebucket parent tasks (tasks with no parentTaskId).
|
|
428
|
-
const isTopLevelTask = task.parentTaskId == null;
|
|
429
|
-
const wasCompleted = prevStatusCode === 'resolved';
|
|
430
|
-
const isCompleted = newStatusCode === 'resolved';
|
|
431
|
-
if (isTopLevelTask && wasCompleted !== isCompleted) {
|
|
432
|
-
const from = isCompleted ? 'live' : 'completed';
|
|
433
|
-
const to = isCompleted ? 'completed' : 'live';
|
|
434
|
-
const updatedTask = { ...task, ...updates };
|
|
435
|
-
migrateTaskBetweenTabs(draft, taskId, updatedTask, from, to);
|
|
436
|
-
didMigrateTab = true;
|
|
437
|
-
}
|
|
438
398
|
}
|
|
439
399
|
if (updates.assignees != null) {
|
|
440
400
|
const prevGroupId = getAssigneesGroupKey(task.assignees);
|
|
@@ -474,18 +434,7 @@ const taskList = (0, toolkit_1.createSlice)({
|
|
|
474
434
|
};
|
|
475
435
|
}
|
|
476
436
|
}
|
|
477
|
-
|
|
478
|
-
// The migration moved the task out of the source byTab and into
|
|
479
|
-
// the destination byTab. The active tab's grouping arrays are
|
|
480
|
-
// now authoritative — mirror them back to the top-level so the
|
|
481
|
-
// UI sees the task gone from Live (or freshly arrived in
|
|
482
|
-
// Completed). Inverse of syncTopLevelToActiveTab, used only on
|
|
483
|
-
// this path.
|
|
484
|
-
copyTabDataToTopLevel(draft, draft.byTab[draft.currentTab]);
|
|
485
|
-
}
|
|
486
|
-
else {
|
|
487
|
-
syncTopLevelToActiveTab(draft);
|
|
488
|
-
}
|
|
437
|
+
syncTopLevelToActiveTab(draft);
|
|
489
438
|
},
|
|
490
439
|
updateTasksListOnUpdateTaskSuccess(draft) {
|
|
491
440
|
draft.updateTasksFetchState.fetchState = 'Completed';
|
|
@@ -498,80 +447,12 @@ const taskList = (0, toolkit_1.createSlice)({
|
|
|
498
447
|
removeTaskFromList(draft, action) {
|
|
499
448
|
removeTaskIds(draft, [action.payload]);
|
|
500
449
|
},
|
|
501
|
-
/**
|
|
502
|
-
* Remove a task id from a single group bucket without touching tab
|
|
503
|
-
* membership or other groupings. Used when the user clears a task's
|
|
504
|
-
* group on the Detail page so the row stops appearing under the old
|
|
505
|
-
* group while saveTaskDetailEpic skips the standard list re-insert.
|
|
506
|
-
*/
|
|
507
|
-
removeTaskFromGroupBucket(draft, action) {
|
|
508
|
-
const { taskId, taskGroupId } = action.payload;
|
|
509
|
-
if (draft.taskIdsByGroupsIds[taskGroupId] != null) {
|
|
510
|
-
draft.taskIdsByGroupsIds[taskGroupId] = draft.taskIdsByGroupsIds[taskGroupId].filter((id) => id !== taskId);
|
|
511
|
-
}
|
|
512
|
-
// Mirror to the active tab's grouping so the UI re-renders.
|
|
513
|
-
const activeTab = draft.byTab[draft.currentTab];
|
|
514
|
-
if (activeTab.taskIdsByGroupsIds[taskGroupId] != null) {
|
|
515
|
-
activeTab.taskIdsByGroupsIds[taskGroupId] =
|
|
516
|
-
activeTab.taskIdsByGroupsIds[taskGroupId].filter((id) => id !== taskId);
|
|
517
|
-
}
|
|
518
|
-
},
|
|
519
450
|
clearTaskList(draft) {
|
|
520
451
|
Object.assign(draft, exports.initialState);
|
|
521
452
|
},
|
|
522
453
|
},
|
|
523
|
-
extraReducers: (builder) => {
|
|
524
|
-
// When the entity store receives updated tasks (e.g. from task detail
|
|
525
|
-
// save, snooze/archive/unarchive, etc.), re-bucket parent tasks between
|
|
526
|
-
// the live and completed tabs based on the new status. Mirrors the
|
|
527
|
-
// backend split in task_handler.py: only `resolved` parents count as
|
|
528
|
-
// completed. Subtasks are nested under their parent row, so they
|
|
529
|
-
// never move between tabs on their own.
|
|
530
|
-
builder.addCase(taskReducer_1.updateTasks, (draft, action) => {
|
|
531
|
-
action.payload.forEach((taskPayload) => {
|
|
532
|
-
// Only re-bucket parents; subtasks (parent_task_id is a non-empty
|
|
533
|
-
// string) are nested under their parent row and don't move tabs.
|
|
534
|
-
if (taskPayload.parent_task_id != null &&
|
|
535
|
-
taskPayload.parent_task_id !== '') {
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
const taskId = taskPayload.task_id;
|
|
539
|
-
// `TaskPayload.status` is required per the type — every producer
|
|
540
|
-
// in this repo sends it, and `mapTaskPayloadToTask` dereferences
|
|
541
|
-
// it unguarded. The optional chain + null guard are defensive
|
|
542
|
-
// only, in case a downstream consumer (web-app-ui / cockpit-ui)
|
|
543
|
-
// ever dispatches `updateTasks` with a partial payload; in that
|
|
544
|
-
// case we treat missing status as "no status change" and skip
|
|
545
|
-
// re-bucketing so we don't migrate a Completed task back into
|
|
546
|
-
// the Live tab.
|
|
547
|
-
const statusCode = taskPayload.status?.code;
|
|
548
|
-
if (statusCode == null) {
|
|
549
|
-
return;
|
|
550
|
-
}
|
|
551
|
-
const isCompleted = statusCode === 'resolved';
|
|
552
|
-
const targetTab = isCompleted ? 'completed' : 'live';
|
|
553
|
-
const otherTab = isCompleted ? 'live' : 'completed';
|
|
554
|
-
// Skip if the task isn't currently in either of these buckets
|
|
555
|
-
// (archived/snoozed/deleted are managed by their own actions).
|
|
556
|
-
const inLive = draft.byTab.live.taskIds.includes(taskId);
|
|
557
|
-
const inCompleted = draft.byTab.completed.taskIds.includes(taskId);
|
|
558
|
-
if (!inLive && !inCompleted) {
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
if (draft.byTab[otherTab].taskIds.includes(taskId)) {
|
|
562
|
-
migrateTaskPayloadBetweenTabs(draft, taskId, taskPayload, otherTab, targetTab);
|
|
563
|
-
}
|
|
564
|
-
else if (!draft.byTab[targetTab].taskIds.includes(taskId)) {
|
|
565
|
-
draft.byTab[targetTab].taskIds.push(taskId);
|
|
566
|
-
}
|
|
567
|
-
});
|
|
568
|
-
// Re-sync the top-level taskIds / grouping arrays for whichever
|
|
569
|
-
// tab the user is currently looking at.
|
|
570
|
-
copyTabDataToTopLevel(draft, draft.byTab[draft.currentTab]);
|
|
571
|
-
});
|
|
572
|
-
},
|
|
573
454
|
});
|
|
574
|
-
_a = taskList.actions, exports.fetchTaskListPage = _a.fetchTaskListPage, exports.fetchTaskList = _a.fetchTaskList, exports.updateTaskList = _a.updateTaskList, exports.updateTaskListTab = _a.updateTaskListTab, exports.updateTaskListFetchStatus = _a.updateTaskListFetchStatus, exports.updateTaskListSearchText = _a.updateTaskListSearchText, exports.updateTaskListUIState = _a.updateTaskListUIState, exports.updateTaskFilters = _a.updateTaskFilters, exports.updateTaskListOnNewGroupCreationSuccess = _a.updateTaskListOnNewGroupCreationSuccess, exports.bulkUpdateTaskList = _a.bulkUpdateTaskList, exports.updateTasksListOnBulkUpdateTasksSuccess = _a.updateTasksListOnBulkUpdateTasksSuccess, exports.updateTasksListOnBulkUpdateTasksFailure = _a.updateTasksListOnBulkUpdateTasksFailure, exports.initiateTaskListLocalData = _a.initiateTaskListLocalData, exports.updateTaskListLocalData = _a.updateTaskListLocalData, exports.updateTaskListOnTaskGroupDeletion = _a.updateTaskListOnTaskGroupDeletion, exports.dragNDropTasks = _a.dragNDropTasks, exports.updateTaskListOnNewTaskCreationSuccess = _a.updateTaskListOnNewTaskCreationSuccess, exports.updateTaskListOnTaskGroupNameUpdate = _a.updateTaskListOnTaskGroupNameUpdate, exports.updateTaskFromListView = _a.updateTaskFromListView, exports.updateTasksListOnUpdateTaskSuccess = _a.updateTasksListOnUpdateTaskSuccess, exports.updateTasksListOnUpdateTaskFailure = _a.updateTasksListOnUpdateTaskFailure, exports.updateTaskListOnCreateTaskFromTemplateSuccess = _a.updateTaskListOnCreateTaskFromTemplateSuccess, exports.removeTaskFromList = _a.removeTaskFromList, exports.
|
|
455
|
+
_a = taskList.actions, exports.fetchTaskListPage = _a.fetchTaskListPage, exports.fetchTaskList = _a.fetchTaskList, exports.updateTaskList = _a.updateTaskList, exports.updateTaskListTab = _a.updateTaskListTab, exports.updateTaskListFetchStatus = _a.updateTaskListFetchStatus, exports.updateTaskListSearchText = _a.updateTaskListSearchText, exports.updateTaskListUIState = _a.updateTaskListUIState, exports.updateTaskFilters = _a.updateTaskFilters, exports.updateTaskListOnNewGroupCreationSuccess = _a.updateTaskListOnNewGroupCreationSuccess, exports.bulkUpdateTaskList = _a.bulkUpdateTaskList, exports.updateTasksListOnBulkUpdateTasksSuccess = _a.updateTasksListOnBulkUpdateTasksSuccess, exports.updateTasksListOnBulkUpdateTasksFailure = _a.updateTasksListOnBulkUpdateTasksFailure, exports.initiateTaskListLocalData = _a.initiateTaskListLocalData, exports.updateTaskListLocalData = _a.updateTaskListLocalData, exports.updateTaskListOnTaskGroupDeletion = _a.updateTaskListOnTaskGroupDeletion, exports.dragNDropTasks = _a.dragNDropTasks, exports.updateTaskListOnNewTaskCreationSuccess = _a.updateTaskListOnNewTaskCreationSuccess, exports.updateTaskListOnTaskGroupNameUpdate = _a.updateTaskListOnTaskGroupNameUpdate, exports.updateTaskFromListView = _a.updateTaskFromListView, exports.updateTasksListOnUpdateTaskSuccess = _a.updateTasksListOnUpdateTaskSuccess, exports.updateTasksListOnUpdateTaskFailure = _a.updateTasksListOnUpdateTaskFailure, exports.updateTaskListOnCreateTaskFromTemplateSuccess = _a.updateTaskListOnCreateTaskFromTemplateSuccess, exports.removeTaskFromList = _a.removeTaskFromList, exports.clearTaskList = _a.clearTaskList;
|
|
575
456
|
exports.default = taskList.reducer;
|
|
576
457
|
/**
|
|
577
458
|
* helpers
|
|
@@ -678,115 +559,6 @@ const copyTabDataToTopLevel = (draft, tabData) => {
|
|
|
678
559
|
draft.taskIdsByDueDate = tabData.taskIdsByDueDate;
|
|
679
560
|
draft.taskIdsByTags = tabData.taskIdsByTags;
|
|
680
561
|
};
|
|
681
|
-
/**
|
|
682
|
-
* Migrate a parent task between two `byTab` buckets (live ↔ completed)
|
|
683
|
-
* when its status flips into / out of `resolved`. The destination tab
|
|
684
|
-
* picks up the task in EVERY grouping dimension (status, priority,
|
|
685
|
-
* group id, assignees, dueDate, tags) using the UPDATED task as the
|
|
686
|
-
* source-of-truth for the new bucket keys. Otherwise the Completed tab
|
|
687
|
-
* shows the task in the right tab-level list but the grouped views
|
|
688
|
-
* (Group by Status, Group by Priority, etc.) miss it until the next
|
|
689
|
-
* full fetch.
|
|
690
|
-
*/
|
|
691
|
-
const migrateTaskBetweenTabs = (draft, taskId, updatedTask, from, to) => {
|
|
692
|
-
const fromTab = draft.byTab[from];
|
|
693
|
-
const toTab = draft.byTab[to];
|
|
694
|
-
// Source tab: drop the task from every grouping dimension.
|
|
695
|
-
removeIdsFromTabData(fromTab, [taskId]);
|
|
696
|
-
// Destination tab: add the task to taskIds (deduped) plus the
|
|
697
|
-
// appropriate bucket inside each grouping dimension based on the
|
|
698
|
-
// updated task.
|
|
699
|
-
if (!toTab.taskIds.includes(taskId)) {
|
|
700
|
-
toTab.taskIds.push(taskId);
|
|
701
|
-
}
|
|
702
|
-
const priorityKey = (0, taskState_1.toPriorityCodeType)(updatedTask.priority.code);
|
|
703
|
-
if (!toTab.taskIdsByPriority[priorityKey].includes(taskId)) {
|
|
704
|
-
toTab.taskIdsByPriority[priorityKey].push(taskId);
|
|
705
|
-
}
|
|
706
|
-
const statusKey = (0, taskState_1.toTaskStatusCodeType)(updatedTask.status.code);
|
|
707
|
-
if (!toTab.taskIdsByStatus[statusKey].includes(taskId)) {
|
|
708
|
-
toTab.taskIdsByStatus[statusKey].push(taskId);
|
|
709
|
-
}
|
|
710
|
-
const dueDateKey = updatedTask.dueDate != null
|
|
711
|
-
? getDueDateGroupKey(updatedTask.dueDate.toString())
|
|
712
|
-
: 'upcoming';
|
|
713
|
-
if (!toTab.taskIdsByDueDate[dueDateKey].includes(taskId)) {
|
|
714
|
-
toTab.taskIdsByDueDate[dueDateKey].push(taskId);
|
|
715
|
-
}
|
|
716
|
-
const assigneeKey = getAssigneesGroupKey(updatedTask.assignees);
|
|
717
|
-
if (toTab.taskIdsByAssignees[assigneeKey] == null) {
|
|
718
|
-
toTab.taskIdsByAssignees[assigneeKey] = [taskId];
|
|
719
|
-
}
|
|
720
|
-
else if (!toTab.taskIdsByAssignees[assigneeKey].includes(taskId)) {
|
|
721
|
-
toTab.taskIdsByAssignees[assigneeKey].push(taskId);
|
|
722
|
-
}
|
|
723
|
-
const tagIds = [...updatedTask.tagIds].sort();
|
|
724
|
-
const tagsKey = tagIds.join(',');
|
|
725
|
-
if (toTab.taskIdsByTags[tagsKey] == null) {
|
|
726
|
-
toTab.taskIdsByTags[tagsKey] = [taskId];
|
|
727
|
-
}
|
|
728
|
-
else if (!toTab.taskIdsByTags[tagsKey].includes(taskId)) {
|
|
729
|
-
toTab.taskIdsByTags[tagsKey].push(taskId);
|
|
730
|
-
}
|
|
731
|
-
(updatedTask.taskGroupIds ?? []).forEach((groupId) => {
|
|
732
|
-
if (toTab.taskIdsByGroupsIds[groupId] == null) {
|
|
733
|
-
toTab.taskIdsByGroupsIds[groupId] = [taskId];
|
|
734
|
-
}
|
|
735
|
-
else if (!toTab.taskIdsByGroupsIds[groupId].includes(taskId)) {
|
|
736
|
-
toTab.taskIdsByGroupsIds[groupId].push(taskId);
|
|
737
|
-
}
|
|
738
|
-
});
|
|
739
|
-
};
|
|
740
|
-
/**
|
|
741
|
-
* `updateTasks` extraReducer variant — same migration semantics but
|
|
742
|
-
* keyed off the raw `TaskPayload` instead of the rich `Task` entity.
|
|
743
|
-
*/
|
|
744
|
-
const migrateTaskPayloadBetweenTabs = (draft, taskId, payload, from, to) => {
|
|
745
|
-
const fromTab = draft.byTab[from];
|
|
746
|
-
const toTab = draft.byTab[to];
|
|
747
|
-
removeIdsFromTabData(fromTab, [taskId]);
|
|
748
|
-
if (!toTab.taskIds.includes(taskId)) {
|
|
749
|
-
toTab.taskIds.push(taskId);
|
|
750
|
-
}
|
|
751
|
-
if (payload.priority?.code != null) {
|
|
752
|
-
const priorityKey = (0, taskState_1.toPriorityCodeType)(payload.priority.code);
|
|
753
|
-
if (!toTab.taskIdsByPriority[priorityKey].includes(taskId)) {
|
|
754
|
-
toTab.taskIdsByPriority[priorityKey].push(taskId);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
if (payload.status?.code != null) {
|
|
758
|
-
const statusKey = (0, taskState_1.toTaskStatusCodeType)(payload.status.code);
|
|
759
|
-
if (!toTab.taskIdsByStatus[statusKey].includes(taskId)) {
|
|
760
|
-
toTab.taskIdsByStatus[statusKey].push(taskId);
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
const dueDateKey = getDueDateGroupKey(payload.due_date);
|
|
764
|
-
if (!toTab.taskIdsByDueDate[dueDateKey].includes(taskId)) {
|
|
765
|
-
toTab.taskIdsByDueDate[dueDateKey].push(taskId);
|
|
766
|
-
}
|
|
767
|
-
const assigneeKey = getAssigneesGroupKey(payload.assignees ?? []);
|
|
768
|
-
if (toTab.taskIdsByAssignees[assigneeKey] == null) {
|
|
769
|
-
toTab.taskIdsByAssignees[assigneeKey] = [taskId];
|
|
770
|
-
}
|
|
771
|
-
else if (!toTab.taskIdsByAssignees[assigneeKey].includes(taskId)) {
|
|
772
|
-
toTab.taskIdsByAssignees[assigneeKey].push(taskId);
|
|
773
|
-
}
|
|
774
|
-
const tagsKey = getTagsGroupKey(payload.tags ?? []);
|
|
775
|
-
if (toTab.taskIdsByTags[tagsKey] == null) {
|
|
776
|
-
toTab.taskIdsByTags[tagsKey] = [taskId];
|
|
777
|
-
}
|
|
778
|
-
else if (!toTab.taskIdsByTags[tagsKey].includes(taskId)) {
|
|
779
|
-
toTab.taskIdsByTags[tagsKey].push(taskId);
|
|
780
|
-
}
|
|
781
|
-
(payload.task_group_ids ?? []).forEach((groupId) => {
|
|
782
|
-
if (toTab.taskIdsByGroupsIds[groupId] == null) {
|
|
783
|
-
toTab.taskIdsByGroupsIds[groupId] = [taskId];
|
|
784
|
-
}
|
|
785
|
-
else if (!toTab.taskIdsByGroupsIds[groupId].includes(taskId)) {
|
|
786
|
-
toTab.taskIdsByGroupsIds[groupId].push(taskId);
|
|
787
|
-
}
|
|
788
|
-
});
|
|
789
|
-
};
|
|
790
562
|
const removeIdsFromTabData = (tabData, taskIds) => {
|
|
791
563
|
const removedSet = new Set(taskIds);
|
|
792
564
|
const isRemoved = (id) => removedSet.has(id);
|
|
@@ -342,7 +342,6 @@ exports.getAllTasks = (0, toolkit_1.createSelector)((state) => state.taskListSta
|
|
|
342
342
|
const taskGroupTemplates = (0, taskGroupTemplateSelector_1.getTaskGroupTemplateByIds)(taskGroupTemplateState, taskGroupTemplateViewState.taskGroupTemplateIds);
|
|
343
343
|
const tabCounts = {
|
|
344
344
|
live: taskListState.byTab.live.taskIds.length,
|
|
345
|
-
completed: taskListState.byTab.completed.taskIds.length,
|
|
346
345
|
archived: taskListState.byTab.archived.taskIds.length,
|
|
347
346
|
deleted: taskListState.byTab.deleted.taskIds.length,
|
|
348
347
|
snoozed: taskListState.byTab.snoozed.taskIds.length,
|