@zeniai/client-epic-state 5.1.86 → 5.1.87

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 (109) hide show
  1. package/lib/entity/aiCfo/aiCfoPayload.d.ts +7 -0
  2. package/lib/entity/aiCfo/aiCfoReducer.d.ts +3 -2
  3. package/lib/entity/aiCfo/aiCfoReducer.js +25 -2
  4. package/lib/entity/aiCfo/aiCfoState.d.ts +7 -0
  5. package/lib/entity/customerSatisfaction/customerSatisfactionReducer.d.ts +1 -1
  6. package/lib/entity/customerSatisfaction/customerSatisfactionReducer.js +6 -2
  7. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  8. package/lib/entity/snackbar/snackbarTypes.js +29 -0
  9. package/lib/esm/entity/aiCfo/aiCfoReducer.js +23 -1
  10. package/lib/esm/entity/customerSatisfaction/customerSatisfactionReducer.js +4 -1
  11. package/lib/esm/entity/snackbar/snackbarTypes.js +29 -0
  12. package/lib/esm/index.js +2 -2
  13. package/lib/esm/view/companyHealthMetricView/companyHealthMetricConfigReducer.js +4 -1
  14. package/lib/esm/view/invoicing/createCreditNote/createCreditNoteEpic.js +24 -4
  15. package/lib/esm/view/invoicing/createInvoice/createInvoiceEpic.js +24 -4
  16. package/lib/esm/view/invoicing/createInvoice/createInvoiceSelector.js +37 -10
  17. package/lib/esm/view/invoicing/discountAction/discountActionEpic.js +33 -9
  18. package/lib/esm/view/invoicing/dunningAction/dunningActionEpic.js +35 -9
  19. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +5 -1
  20. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +32 -5
  21. package/lib/esm/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +23 -3
  22. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +24 -4
  23. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +24 -4
  24. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.js +20 -3
  25. package/lib/esm/view/invoicing/invoiceAction/invoiceActionEpic.js +60 -17
  26. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +30 -0
  27. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +4 -29
  28. package/lib/esm/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +29 -10
  29. package/lib/esm/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +28 -5
  30. package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +24 -4
  31. package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +22 -14
  32. package/lib/esm/view/invoicing/recordPayment/recordPaymentEpic.js +46 -7
  33. package/lib/esm/view/invoicing/settingsView/settingsViewEpics.js +26 -8
  34. package/lib/esm/view/invoicing/settingsView/settingsViewReducer.js +1 -1
  35. package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +4 -1
  36. package/lib/esm/view/invoicing/subscriptionAction/subscriptionActionEpic.js +41 -9
  37. package/lib/esm/view/vendorFiling1099/vendorFiling1099UploadDetails/vendorFiling1099UploadDetailsReducer.js +4 -1
  38. package/lib/esm/view/vendorTabView/vendorTabViewReducer.js +4 -1
  39. package/lib/index.d.ts +6 -5
  40. package/lib/index.js +7 -7
  41. package/lib/view/companyHealthMetricView/companyHealthMetricConfigReducer.d.ts +1 -1
  42. package/lib/view/companyHealthMetricView/companyHealthMetricConfigReducer.js +5 -2
  43. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  44. package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.d.ts +2 -1
  45. package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.js +23 -3
  46. package/lib/view/invoicing/createInvoice/createInvoiceEpic.d.ts +2 -1
  47. package/lib/view/invoicing/createInvoice/createInvoiceEpic.js +23 -3
  48. package/lib/view/invoicing/createInvoice/createInvoiceSelector.d.ts +22 -8
  49. package/lib/view/invoicing/createInvoice/createInvoiceSelector.js +37 -10
  50. package/lib/view/invoicing/discountAction/discountActionEpic.d.ts +2 -1
  51. package/lib/view/invoicing/discountAction/discountActionEpic.js +32 -8
  52. package/lib/view/invoicing/dunningAction/dunningActionEpic.d.ts +2 -1
  53. package/lib/view/invoicing/dunningAction/dunningActionEpic.js +34 -8
  54. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.d.ts +3 -1
  55. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +5 -1
  56. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.d.ts +2 -1
  57. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +31 -4
  58. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.d.ts +2 -1
  59. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +22 -2
  60. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.d.ts +2 -1
  61. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +23 -3
  62. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.d.ts +2 -1
  63. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +23 -3
  64. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.d.ts +2 -1
  65. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.js +19 -2
  66. package/lib/view/invoicing/invoiceAction/invoiceActionEpic.d.ts +2 -1
  67. package/lib/view/invoicing/invoiceAction/invoiceActionEpic.js +59 -16
  68. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewPayload.d.ts +13 -0
  69. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.d.ts +1 -1
  70. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +30 -0
  71. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.d.ts +11 -31
  72. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +4 -29
  73. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewState.d.ts +15 -0
  74. package/lib/view/invoicing/invoicingQboView/epics/invoicingQboViewActionType.d.ts +2 -1
  75. package/lib/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +28 -9
  76. package/lib/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +27 -4
  77. package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.d.ts +2 -1
  78. package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +23 -3
  79. package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.d.ts +24 -7
  80. package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +23 -16
  81. package/lib/view/invoicing/recordPayment/recordPaymentEpic.d.ts +2 -1
  82. package/lib/view/invoicing/recordPayment/recordPaymentEpic.js +45 -6
  83. package/lib/view/invoicing/settingsView/settingsViewEpics.d.ts +2 -1
  84. package/lib/view/invoicing/settingsView/settingsViewEpics.js +25 -7
  85. package/lib/view/invoicing/settingsView/settingsViewReducer.d.ts +10 -1
  86. package/lib/view/invoicing/settingsView/settingsViewReducer.js +1 -1
  87. package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +4 -2
  88. package/lib/view/invoicing/settingsView/settingsViewSelector.js +4 -1
  89. package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.d.ts +2 -1
  90. package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.js +40 -8
  91. package/lib/view/vendorFiling1099/vendorFiling1099UploadDetails/vendorFiling1099UploadDetailsReducer.d.ts +1 -1
  92. package/lib/view/vendorFiling1099/vendorFiling1099UploadDetails/vendorFiling1099UploadDetailsReducer.js +5 -2
  93. package/lib/view/vendorTabView/vendorTabViewReducer.d.ts +1 -1
  94. package/lib/view/vendorTabView/vendorTabViewReducer.js +5 -2
  95. package/package.json +1 -1
  96. package/lib/__testHelpers__/apiFailure.json +0 -6
  97. package/lib/entity/vendor/__mocks__/vendorMock.d.ts +0 -7
  98. package/lib/entity/vendor/__mocks__/vendorMock.js +0 -311
  99. package/lib/entity/vendor/__mocks__/vendorStateMocks.d.ts +0 -8
  100. package/lib/entity/vendor/__mocks__/vendorStateMocks.js +0 -415
  101. package/lib/view/accountMappingView/__mocks__/accountMappingSelectorMock.d.ts +0 -11
  102. package/lib/view/accountMappingView/__mocks__/accountMappingSelectorMock.js +0 -4659
  103. package/lib/view/addressView/__mocks__/addressViewMocks.d.ts +0 -35
  104. package/lib/view/addressView/__mocks__/addressViewMocks.js +0 -239
  105. package/lib/view/addressView/__mocks__/json/createAddressResponse.json +0 -23
  106. package/lib/view/addressView/__mocks__/json/createCompanyAddressSuccess.json +0 -258
  107. package/lib/view/addressView/__mocks__/json/createCompanyUserAddressSuccess.json +0 -418
  108. package/lib/view/addressView/__mocks__/json/fetchAddressResponse.json +0 -24
  109. package/lib/view/addressView/__mocks__/json/updateAddressResponse.json +0 -24
