@zeniai/client-epic-state 5.1.45-betaDI3 → 5.1.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  2. package/lib/entity/snackbar/snackbarTypes.js +0 -3
  3. package/lib/entity/task/taskPayload.d.ts +1 -3
  4. package/lib/entity/task/taskPayload.js +2 -24
  5. package/lib/entity/task/taskReducer.d.ts +1 -8
  6. package/lib/entity/task/taskReducer.js +4 -29
  7. package/lib/entity/task/taskState.d.ts +0 -2
  8. package/lib/entity/tenant/epic/saveExternalConnectionEpic.d.ts +1 -2
  9. package/lib/entity/tenant/epic/saveExternalConnectionEpic.js +0 -17
  10. package/lib/epic.d.ts +3 -6
  11. package/lib/epic.js +3 -6
  12. package/lib/esm/entity/snackbar/snackbarTypes.js +0 -3
  13. package/lib/esm/entity/task/taskPayload.js +2 -24
  14. package/lib/esm/entity/task/taskReducer.js +3 -28
  15. package/lib/esm/entity/tenant/epic/saveExternalConnectionEpic.js +0 -17
  16. package/lib/esm/epic.js +3 -6
  17. package/lib/esm/index.js +8 -8
  18. package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +1 -31
  19. package/lib/esm/view/aiCfoView/epics/fetchSkillsEpic.js +8 -33
  20. package/lib/esm/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +0 -3
  21. package/lib/esm/view/companyTaskManagerView/epics/fetchTaskManagerMetricsEpic.js +1 -7
  22. package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +0 -7
  23. package/lib/esm/view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic.js +0 -1
  24. package/lib/esm/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +9 -70
  25. package/lib/esm/view/taskManager/taskDetailView/taskDetailReducer.js +2 -56
  26. package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +9 -35
  27. package/lib/esm/view/taskManager/taskListView/epics/fetchTaskListEpic.js +1 -3
  28. package/lib/esm/view/taskManager/taskListView/taskList.js +0 -1
  29. package/lib/esm/view/taskManager/taskListView/taskListReducer.js +18 -310
  30. package/lib/esm/view/taskManager/taskListView/taskListSelector.js +0 -1
  31. package/lib/esm/view/taskManager/taskListView/taskListViewHelpers.js +0 -58
  32. package/lib/esm/view/transactionDetail/epics/saveTransactionHelper.js +0 -22
  33. package/lib/esm/view/transactionDetail/epics/updateTransactionDetailEpic.js +3 -75
  34. package/lib/esm/view/transactionDetail/journalEntryLinesViewModel.js +0 -58
  35. package/lib/esm/view/transactionDetail/transactionDetailLocalDataHelper.js +8 -10
  36. package/lib/esm/view/transactionDetail/transactionDetailReducer.js +1 -66
  37. package/lib/index.d.ts +11 -12
  38. package/lib/index.js +28 -37
  39. package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +0 -10
  40. package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +2 -7
  41. package/lib/view/aiCfoView/aiCfoViewReducer.js +2 -32
  42. package/lib/view/aiCfoView/aiCfoViewState.d.ts +1 -5
  43. package/lib/view/aiCfoView/epics/fetchSkillsEpic.js +8 -33
  44. package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +0 -3
  45. package/lib/view/companyTaskManagerView/epics/fetchTaskManagerMetricsEpic.js +1 -7
  46. package/lib/view/companyView/types/cockpitTypes.d.ts +0 -3
  47. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  48. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +0 -7
  49. package/lib/view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic.js +0 -1
  50. package/lib/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.d.ts +2 -2
  51. package/lib/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +8 -69
  52. package/lib/view/taskManager/taskDetailView/taskDetail.d.ts +0 -15
  53. package/lib/view/taskManager/taskDetailView/taskDetailReducer.d.ts +2 -14
  54. package/lib/view/taskManager/taskDetailView/taskDetailReducer.js +3 -57
  55. package/lib/view/taskManager/taskDetailView/taskDetailSelector.d.ts +1 -3
  56. package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +7 -33
  57. package/lib/view/taskManager/taskListView/epics/fetchTaskListEpic.js +1 -3
  58. package/lib/view/taskManager/taskListView/taskList.d.ts +1 -1
  59. package/lib/view/taskManager/taskListView/taskList.js +0 -1
  60. package/lib/view/taskManager/taskListView/taskListPayload.d.ts +0 -4
  61. package/lib/view/taskManager/taskListView/taskListReducer.d.ts +2 -6
  62. package/lib/view/taskManager/taskListView/taskListReducer.js +19 -311
  63. package/lib/view/taskManager/taskListView/taskListSelector.js +0 -1
  64. package/lib/view/taskManager/taskListView/taskListViewHelpers.d.ts +0 -11
  65. package/lib/view/taskManager/taskListView/taskListViewHelpers.js +1 -60
  66. package/lib/view/transactionDetail/epics/saveTransactionHelper.js +0 -22
  67. package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.d.ts +1 -5
  68. package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.js +4 -77
  69. package/lib/view/transactionDetail/journalEntryLinesViewModel.d.ts +0 -27
  70. package/lib/view/transactionDetail/journalEntryLinesViewModel.js +1 -61
  71. package/lib/view/transactionDetail/transactionDetailLocalDataHelper.js +8 -10
  72. package/lib/view/transactionDetail/transactionDetailReducer.d.ts +2 -11
  73. package/lib/view/transactionDetail/transactionDetailReducer.js +2 -67
  74. package/lib/view/transactionDetail/transactionDetailState.d.ts +1 -8
  75. package/lib/view/transactionDetail/transactionDetailTypes.d.ts +0 -2
  76. package/package.json +1 -1
  77. package/lib/esm/view/aiCfoView/epics/submitFeedbackEpic.js +0 -39
  78. package/lib/esm/view/taskManager/taskDetailView/epics/createSubTaskEpic.js +0 -96
  79. package/lib/esm/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.js +0 -53
  80. package/lib/view/aiCfoView/epics/submitFeedbackEpic.d.ts +0 -13
  81. package/lib/view/aiCfoView/epics/submitFeedbackEpic.js +0 -43
  82. package/lib/view/taskManager/taskDetailView/epics/createSubTaskEpic.d.ts +0 -9
  83. package/lib/view/taskManager/taskDetailView/epics/createSubTaskEpic.js +0 -100
  84. package/lib/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.d.ts +0 -8
  85. package/lib/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.js +0 -57
