@zeniai/client-epic-state 5.1.45 → 5.1.46

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 +3 -0
  3. package/lib/entity/task/taskPayload.d.ts +3 -1
  4. package/lib/entity/task/taskPayload.js +24 -2
  5. package/lib/entity/task/taskReducer.d.ts +8 -1
  6. package/lib/entity/task/taskReducer.js +29 -4
  7. package/lib/entity/task/taskState.d.ts +2 -0
  8. package/lib/entity/tenant/epic/saveExternalConnectionEpic.d.ts +2 -1
  9. package/lib/entity/tenant/epic/saveExternalConnectionEpic.js +17 -0
  10. package/lib/epic.d.ts +6 -3
  11. package/lib/epic.js +6 -3
  12. package/lib/esm/entity/snackbar/snackbarTypes.js +3 -0
  13. package/lib/esm/entity/task/taskPayload.js +24 -2
  14. package/lib/esm/entity/task/taskReducer.js +28 -3
  15. package/lib/esm/entity/tenant/epic/saveExternalConnectionEpic.js +17 -0
  16. package/lib/esm/epic.js +6 -3
  17. package/lib/esm/index.js +8 -8
  18. package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +31 -1
  19. package/lib/esm/view/aiCfoView/epics/fetchSkillsEpic.js +33 -8
  20. package/lib/esm/view/aiCfoView/epics/submitFeedbackEpic.js +39 -0
  21. package/lib/esm/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +3 -0
  22. package/lib/esm/view/companyTaskManagerView/epics/fetchTaskManagerMetricsEpic.js +7 -1
  23. package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +7 -0
  24. package/lib/esm/view/taskManager/taskDetailView/epics/createSubTaskEpic.js +96 -0
  25. package/lib/esm/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.js +53 -0
  26. package/lib/esm/view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic.js +1 -0
  27. package/lib/esm/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +70 -9
  28. package/lib/esm/view/taskManager/taskDetailView/taskDetailReducer.js +56 -2
  29. package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +35 -9
  30. package/lib/esm/view/taskManager/taskListView/epics/fetchTaskListEpic.js +3 -1
  31. package/lib/esm/view/taskManager/taskListView/taskList.js +1 -0
  32. package/lib/esm/view/taskManager/taskListView/taskListReducer.js +310 -18
  33. package/lib/esm/view/taskManager/taskListView/taskListSelector.js +1 -0
  34. package/lib/esm/view/taskManager/taskListView/taskListViewHelpers.js +58 -0
  35. package/lib/esm/view/transactionDetail/epics/saveTransactionHelper.js +22 -0
  36. package/lib/esm/view/transactionDetail/epics/updateTransactionDetailEpic.js +75 -3
  37. package/lib/esm/view/transactionDetail/journalEntryLinesViewModel.js +58 -0
  38. package/lib/esm/view/transactionDetail/transactionDetailLocalDataHelper.js +10 -8
  39. package/lib/esm/view/transactionDetail/transactionDetailReducer.js +66 -1
  40. package/lib/index.d.ts +12 -11
  41. package/lib/index.js +37 -28
  42. package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +10 -0
  43. package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +7 -2
  44. package/lib/view/aiCfoView/aiCfoViewReducer.js +32 -2
  45. package/lib/view/aiCfoView/aiCfoViewState.d.ts +5 -1
  46. package/lib/view/aiCfoView/epics/fetchSkillsEpic.js +33 -8
  47. package/lib/view/aiCfoView/epics/submitFeedbackEpic.d.ts +13 -0
  48. package/lib/view/aiCfoView/epics/submitFeedbackEpic.js +43 -0
  49. package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +3 -0
  50. package/lib/view/companyTaskManagerView/epics/fetchTaskManagerMetricsEpic.js +7 -1
  51. package/lib/view/companyView/types/cockpitTypes.d.ts +3 -0
  52. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  53. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +7 -0
  54. package/lib/view/taskManager/taskDetailView/epics/createSubTaskEpic.d.ts +9 -0
  55. package/lib/view/taskManager/taskDetailView/epics/createSubTaskEpic.js +100 -0
  56. package/lib/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.d.ts +8 -0
  57. package/lib/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.js +57 -0
  58. package/lib/view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic.js +1 -0
  59. package/lib/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.d.ts +2 -2
  60. package/lib/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +69 -8
  61. package/lib/view/taskManager/taskDetailView/taskDetail.d.ts +15 -0
  62. package/lib/view/taskManager/taskDetailView/taskDetailReducer.d.ts +14 -2
  63. package/lib/view/taskManager/taskDetailView/taskDetailReducer.js +57 -3
  64. package/lib/view/taskManager/taskDetailView/taskDetailSelector.d.ts +3 -1
  65. package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +33 -7
  66. package/lib/view/taskManager/taskListView/epics/fetchTaskListEpic.js +3 -1
  67. package/lib/view/taskManager/taskListView/taskList.d.ts +1 -1
  68. package/lib/view/taskManager/taskListView/taskList.js +1 -0
  69. package/lib/view/taskManager/taskListView/taskListPayload.d.ts +4 -0
  70. package/lib/view/taskManager/taskListView/taskListReducer.d.ts +6 -2
  71. package/lib/view/taskManager/taskListView/taskListReducer.js +311 -19
  72. package/lib/view/taskManager/taskListView/taskListSelector.js +1 -0
  73. package/lib/view/taskManager/taskListView/taskListViewHelpers.d.ts +11 -0
  74. package/lib/view/taskManager/taskListView/taskListViewHelpers.js +60 -1
  75. package/lib/view/transactionDetail/epics/saveTransactionHelper.js +22 -0
  76. package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.d.ts +5 -1
  77. package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.js +77 -4
  78. package/lib/view/transactionDetail/journalEntryLinesViewModel.d.ts +27 -0
  79. package/lib/view/transactionDetail/journalEntryLinesViewModel.js +61 -1
  80. package/lib/view/transactionDetail/transactionDetailLocalDataHelper.js +10 -8
  81. package/lib/view/transactionDetail/transactionDetailReducer.d.ts +11 -2
  82. package/lib/view/transactionDetail/transactionDetailReducer.js +67 -2
  83. package/lib/view/transactionDetail/transactionDetailState.d.ts +8 -1
  84. package/lib/view/transactionDetail/transactionDetailTypes.d.ts +2 -0
  85. package/package.json +1 -1