@@ -1,3 +1,4 @@
1
+ import { ID } from '../../commonStateTypes/common';
1
2
  import { ZeniAPIResponse } from '../../responsePayload';
2
3
  export interface TableVisualizationPayload {
3
4
  columns: string[];
@@ -101,10 +102,16 @@ export interface AiCfoAnswerPayload {
101
102
  artifact?: string | null;
102
103
  artifact_host_url?: string | null;
103
104
  artifact_title?: string | null;
105
+ exports?: AiCfoExportPayload[] | null;
104
106
  follow_up_questions?: string[];
105
107
  suggested_reply?: string | null;
106
108
  table?: AiCfoVisualizationPayload | null;
107
109
  }
110
+ export interface AiCfoExportPayload {
111
+ export_id: ID;
112
+ name: string;
113
+ size_bytes: number | null;
114
+ }
108
115
  export interface ChatSessionPayload {
109
116
  chat_session_id: string;
110
117
  chat_session_summary: string | null;
@@ -1,10 +1,11 @@
1
1
  import { ID } from '../../commonStateTypes/common';
2
2
  import { ZeniDate } from '../../zeniDayJS';
3
- import { AiCfoAnswerPayload, AiCfoVisualizationPayload, ChatSessionPayload, MessagePayload } from './aiCfoPayload';
4
- import { AiCfoState, AiCfoVisualization, FileAttachmentMetadata, SyntheticAiCfoAnswerKind } from './aiCfoState';
3
+ import { AiCfoAnswerPayload, AiCfoExportPayload, AiCfoVisualizationPayload, ChatSessionPayload, MessagePayload } from './aiCfoPayload';
4
+ import { AiCfoExport, AiCfoState, AiCfoVisualization, FileAttachmentMetadata, SyntheticAiCfoAnswerKind } from './aiCfoState';
5
5
  import type { CardPolicyUploadSource, CardPolicyWizardPlan } from './aiCfoState';
6
6
  export declare const initialAiCfoState: AiCfoState;
7
7
  export declare const toAiCfoVisualization: (visualization: AiCfoVisualizationPayload) => AiCfoVisualization | undefined;
8
+ export declare const toAiCfoExports: (payload: AiCfoExportPayload[] | null | undefined) => AiCfoExport[] | undefined;
8
9
  export declare const setNewSession: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
9
10
  chatSessionId: ID;
10
11
  createdAt: ZeniDate;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.clearSyntheticAiCfoAnswers = exports.removeSyntheticAiCfoAnswer = exports.updateSyntheticAiCfoAnswer = exports.appendSyntheticAiCfoAnswer = exports.updateAiCfoAnswerCardPolicyWizardPlan = exports.deleteQuestion = exports.clearAiCfo = exports.addQuestionPayload = exports.upsertOrAddQuestionAnswerPayload = exports.upsertAnswerPayload = exports.setChatHistory = exports.setSessions = exports.clearSession = exports.setNewSession = exports.toAiCfoVisualization = exports.initialAiCfoState = void 0;
4
+ exports.clearSyntheticAiCfoAnswers = exports.removeSyntheticAiCfoAnswer = exports.updateSyntheticAiCfoAnswer = exports.appendSyntheticAiCfoAnswer = exports.updateAiCfoAnswerCardPolicyWizardPlan = exports.deleteQuestion = exports.clearAiCfo = exports.addQuestionPayload = exports.upsertOrAddQuestionAnswerPayload = exports.upsertAnswerPayload = exports.setChatHistory = exports.setSessions = exports.clearSession = exports.setNewSession = exports.toAiCfoExports = exports.toAiCfoVisualization = exports.initialAiCfoState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  const rootActions_1 = require("../../rootActions");
7
7
  const zeniDayJS_1 = require("../../zeniDayJS");
@@ -121,6 +121,7 @@ function chatHistoryToQA(history) {
121
121
  artifact: parsedAgentMessage.artifact ?? undefined,
122
122
  artifactTitle: parsedAgentMessage.artifact_title ?? undefined,
123
123
  artifactHostUrl: parsedAgentMessage.artifact_host_url ?? undefined,
124
+ exports: (0, exports.toAiCfoExports)(parsedAgentMessage.exports),
124
125
  },
125
126
  createdAt: (0, zeniDayJS_1.date)(agentMessage.created_at),
126
127
  };
@@ -311,6 +312,27 @@ const toCardPolicyInitialData = (payload) => {
311
312
  wizardPlan: toCardPolicyWizardPlan(payload.wizard_plan),
312
313
  };
313
314
  };