@@ -383,36 +383,6 @@ const aiCfoView = createSlice({
383
383
  const { chatSessionId } = action.payload;
384
384
  delete draft.deleteChatSessionStateByChatSessionId[chatSessionId];
385
385
  },
386
- // AI CFO answer feedback (👍/👎). Fire-and-forget: submitFeedbackEpic POSTs to /1.0/feedback
387
- // and the server emits the analytics event + routes negatives, so there's no view state to
388
- // mutate — the reducers are intentional no-ops; prepare carries the params.
389
- submitFeedback: {
390
- reducer() { },
391
- prepare(chatSessionId, chatMessageId, feedbackType, questionText, answerText, model) {
392
- return {
393
- payload: {
394
- chatMessageId,
395
- chatSessionId,
396
- feedbackType,
397
- answerText,
398
- model,
399
- questionText,
400
- },
401
- };
402
- },
403
- },
404
- submitFeedbackSuccess: {
405
- reducer() { },
406
- prepare(chatMessageId) {
407
- return { payload: { chatMessageId } };
408
- },
409
- },
410
- submitFeedbackFailure: {
411
- reducer() { },
412
- prepare(chatMessageId, error) {
413
- return { payload: { chatMessageId, error } };
414
- },
415
- },
416
386
  clearInput(draft) {
417
387
  draft.uiState.currentInput = '';
418
388
  },
@@ -511,5 +481,5 @@ const aiCfoView = createSlice({
511
481
  },
512
482
  },
513
483
  });