@@ -21,6 +21,9 @@ const fetchCompanyTaskManagerViewEpic = (actions$, _state$, zeniAPI) => actions$
21
21
  ...(filters?.categories != null && filters.categories.length > 0
22
22
  ? { filter_by: toFilterByPayload(filters) }
23
23
  : {}),
24
+ task_group_scopes: filters?.taskGroupScopes != null && filters.taskGroupScopes.length > 0
25
+ ? filters.taskGroupScopes
26
+ : ['internal'],
24
27
  };
25
28
  return zeniAPI
26
29
  .getJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/cockpit-panels/tasks-es?query=${encodeURIComponent(JSON.stringify(queryValue))}`)
@@ -6,7 +6,13 @@ const operators_1 = require("rxjs/operators");
6
6
  const responsePayload_1 = require("../../../responsePayload");
7
7
  const companyTaskManagerViewReducer_1 = require("../companyTaskManagerViewReducer");
8
8
  const fetchTaskManagerMetricsEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(companyTaskManagerViewReducer_1.fetchTaskManagerMetrics.match), (0, operators_1.switchMap)(() => {
9
- const query = JSON.stringify({ is_filter_by_logged_in_user: true });
9
+ // Include subtasks so the cockpit count matches the customer dashboard
10
+ // pending count. The dashboard counts every task (subtasks included);
11
+ // cockpit's default of include_subtasks=false otherwise undercounts.
12
+ const query = JSON.stringify({
13
+ is_filter_by_logged_in_user: true,
14
+ include_subtasks: true,
15
+ });
10
16
  return zeniAPI
11
17
  .getJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/cockpit-panels/tasks-es-metrics?query=${encodeURIComponent(query)}`)