315
+ // Drops entries missing id or name (broken download path); returns undefined, not [], so the field stays absent.
316
+ const toAiCfoExports = (payload) => {
317
+ if (!Array.isArray(payload)) {
318
+ return undefined;
319
+ }
320
+ const mapped = payload.flatMap((entry) => {
321
+ // Falsy, not `== null`: an empty string would reach the UI as a blank, failing button.
322
+ if (!entry?.export_id || !entry?.name) {
323
+ return [];
324
+ }
325
+ return [
326
+ {
327
+ exportId: entry.export_id,
328
+ name: entry.name,
329
+ sizeBytes: entry.size_bytes ?? undefined,
330
+ },
331
+ ];
332
+ });
333
+ return mapped.length > 0 ? mapped : undefined;
334
+ };
335
+ exports.toAiCfoExports = toAiCfoExports;
314
336
  const toAiCfoVisualizationData = (data) => {
315
337
  if ('x' in data && 'y' in data) {
316
338
  // Normalize y to always be an array
@@ -353,7 +375,7 @@ const toAiCfoVisualizationData = (data) => {
353
375
  };
354
376
  };
355
377
  const toResponseBlockType = (answer, userId) => {
356
- const { metadata, state, type, text, visualization, table, follow_up_questions, suggested_reply, assumptions, insights, summarized_title, artifact, artifact_title, artifact_host_url, } = answer;
378
+ const { metadata, state, type, text, visualization, table, follow_up_questions, suggested_reply, assumptions, insights, summarized_title, artifact, artifact_title, artifact_host_url, exports, } = answer;
357
379
  const { chat_session_id, message_id, timestamp, chain_of_thought_action_steps: chainOfThoughtActionSteps = [], } = metadata;
358
380
  return {
359
381
  messageId: message_id,
@@ -375,6 +397,7 @@ const toResponseBlockType = (answer, userId) => {
375
397
  artifact: artifact ?? undefined,
376
398
  artifactTitle: artifact_title ?? undefined,
377
399
  artifactHostUrl: artifact_host_url ?? undefined,
400
+ exports: (0, exports.toAiCfoExports)(exports),
378
401
  },
379
402
  createdAt: (0, zeniDayJS_1.date)(timestamp),
380
403
  };
@@ -154,6 +154,12 @@ export interface ResponseBlockBase {
154
154
  state: AiCfoAnswerStateType;
155
155
  userId: ID;
156
156
  }
157
+ /** A downloadable spreadsheet attached to one answer. See AiCfoExportPayload. */
158
+ export interface AiCfoExport {
159
+ exportId: ID;
160
+ name: string;
161
+ sizeBytes?: number;
162
+ }
157
163
  export interface AnswerContentBlockBase {
158
164
  assumptions: string;
159
165
  chainOfThoughtActionSteps: string[];
@@ -163,6 +169,7 @@ export interface AnswerContentBlockBase {
163
169
  artifact?: string;
164
170
  artifactHostUrl?: string;
165
171
  artifactTitle?: string;
172
+ exports?: AiCfoExport[];
166
173
  suggestedReply?: string;
167
174
  summarizedTitle?: string;
168
175
  table?: AiCfoVisualization;
@@ -1,7 +1,7 @@
1
1
  import { CustomerSatisfactionPayload } from './customerSatisfactionPayload';
2
2
  import { CustomerSatisfactionState } from './customerSatisfactionState';
3
3
  export declare const initialState: CustomerSatisfactionState;
4
- export declare const updateCustomerSatisfaction: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
4
+ export declare const clearAllCustomerSatisfaction: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"customerSatisfaction/clearAllCustomerSatisfaction">, updateCustomerSatisfaction: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
5
5
  payload: CustomerSatisfactionPayload[];
6
6
  }, "customerSatisfaction/updateCustomerSatisfaction">;
7
7
  declare const _default: import("redux").Reducer<CustomerSatisfactionState>;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
+ var _a;
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.updateCustomerSatisfaction = exports.initialState = void 0;
4
+ exports.updateCustomerSatisfaction = exports.clearAllCustomerSatisfaction = exports.initialState = void 0;
4
5
  const toolkit_1 = require("@reduxjs/toolkit");
5
6
  const rootActions_1 = require("../../rootActions");
6
7
  const customerSatisfactionReducerHelpers_1 = require("./customerSatisfactionReducerHelpers");
@@ -18,10 +19,13 @@ const customerSatisfaction = (0, toolkit_1.createSlice)({
18
19
  draft.customerSatisfactionByCompanyId[newRecord.companyId] = newRecord;
19
20
  });
20
21
  },
22
+ clearAllCustomerSatisfaction() {
23
+ return exports.initialState;
24
+ },
21
25
  },
22
26
  extraReducers: (builder) => {
23
27
  builder.addCase(rootActions_1.clearAll, () => exports.initialState);
24
28
  },
25
29
  });