514
- export const { submitQuestion, submitQuestionSuccess, submitQuestionFailure, updateResponseState, updateAiCfoViewScrollPosition, updateCurrentInput, submitFeedback, submitFeedbackSuccess, submitFeedbackFailure, clearInput, setSession, createSession, createSessionSuccess, createSessionFailure, createSessionAndSubmit, initializeNewSessionState, createSessionAndSubmitSuccess, createSessionAndSubmitFailure, fetchChatSessionsForUser, fetchChatSessionsForUserSuccess, fetchChatSessionsForUserFailure, fetchChatHistory, fetchChatHistorySuccess, fetchChatHistoryFailure, clearCurrentSessionId, clearLastContextMessage, stopSubmit, stopSubmitSuccess, stopSubmitFailure, stopSubmitQuestion, stopSubmitQuestionSuccess, stopSubmitQuestionFailure, acceptMasterTOS, acceptMasterTOSSuccess, acceptMasterTOSFailure, deleteChatSession, deleteChatSessionSuccess, deleteChatSessionFailure, clearDeleteChatSessionStatus, clearAiCfoView, updateCotCollapsedState, fetchSuggestedQuestions, fetchSuggestedQuestionsSuccess, fetchSuggestedQuestionsFailure, fetchSkills, fetchSkillsSuccess, fetchSkillsFailure, applyAiCfoSidePanelHostPageTransition, clearAiCfoSidePanelHostPageContext, } = aiCfoView.actions;
484
+ export const { submitQuestion, submitQuestionSuccess, submitQuestionFailure, updateResponseState, updateAiCfoViewScrollPosition, updateCurrentInput, clearInput, setSession, createSession, createSessionSuccess, createSessionFailure, createSessionAndSubmit, initializeNewSessionState, createSessionAndSubmitSuccess, createSessionAndSubmitFailure, fetchChatSessionsForUser, fetchChatSessionsForUserSuccess, fetchChatSessionsForUserFailure, fetchChatHistory, fetchChatHistorySuccess, fetchChatHistoryFailure, clearCurrentSessionId, clearLastContextMessage, stopSubmit, stopSubmitSuccess, stopSubmitFailure, stopSubmitQuestion, stopSubmitQuestionSuccess, stopSubmitQuestionFailure, acceptMasterTOS, acceptMasterTOSSuccess, acceptMasterTOSFailure, deleteChatSession, deleteChatSessionSuccess, deleteChatSessionFailure, clearDeleteChatSessionStatus, clearAiCfoView, updateCotCollapsedState, fetchSuggestedQuestions, fetchSuggestedQuestionsSuccess, fetchSuggestedQuestionsFailure, fetchSkills, fetchSkillsSuccess, fetchSkillsFailure, applyAiCfoSidePanelHostPageTransition, clearAiCfoSidePanelHostPageContext, } = aiCfoView.actions;
515
485
  export default aiCfoView.reducer;
