@zeniai/client-epic-state 5.1.41-beta0ND → 5.1.41-betaDI3
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/commonStateTypes/selectorTypes/pickAndMergeForecastCalculatedSection.d.ts +1 -1
- package/lib/entity/account/accountSelector.d.ts +6 -6
- package/lib/entity/account/pickAndMergeForecastAccountReport.d.ts +18 -18
- package/lib/entity/accountGroup/accountGroupSelector.d.ts +44 -44
- package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +1 -1
- package/lib/entity/task/taskPayload.d.ts +2 -1
- package/lib/entity/task/taskPayload.js +8 -1
- package/lib/entity/task/taskReducer.d.ts +8 -1
- package/lib/entity/task/taskReducer.js +29 -4
- package/lib/entity/task/taskState.d.ts +1 -0
- package/lib/entity/tenant/epic/saveExternalConnectionEpic.js +7 -15
- package/lib/entity/toastNotification/epic/pushToastNotificationEpic.d.ts +3 -3
- package/lib/epic.d.ts +5 -3
- package/lib/epic.js +5 -3
- package/lib/esm/entity/snackbar/snackbarTypes.js +1 -1
- package/lib/esm/entity/task/taskPayload.js +8 -1
- package/lib/esm/entity/task/taskReducer.js +28 -3
- package/lib/esm/entity/tenant/epic/saveExternalConnectionEpic.js +7 -15
- package/lib/esm/epic.js +5 -3
- package/lib/esm/index.js +711 -0
- package/lib/esm/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +3 -0
- package/lib/esm/view/companyTaskManagerView/epics/fetchTaskManagerMetricsEpic.js +7 -1
- package/lib/esm/view/taskManager/taskDetailView/epics/createSubTaskEpic.js +96 -0
- package/lib/esm/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.js +53 -0
- package/lib/esm/view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic.js +1 -0
- package/lib/esm/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +70 -9
- package/lib/esm/view/taskManager/taskDetailView/taskDetailReducer.js +56 -2
- package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +32 -9
- package/lib/esm/view/taskManager/taskListView/epics/fetchTaskListEpic.js +3 -1
- package/lib/esm/view/taskManager/taskListView/taskList.js +1 -0
- package/lib/esm/view/taskManager/taskListView/taskListReducer.js +240 -12
- package/lib/esm/view/taskManager/taskListView/taskListSelector.js +1 -0
- package/lib/esm/view/taskManager/taskListView/taskListViewHelpers.js +58 -0
- package/lib/index.d.ts +995 -0
- package/lib/index.js +2612 -0
- package/lib/view/addressView/epic/fetchAddressEpic.d.ts +1 -1
- package/lib/view/addressView/epic/updateAddressEpic.d.ts +1 -1
- package/lib/view/aiAccountantView/epics/cancelAiAccountantOnboardingEpic.d.ts +3 -3
- package/lib/view/aiAccountantView/epics/fetchAiAccountantCustomersEpic.d.ts +2 -2
- package/lib/view/aiAccountantView/epics/fetchAiAccountantJobsEpic.d.ts +3 -3
- package/lib/view/aiAccountantView/epics/triggerAiAccountantJobEpic.d.ts +3 -3
- package/lib/view/aiCfoView/epics/deleteChatSessionEpic.d.ts +5 -5
- package/lib/view/auditReportView/auditReportViewSelector.d.ts +1 -1
- package/lib/view/billPayCard/billPayCardSelector.d.ts +3 -3
- package/lib/view/cardBalance/cardBalanceEpic.d.ts +2 -2
- package/lib/view/cardBalance/cardBalanceSelector.d.ts +8 -8
- package/lib/view/cardBalance/statementCloseDayEpic.d.ts +3 -3
- package/lib/view/cardPayment/epic/addCardPaymentSourceEpic.d.ts +4 -4
- package/lib/view/cardPayment/epic/confirmCardSetupIntentEpic.d.ts +4 -4
- package/lib/view/cardPayment/epic/createCardSetupIntentEpic.d.ts +5 -5
- package/lib/view/cardPayment/epic/fetchPaymentSourcesEpic.d.ts +5 -5
- package/lib/view/cashBalance/cashBalanceEpic.d.ts +2 -2
- package/lib/view/cashBalance/cashBalanceSelector.d.ts +8 -8
- package/lib/view/cashInCashOut/cashInCashOutEpic.d.ts +5 -5
- package/lib/view/cashInCashOut/cashInCashOutSelector.d.ts +5 -5
- package/lib/view/cashPosition/cashPositionEpic.d.ts +3 -3
- package/lib/view/cashPosition/cashPositionSelector.d.ts +5 -5
- package/lib/view/companyConfigView/companyConfigSelector.d.ts +2 -2
- package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +3 -0
- package/lib/view/companyTaskManagerView/epics/fetchTaskManagerMetricsEpic.js +7 -1
- package/lib/view/companyView/epic/companyPassport/saveCompanyPassportDetailsEpic.d.ts +1 -1
- package/lib/view/companyView/types/cockpitTypes.d.ts +3 -0
- package/lib/view/createTransferEntry/createTransferEntrySelector.d.ts +1 -1
- package/lib/view/creditAgentView/epics/saveCreditAgentMacroEpic.d.ts +3 -3
- package/lib/view/creditAgentView/epics/scheduleTenantCreditScoreCronEpic.d.ts +3 -3
- package/lib/view/creditAgentView/epics/updateCardProfileEpic.d.ts +3 -3
- package/lib/view/expenseAutomationView/epics/accountRecon/reparseStatementEpic.d.ts +4 -4
- package/lib/view/expenseAutomationView/epics/accountRecon/updateStatementInfoEpic.d.ts +3 -3
- package/lib/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementEpic.d.ts +1 -1
- package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.d.ts +1 -1
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/forecastList/forecastListSelector.d.ts +4 -4
- package/lib/view/insightsCard/insightsCardEpic.d.ts +1 -1
- package/lib/view/people/changeZeniPersonRolesEpic.d.ts +5 -5
- package/lib/view/people/deletePersonEpic.d.ts +4 -4
- package/lib/view/people/fetchPeopleEpic.d.ts +2 -2
- package/lib/view/people/invitePeopleEpic.d.ts +7 -7
- package/lib/view/people/inviteZeniPeopleEpic.d.ts +7 -7
- package/lib/view/people/resendInviteEpic.d.ts +3 -3
- package/lib/view/reimbursementCard/reimbursementCardSelector.d.ts +3 -3
- package/lib/view/reportUIOptions/updateReportUIOptionCOABalancesRangeEpic.d.ts +11 -11
- package/lib/view/reportUIOptions/updateReportUIOptionCompareModeEpic.d.ts +8 -8
- package/lib/view/reportUIOptions/updateReportUIOptionThisPeriodEpic.d.ts +8 -8
- package/lib/view/settingsView/epic/fetchBankAccountsListEpic.d.ts +3 -3
- package/lib/view/settingsView/epic/saveNotificationSettingsEpic.d.ts +3 -3
- package/lib/view/spendManagement/billPay/magicLinkView/magicLinkViewSelector.d.ts +2 -2
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.d.ts +4 -4
- package/lib/view/spendManagement/helpers.d.ts +1 -1
- package/lib/view/spendManagement/reimbursement/editRemiView/epics/fetchRecommendationsAndUpdateMerchantRecommendationsEpic.d.ts +3 -3
- package/lib/view/tagView/epics/createTagEpic.d.ts +3 -3
- package/lib/view/tagView/epics/deleteTagEpic.d.ts +7 -7
- package/lib/view/taskManager/taskDetailView/epics/createSubTaskEpic.d.ts +9 -0
- package/lib/view/taskManager/taskDetailView/epics/createSubTaskEpic.js +100 -0
- package/lib/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.d.ts +8 -0
- package/lib/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.js +57 -0
- package/lib/view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic.js +1 -0
- package/lib/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.d.ts +2 -2
- package/lib/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +69 -8
- package/lib/view/taskManager/taskDetailView/taskDetail.d.ts +15 -0
- package/lib/view/taskManager/taskDetailView/taskDetailReducer.d.ts +14 -2
- package/lib/view/taskManager/taskDetailView/taskDetailReducer.js +57 -3
- package/lib/view/taskManager/taskDetailView/taskDetailSelector.d.ts +2 -1
- package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +30 -7
- package/lib/view/taskManager/taskListView/epics/fetchTaskListEpic.js +3 -1
- package/lib/view/taskManager/taskListView/taskList.d.ts +1 -1
- package/lib/view/taskManager/taskListView/taskList.js +1 -0
- package/lib/view/taskManager/taskListView/taskListPayload.d.ts +4 -0
- package/lib/view/taskManager/taskListView/taskListReducer.d.ts +6 -2
- package/lib/view/taskManager/taskListView/taskListReducer.js +241 -13
- package/lib/view/taskManager/taskListView/taskListSelector.js +1 -0
- package/lib/view/taskManager/taskListView/taskListViewHelpers.d.ts +11 -0
- package/lib/view/taskManager/taskListView/taskListViewHelpers.js +60 -1
- package/lib/view/tasksCard/tasksCardSelector.d.ts +2 -2
- package/lib/view/topEx/topExEpic.d.ts +2 -2
- package/lib/view/topEx/topExSelector.d.ts +7 -7
- package/lib/view/transactionDetail/epics/uploadMissingAttachmentSuccessEpic.d.ts +5 -5
- package/lib/view/transactionDetail/transactionDetailLocalDataHelper.d.ts +1 -1
- package/lib/view/userRoleConfigView/userRoleConfigSelector.d.ts +2 -2
- package/lib/view/zeniOAuthView/epics/approveOAuthConsentEpic.d.ts +3 -3
- package/package.json +1 -1
|
@@ -6,9 +6,9 @@ import { deleteTag, updateDeleteTagStatus } from '../tagViewReducer';
|
|
|
6
6
|
export type ActionType = ReturnType<typeof deleteTag> | ReturnType<typeof updateDeleteTagStatus> | ReturnType<typeof updateTags>;
|
|
7
7
|
export declare const deleteTagEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => import("rxjs").Observable<{
|
|
8
8
|
payload: {
|
|
9
|
-
messageSection: import("
|
|
10
|
-
messageText: import("
|
|
11
|
-
type: import("
|
|
9
|
+
messageSection: import("../../..").SnackbarMessageSections;
|
|
10
|
+
messageText: import("../../..").SnackbarMessageSectionTexts;
|
|
11
|
+
type: import("../../..").SnackbarMessageType;
|
|
12
12
|
showStatusIcon?: boolean;
|
|
13
13
|
variables?: {
|
|
14
14
|
variableName: string;
|
|
@@ -18,8 +18,8 @@ export declare const deleteTagEpic: (actions$: ActionsObservable<ActionType>, _s
|
|
|
18
18
|
type: "snackbar/openSnackbar";
|
|
19
19
|
} | {
|
|
20
20
|
payload: {
|
|
21
|
-
fetchState: import("
|
|
22
|
-
tagId: import("
|
|
21
|
+
fetchState: import("../../..").FetchState;
|
|
22
|
+
tagId: import("../../..").ID;
|
|
23
23
|
error?: import("../../../responsePayload").ZeniAPIStatus;
|
|
24
24
|
};
|
|
25
25
|
type: "tagView/updateDeleteTagStatus";
|
|
@@ -28,8 +28,8 @@ export declare const deleteTagEpic: (actions$: ActionsObservable<ActionType>, _s
|
|
|
28
28
|
type: "tag/removeTag";
|
|
29
29
|
} | {
|
|
30
30
|
payload: {
|
|
31
|
-
tagId: import("
|
|
32
|
-
taskId: import("
|
|
31
|
+
tagId: import("../../..").ID | undefined;
|
|
32
|
+
taskId: import("../../..").ID | undefined;
|
|
33
33
|
};
|
|
34
34
|
type: "taskDetailView/updateDeletedTagToLocalStore";
|
|
35
35
|
}>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
+
import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
3
|
+
import { appendSubTaskId, updateTasks } from '../../../../entity/task/taskReducer';
|
|
4
|
+
import { RootState } from '../../../../reducer';
|
|
5
|
+
import { ZeniAPI } from '../../../../zeniAPI';
|
|
6
|
+
import { updateTaskListOnNewTaskCreationSuccess } from '../../taskListView/taskListReducer';
|
|
7
|
+
import { createSubTask, createSubTaskSuccessOrFailure } from '../taskDetailReducer';
|
|
8
|
+
export type ActionType = ReturnType<typeof createSubTask> | ReturnType<typeof updateTasks> | ReturnType<typeof appendSubTaskId> | ReturnType<typeof openSnackbar> | ReturnType<typeof updateTaskListOnNewTaskCreationSuccess> | ReturnType<typeof createSubTaskSuccessOrFailure>;
|
|
9
|
+
export declare const createSubTaskEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => import("rxjs").Observable<ActionType>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSubTaskEpic = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const formatMinutesToFromHHMM_1 = require("../../../../commonStateTypes/fiscalYearHelpers/formatMinutesToFromHHMM");
|
|
7
|
+
const snackbarReducer_1 = require("../../../../entity/snackbar/snackbarReducer");
|
|
8
|
+
const taskReducer_1 = require("../../../../entity/task/taskReducer");
|
|
9
|
+
const taskSelector_1 = require("../../../../entity/task/taskSelector");
|
|
10
|
+
const responsePayload_1 = require("../../../../responsePayload");
|
|
11
|
+
const taskListReducer_1 = require("../../taskListView/taskListReducer");
|
|
12
|
+
const taskDetailReducer_1 = require("../taskDetailReducer");
|
|
13
|
+
const createSubTaskEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(taskDetailReducer_1.createSubTask.match), (0, operators_1.mergeMap)((action) => {
|
|
14
|
+
const state = state$.value;
|
|
15
|
+
const parentTask = (0, taskSelector_1.getTaskById)(state.taskState, action.payload.parentTaskId);
|
|
16
|
+
// Subtasks inherit every parent group membership, not just the first,
|
|
17
|
+
// so the subtask surfaces in all the same buckets as its parent.
|
|
18
|
+
const parentTaskGroupIds = parentTask?.taskGroupIds ?? [];
|
|
19
|
+
const parentTaskGroupId = parentTaskGroupIds[0];
|
|
20
|
+
const isTaskListFetched = state.taskListState.fetchState === 'Completed';
|
|
21
|
+
const payload = prepareSubTaskPayload(action.payload, parentTaskGroupIds);
|
|
22
|
+
return zeniAPI
|
|
23
|
+
.postAndGetJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/tasks`, payload)
|
|
24
|
+
.pipe((0, operators_1.mergeMap)((response) => {
|
|
25
|
+
if ((0, responsePayload_1.isSuccessResponse)(response) &&
|
|
26
|
+
response.data != null &&
|
|
27
|
+
response.data.tasks.length > 0) {
|
|
28
|
+
const newTaskId = response.data.tasks[0].task_id;
|
|
29
|
+
const actions = [
|
|
30
|
+
(0, taskReducer_1.updateTasks)(response.data.tasks),
|
|
31
|
+
(0, taskReducer_1.appendSubTaskId)({
|
|
32
|
+
parentTaskId: action.payload.parentTaskId,
|
|
33
|
+
subTaskId: newTaskId,
|
|
34
|
+
}),
|
|
35
|
+
(0, taskDetailReducer_1.createSubTaskSuccessOrFailure)({
|
|
36
|
+
fetchState: 'Completed',
|
|
37
|
+
newTaskId,
|
|
38
|
+
}),
|
|
39
|
+
(0, snackbarReducer_1.openSnackbar)({
|
|
40
|
+
messageSection: 'create_sub_task',
|
|
41
|
+
messageText: 'success',
|
|
42
|
+
type: 'success',
|
|
43
|
+
}),
|
|
44
|
+
];
|
|
45
|
+
// The task list is keyed on parent tasks (no parent_task_id)
|
|
46
|
+
// — subtasks belong to their parent's children list, not the
|
|
47
|
+
// top-level list. Pushing a subtask into the list would
|
|
48
|
+
// surface it as an orphan row at the top of the group.
|
|
49
|
+
// Only fire the list-update for actual parent tasks.
|
|
50
|
+
const createdTask = response.data.tasks[0];
|
|
51
|
+
const isSubtask = createdTask.parent_task_id != null &&
|
|
52
|
+
createdTask.parent_task_id !== '';
|
|
53
|
+
if (!isSubtask &&
|
|
54
|
+
isTaskListFetched === true &&
|
|
55
|
+
parentTaskGroupId != null) {
|
|
56
|
+
actions.push((0, taskListReducer_1.updateTaskListOnNewTaskCreationSuccess)({
|
|
57
|
+
taskGroupId: parentTaskGroupId,
|
|
58
|
+
task: createdTask,
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
return (0, rxjs_1.from)(actions);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return (0, rxjs_1.of)((0, taskDetailReducer_1.createSubTaskSuccessOrFailure)({
|
|
65
|
+
fetchState: 'Error',
|
|
66
|
+
error: response.status,
|
|
67
|
+
}), (0, snackbarReducer_1.openSnackbar)({
|
|
68
|
+
messageSection: 'create_sub_task',
|
|
69
|
+
messageText: 'failed',
|
|
70
|
+
type: 'error',
|
|
71
|
+
variables: [
|
|
72
|
+
{
|
|
73
|
+
variableName: '_api-error_',
|
|
74
|
+
variableValue: response.status.message,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, taskDetailReducer_1.createSubTaskSuccessOrFailure)({
|
|
80
|
+
fetchState: 'Error',
|
|
81
|
+
error: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Create Sub Task REST API call errored out' +
|
|
82
|
+
JSON.stringify(error)),
|
|
83
|
+
}))));
|
|
84
|
+
}));
|
|
85
|
+
exports.createSubTaskEpic = createSubTaskEpic;
|
|
86
|
+
const prepareSubTaskPayload = (subTask, parentTaskGroupIds) => ({
|
|
87
|
+
name: subTask.name,
|
|
88
|
+
assignees: subTask.assignee,
|
|
89
|
+
description: subTask.description,
|
|
90
|
+
priority: subTask.priority,
|
|
91
|
+
status: subTask.status,
|
|
92
|
+
tags: subTask.tagIds,
|
|
93
|
+
time_spent: (0, formatMinutesToFromHHMM_1.convertHHMMStrToMinutes)(subTask.timeSpent),
|
|
94
|
+
group_assignees: subTask.groupAssignees,
|
|
95
|
+
parent_task_id: subTask.parentTaskId,
|
|
96
|
+
// Inherit every parent group, not just the first — see callsite for
|
|
97
|
+
// the two-scope rationale.
|
|
98
|
+
task_group_ids: parentTaskGroupIds,
|
|
99
|
+
due_date: subTask.dueDate?.format('YYYY-MM-DD') ?? null,
|
|
100
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { setSubTaskIds, updateTasks } from '../../../../entity/task/taskReducer';
|
|
4
|
+
import { RootState } from '../../../../reducer';
|
|
5
|
+
import { ZeniAPI } from '../../../../zeniAPI';
|
|
6
|
+
import { fetchSubTasks, updateSubTasks, updateSubTasksFetchStatus } from '../taskDetailReducer';
|
|
7
|
+
export type ActionType = ReturnType<typeof fetchSubTasks> | ReturnType<typeof updateTasks> | ReturnType<typeof setSubTaskIds> | ReturnType<typeof updateSubTasks> | ReturnType<typeof updateSubTasksFetchStatus>;
|
|
8
|
+
export declare const fetchSubTasksEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchSubTasksEpic = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const taskReducer_1 = require("../../../../entity/task/taskReducer");
|
|
7
|
+
const responsePayload_1 = require("../../../../responsePayload");
|
|
8
|
+
const taskDetailReducer_1 = require("../taskDetailReducer");
|
|
9
|
+
const fetchSubTasksEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(taskDetailReducer_1.fetchSubTasks.match),
|
|
10
|
+
// Use mergeMap, not switchMap: switchMap cancels in-flight requests for
|
|
11
|
+
// the previous parent without dispatching success or failure, leaving
|
|
12
|
+
// subTaskListFetchStatusByParentId stuck at In-Progress and blocking the
|
|
13
|
+
// detail page's combined fetchStatus via reduceAnyFetchState. Per-parent
|
|
14
|
+
// races on the same parentTaskId are handled last-write-wins downstream.
|
|
15
|
+
(0, operators_1.mergeMap)((action) => {
|
|
16
|
+
const { parentTaskId } = action.payload;
|
|
17
|
+
const query = JSON.stringify({
|
|
18
|
+
task_type: 'subtasks',
|
|
19
|
+
parent_task_id: parentTaskId,
|
|
20
|
+
});
|
|
21
|
+
return zeniAPI
|
|
22
|
+
.getJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/tasks?query=${encodeURIComponent(query)}`)
|
|
23
|
+
.pipe((0, operators_1.mergeMap)((response) => {
|
|
24
|
+
if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
|
|
25
|
+
const { tasks } = response.data;
|
|
26
|
+
// Keep the parent's `subTasksIds` in sync with the fetched
|
|
27
|
+
// bucket. Without this, the parent entity record can drift
|
|
28
|
+
// out of sync with what the children fetch returned —
|
|
29
|
+
// e.g. a server-side delete won't drop from the parent
|
|
30
|
+
// record until the next list re-fetch.
|
|
31
|
+
const fetchedChildIds = tasks
|
|
32
|
+
.filter((t) => t.parent_task_id === parentTaskId)
|
|
33
|
+
.map((t) => t.task_id);
|
|
34
|
+
return (0, rxjs_1.of)((0, taskReducer_1.updateTasks)(tasks), (0, taskReducer_1.setSubTaskIds)({
|
|
35
|
+
parentTaskId,
|
|
36
|
+
subTaskIds: fetchedChildIds,
|
|
37
|
+
}), (0, taskDetailReducer_1.updateSubTasks)({
|
|
38
|
+
parentTaskId,
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
return (0, rxjs_1.of)((0, taskDetailReducer_1.updateSubTasksFetchStatus)({
|
|
43
|
+
parentTaskId,
|
|
44
|
+
fetchState: 'Error',
|
|
45
|
+
error: response.status,
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
}), (0, operators_1.catchError)((error) => {
|
|
49
|
+
return (0, rxjs_1.of)((0, taskDetailReducer_1.updateSubTasksFetchStatus)({
|
|
50
|
+
parentTaskId,
|
|
51
|
+
fetchState: 'Error',
|
|
52
|
+
error: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch Sub Tasks REST API call errored out' +
|
|
53
|
+
JSON.stringify(error)),
|
|
54
|
+
}));
|
|
55
|
+
}));
|
|
56
|
+
}));
|
|
57
|
+
exports.fetchSubTasksEpic = fetchSubTasksEpic;
|
|
@@ -34,6 +34,7 @@ const initializeTaskToLocalStoreEpic = (actions$, state$) => actions$.pipe((0, o
|
|
|
34
34
|
recurringStartDate: task.recurringStartDate,
|
|
35
35
|
timeSpent: task.timeSpent,
|
|
36
36
|
isPrivate: task.isPrivate,
|
|
37
|
+
taskGroupId: task.taskGroupIds[0],
|
|
37
38
|
};
|
|
38
39
|
const actions = [
|
|
39
40
|
(0, taskDetailReducer_1.saveTaskUpdatesToLocalStore)({ taskDetailLocalData, taskId }),
|
|
@@ -3,7 +3,7 @@ import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
|
3
3
|
import { updateTasks } from '../../../../entity/task/taskReducer';
|
|
4
4
|
import { RootState } from '../../../../reducer';
|
|
5
5
|
import { ZeniAPI } from '../../../../zeniAPI';
|
|
6
|
-
import { updateTaskListOnNewTaskCreationSuccess } from '../../taskListView/taskListReducer';
|
|
6
|
+
import { removeTaskFromGroupBucket, updateTaskListOnNewTaskCreationSuccess } from '../../taskListView/taskListReducer';
|
|
7
7
|
import { saveTaskDetail, saveTaskSuccessOrFailure } from '../taskDetailReducer';
|
|
8
|
-
export type ActionType = ReturnType<typeof saveTaskDetail> | ReturnType<typeof updateTasks> | ReturnType<typeof openSnackbar> | ReturnType<typeof updateTaskListOnNewTaskCreationSuccess> | ReturnType<typeof saveTaskSuccessOrFailure>;
|
|
8
|
+
export type ActionType = ReturnType<typeof saveTaskDetail> | ReturnType<typeof updateTasks> | ReturnType<typeof openSnackbar> | ReturnType<typeof updateTaskListOnNewTaskCreationSuccess> | ReturnType<typeof removeTaskFromGroupBucket> | ReturnType<typeof saveTaskSuccessOrFailure>;
|
|
9
9
|
export declare const saveTaskDetailEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => import("rxjs").Observable<ActionType>;
|
|
@@ -15,17 +15,46 @@ const saveTaskDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, oper
|
|
|
15
15
|
const { taskId, taskGroupId } = action.payload;
|
|
16
16
|
const state = state$.value;
|
|
17
17
|
const isTaskListFetched = state.taskListState.fetchState === 'Completed';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
// On edit, prefer the locally-edited group; fall back to the entity's
|
|
19
|
+
// current group. On create, use the taskGroupId from the action payload.
|
|
20
|
+
const localTaskGroupId = taskId != null
|
|
21
|
+
? state.taskDetailState.editTaskStateById[taskId]?.taskDetailLocalData
|
|
22
|
+
?.taskGroupId
|
|
23
|
+
: undefined;
|
|
24
|
+
// groupWasCleared distinguishes "user explicitly cleared the group"
|
|
25
|
+
// (localTaskGroupId === null → send []) from "user did not touch it"
|
|
26
|
+
// (undefined → fall back to entity). Without this, the `??` fallback
|
|
27
|
+
// would resurrect the stale entity value after a clear.
|
|
28
|
+
const groupWasCleared = taskId != null && localTaskGroupId === null;
|
|
29
|
+
const entityTaskGroupIds = taskId != null
|
|
30
|
+
? ((0, taskSelector_1.getTaskById)(state.taskState, taskId)?.taskGroupIds ?? [])
|
|
31
|
+
: [];
|
|
32
|
+
// Distinguish three save shapes:
|
|
33
|
+
// - cleared → []
|
|
34
|
+
// - user picked a different group locally → [localTaskGroupId]
|
|
35
|
+
// - no local edit → entire entityTaskGroupIds (preserves multi-
|
|
36
|
+
// group membership; without this, unrelated field edits silently
|
|
37
|
+
// drop extra groups).
|
|
38
|
+
const localGroupChanged = localTaskGroupId != null;
|
|
39
|
+
const taskGroupIdsForPayload = groupWasCleared
|
|
40
|
+
? []
|
|
41
|
+
: localGroupChanged
|
|
42
|
+
? [localTaskGroupId]
|
|
43
|
+
: taskId != null
|
|
44
|
+
? entityTaskGroupIds
|
|
45
|
+
: taskGroupId != null
|
|
46
|
+
? [taskGroupId]
|
|
47
|
+
: [];
|
|
48
|
+
// Keep `updatedTaskGroupId` (single id) for downstream list-update
|
|
49
|
+
// dispatches that still bucket against one group at a time.
|
|
50
|
+
const updatedTaskGroupId = taskGroupIdsForPayload[0];
|
|
51
|
+
const payload = prepareTaskPayload(state, taskId, taskGroupIdsForPayload);
|
|
22
52
|
const saveTaskApi = taskId != null
|
|
23
53
|
? zeniAPI.putAndGetJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/tasks/${taskId}`, payload)
|
|
24
54
|
: zeniAPI.postAndGetJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/tasks`, payload);
|
|
25
55
|
return saveTaskApi.pipe((0, operators_1.mergeMap)((response) => {
|
|
26
56
|
if ((0, responsePayload_1.isSuccessResponse)(response) &&
|
|
27
57
|
response.data != null &&
|
|
28
|
-
updatedTaskGroupId != null &&
|
|
29
58
|
response.data.tasks.length > 0) {
|
|
30
59
|
const newTaskId = response.data.tasks[0].task_id;
|
|
31
60
|
const actions = [
|
|
@@ -36,7 +65,24 @@ const saveTaskDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, oper
|
|
|
36
65
|
taskId,
|
|
37
66
|
}),
|
|
38
67
|
];
|
|
39
|
-
|
|
68
|
+
// Only suppress the list-insert on the live/completed tabs
|
|
69
|
+
// when the saved task's status no longer matches the tab —
|
|
70
|
+
// otherwise doUpdateTaskList writes the row back into the
|
|
71
|
+
// current tab's grouping arrays even after updateTasks moved
|
|
72
|
+
// it to Completed. Archived/snoozed/deleted are owned by
|
|
73
|
+
// their dedicated actions and must keep the pre-PR optimistic
|
|
74
|
+
// update path so their grouping arrays don't go stale.
|
|
75
|
+
const savedTask = response.data.tasks[0];
|
|
76
|
+
const savedIsCompleted = savedTask.status?.code === 'resolved';
|
|
77
|
+
const activeTab = state.taskListState.currentTab;
|
|
78
|
+
const isLiveOrCompletedTab = activeTab === 'live' || activeTab === 'completed';
|
|
79
|
+
const statusMatchesActiveTab = !isLiveOrCompletedTab ||
|
|
80
|
+
(savedIsCompleted && activeTab === 'completed') ||
|
|
81
|
+
(!savedIsCompleted && activeTab === 'live');
|
|
82
|
+
if (isTaskListFetched === true &&
|
|
83
|
+
groupWasCleared === false &&
|
|
84
|
+
updatedTaskGroupId != null &&
|
|
85
|
+
statusMatchesActiveTab === true) {
|
|
40
86
|
actions.push((0, taskListReducer_1.updateTaskListOnNewTaskCreationSuccess)({
|
|
41
87
|
taskGroupId: updatedTaskGroupId,
|
|
42
88
|
task: response.data.tasks[0],
|
|
@@ -45,6 +91,21 @@ const saveTaskDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, oper
|
|
|
45
91
|
: undefined,
|
|
46
92
|
}));
|
|
47
93
|
}
|
|
94
|
+
else if (isTaskListFetched === true &&
|
|
95
|
+
groupWasCleared === true &&
|
|
96
|
+
taskId != null) {
|
|
97
|
+
// Group was cleared — skip the list-insert action (no
|
|
98
|
+
// destination bucket) and explicitly drop the row from every
|
|
99
|
+
// previously-held group so the list re-renders without the
|
|
100
|
+
// stale entry under the old group until next refetch.
|
|
101
|
+
const previousTask = (0, taskSelector_1.getTaskById)(state.taskState, taskId);
|
|
102
|
+
previousTask?.taskGroupIds.forEach((previousGroupId) => {
|
|
103
|
+
actions.push((0, taskListReducer_1.removeTaskFromGroupBucket)({
|
|
104
|
+
taskId,
|
|
105
|
+
taskGroupId: previousGroupId,
|
|
106
|
+
}));
|
|
107
|
+
});
|
|
108
|
+
}
|
|
48
109
|
return (0, rxjs_1.from)(actions);
|
|
49
110
|
}
|
|
50
111
|
else {
|
|
@@ -71,7 +132,7 @@ const saveTaskDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, oper
|
|
|
71
132
|
}))));
|
|
72
133
|
}));
|
|
73
134
|
exports.saveTaskDetailEpic = saveTaskDetailEpic;
|
|
74
|
-
const prepareTaskPayload = (state, taskId,
|
|
135
|
+
const prepareTaskPayload = (state, taskId, taskGroupIds) => {
|
|
75
136
|
const { taskDetailState, taskState } = state;
|
|
76
137
|
const syncToken = taskId != null ? ((0, taskSelector_1.getTaskById)(taskState, taskId)?.syncToken ?? '') : '';
|
|
77
138
|
const sourceState = taskId != null
|
|
@@ -100,7 +161,7 @@ const prepareTaskPayload = (state, taskId, taskGroupId) => {
|
|
|
100
161
|
? (localData.recurringDaysOfWeek ?? [])
|
|
101
162
|
: [],
|
|
102
163
|
sync_token: syncToken,
|
|
103
|
-
task_group_ids:
|
|
164
|
+
task_group_ids: taskGroupIds,
|
|
104
165
|
time_spent: (0, formatMinutesToFromHHMM_1.convertHHMMStrToMinutes)(localData.timeSpent),
|
|
105
166
|
group_assignees: localData.groupAssignees,
|
|
106
167
|
...(taskId == null ? { is_private: localData.isPrivate ?? false } : {}),
|
|
@@ -3,9 +3,23 @@ import { DayOfWeek, PriorityCodeType, TaskStatusCodeType, TaskType } from '../..
|
|
|
3
3
|
import { ZeniDate } from '../../../zeniDayJS';
|
|
4
4
|
import { RecurringDatePickerOptions, RecurringFrequencyType } from '../../common/recurringViewHelper';
|
|
5
5
|
import { CommonHistoryView } from '../../spendManagement/commonHistoryView/commonHistory';
|
|
6
|
+
export interface CreateSubTaskPayload {
|
|
7
|
+
assignee: ID[];
|
|
8
|
+
description: string;
|
|
9
|
+
groupAssignees: ID[];
|
|
10
|
+
name: string;
|
|
11
|
+
parentTaskId: ID;
|
|
12
|
+
priority: PriorityCodeType;
|
|
13
|
+
status: TaskStatusCodeType;
|
|
14
|
+
tagIds: ID[];
|
|
15
|
+
timeSpent: string;
|
|
16
|
+
dueDate?: ZeniDate;
|
|
17
|
+
}
|
|
6
18
|
export interface TaskDetailViewState {
|
|
7
19
|
editTaskStateById: Record<ID, EditTaskDetail>;
|
|
8
20
|
newTaskState: EditTaskDetail;
|
|
21
|
+
subTaskCreateStatus: FetchStateAndError;
|
|
22
|
+
subTaskListFetchStatusByParentId: Record<ID, FetchStateAndError>;
|
|
9
23
|
taskHistoryById: Record<ID, CommonHistoryView>;
|
|
10
24
|
}
|
|
11
25
|
export interface EditTaskDetail {
|
|
@@ -40,6 +54,7 @@ export interface EditTaskLocalData {
|
|
|
40
54
|
recurringStartDate?: ZeniDate;
|
|
41
55
|
savedRecurringEndDate?: ZeniDate;
|
|
42
56
|
savedRecurringTasksCount?: number;
|
|
57
|
+
taskGroupId?: ID | null;
|
|
43
58
|
}
|
|
44
59
|
export declare const initialTaskDetailLocalData: EditTaskLocalData;
|
|
45
60
|
export declare const initialTaskDetail: EditTaskDetail;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FetchState, ID } from '../../../commonStateTypes/common';
|
|
2
2
|
import { ZeniAPIStatus } from '../../../responsePayload';
|
|
3
3
|
import { HistoricEventPayload } from '../../spendManagement/commonHistoryView/commonHistoryPayload';
|
|
4
|
-
import { EditTaskLocalData, TaskDetailViewState } from './taskDetail';
|
|
4
|
+
import { CreateSubTaskPayload, EditTaskLocalData, TaskDetailViewState } from './taskDetail';
|
|
5
5
|
export declare const initialState: TaskDetailViewState;
|
|
6
6
|
export declare const fetchTaskDetailPage: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[cacheOverride: boolean, taskId?: string | undefined], {
|
|
7
7
|
cacheOverride: boolean;
|
|
@@ -34,7 +34,19 @@ export declare const fetchTaskDetailPage: import("@reduxjs/toolkit").ActionCreat
|
|
|
34
34
|
error?: ZeniAPIStatus;
|
|
35
35
|
newTaskId?: ID;
|
|
36
36
|
taskId?: ID;
|
|
37
|
-
}, "taskDetailView/saveTaskSuccessOrFailure">,
|
|
37
|
+
}, "taskDetailView/saveTaskSuccessOrFailure">, createSubTask: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: CreateSubTaskPayload], CreateSubTaskPayload, "taskDetailView/createSubTask", never, never>, createSubTaskSuccessOrFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
38
|
+
fetchState: FetchState;
|
|
39
|
+
error?: ZeniAPIStatus;
|
|
40
|
+
newTaskId?: ID;
|
|
41
|
+
}, "taskDetailView/createSubTaskSuccessOrFailure">, resetSubTaskCreateStatus: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"taskDetailView/resetSubTaskCreateStatus">, fetchSubTasks: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[parentTaskId: string], {
|
|
42
|
+
parentTaskId: string;
|
|
43
|
+
}, "taskDetailView/fetchSubTasks", never, never>, updateSubTasks: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
44
|
+
parentTaskId: ID;
|
|
45
|
+
}, "taskDetailView/updateSubTasks">, updateSubTasksFetchStatus: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
46
|
+
fetchState: FetchState;
|
|
47
|
+
parentTaskId: ID;
|
|
48
|
+
error?: ZeniAPIStatus;
|
|
49
|
+
}, "taskDetailView/updateSubTasksFetchStatus">, deleteTask: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[taskId?: string | undefined], {
|
|
38
50
|
taskId: string | undefined;
|
|
39
51
|
}, "taskDetailView/deleteTask", never, never>, removeTaskDetail: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "taskDetailView/removeTaskDetail">, deleteTaskSuccessOrFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
40
52
|
fetchState: FetchState;
|
|
@@ -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.saveTaskSuccessOrFailure = exports.archiveTaskSuccessOrFailure = exports.archiveTask = exports.saveTaskDetail = exports.discardTaskUpdatesInLocalStore = exports.saveTaskUpdatesToLocalStore = exports.updateEditTaskFetchStatus = exports.initializeTaskToLocalStore = exports.fetchTaskDetail = exports.fetchTaskDetailPage = exports.initialState = void 0;
|
|
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.updateSubTasksFetchStatus = exports.updateSubTasks = exports.fetchSubTasks = exports.resetSubTaskCreateStatus = exports.createSubTaskSuccessOrFailure = exports.createSubTask = 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,6 +13,11 @@ 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: {},
|
|
16
21
|
taskHistoryById: {},
|
|
17
22
|
};
|
|
18
23
|
const taskDetailView = (0, toolkit_1.createSlice)({
|
|
@@ -57,7 +62,7 @@ const taskDetailView = (0, toolkit_1.createSlice)({
|
|
|
57
62
|
updateEditTaskFetchStatus(draft, action) {
|
|
58
63
|
const { taskId, fetchState, error } = action.payload;
|
|
59
64
|
draft.editTaskStateById[taskId] = {
|
|
60
|
-
...draft.editTaskStateById[taskId],
|
|
65
|
+
...(draft.editTaskStateById[taskId] ?? taskDetail_1.initialTaskDetail),
|
|
61
66
|
fetchTaskStatus: {
|
|
62
67
|
fetchState,
|
|
63
68
|
error: fetchState === 'Error' ? error : undefined,
|
|
@@ -325,10 +330,59 @@ const taskDetailView = (0, toolkit_1.createSlice)({
|
|
|
325
330
|
error,
|
|
326
331
|
};
|
|
327
332
|
},
|
|
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
|
+
},
|
|
328
382
|
clearTaskDetail(draft) {
|
|
329
383
|
Object.assign(draft, exports.initialState);
|
|
330
384
|
},
|
|
331
385
|
},
|
|
332
386
|
});
|
|
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;
|
|
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.createSubTask = _a.createSubTask, exports.createSubTaskSuccessOrFailure = _a.createSubTaskSuccessOrFailure, exports.resetSubTaskCreateStatus = _a.resetSubTaskCreateStatus, exports.fetchSubTasks = _a.fetchSubTasks, exports.updateSubTasks = _a.updateSubTasks, exports.updateSubTasksFetchStatus = _a.updateSubTasksFetchStatus, 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;
|
|
334
388
|
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 { TaskPriority, TaskStatus } from '../../../entity/task/taskState';
|
|
5
|
+
import { Task, 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,6 +14,7 @@ export interface TaskDetailSelectorView extends SelectorView {
|
|
|
14
14
|
deleteFileStatusById: Record<ID, FetchStateAndError | undefined>;
|
|
15
15
|
files: File[];
|
|
16
16
|
showTaskDetailFormFooter: boolean;
|
|
17
|
+
subtasks: Task[];
|
|
17
18
|
taskDetailView: EditTaskDetail;
|
|
18
19
|
taskHistory: HistoricEvent[];
|
|
19
20
|
updateFileStatusById: Record<ID, FetchStateAndError | undefined>;
|
|
@@ -33,8 +33,13 @@ const getTaskDetail = (state, taskId) => {
|
|
|
33
33
|
let recurringSourceTaskId = undefined;
|
|
34
34
|
let snoozedUntil = undefined;
|
|
35
35
|
let taskGroupId = undefined;
|
|
36
|
+
let subtasks = [];
|
|
36
37
|
if (taskId != null && sourceTaskDetail != null) {
|
|
37
38
|
const taskEntity = (0, taskSelector_1.getTaskById)(taskState, taskId);
|
|
39
|
+
subtasks =
|
|
40
|
+
taskEntity != null
|
|
41
|
+
? (0, taskSelector_1.getTasksByIds)(taskState, taskEntity.subTasksIds)
|
|
42
|
+
: [];
|
|
38
43
|
const fileIdsInEntity = taskEntity?.fileIds ?? [];
|
|
39
44
|
if (taskEntity != null) {
|
|
40
45
|
createdByUser = (0, userAndRole_1.getUserAndUserRole)(userState, userRoleState, addressState, taskEntity.createdBy);
|
|
@@ -44,26 +49,37 @@ const getTaskDetail = (state, taskId) => {
|
|
|
44
49
|
snoozedUntil = taskEntity.snoozedUntil;
|
|
45
50
|
taskGroupId = taskEntity.taskGroupIds[0];
|
|
46
51
|
}
|
|
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;
|
|
47
61
|
if (fileIdsInEntity.length > 0) {
|
|
48
|
-
fetchStatus = (0, reduceFetchState_1.
|
|
62
|
+
fetchStatus = (0, reduceFetchState_1.reduceAnyFetchState)([
|
|
49
63
|
fileViewState.fetchFilesStatus,
|
|
50
64
|
sourceTaskDetail.fetchTaskStatus,
|
|
51
65
|
userList,
|
|
52
66
|
classListState,
|
|
67
|
+
subTaskStatus,
|
|
53
68
|
]);
|
|
54
69
|
}
|
|
55
70
|
else {
|
|
56
|
-
fetchStatus = (0, reduceFetchState_1.
|
|
71
|
+
fetchStatus = (0, reduceFetchState_1.reduceAnyFetchState)([
|
|
57
72
|
sourceTaskDetail.fetchTaskStatus,
|
|
58
73
|
userList,
|
|
59
74
|
classListState,
|
|
75
|
+
subTaskStatus,
|
|
60
76
|
]);
|
|
61
77
|
}
|
|
62
78
|
showTaskDetailFormFooter = showFormFooter(sourceTaskDetail.taskDetailLocalData, taskEntity);
|
|
63
79
|
taskHistory = taskDetailState.taskHistoryById[taskId]?.historicEvents ?? [];
|
|
64
80
|
}
|
|
65
81
|
else if (taskId == null) {
|
|
66
|
-
fetchStatus = (0, reduceFetchState_1.
|
|
82
|
+
fetchStatus = (0, reduceFetchState_1.reduceAnyFetchState)([userList, classListState]);
|
|
67
83
|
}
|
|
68
84
|
const { classIds } = classListState;
|
|
69
85
|
const allAccountingClasses = (0, classSelector_1.getClassesByIds)(classState, {
|
|
@@ -96,6 +112,7 @@ const getTaskDetail = (state, taskId) => {
|
|
|
96
112
|
showTaskDetailFormFooter,
|
|
97
113
|
snoozedUntil,
|
|
98
114
|
taskGroupId,
|
|
115
|
+
subtasks,
|
|
99
116
|
};
|
|
100
117
|
};
|
|
101
118
|
exports.getTaskDetail = getTaskDetail;
|
|
@@ -144,13 +161,16 @@ exports.allTaskPriority = [
|
|
|
144
161
|
},
|
|
145
162
|
];
|
|
146
163
|
const showFormFooter = (taskDetailLocalData, taskDetailInStore) => {
|
|
147
|
-
if (
|
|
164
|
+
if (taskDetailInStore == null) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
if (taskDetailLocalData.name !== taskDetailInStore.name ||
|
|
148
168
|
taskDetailLocalData.description !== taskDetailInStore.description ||
|
|
149
169
|
taskDetailLocalData.priority !== taskDetailInStore.priority.code ||
|
|
150
170
|
taskDetailLocalData.status !== taskDetailInStore.status.code ||
|
|
151
171
|
!(0, isEqual_1.default)(taskDetailInStore.tagIds, taskDetailLocalData.tagIds) ||
|
|
152
|
-
!(0, isEqual_1.default)(taskDetailLocalData.assignee, taskDetailInStore
|
|
153
|
-
!(0, isEqual_1.default)(taskDetailLocalData.groupAssignees, taskDetailInStore
|
|
172
|
+
!(0, isEqual_1.default)(taskDetailLocalData.assignee, taskDetailInStore.assignees ?? []) ||
|
|
173
|
+
!(0, isEqual_1.default)(taskDetailLocalData.groupAssignees, taskDetailInStore.groupAssignees ?? []) ||
|
|
154
174
|
!(0, isEqual_1.default)(taskDetailLocalData.fileIds, taskDetailInStore.fileIds ?? []) ||
|
|
155
175
|
!(0, isEqual_1.default)(taskDetailLocalData.dueDate, taskDetailInStore.dueDate) ||
|
|
156
176
|
!(0, isEqual_1.default)(taskDetailLocalData.type, taskDetailInStore.type) ||
|
|
@@ -158,7 +178,10 @@ const showFormFooter = (taskDetailLocalData, taskDetailInStore) => {
|
|
|
158
178
|
!(0, isEqual_1.default)(taskDetailLocalData.recurringFrequency, taskDetailInStore.recurringFrequency) ||
|
|
159
179
|
!(0, isEqual_1.default)(taskDetailLocalData.recurringDaysOfWeek, taskDetailInStore.recurringDaysOfWeek) ||
|
|
160
180
|
!(0, isEqual_1.default)(taskDetailLocalData.recurringStartDate, taskDetailInStore.recurringStartDate) ||
|
|
161
|
-
!(0, isEqual_1.default)(taskDetailLocalData.timeSpent, taskDetailInStore.timeSpent)
|
|
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)) {
|
|
162
185
|
return true;
|
|
163
186
|
}
|
|
164
187
|
return false;
|
|
@@ -12,15 +12,17 @@ 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 } = response.data;
|
|
15
|
+
const { tasks, deleted, archived, snoozed, completed } = response.data;
|
|
16
16
|
const allTasks = [
|
|
17
17
|
...tasks,
|
|
18
|
+
...(completed ?? []),
|
|
18
19
|
...(deleted ?? []),
|
|
19
20
|
...(archived ?? []),
|
|
20
21
|
...(snoozed ?? []),
|
|
21
22
|
];
|
|
22
23
|
return (0, rxjs_1.of)((0, taskReducer_1.updateTasks)(allTasks), (0, taskListReducer_1.updateTaskList)({
|
|
23
24
|
data: tasks,
|
|
25
|
+
completed: completed ?? [],
|
|
24
26
|
deleted: deleted ?? [],
|
|
25
27
|
archived: archived ?? [],
|
|
26
28
|
snoozed: snoozed ?? [],
|