26
- exports.updateCustomerSatisfaction = customerSatisfaction.actions.updateCustomerSatisfaction;
30
+ _a = customerSatisfaction.actions, exports.clearAllCustomerSatisfaction = _a.clearAllCustomerSatisfaction, exports.updateCustomerSatisfaction = _a.updateCustomerSatisfaction;
27
31
  exports.default = customerSatisfaction.reducer;
@@ -1,4 +1,4 @@
1
- export declare const toSnackbarMessageSection: (v: string) => "reconcile" | "save_reconcile_for_later" | "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" | "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" | "accounting_projects_enabled_update" | "accounting_projects_qbo_not_enabled" | "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" | "accounting_projects_qbo_reconnect_failed";
1
+ export declare const toSnackbarMessageSection: (v: string) => "reconcile" | "save_reconcile_for_later" | "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" | "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" | "accounting_projects_enabled_update" | "accounting_projects_qbo_not_enabled" | "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" | "accounting_projects_qbo_reconnect_failed" | "invoicing_dunning_case_resolved" | "invoicing_dunning_retry" | "invoicing_dunning_cancel" | "invoicing_dunning_settings_save" | "invoicing_qbo_backfill" | "invoicing_qbo_sync_health_retry" | "invoicing_qbo_settings_save" | "invoicing_branding_save" | "invoicing_discount_archive" | "invoicing_discount_unarchive" | "invoicing_discount_delete" | "invoicing_invoice_reminder_sent" | "invoicing_invoice_regenerated" | "invoicing_invoice_voided" | "invoicing_catalog_item_saved" | "invoicing_customer_saved" | "invoicing_subscription_saved" | "invoicing_coupon_saved" | "invoicing_invoice_saved" | "invoicing_credit_note_saved" | "invoicing_payment_recorded" | "invoicing_subscription_activated" | "invoicing_subscription_cancellation_removed" | "invoicing_subscription_cancelled" | "invoicing_subscription_non_renewing" | "invoicing_subscription_paused" | "invoicing_subscription_reactivated" | "invoicing_subscription_resumed" | "invoicing_subscription_term_end_changed";
2
2
  export type SnackbarMessageSections = ReturnType<typeof toSnackbarMessageSection>;
3
3
  export declare const toSnackbarMessageSectionTexts: (v: string) => "notification" | "failed" | "success";
4
4
  export type SnackbarMessageSectionTexts = ReturnType<typeof toSnackbarMessageSectionTexts>;
@@ -230,6 +230,35 @@ const ALL_SNACKBAR_MESSAGE_SECTIONS = [
230
230
  'qbo_connection_already_linked',
231
231
  'qbo_connection_failed',
232
232
  'accounting_projects_qbo_reconnect_failed',
233
+ 'invoicing_dunning_case_resolved',
234
+ 'invoicing_dunning_retry',
235
+ 'invoicing_dunning_cancel',
236
+ 'invoicing_dunning_settings_save',
237
+ 'invoicing_qbo_backfill',
238
+ 'invoicing_qbo_sync_health_retry',
239
+ 'invoicing_qbo_settings_save',
240
+ 'invoicing_branding_save',
241
+ 'invoicing_discount_archive',
242
+ 'invoicing_discount_unarchive',
243
+ 'invoicing_discount_delete',
244
+ 'invoicing_invoice_reminder_sent',
245
+ 'invoicing_invoice_regenerated',
246
+ 'invoicing_invoice_voided',
247
+ 'invoicing_catalog_item_saved',
248
+ 'invoicing_customer_saved',
249
+ 'invoicing_subscription_saved',
250
+ 'invoicing_coupon_saved',
251
+ 'invoicing_invoice_saved',
252
+ 'invoicing_credit_note_saved',
253
+ 'invoicing_payment_recorded',
254
+ 'invoicing_subscription_activated',
255
+ 'invoicing_subscription_cancellation_removed',
256
+ 'invoicing_subscription_cancelled',
257
+ 'invoicing_subscription_non_renewing',
258
+ 'invoicing_subscription_paused',
259
+ 'invoicing_subscription_reactivated',
260
+ 'invoicing_subscription_resumed',
261
+ 'invoicing_subscription_term_end_changed',
233
262
  ];
234
263
  const toSnackbarMessageSection = (v) => (0, stringToUnion_1.stringToUnion)(v, ALL_SNACKBAR_MESSAGE_SECTIONS);
235
264
  exports.toSnackbarMessageSection = toSnackbarMessageSection;