@@ -2,39 +2,14 @@ import { of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
3
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
4
4
  import { fetchSkills, fetchSkillsFailure, fetchSkillsSuccess, } from '../aiCfoViewReducer';
5
- const isNonBlankString = (value) => typeof value === 'string' && value.trim() !== '';
6
- // parameter_hints is a free-form {param: exampleValue(s)} map; flatten its non-blank
7
- // string values (a single string or an array of them) into display-ready "try: …"
8
- // phrases. The container check is a runtime guard, not a type check: /1.0/skills is not
9
- // schema-validated, so a malformed non-object payload would otherwise make Object.values
10
- // split a string into characters.
11
- const toExampleHints = (parameterHints) => {
12
- if (parameterHints == null ||
13
- typeof parameterHints !== 'object' ||
14
- Array.isArray(parameterHints)) {
15
- return [];
16
- }
17
- const hints = Object.values(parameterHints).flatMap((value) => {
18
- if (isNonBlankString(value)) {
19
- return [value.trim()];
20
- }
21
- if (Array.isArray(value)) {
22
- return value.filter(isNonBlankString).map((item) => item.trim());
23
- }
24
- return [];
25
- });
26
- // The menu joins these into one flat "try: a · b" line, so a repeated phrase reads as
27
- // a broken duplicate to the user — dedupe across parameter keys and array entries.
28
- return Array.from(new Set(hints));
29
- };
30
- const toSkill = (skillSummaryPayload) => ({
31
- macroId: skillSummaryPayload.macro_id,
32
- name: skillSummaryPayload.name,
33
- displayName: skillSummaryPayload.display_name,
34
- description: skillSummaryPayload.description,
35
- semver: skillSummaryPayload.semver,
36
- exampleHints: toExampleHints(skillSummaryPayload.parameter_hints),
37
- hasScripts: skillSummaryPayload.has_scripts,
5
+ const toSkill = (s) => ({
6
+ macroId: s.macro_id,
7
+ name: s.name,
8
+ displayName: s.display_name,
9
+ description: s.description,
10
+ semver: s.semver,
11
+ parameterHints: s.parameter_hints,
12
+ hasScripts: s.has_scripts,
38
13
  });
39
14
  /** GET {aiCfoMicroServiceBaseUrl}/1.0/skills — chat-visible skills for the `/` menu. */
40
15
  export const fetchSkillsEpic = (actions$,
@@ -18,9 +18,6 @@ export const fetchCompanyTaskManagerViewEpic = (actions$, _state$, zeniAPI) => a
18
18
  ...(filters?.categories != null && filters.categories.length > 0
19
19
  ? { filter_by: toFilterByPayload(filters) }
20
20
  : {}),
21
- task_group_scopes: filters?.taskGroupScopes != null && filters.taskGroupScopes.length > 0
22
- ? filters.taskGroupScopes
23
- : ['internal'],
24
21
  };
25
22
  return zeniAPI
26
23
  .getJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/cockpit-panels/tasks-es?query=${encodeURIComponent(JSON.stringify(queryValue))}`)
@@ -3,13 +3,7 @@ import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
3
  import { isSuccessResponse } from '../../../responsePayload';
4
4
  import { fetchTaskManagerMetrics, updateTaskManagerMetrics, updateTaskManagerMetricsOnFailure, } from '../companyTaskManagerViewReducer';
5
5
  export const fetchTaskManagerMetricsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchTaskManagerMetrics.match), switchMap(() => {
6
- // Include subtasks so the cockpit count matches the customer dashboard
7
- // pending count. The dashboard counts every task (subtasks included);
8
- // cockpit's default of include_subtasks=false otherwise undercounts.
9
- const query = JSON.stringify({
10
- is_filter_by_logged_in_user: true,
11
- include_subtasks: true,
12
- });
6
+ const query = JSON.stringify({ is_filter_by_logged_in_user: true });
13
7
  return zeniAPI
14
8
  .getJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/cockpit-panels/tasks-es-metrics?query=${encodeURIComponent(query)}`)
15
9
  .pipe(mergeMap((response) => {
@@ -168,13 +168,6 @@ const expenseAutomationTransactionsView = createSlice({
168
168
  if (searchString !== undefined) {
169
169
  draft.transactionCategorizationView[selectedTab].uiState.searchString =
170
170
  searchString;
171
- // When search is cleared, drop all sub-tab snapshots. A snapshot
172
- // captured while search was active holds filtered row IDs — restoring
173
- // it after the clear would show stale search results instead of the
174
- // full unfiltered list.
175
- if (searchString === '' && selectedTab === 'autoCategorized') {
176
- draft.autoCategorizedSubTabCache = {};
177
- }
178
171
  }
179
172
  draft.transactionCategorizationView[selectedTab].error = undefined;
180
173
  const monthYearPeriod = {
@@ -28,7 +28,6 @@ export const initializeTaskToLocalStoreEpic = (actions$, state$) => actions$.pip
28
28
  recurringStartDate: task.recurringStartDate,
29
29
  timeSpent: task.timeSpent,
30
30
  isPrivate: task.isPrivate,
31
- taskGroupId: task.taskGroupIds[0],
32
31
  };
33
32
  const actions = [
34
33
  saveTaskUpdatesToLocalStore({ taskDetailLocalData, taskId }),
@@ -6,52 +6,23 @@ import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
6
6
  import { updateTasks } from '../../../../entity/task/taskReducer';
7
7
  import { getTaskById } from '../../../../entity/task/taskSelector';
8
8
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
9
- import { removeTaskFromGroupBucket, updateTaskListOnNewTaskCreationSuccess, } from '../../taskListView/taskListReducer';
9
+ import { updateTaskListOnNewTaskCreationSuccess } from '../../taskListView/taskListReducer';
10
10
  import { saveTaskDetail, saveTaskSuccessOrFailure } from '../taskDetailReducer';
11
11
  export const saveTaskDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(saveTaskDetail.match), mergeMap((action) => {
12
12
  const { taskId, taskGroupId } = action.payload;
13
13
  const state = state$.value;
14
14
  const isTaskListFetched = state.taskListState.fetchState === 'Completed';
15
- // On edit, prefer the locally-edited group; fall back to the entity's
16
- // current group. On create, use the taskGroupId from the action payload.
17
- const localTaskGroupId = taskId != null
18
- ? state.taskDetailState.editTaskStateById[taskId]?.taskDetailLocalData
19
- ?.taskGroupId
20
- : undefined;
21
- // groupWasCleared distinguishes "user explicitly cleared the group"
22
- // (localTaskGroupId === null → send []) from "user did not touch it"
23
- // (undefined → fall back to entity). Without this, the `??` fallback
24
- // would resurrect the stale entity value after a clear.
25
- const groupWasCleared = taskId != null && localTaskGroupId === null;
26
- const entityTaskGroupIds = taskId != null
27
- ? (getTaskById(state.taskState, taskId)?.taskGroupIds ?? [])
28
- : [];
29
- // Distinguish three save shapes:
30
- // - cleared → []
31
- // - user picked a different group locally → [localTaskGroupId]
32
- // - no local edit → entire entityTaskGroupIds (preserves multi-
33
- // group membership; without this, unrelated field edits silently
34
- // drop extra groups).
35
- const localGroupChanged = localTaskGroupId != null;
36
- const taskGroupIdsForPayload = groupWasCleared
37
- ? []
38
- : localGroupChanged
39
- ? [localTaskGroupId]
40
- : taskId != null
41
- ? entityTaskGroupIds
42
- : taskGroupId != null
43
- ? [taskGroupId]
44
- : [];
45
- // Keep `updatedTaskGroupId` (single id) for downstream list-update
46
- // dispatches that still bucket against one group at a time.
47
- const updatedTaskGroupId = taskGroupIdsForPayload[0];
48
- const payload = prepareTaskPayload(state, taskId, taskGroupIdsForPayload);
15
+ const updatedTaskGroupId = taskId == null
16
+ ? taskGroupId
17
+ : getTaskById(state.taskState, taskId)?.taskGroupIds[0];
18
+ const payload = prepareTaskPayload(state, taskId, updatedTaskGroupId);
49
19
  const saveTaskApi = taskId != null
50
20
  ? zeniAPI.putAndGetJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/tasks/${taskId}`, payload)
51
21
  : zeniAPI.postAndGetJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/tasks`, payload);
52
22
  return saveTaskApi.pipe(mergeMap((response) => {
53
23
  if (isSuccessResponse(response) &&
54
24
  response.data != null &&
25
+ updatedTaskGroupId != null &&
55
26
  response.data.tasks.length > 0) {
56
27
  const newTaskId = response.data.tasks[0].task_id;
57
28
  const actions = [
@@ -62,24 +33,7 @@ export const saveTaskDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(f
62
33
  taskId,
63
34
  }),
64
35
  ];
65
- // Only suppress the list-insert on the live/completed tabs
66
- // when the saved task's status no longer matches the tab —
67
- // otherwise doUpdateTaskList writes the row back into the
68
- // current tab's grouping arrays even after updateTasks moved
69
- // it to Completed. Archived/snoozed/deleted are owned by
70
- // their dedicated actions and must keep the pre-PR optimistic
71
- // update path so their grouping arrays don't go stale.
72
- const savedTask = response.data.tasks[0];
73
- const savedIsCompleted = savedTask.status?.code === 'resolved';
74
- const activeTab = state.taskListState.currentTab;
75
- const isLiveOrCompletedTab = activeTab === 'live' || activeTab === 'completed';
76
- const statusMatchesActiveTab = !isLiveOrCompletedTab ||
77
- (savedIsCompleted && activeTab === 'completed') ||
78
- (!savedIsCompleted && activeTab === 'live');
79
- if (isTaskListFetched === true &&
80
- groupWasCleared === false &&
81
- updatedTaskGroupId != null &&
82
- statusMatchesActiveTab === true) {
36
+ if (isTaskListFetched === true) {
83
37
  actions.push(updateTaskListOnNewTaskCreationSuccess({
84
38
  taskGroupId: updatedTaskGroupId,
85
39
  task: response.data.tasks[0],
@@ -88,21 +42,6 @@ export const saveTaskDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(f
88
42
  : undefined,
89
43
  }));
90
44
  }
91
- else if (isTaskListFetched === true &&
92
- groupWasCleared === true &&
93
- taskId != null) {
94
- // Group was cleared — skip the list-insert action (no
95
- // destination bucket) and explicitly drop the row from every
96
- // previously-held group so the list re-renders without the
97
- // stale entry under the old group until next refetch.
98
- const previousTask = getTaskById(state.taskState, taskId);
99
- previousTask?.taskGroupIds.forEach((previousGroupId) => {
100
- actions.push(removeTaskFromGroupBucket({
101
- taskId,
102
- taskGroupId: previousGroupId,
103
- }));
104
- });
105
- }
106
45
  return from(actions);
107
46
  }
108
47
  else {
@@ -128,7 +67,7 @@ export const saveTaskDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(f
128
67
  error: createZeniAPIStatus('Unexpected Error', 'Save Task REST API call errored out' + JSON.stringify(error)),
129
68
  }))));
130
69
  }));
131
- const prepareTaskPayload = (state, taskId, taskGroupIds) => {
70
+ const prepareTaskPayload = (state, taskId, taskGroupId) => {
132
71
  const { taskDetailState, taskState } = state;
133
72
  const syncToken = taskId != null ? (getTaskById(taskState, taskId)?.syncToken ?? '') : '';
134
73
  const sourceState = taskId != null
@@ -157,7 +96,7 @@ const prepareTaskPayload = (state, taskId, taskGroupIds) => {
157
96
  ? (localData.recurringDaysOfWeek ?? [])
158
97
  : [],
159
98
  sync_token: syncToken,
160
- task_group_ids: taskGroupIds,
99
+ task_group_ids: taskGroupId != null ? [taskGroupId] : [],
161
100
  time_spent: convertHHMMStrToMinutes(localData.timeSpent),
162
101
  group_assignees: localData.groupAssignees,
163
102
  ...(taskId == null ? { is_private: localData.isPrivate ?? false } : {}),
@@ -6,11 +6,6 @@ import { initialTaskDetail, } from './taskDetail';
6
6
  export const initialState = {
7
7
  newTaskState: initialTaskDetail,
8
8
  editTaskStateById: {},
9
- subTaskCreateStatus: {
10
- fetchState: 'Not-Started',
11
- error: undefined,
12
- },
13
- subTaskListFetchStatusByParentId: {},
14
9
  taskHistoryById: {},
15
10
  };
16
11
  const taskDetailView = createSlice({
@@ -55,7 +50,7 @@ const taskDetailView = createSlice({
55
50
  updateEditTaskFetchStatus(draft, action) {
56
51
  const { taskId, fetchState, error } = action.payload;
57
52
  draft.editTaskStateById[taskId] = {
58
- ...(draft.editTaskStateById[taskId] ?? initialTaskDetail),
53
+ ...draft.editTaskStateById[taskId],
59
54
  fetchTaskStatus: {
60
55
  fetchState,
61
56
  error: fetchState === 'Error' ? error : undefined,
@@ -323,59 +318,10 @@ const taskDetailView = createSlice({
323
318
  error,
324
319
  };
325
320
  },
326
- createSubTask: {
327
- reducer(draft) {
328
- draft.subTaskCreateStatus = {
329
- fetchState: 'In-Progress',
330
- error: undefined,
331
- };
332
- },
333
- prepare(payload) {
334
- return { payload };
335
- },
336
- },
337
- createSubTaskSuccessOrFailure(draft, action) {
338
- const { fetchState, error } = action.payload;
339
- draft.subTaskCreateStatus = {
340
- fetchState,
341
- error,
342
- };
343
- },
344
- resetSubTaskCreateStatus(draft) {
345
- draft.subTaskCreateStatus = {
346
- ...initialState.subTaskCreateStatus,
347
- };
348
- },
349
- fetchSubTasks: {
350
- reducer(draft, action) {
351
- const { parentTaskId } = action.payload;
352
- draft.subTaskListFetchStatusByParentId[parentTaskId] = {
353
- fetchState: 'In-Progress',
354
- error: undefined,
355
- };
356
- },
357
- prepare(parentTaskId) {
358
- return { payload: { parentTaskId } };
359
- },
360
- },
361
- updateSubTasks(draft, action) {
362
- const { parentTaskId } = action.payload;
363
- draft.subTaskListFetchStatusByParentId[parentTaskId] = {
364
- fetchState: 'Completed',
365
- error: undefined,
366
- };
367
- },
368
- updateSubTasksFetchStatus(draft, action) {
369
- const { parentTaskId, fetchState, error } = action.payload;
370
- draft.subTaskListFetchStatusByParentId[parentTaskId] = {
371
- fetchState,
372
- error,
373
- };
374
- },
375
321
  clearTaskDetail(draft) {
376
322
  Object.assign(draft, initialState);
377
323
  },
378
324
  },
379
325
  });
380
- export const { fetchTaskDetailPage, fetchTaskDetail, initializeTaskToLocalStore, updateEditTaskFetchStatus, saveTaskUpdatesToLocalStore, discardTaskUpdatesInLocalStore, saveTaskDetail, archiveTask, archiveTaskSuccessOrFailure, saveTaskSuccessOrFailure, createSubTask, createSubTaskSuccessOrFailure, resetSubTaskCreateStatus, fetchSubTasks, updateSubTasks, updateSubTasksFetchStatus, deleteTask, removeTaskDetail, deleteTaskSuccessOrFailure, snoozeTask, snoozeTaskSuccessOrFailure, unsnoozeTask, fetchTaskHistory, updateTaskHistory, updateTaskHistoryFetchStatus, clearTaskDetail, updateCreatedTagToLocalStore, updateDeletedTagToLocalStore, } = taskDetailView.actions;
326
+ export const { fetchTaskDetailPage, fetchTaskDetail, initializeTaskToLocalStore, updateEditTaskFetchStatus, saveTaskUpdatesToLocalStore, discardTaskUpdatesInLocalStore, saveTaskDetail, archiveTask, archiveTaskSuccessOrFailure, saveTaskSuccessOrFailure, deleteTask, removeTaskDetail, deleteTaskSuccessOrFailure, snoozeTask, snoozeTaskSuccessOrFailure, unsnoozeTask, fetchTaskHistory, updateTaskHistory, updateTaskHistoryFetchStatus, clearTaskDetail, updateCreatedTagToLocalStore, updateDeletedTagToLocalStore, } = taskDetailView.actions;
381
327
  export default taskDetailView.reducer;
@@ -1,8 +1,8 @@
1
1
  import isEqual from 'lodash/isEqual';
2
- import { reduceAnyFetchState } from '../../../commonStateTypes/reduceFetchState';
2
+ import { reduceFetchState } from '../../../commonStateTypes/reduceFetchState';
3
3
  import { getClassesByIds } from '../../../entity/class/classSelector';
4
4
  import { getFilesByFileIds } from '../../../entity/file/fileSelector';
5
- import { getTaskById, getTasksByIds } from '../../../entity/task/taskSelector';
5
+ import { getTaskById } from '../../../entity/task/taskSelector';
6
6
  import { getUserAndUserRole, } from '../../companyView/types/userAndRole';
7
7
  import { getFileDeleteStatusById, getFileUpdateNameStatusById, } from '../../fileView/fileViewSelector';
8
8
  import { getUserList, } from '../../userListView/userListViewSelector';
@@ -24,58 +24,40 @@ export const getTaskDetail = (state, taskId) => {
24
24
  let createdByUser = undefined;
25
25
  let isArchived = undefined;
26
26
  let isDeleted = undefined;
27
- let depth = undefined;
28
27
  let recurringSourceTaskId = undefined;
29
28
  let snoozedUntil = undefined;
30
29
  let taskGroupId = undefined;
31
- let subtasks = [];
32
30
  if (taskId != null && sourceTaskDetail != null) {
33
31
  const taskEntity = getTaskById(taskState, taskId);
34
- subtasks =
35
- taskEntity != null
36
- ? getTasksByIds(taskState, taskEntity.subTasksIds)
37
- : [];
38
32
  const fileIdsInEntity = taskEntity?.fileIds ?? [];
39
33
  if (taskEntity != null) {
40
34
  createdByUser = getUserAndUserRole(userState, userRoleState, addressState, taskEntity.createdBy);
41
- depth = taskEntity.depth;
42
35
  isArchived = taskEntity.isArchived;
43
36
  isDeleted = taskEntity.isDeleted;
44
37
  recurringSourceTaskId = taskEntity.recurringSourceTaskId;
45
38
  snoozedUntil = taskEntity.snoozedUntil;
46
39
  taskGroupId = taskEntity.taskGroupIds[0];
47
40
  }
48
- // Treat "no entry" as Completed so it doesn't block the combined
49
- // fetch state. The Not-Started default would pin the detail page
50
- // below Completed forever before the first fetchSubTasks dispatches.
51
- const completedSubTaskStatus = {
52
- fetchState: 'Completed',
53
- error: undefined,
54
- };
55
- const subTaskStatus = taskDetailState.subTaskListFetchStatusByParentId[taskId] ??
56
- completedSubTaskStatus;
57
41
  if (fileIdsInEntity.length > 0) {
58
- fetchStatus = reduceAnyFetchState([
42
+ fetchStatus = reduceFetchState([
59
43
  fileViewState.fetchFilesStatus,
60
44
  sourceTaskDetail.fetchTaskStatus,
61
45
  userList,
62
46
  classListState,
63
- subTaskStatus,
64
47
  ]);
65
48
  }
66
49
  else {
67
- fetchStatus = reduceAnyFetchState([
50
+ fetchStatus = reduceFetchState([
68
51
  sourceTaskDetail.fetchTaskStatus,
69
52
  userList,
70
53
  classListState,
71
- subTaskStatus,
72
54
  ]);
73
55
  }
74
56
  showTaskDetailFormFooter = showFormFooter(sourceTaskDetail.taskDetailLocalData, taskEntity);
75
57
  taskHistory = taskDetailState.taskHistoryById[taskId]?.historicEvents ?? [];
76
58
  }
77
59
  else if (taskId == null) {
78
- fetchStatus = reduceAnyFetchState([userList, classListState]);
60
+ fetchStatus = reduceFetchState([userList, classListState]);
79
61
  }
80
62
  const { classIds } = classListState;
81
63
  const allAccountingClasses = getClassesByIds(classState, {
@@ -102,14 +84,12 @@ export const getTaskDetail = (state, taskId) => {
102
84
  error: fetchStatus.error,
103
85
  version: 0,
104
86
  createdByUser,
105
- depth,
106
87
  isArchived,
107
88
  isDeleted,
108
89
  recurringSourceTaskId,
109
90
  showTaskDetailFormFooter,
110
91
  snoozedUntil,
111
92
  taskGroupId,
112
- subtasks,
113
93
  };
114
94
  };
115
95
  export const allTaskStatus = [
@@ -157,16 +137,13 @@ export const allTaskPriority = [
157
137
  },
158
138
  ];
159
139
  const showFormFooter = (taskDetailLocalData, taskDetailInStore) => {
160
- if (taskDetailInStore == null) {
161
- return false;
162
- }
163
- if (taskDetailLocalData.name !== taskDetailInStore.name ||
140
+ if (taskDetailLocalData.name !== taskDetailInStore?.name ||
164
141
  taskDetailLocalData.description !== taskDetailInStore.description ||
165
142
  taskDetailLocalData.priority !== taskDetailInStore.priority.code ||
166
143
  taskDetailLocalData.status !== taskDetailInStore.status.code ||
167
144
  !isEqual(taskDetailInStore.tagIds, taskDetailLocalData.tagIds) ||
168
- !isEqual(taskDetailLocalData.assignee, taskDetailInStore.assignees ?? []) ||
169
- !isEqual(taskDetailLocalData.groupAssignees, taskDetailInStore.groupAssignees ?? []) ||
145
+ !isEqual(taskDetailLocalData.assignee, taskDetailInStore?.assignees ?? []) ||
146
+ !isEqual(taskDetailLocalData.groupAssignees, taskDetailInStore?.groupAssignees ?? []) ||
170
147
  !isEqual(taskDetailLocalData.fileIds, taskDetailInStore.fileIds ?? []) ||
171
148
  !isEqual(taskDetailLocalData.dueDate, taskDetailInStore.dueDate) ||
172
149
  !isEqual(taskDetailLocalData.type, taskDetailInStore.type) ||
@@ -174,10 +151,7 @@ const showFormFooter = (taskDetailLocalData, taskDetailInStore) => {
174
151
  !isEqual(taskDetailLocalData.recurringFrequency, taskDetailInStore.recurringFrequency) ||
175
152
  !isEqual(taskDetailLocalData.recurringDaysOfWeek, taskDetailInStore.recurringDaysOfWeek) ||
176
153
  !isEqual(taskDetailLocalData.recurringStartDate, taskDetailInStore.recurringStartDate) ||
177
- !isEqual(taskDetailLocalData.timeSpent, taskDetailInStore.timeSpent) ||
178
- !isEqual(taskDetailLocalData.taskGroupId, taskDetailInStore.taskGroupIds.length > 0
179
- ? taskDetailInStore.taskGroupIds[0]
180
- : undefined)) {
154
+ !isEqual(taskDetailLocalData.timeSpent, taskDetailInStore.timeSpent)) {
181
155
  return true;
182
156
  }
183
157
  return false;
@@ -9,17 +9,15 @@ export const fetchTaskListEpic = (actions$, _state$, zeniAPI) => actions$.pipe(f
9
9
  .getJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/tasks?query=${encodeURIComponent(`{"task_type": "all"}`)}`)
10
10
  .pipe(mergeMap((response) => {
11
11
  if (isSuccessResponse(response) && response.data != null) {
12
- const { tasks, deleted, archived, snoozed, completed } = response.data;
12
+ const { tasks, deleted, archived, snoozed } = response.data;
13
13
  const allTasks = [
14
14
  ...tasks,
15
- ...(completed ?? []),
16
15
  ...(deleted ?? []),
17
16
  ...(archived ?? []),
18
17
  ...(snoozed ?? []),
19
18
  ];
20
19
  return of(updateTasks(allTasks), updateTaskList({
21
20
  data: tasks,
22
- completed: completed ?? [],
23
21
  deleted: deleted ?? [],
24
22
  archived: archived ?? [],
25
23
  snoozed: snoozed ?? [],
@@ -1,7 +1,6 @@
1
1
  import { stringToUnion, stringToUnionStrict, } from '../../../commonStateTypes/stringToUnion';
2
2
  export const ALL_TASK_LIST_TABS = [
3
3
  'live',
4
- 'completed',
5
4
  'archived',
6
5
  'deleted',
7
6
  'snoozed',