12
18
  .pipe((0, operators_1.mergeMap)((response) => {
@@ -25,9 +25,12 @@ export interface CockpitFilterCategory {
25
25
  valuesCombinationOperator: 'ANY' | 'ALL';
26
26
  field?: AiAccountantFilterCategoryField | ManagementViewFilterCategoryField | SubscriptionViewFilterCategoryField | PortfolioViewFilterCategoryField | HealthMonitorViewFilterCategoryField | TaskManagerViewFilterCategoryField;
27
27
  }
28
+ /** Scope filter for cockpit Bird's-Eye View task lists. */
29
+ export type TaskGroupScope = 'internal' | 'external';
28
30
  export interface CockpitFilters {
29
31
  categories?: CockpitFilterCategory[];
30
32
  categoryCombinationOperator?: 'AND' | 'OR';
33
+ taskGroupScopes?: TaskGroupScope[];
31
34
  }
32
35
  export declare const MANAGEMENT_STATUS_CODES: string[];
33
36
  export declare const toManagementStatusCodeType: (v: string) => string;
@@ -39,7 +39,7 @@ export declare const getLineItemsByTransactionsIdsFromResponse: (transactions: S
39
39
  export declare const getLineItemsByTransactionIdsFromLocalData: (transactionLocalData: TransactionReviewLocalDataSelectorView[], selectedTab: TransactionsTab) => Record<ID, string[]>;
40
40
  export declare const mergeTabSpecificLineItems: (currentTabSpecificLineItems: TabSpecificLineItems, selectedTab: TransactionsTab, newLineItems: TabSpecificLineItems) => TabSpecificLineItems;
41
41
  export declare const getSnackbarMessageForTransactionReview: (updatedCount: number, failedCount: number, categorizedCount: number) => {
42
- messageSection: "common" | "transactionDetails_updatingPastTransactions" | "transactionDetails_transactionUpdated" | "cockpit_month_end_email_sent" | "cockpit_month_end_email_save" | "cockpit_month_end_email_attachment_upload" | "je_bill_link" | "je_posted" | "audit_score_updated" | "people_invite_people" | "people_invite_multiple_people" | "people_delete_person" | "people_update_person" | "reimbursement_updated" | "reimbursement_deleted" | "reimbursement_cancelled_deleted" | "reimbursement_cancelled" | "reimbursement_approved" | "reimbursement_rejected" | "reimbursement_sent_for_approval" | "account_added" | "business_verification_save" | "business_verification_submit" | "business_verification_from_bills_submit" | "plaid_connection" | "unlink_deposit_account" | "reimbursement_setup" | "reimbursement_approval_create" | "reimbursement_duplicate_approval_create" | "reimbursement_approval_update" | "reimbursement_duplicate_approval_update" | "reimbursement_approval_delete" | "reimbursement_approval_reorder" | "reimbursement_create_mileage" | "reimbursement_update_mileage" | "reimbursement_accept_term" | "reimbursement_accept_employee_term" | "reimbursement_bulk_submit" | "reimbursement_bulk_processed" | "bill_pay_setup" | "zeni_accounts_setup" | "bill_pay_approval_create" | "bill_pay_duplicate_approval_create" | "bill_pay_approval_update" | "bill_pay_duplicate_approval_update" | "bill_pay_approval_delete" | "bill_pay_approval_reorder" | "bill_pay_updated" | "bill_pay_deleted" | "bill_pay_cancelled_deleted" | "bill_pay_cancelled" | "bill_pay_approved" | "real_time_approver_added" | "bill_pay_rejected" | "bill_pay_sent_for_approval" | "bill_pay_accept_term" | "bill_pay_bulk_submit" | "bill_pay_bulk_processed" | "bill_pay_refund" | "bill_pay_retry" | "bill_pay_marked_as_paid" | "zeni_account_accept_term" | "update_vendor" | "data_refresh_update" | "delete_bank_account" | "create_bank_account" | "create_bank_account_ach" | "create_bank_account_wire" | "create_bank_account_international" | "transfer_money" | "update_zeni_account_nickname" | "create_checking_account" | "deposit_check" | "create_vendor" | "onboarding_customer_view" | "onboarding_customer_view_complete" | "onboarding_customer_identity_verification_save" | "onboarding_customer_identity_verification_submit" | "onboarding_customer_business_verification_save" | "onboarding_customer_business_verification_submit" | "retry_bank_account_connection" | "dashboard_invite_sent" | "onboarding_info_saved" | "approve_original_merchant" | "approve_global_merchant" | "reject_global_merchant" | "create_global_merchant" | "fetch_global_merchant_no_recommendation" | "save_vendor_renamed" | "save_vendor_sent_for_review" | "save_vendor_marked_as_employee" | "save_vendor_marked_as_local_contractor" | "charge_card_setup" | "charge_card_accept_term" | "charge_card_receipt_upload" | "charge_card_resend_invite" | "charge_card_revoke_invite" | "card_policy_created" | "card_policy_updated" | "card_policy_deleted" | "charge_card_update_limit" | "charge_cards_update_limit" | "close_charge_card" | "lock_charge_card" | "lock_charge_card_card_user" | "lock_charge_cards" | "unlock_charge_card" | "unlock_charge_card_card_user" | "unlock_charge_cards" | "close_charge_cards" | "revoke_invite_charge_cards" | "charge_card_express_interest" | "create_schedule" | "save_schedule" | "delete_schedule" | "ignore_schedule" | "save_task_detail" | "fetch_task_detail" | "delete_task" | "archive_task" | "snooze_task" | "unsnooze_task" | "create_tag" | "delete_tag" | "update_charge_card" | "update_charge_card_name" | "update_charge_card_name_card_user" | "issue_charge_card" | "issue_charge_cards" | "notification_settings_saved" | "referral_invite_sent" | "notification_mark_as_read" | "mark_as_complete_schedule" | "cancel_journal_entry" | "settings_accounting_accounts_updated" | "create_card_setup" | "confirm_card_setup" | "add_card_payment_source" | "fetch_payment_sources" | "task_assigned_toast_notification" | "task_due_tomorrow_toast_notification" | "task_deleted_toast_notification" | "task_archived_toast_notification" | "task_overdue_toast_notification" | "task_overdue_toast_notification_creator" | "task_notification_count" | "task_activities_toast_notification" | "task_created_toast_notification" | "task_group_creation_success" | "task_group_deletion_success" | "task_group_update_success" | "primary_funding_account_updated" | "task_time_spent_validation" | "missing_receipts_attachment" | "flux_analysis_unreviewed" | "flux_analysis_reviewed" | "receipt_match" | "receipts_upload" | "receipts_bulk_match" | "billing_address_view" | "express_pay_submit" | "exclude_transaction" | "reconcile" | "save_reconcile_for_later" | "recon_transaction_categorize" | "recon_transaction_match" | "update_debit_card_pin_attempt" | "set_debit_card_pin" | "ai_cfo_create_session_and_submit" | "ai_cfo_chat_session_deleted" | "charge_card_auto_pay_enable" | "charge_card_auto_pay_disable" | "treasury_setup" | "treasury_accept_term" | "treasury_transfer_money" | "treasury_transfer_money_failed" | "auto_transfer_rule_create" | "auto_transfer_rule_update" | "auto_transfer_rule_delete" | "auto_transfer_rule_pause" | "auto_transfer_rule_resume" | "treasury_update_portfolio_allocation" | "send_email_magic_link_to_user" | "complete_profile_done" | "create_transfer_entry" | "reports_resync" | "invalid_phone_number" | "transactions_categorized_updated_failed" | "transaction_categorized_updated_failed" | "transactionsCategorized_transactionsUpdated" | "transactionsCategorized_transactionUpdated" | "transactionCategorized_transactionsUpdated" | "transactionCategorized_transactionUpdated" | "transactionsCategorized_transactionsFailed" | "transactionsCategorized_transactionFailed" | "transactionCategorized_transactionsFailed" | "transactionCategorized_transactionFailed" | "transactionsUpdated_transactionsFailed" | "transactionsUpdated_transactionFailed" | "transactionUpdated_transactionsFailed" | "transactionUpdated_transactionFailed" | "transactionsCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionsUpdated_transactionFailed" | "transactionsCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionUpdated_transactionFailed" | "transactionCategorized_transactionsUpdated_transactionFailed" | "transactionCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionUpdated_transactionFailed" | "accounting_classes_enabled_update" | "capitalization_threshold_update" | "account_excluded_from_reconciliation" | "account_included_in_reconciliation" | "statement_parsing_in_progress" | "statement_parsing_complete" | "ai_accountant_trigger_job" | "oauth_consent_approve" | "oauth_consent_invalid_request" | "credit_agent_update_profile" | "credit_agent_save_macro" | "credit_agent_schedule_cron";
42
+ messageSection: "common" | "transactionDetails_updatingPastTransactions" | "transactionDetails_transactionUpdated" | "cockpit_month_end_email_sent" | "cockpit_month_end_email_save" | "cockpit_month_end_email_attachment_upload" | "je_bill_link" | "je_posted" | "audit_score_updated" | "people_invite_people" | "people_invite_multiple_people" | "people_delete_person" | "people_update_person" | "reimbursement_updated" | "reimbursement_deleted" | "reimbursement_cancelled_deleted" | "reimbursement_cancelled" | "reimbursement_approved" | "reimbursement_rejected" | "reimbursement_sent_for_approval" | "account_added" | "business_verification_save" | "business_verification_submit" | "business_verification_from_bills_submit" | "plaid_connection" | "unlink_deposit_account" | "reimbursement_setup" | "reimbursement_approval_create" | "reimbursement_duplicate_approval_create" | "reimbursement_approval_update" | "reimbursement_duplicate_approval_update" | "reimbursement_approval_delete" | "reimbursement_approval_reorder" | "reimbursement_create_mileage" | "reimbursement_update_mileage" | "reimbursement_accept_term" | "reimbursement_accept_employee_term" | "reimbursement_bulk_submit" | "reimbursement_bulk_processed" | "bill_pay_setup" | "zeni_accounts_setup" | "bill_pay_approval_create" | "bill_pay_duplicate_approval_create" | "bill_pay_approval_update" | "bill_pay_duplicate_approval_update" | "bill_pay_approval_delete" | "bill_pay_approval_reorder" | "bill_pay_updated" | "bill_pay_deleted" | "bill_pay_cancelled_deleted" | "bill_pay_cancelled" | "bill_pay_approved" | "real_time_approver_added" | "bill_pay_rejected" | "bill_pay_sent_for_approval" | "bill_pay_accept_term" | "bill_pay_bulk_submit" | "bill_pay_bulk_processed" | "bill_pay_refund" | "bill_pay_retry" | "bill_pay_marked_as_paid" | "zeni_account_accept_term" | "update_vendor" | "data_refresh_update" | "delete_bank_account" | "create_bank_account" | "create_bank_account_ach" | "create_bank_account_wire" | "create_bank_account_international" | "transfer_money" | "update_zeni_account_nickname" | "create_checking_account" | "deposit_check" | "create_vendor" | "onboarding_customer_view" | "onboarding_customer_view_complete" | "onboarding_customer_identity_verification_save" | "onboarding_customer_identity_verification_submit" | "onboarding_customer_business_verification_save" | "onboarding_customer_business_verification_submit" | "retry_bank_account_connection" | "dashboard_invite_sent" | "onboarding_info_saved" | "approve_original_merchant" | "approve_global_merchant" | "reject_global_merchant" | "create_global_merchant" | "fetch_global_merchant_no_recommendation" | "save_vendor_renamed" | "save_vendor_sent_for_review" | "save_vendor_marked_as_employee" | "save_vendor_marked_as_local_contractor" | "charge_card_setup" | "charge_card_accept_term" | "charge_card_receipt_upload" | "charge_card_resend_invite" | "charge_card_revoke_invite" | "card_policy_created" | "card_policy_updated" | "card_policy_deleted" | "charge_card_update_limit" | "charge_cards_update_limit" | "close_charge_card" | "lock_charge_card" | "lock_charge_card_card_user" | "lock_charge_cards" | "unlock_charge_card" | "unlock_charge_card_card_user" | "unlock_charge_cards" | "close_charge_cards" | "revoke_invite_charge_cards" | "charge_card_express_interest" | "create_schedule" | "save_schedule" | "delete_schedule" | "ignore_schedule" | "save_task_detail" | "fetch_task_detail" | "delete_task" | "archive_task" | "snooze_task" | "unsnooze_task" | "create_tag" | "delete_tag" | "update_charge_card" | "update_charge_card_name" | "update_charge_card_name_card_user" | "issue_charge_card" | "issue_charge_cards" | "notification_settings_saved" | "referral_invite_sent" | "notification_mark_as_read" | "mark_as_complete_schedule" | "cancel_journal_entry" | "settings_accounting_accounts_updated" | "create_card_setup" | "confirm_card_setup" | "add_card_payment_source" | "fetch_payment_sources" | "task_assigned_toast_notification" | "task_due_tomorrow_toast_notification" | "task_deleted_toast_notification" | "task_archived_toast_notification" | "task_overdue_toast_notification" | "task_overdue_toast_notification_creator" | "task_notification_count" | "task_activities_toast_notification" | "task_created_toast_notification" | "task_group_creation_success" | "task_group_deletion_success" | "task_group_update_success" | "primary_funding_account_updated" | "task_time_spent_validation" | "missing_receipts_attachment" | "flux_analysis_unreviewed" | "flux_analysis_reviewed" | "receipt_match" | "receipts_upload" | "receipts_bulk_match" | "billing_address_view" | "express_pay_submit" | "exclude_transaction" | "reconcile" | "save_reconcile_for_later" | "recon_transaction_categorize" | "recon_transaction_match" | "update_debit_card_pin_attempt" | "set_debit_card_pin" | "ai_cfo_create_session_and_submit" | "ai_cfo_chat_session_deleted" | "charge_card_auto_pay_enable" | "charge_card_auto_pay_disable" | "treasury_setup" | "treasury_accept_term" | "treasury_transfer_money" | "treasury_transfer_money_failed" | "auto_transfer_rule_create" | "auto_transfer_rule_update" | "auto_transfer_rule_delete" | "auto_transfer_rule_pause" | "auto_transfer_rule_resume" | "treasury_update_portfolio_allocation" | "send_email_magic_link_to_user" | "complete_profile_done" | "create_transfer_entry" | "reports_resync" | "invalid_phone_number" | "transactions_categorized_updated_failed" | "transaction_categorized_updated_failed" | "transactionsCategorized_transactionsUpdated" | "transactionsCategorized_transactionUpdated" | "transactionCategorized_transactionsUpdated" | "transactionCategorized_transactionUpdated" | "transactionsCategorized_transactionsFailed" | "transactionsCategorized_transactionFailed" | "transactionCategorized_transactionsFailed" | "transactionCategorized_transactionFailed" | "transactionsUpdated_transactionsFailed" | "transactionsUpdated_transactionFailed" | "transactionUpdated_transactionsFailed" | "transactionUpdated_transactionFailed" | "transactionsCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionsUpdated_transactionFailed" | "transactionsCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionUpdated_transactionFailed" | "transactionCategorized_transactionsUpdated_transactionFailed" | "transactionCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionUpdated_transactionFailed" | "accounting_classes_enabled_update" | "capitalization_threshold_update" | "account_excluded_from_reconciliation" | "account_included_in_reconciliation" | "statement_parsing_in_progress" | "statement_parsing_complete" | "ai_accountant_trigger_job" | "oauth_consent_approve" | "oauth_consent_invalid_request" | "credit_agent_update_profile" | "credit_agent_save_macro" | "credit_agent_schedule_cron" | "create_sub_task" | "qbo_connection_already_linked" | "qbo_connection_failed";
43
43
  messageText: "notification" | "failed" | "success";
44
44
  type: "error" | "success" | "info";
45
45
  variables: {
@@ -175,6 +175,13 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
175
175
  if (searchString !== undefined) {
176
176
  draft.transactionCategorizationView[selectedTab].uiState.searchString =
177
177
  searchString;
178
+ // When search is cleared, drop all sub-tab snapshots. A snapshot
179
+ // captured while search was active holds filtered row IDs — restoring
180
+ // it after the clear would show stale search results instead of the
181
+ // full unfiltered list.
182
+ if (searchString === '' && selectedTab === 'autoCategorized') {
183
+ draft.autoCategorizedSubTabCache = {};
184
+ }
178
185
  }
179
186
  draft.transactionCategorizationView[selectedTab].error = undefined;
180
187
  const monthYearPeriod = {
@@ -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
- const updatedTaskGroupId = taskId == null
19
- ? taskGroupId
20
- : (0, taskSelector_1.getTaskById)(state.taskState, taskId)?.taskGroupIds[0];
21
- const payload = prepareTaskPayload(state, taskId, updatedTaskGroupId);
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
- if (isTaskListFetched === true) {
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, taskGroupId) => {
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: taskGroupId != null ? [taskGroupId] : [],
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">, deleteTask: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[taskId?: string | undefined], {
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,11 +14,13 @@ 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>;
20
21
  userList: UserListSelectorView;
21
22
  createdByUser?: UserAndRole;
23
+ depth?: number;
22
24
  isArchived?: boolean;
23
25
  isDeleted?: boolean;
24
26
  recurringSourceTaskId?: ID;