@@ -117,6 +117,7 @@ function chatHistoryToQA(history) {
117
117
  artifact: parsedAgentMessage.artifact ?? undefined,
118
118
  artifactTitle: parsedAgentMessage.artifact_title ?? undefined,
119
119
  artifactHostUrl: parsedAgentMessage.artifact_host_url ?? undefined,
120
+ exports: toAiCfoExports(parsedAgentMessage.exports),
120
121
  },
121
122
  createdAt: zeniDate(agentMessage.created_at),
122
123
  };
@@ -306,6 +307,26 @@ const toCardPolicyInitialData = (payload) => {
306
307
  wizardPlan: toCardPolicyWizardPlan(payload.wizard_plan),
307
308
  };
308
309
  };
310
+ // Drops entries missing id or name (broken download path); returns undefined, not [], so the field stays absent.
311
+ export const toAiCfoExports = (payload) => {
312
+ if (!Array.isArray(payload)) {
313
+ return undefined;
314
+ }
315
+ const mapped = payload.flatMap((entry) => {
316
+ // Falsy, not `== null`: an empty string would reach the UI as a blank, failing button.
317
+ if (!entry?.export_id || !entry?.name) {
318
+ return [];
319
+ }
320
+ return [
321
+ {
322
+ exportId: entry.export_id,
323
+ name: entry.name,
324
+ sizeBytes: entry.size_bytes ?? undefined,
325
+ },
326
+ ];
327
+ });
328
+ return mapped.length > 0 ? mapped : undefined;
329
+ };
309
330
  const toAiCfoVisualizationData = (data) => {
310
331
  if ('x' in data && 'y' in data) {
311
332
  // Normalize y to always be an array
@@ -348,7 +369,7 @@ const toAiCfoVisualizationData = (data) => {
348
369
  };
349
370
  };
350
371
  const toResponseBlockType = (answer, userId) => {
351
- const { metadata, state, type, text, visualization, table, follow_up_questions, suggested_reply, assumptions, insights, summarized_title, artifact, artifact_title, artifact_host_url, } = answer;
372
+ const { metadata, state, type, text, visualization, table, follow_up_questions, suggested_reply, assumptions, insights, summarized_title, artifact, artifact_title, artifact_host_url, exports, } = answer;
352
373
  const { chat_session_id, message_id, timestamp, chain_of_thought_action_steps: chainOfThoughtActionSteps = [], } = metadata;
353
374
  return {
354
375
  messageId: message_id,
@@ -370,6 +391,7 @@ const toResponseBlockType = (answer, userId) => {
370
391
  artifact: artifact ?? undefined,
371
392
  artifactTitle: artifact_title ?? undefined,
372
393
  artifactHostUrl: artifact_host_url ?? undefined,
394
+ exports: toAiCfoExports(exports),
373
395
  },
374
396
  createdAt: zeniDate(timestamp),
375
397
  };
@@ -15,10 +15,13 @@ const customerSatisfaction = createSlice({
15
15
  draft.customerSatisfactionByCompanyId[newRecord.companyId] = newRecord;
16
16
  });
17
17
  },
18
+ clearAllCustomerSatisfaction() {
19
+ return initialState;
20
+ },
18
21
  },
19
22
  extraReducers: (builder) => {
20
23
  builder.addCase(clearAll, () => initialState);
21
24
  },
22
25
  });
23
- export const { updateCustomerSatisfaction } = customerSatisfaction.actions;
26
+ export const { clearAllCustomerSatisfaction, updateCustomerSatisfaction } = customerSatisfaction.actions;
24
27
  export default customerSatisfaction.reducer;
@@ -227,6 +227,35 @@ const ALL_SNACKBAR_MESSAGE_SECTIONS = [
227
227
  'qbo_connection_already_linked',
228
228
  'qbo_connection_failed',
229
229
  'accounting_projects_qbo_reconnect_failed',
230
+ 'invoicing_dunning_case_resolved',
231
+ 'invoicing_dunning_retry',
232
+ 'invoicing_dunning_cancel',
233
+ 'invoicing_dunning_settings_save',
234
+ 'invoicing_qbo_backfill',
235
+ 'invoicing_qbo_sync_health_retry',
236
+ 'invoicing_qbo_settings_save',
237
+ 'invoicing_branding_save',
238
+ 'invoicing_discount_archive',
239
+ 'invoicing_discount_unarchive',
240
+ 'invoicing_discount_delete',
241
+ 'invoicing_invoice_reminder_sent',
242
+ 'invoicing_invoice_regenerated',
243
+ 'invoicing_invoice_voided',
244
+ 'invoicing_catalog_item_saved',
245
+ 'invoicing_customer_saved',
246
+ 'invoicing_subscription_saved',
247
+ 'invoicing_coupon_saved',
248
+ 'invoicing_invoice_saved',
249
+ 'invoicing_credit_note_saved',
250
+ 'invoicing_payment_recorded',
251
+ 'invoicing_subscription_activated',
252
+ 'invoicing_subscription_cancellation_removed',
253
+ 'invoicing_subscription_cancelled',
254
+ 'invoicing_subscription_non_renewing',
255
+ 'invoicing_subscription_paused',
256
+ 'invoicing_subscription_reactivated',
257
+ 'invoicing_subscription_resumed',
258
+ 'invoicing_subscription_term_end_changed',
230
259
  ];
231
260
  export const toSnackbarMessageSection = (v) => stringToUnion(v, ALL_SNACKBAR_MESSAGE_SECTIONS);
232
261
  // Keeping this different from the message type, since we may not have messages in all instances
package/lib/esm/index.js CHANGED
@@ -674,7 +674,7 @@ export { cancelAiAccountantOnboarding, clearAiAccountantView, fetchAiAccountantC
674
674
  export { getAiAccountantCockpitView, } from './view/aiAccountantView/aiAccountantViewSelector';
675
675
  export { fetchChatSessionsForUser, createSession, submitQuestion, updateAiCfoViewScrollPosition, updateCurrentInput, updateCotCollapsedState, clearInput, setSession, clearAiCfoView, clearCurrentSessionId, clearDeleteChatSessionStatus, clearLastContextMessage, createSessionAndSubmit, stopSubmit, stopSubmitQuestion, fetchChatHistory, acceptMasterTOS, deleteChatSession, submitFeedback, updateResponseState, fetchSuggestedQuestions, fetchSuggestedQuestionsSuccess, fetchSuggestedQuestionsFailure, fetchSkills, fetchSkillsSuccess, fetchSkillsFailure, applyAiCfoSidePanelHostPageTransition, clearAiCfoSidePanelHostPageContext, } from './view/aiCfoView/aiCfoViewReducer';
676
676
  export { getAiCfoView, getSuggestedQuestionsForPageContext, getSkills, } from './view/aiCfoView/aiCfoViewSelector';
677
- export { setNewSession, setSessions, updateAiCfoAnswerCardPolicyWizardPlan, upsertAnswerPayload, upsertOrAddQuestionAnswerPayload, addQuestionPayload, clearSession, clearAiCfo, toAiCfoVisualization, appendSyntheticAiCfoAnswer, updateSyntheticAiCfoAnswer, removeSyntheticAiCfoAnswer, clearSyntheticAiCfoAnswers, } from './entity/aiCfo/aiCfoReducer';
677
+ export { setNewSession, setSessions, updateAiCfoAnswerCardPolicyWizardPlan, upsertAnswerPayload, upsertOrAddQuestionAnswerPayload, addQuestionPayload, clearSession, clearAiCfo, toAiCfoExports, toAiCfoVisualization, appendSyntheticAiCfoAnswer, updateSyntheticAiCfoAnswer, removeSyntheticAiCfoAnswer, clearSyntheticAiCfoAnswers, } from './entity/aiCfo/aiCfoReducer';
678
678
  export { getAllQuestionAnswersForChatSession, getQuestionAnswerByIdForChatSession, getAllQuestionsForChatSession, getAiCfoSelectorView, getSyntheticAiCfoAnswersForChatSession, getSyntheticAiCfoAnswerByQuestionAnswerId, } from './entity/aiCfo/aiCfoSelector';
679
679
  export { ALL_AI_CFO_CHARTS_TYPES, ALL_AI_CFO_VISUALIZATION_TYPES, ALL_AI_CFO_ANSWER_STATE_TYPES, ALL_AI_CFO_ANSWER_RESPONSE_TYPES, ALL_INTERACTIVE_FORM_TYPES, toAiCfoVisualizationType, toAiCfoVisualizationTypeStrict, toAiCfoChartType, toAiCfoChartTypeStrict, toAiCfoAnswerStateType, toAiCfoAnswerStateTypeStrict, toAiCfoAnswerResponseType, toAiCfoAnswerResponseTypeStrict, toInteractiveFormType, toInteractiveFormTypeStrict, ALL_SYNTHETIC_AI_CFO_ANSWER_KINDS, toMessageSender, toMessageType, } from './entity/aiCfo/aiCfoState';
680
680
  // ── Card Policy (shared between manual + AI-driven flows) ────────────
@@ -735,7 +735,7 @@ export { resetRecordPayment, initializeRecordPaymentDraft, submitRecordPayment,
735
735
  export { initializeIssueCreditNoteDraft, issueCreditNoteFailure, issueCreditNoteSuccess, resetIssueCreditNote, submitIssueCreditNote, updateIssueCreditNoteFormDraft, } from './view/invoicing/issueCreditNote/issueCreditNoteReducer';
736
736
  export { computeIssueCreditNoteTotal, initializeIssueCreditNoteDraftFromInvoice, localDataToIssueCreditNotePayload, } from './view/invoicing/issueCreditNote/issueCreditNotePayload';
737
737
  export { INVOICING_CREDIT_NOTE_REASON_CODES, initialIssueCreditNoteFormLocalData, } from './view/invoicing/issueCreditNote/issueCreditNoteFormConfig';
738
- export { getIssueCreditNoteFormView, getIssueCreditNoteView, } from './view/invoicing/issueCreditNote/issueCreditNoteSelector';
738
+ export { getIssueCreditNoteView } from './view/invoicing/issueCreditNote/issueCreditNoteSelector';
739
739
  export { createCreditNoteFailure, createCreditNoteSuccess, resetCreateCreditNote, submitCreateCreditNote, updateCreateCreditNoteFormDraft, } from './view/invoicing/createCreditNote/createCreditNoteReducer';
740
740
  export { localDataToCreateCreditNotePayload } from './view/invoicing/createCreditNote/createCreditNotePayload';
741
741
  export { initialCreateCreditNoteFormLocalData } from './view/invoicing/createCreditNote/createCreditNoteFormConfig';
@@ -31,10 +31,13 @@ const companyHealthMetricConfigView = createSlice({
31
31
  draft.fetchState = 'Error';
32
32
  draft.error = action.payload;
33
33
  },
34
+ clearCompanyHealthMetricConfigView() {
35
+ return initialState;
36
+ },
34
37
  },
35
38
  extraReducers: (builder) => {
36
39
  builder.addCase(clearAll, () => initialState);
37
40
  },
38
41
  });
39
- export const { fetchCompanyHealthMetricConfig, updateCompanyHealthMetricConfig, updateCompanyHealthMetricConfigFailure, } = companyHealthMetricConfigView.actions;
42
+ export const { clearCompanyHealthMetricConfigView, fetchCompanyHealthMetricConfig, updateCompanyHealthMetricConfig, updateCompanyHealthMetricConfigFailure, } = companyHealthMetricConfigView.actions;
40
43
  export default companyHealthMetricConfigView.reducer;
@@ -1,6 +1,7 @@
1
- import { of } from 'rxjs';
1
+ import { from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateInvoicingCreditNotes } from '../../../entity/invoicing/creditNote/creditNoteReducer';
4
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
4
5
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
5
6
  import { localDataToCreateCreditNotePayload, } from './createCreditNotePayload';
6
7
  import { createCreditNoteFailure, createCreditNoteSuccess, submitCreateCreditNote, } from './createCreditNoteReducer';
@@ -15,9 +16,28 @@ export const createCreditNoteEpic = (actions$, state$, zeniAPI) => actions$.pipe
15
16
  return [
16
17
  updateInvoicingCreditNotes([response.data], 'merge'),
17
18
  createCreditNoteSuccess({ creditNoteId: response.data.id }),
19
+ openSnackbar({
20
+ messageSection: 'invoicing_credit_note_saved',
21
+ messageText: 'success',
22
+ type: 'success',
23
+ }),
18
24
  ];
19
25
  }
20
- return of(createCreditNoteFailure(response.status));
21
- }), catchError((error) => of(createCreditNoteFailure(createZeniAPIStatus('Unexpected Error', 'Create credit note REST API call errored out ' +
22
- JSON.stringify(error))))));
26
+ return from([
27
+ createCreditNoteFailure(response.status),
28
+ openSnackbar({
29
+ messageSection: 'invoicing_credit_note_saved',
30
+ messageText: 'failed',
31
+ type: 'error',
32
+ }),
33
+ ]);
34
+ }), catchError((error) => from([
35
+ createCreditNoteFailure(createZeniAPIStatus('Unexpected Error', 'Create credit note REST API call errored out ' +
36
+ JSON.stringify(error))),
37
+ openSnackbar({
38
+ messageSection: 'invoicing_credit_note_saved',
39
+ messageText: 'failed',
40
+ type: 'error',
41
+ }),
42
+ ])));
23
43
  }));
@@ -1,8 +1,9 @@
1
- import { of } from 'rxjs';
1
+ import { from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateAddresses } from '../../../entity/address/addressReducer';
4
4
  import { extractInvoicingInvoiceAddresses } from '../../../entity/invoicing/invoice/invoicePayload';
5
5
  import { updateInvoices } from '../../../entity/invoicing/invoice/invoiceReducer';
6
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
6
7
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
7
8
  import { addInvoiceToList } from '../invoiceList/invoiceListReducer';
8
9
  import { createInvoice, createInvoiceFailure, createInvoiceSuccess, } from './createInvoiceReducer';
@@ -22,9 +23,28 @@ export const createInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe(f
22
23
  status: response.data.status,
23
24
  }),
24
25
  createInvoiceSuccess({ invoiceId: response.data.id }),
26
+ openSnackbar({
27
+ messageSection: 'invoicing_invoice_saved',
28
+ messageText: 'success',
29
+ type: 'success',
30
+ }),
25
31
  ];
26
32
  }
27
- return of(createInvoiceFailure(response.status));
28
- }), catchError((error) => of(createInvoiceFailure(createZeniAPIStatus('Unexpected Error', 'Create invoice REST API call errored out ' +
29
- JSON.stringify(error))))));
33
+ return from([
34
+ createInvoiceFailure(response.status),
35
+ openSnackbar({
36
+ messageSection: 'invoicing_invoice_saved',
37
+ messageText: 'failed',
38
+ type: 'error',
39
+ }),
40
+ ]);
41
+ }), catchError((error) => from([
42
+ createInvoiceFailure(createZeniAPIStatus('Unexpected Error', 'Create invoice REST API call errored out ' +
43
+ JSON.stringify(error))),
44
+ openSnackbar({
45
+ messageSection: 'invoicing_invoice_saved',
46
+ messageText: 'failed',
47
+ type: 'error',
48
+ }),
49
+ ])));
30
50
  }));
@@ -1,25 +1,52 @@
1
+ import { getAddressByAddressId } from '../../../entity/address/addressSelector';
1
2
  import { getInvoicingCatalogListView, getInvoicingCatalogPrices, } from '../invoicingCatalogListView/invoicingCatalogListViewSelector';
2
3
  import { getInvoicingCustomerListView } from '../invoicingCustomerListView/invoicingCustomerListViewSelector';
3
4
  import { getInvoicingSettings } from '../settingsView/settingsViewSelector';
5
+ /**
6
+ * Display name for a customer option: company, else the full name, else the
7
+ * email, else the raw id.
8
+ */
9
+ const customerDisplayName = (customer) => {
10
+ const fullName = [customer.firstName, customer.lastName]
11
+ .filter((part) => part != null && part.trim() !== '')
12
+ .join(' ')
13
+ .trim();
14
+ const company = customer.company?.trim() ?? '';
15
+ const email = customer.email?.trim() ?? '';
16
+ return company !== ''
17
+ ? company
18
+ : fullName !== ''
19
+ ? fullName
20
+ : email !== ''
21
+ ? email
22
+ : customer.id;
23
+ };
4
24
  /**
5
25
  * Single bundled view for the create-invoice screen — web-ui consumes only this.
6
26
  * Carries the form draft (`localData`), the option sources the form needs
7
- * (customers, catalog plans/products, settings), the create-invoice fetch
8
- * state/error, and the id of the invoice last created (`savedInvoiceId`, to
9
- * navigate on success). Returns raw entity lists; the screen maps them to its
10
- * option shapes.
27
+ * (customer picker rows, catalog plan names, products, settings), the
28
+ * create-invoice fetch state/error, and the id of the invoice last created
29
+ * (`savedInvoiceId`, to navigate on success).
11
30
  */
12
31
  export const getCreateInvoiceFormView = (state) => {
13
32
  const createInvoiceState = state.invoicingCreateInvoiceState;
14
33
  const catalogListView = getInvoicingCatalogListView(state);
15
- const plans = getInvoicingCatalogPrices(catalogListView.plans);
16
34
  return {
17
- customers: getInvoicingCustomerListView(state).customers,
35
+ customers: getInvoicingCustomerListView(state).customers.map((customer) => ({
36
+ billingAddress: customer.billingAddressId != null
37
+ ? getAddressByAddressId(state.addressState, customer.billingAddressId)
38
+ : undefined,
39
+ email: customer.email,
40
+ id: customer.id,
41
+ name: customerDisplayName(customer),
42
+ })),
18
43
  localData: createInvoiceState.formDraft,
19
- planNames: plans
20
- .map((plan) => plan.name ?? '')
21
- .filter((name) => name !== ''),
22
- plans,
44
+ planNames: catalogListView.plans.flatMap((plan) => (plan.subFamilies ?? [])
45
+ .filter((subFamily) => (subFamily.name ?? '') !== '')
46
+ .map((subFamily) => ({
47
+ planName: plan.name ?? '',
48
+ subFamilyName: subFamily.name ?? '',
49
+ }))),
23
50
  products: getInvoicingCatalogPrices(catalogListView.products),
24
51
  savedInvoiceId: createInvoiceState.createdInvoiceId,
25
52
  settings: getInvoicingSettings(state),
@@ -1,11 +1,28 @@
1
- import { of } from 'rxjs';
1
+ import { from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateInvoicingCoupons } from '../../../entity/invoicing/coupon/couponReducer';
4
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
4
5
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
5
6
  import { runInvoicingDiscountAction, runInvoicingDiscountActionFailure, runInvoicingDiscountActionSuccess, } from './discountActionReducer';
7
+ /** Snackbar copy per action kind; unlisted kinds run without one. */
8
+ const SNACKBAR_SECTION_BY_KIND = {
9
+ archive: 'invoicing_discount_archive',
10
+ delete: 'invoicing_discount_delete',
11
+ unarchive: 'invoicing_discount_unarchive',
12
+ };
6
13
  export const runInvoicingDiscountActionEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(runInvoicingDiscountAction.match), mergeMap((action) => {
7
14
  const { action: kind, id } = action.payload;
8
15
  const requestBody = { action: kind };
16
+ const snackbarSection = SNACKBAR_SECTION_BY_KIND[kind];
17
+ const snackbar = (messageText) => snackbarSection == null
18
+ ? []
19
+ : [
20
+ openSnackbar({
21
+ messageSection: snackbarSection,
22
+ messageText,
23
+ type: messageText === 'success' ? 'success' : 'error',
24
+ }),
25
+ ];
9
26
  const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/discounts/${encodeURIComponent(id)}/actions`;
10
27
  return zeniAPI
11
28
  .postAndGetJSON(apiUrl, requestBody)
@@ -14,15 +31,22 @@ export const runInvoicingDiscountActionEpic = (actions$, _state$, zeniAPI) => ac
14
31
  return [
15
32
  updateInvoicingCoupons([response.data], 'merge'),
16
33
  runInvoicingDiscountActionSuccess({ id }),
34
+ ...snackbar('success'),
17
35
  ];
18
36
  }
19
- return of(runInvoicingDiscountActionFailure({
20
- error: response.status,
37
+ return from([
38
+ runInvoicingDiscountActionFailure({
39
+ error: response.status,
40
+ id,
41
+ }),
42
+ ...snackbar('failed'),
43
+ ]);
44
+ }), catchError((error) => from([
45
+ runInvoicingDiscountActionFailure({
46
+ error: createZeniAPIStatus('Unexpected Error', 'Discount action REST API call errored out ' +
47
+ JSON.stringify(error)),
21
48
  id,
22
- }));
23
- }), catchError((error) => of(runInvoicingDiscountActionFailure({
24
- error: createZeniAPIStatus('Unexpected Error', 'Discount action REST API call errored out ' +
25
- JSON.stringify(error)),
26
- id,
27
- }))));
49
+ }),
50
+ ...snackbar('failed'),
51
+ ])));
28
52
  }));