@zeniai/client-epic-state 5.0.51-betaRD1 → 5.0.51-betaRD3

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.
@@ -3,16 +3,18 @@ import { RootState } from '../../../reducer';
3
3
  import { ZeniAPI } from '../../../zeniAPI';
4
4
  import { saveConnectorCredentials, saveConnectorCredentialsFailure, saveConnectorCredentialsSuccess } from '../tenantReducer';
5
5
  export type ActionType = ReturnType<typeof saveConnectorCredentials> | ReturnType<typeof saveConnectorCredentialsSuccess> | ReturnType<typeof saveConnectorCredentialsFailure>;
6
- export declare const saveConnectorCredentialsEpic: (actions$: ActionsObservable<ActionType>, _: StateObservable<RootState>, zeniAPI: ZeniAPI) => import("rxjs").Observable<{
6
+ export declare const saveConnectorCredentialsEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => import("rxjs").Observable<{
7
7
  payload: {
8
8
  tenantId: string;
9
9
  connectionType: "revenue" | "payments";
10
+ connectionName: "chargebee" | "hubspot" | "stripe" | "mercury" | "paypal";
10
11
  connectionPayload: import("../tenantPayload").ConnectionDataPayload;
11
12
  };
12
13
  type: "tenant/saveConnectorCredentialsSuccess";
13
14
  } | {
14
15
  payload: {
15
16
  tenantId: string;
17
+ connectionName: "chargebee" | "hubspot" | "stripe" | "mercury" | "paypal";
16
18
  status: import("../../../responsePayload").ZeniAPIStatus<Record<string, unknown>>;
17
19
  };
18
20
  type: "tenant/saveConnectorCredentialsFailure";
@@ -12,26 +12,31 @@ const tenantReducer_1 = require("../tenantReducer");
12
12
  // connector-specific (api_key, or client_id+client_secret) and is forwarded
13
13
  // verbatim to the BE — connector-side validation lives in
14
14
  // prepare_credential_update_args on the tenant service.
15
- const saveConnectorCredentialsEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(tenantReducer_1.saveConnectorCredentials.match), (0, operators_1.switchMap)((action) => zeniAPI
16
- .postAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/connectors/${action.payload.connectionName}/credentials`, action.payload.credentials, Object.assign({ 'zeni-tenant-id': action.payload.tenantId }))
15
+ const saveConnectorCredentialsEpic = (actions$,
16
+ // Underscore prefix marks the parameter as intentionally unused today but
17
+ // names what it will become — when we wire an in-progress guard (so a
18
+ // second save click can't `switchMap`-cancel an in-flight save and leave
19
+ // the BE in an indeterminate state), drop the underscore and read state
20
+ // here.
21
+ _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(tenantReducer_1.saveConnectorCredentials.match), (0, operators_1.switchMap)((action) => zeniAPI
22
+ .postAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/connectors/${action.payload.connectionName}/credentials`, action.payload.credentials, { 'zeni-tenant-id': action.payload.tenantId })
17
23
  .pipe((0, operators_1.mergeMap)((response) => {
18
- if ((0, responsePayload_1.isSuccessResponse)(response)) {
24
+ if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
19
25
  return (0, rxjs_1.from)([
20
- (0, tenantReducer_1.saveConnectorCredentialsSuccess)(action.payload.tenantId, action.payload.connectionType, response.data // eslint-disable-line @typescript-eslint/no-non-null-assertion
21
- ),
26
+ (0, tenantReducer_1.saveConnectorCredentialsSuccess)(action.payload.tenantId, action.payload.connectionType, action.payload.connectionName, response.data),
22
27
  ]);
23
28
  }
24
29
  const status = response.status ??
25
30
  (0, responsePayload_1.createZeniAPIStatus)('Failed to save connection. Please try again.');
26
31
  return (0, rxjs_1.from)([
27
- (0, tenantReducer_1.saveConnectorCredentialsFailure)(action.payload.tenantId, status),
32
+ (0, tenantReducer_1.saveConnectorCredentialsFailure)(action.payload.tenantId, action.payload.connectionName, status),
28
33
  ]);
29
34
  }), (0, operators_1.catchError)((error) => {
30
35
  const message = error instanceof Error
31
36
  ? error.message
32
37
  : 'Unexpected error saving connection.';
33
38
  return (0, rxjs_1.from)([
34
- (0, tenantReducer_1.saveConnectorCredentialsFailure)(action.payload.tenantId, (0, responsePayload_1.createZeniAPIStatus)(message)),
39
+ (0, tenantReducer_1.saveConnectorCredentialsFailure)(action.payload.tenantId, action.payload.connectionName, (0, responsePayload_1.createZeniAPIStatus)(message)),
35
40
  ]);
36
41
  }))));
37
42
  exports.saveConnectorCredentialsEpic = saveConnectorCredentialsEpic;
@@ -17,6 +17,23 @@ export declare const toExternalIntegrationType: (v: string) => "revenue" | "paym
17
17
  export type ExternalIntegrationType = ReturnType<typeof toExternalIntegrationType>;
18
18
  export declare const toExternalSupportedTool: (v: string) => "chargebee" | "hubspot" | "stripe" | "mercury" | "paypal";
19
19
  export type ExternalSupportedTool = ReturnType<typeof toExternalSupportedTool>;
20
+ export type ConnectorCredentialsBySlug = {
21
+ connectionName: 'stripe';
22
+ credentials: {
23
+ api_key: string;
24
+ };
25
+ } | {
26
+ connectionName: 'mercury';
27
+ credentials: {
28
+ api_key: string;
29
+ };
30
+ } | {
31
+ connectionName: 'paypal';
32
+ credentials: {
33
+ client_id: string;
34
+ client_secret: string;
35
+ };
36
+ };
20
37
  export declare const initialState: TenantState;
21
38
  export declare const updateTenants: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenants: TenantPayload[], userTenantPayload?: TenantUserPayload | undefined, tenantUpdated?: any], {
22
39
  tenants: TenantPayload[];
@@ -126,17 +143,36 @@ export declare const updateTenants: import("@reduxjs/toolkit").ActionCreatorWith
126
143
  }, "tenant/saveOAuthConnectionSuccess", never, never>, saveOAuthConnectionFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenantId: string, status: ZeniAPIStatus<Record<string, unknown>>], {
127
144
  tenantId: string;
128
145
  status: ZeniAPIStatus<Record<string, unknown>>;
129
- }, "tenant/saveOAuthConnectionFailure", never, never>, saveConnectorCredentials: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenantId: string, connectionType: "revenue" | "payments", connectionName: "chargebee" | "hubspot" | "stripe" | "mercury" | "paypal", credentials: Record<string, string>], {
146
+ }, "tenant/saveOAuthConnectionFailure", never, never>, saveConnectorCredentials: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenantId: string, connectionType: "revenue" | "payments", args: ConnectorCredentialsBySlug], {
147
+ connectionName: "stripe";
148
+ credentials: {
149
+ api_key: string;
150
+ };
130
151
  tenantId: string;
131
152
  connectionType: "revenue" | "payments";
132
- connectionName: "chargebee" | "hubspot" | "stripe" | "mercury" | "paypal";
133
- credentials: Record<string, string>;
134
- }, "tenant/saveConnectorCredentials", never, never>, saveConnectorCredentialsSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenantId: string, connectionType: "revenue" | "payments", connectionPayload: ConnectionDataPayload], {
153
+ } | {
154
+ connectionName: "mercury";
155
+ credentials: {
156
+ api_key: string;
157
+ };
158
+ tenantId: string;
159
+ connectionType: "revenue" | "payments";
160
+ } | {
161
+ connectionName: "paypal";
162
+ credentials: {
163
+ client_id: string;
164
+ client_secret: string;
165
+ };
135
166
  tenantId: string;
136
167
  connectionType: "revenue" | "payments";
168
+ }, "tenant/saveConnectorCredentials", never, never>, saveConnectorCredentialsSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenantId: string, connectionType: "revenue" | "payments", connectionName: "chargebee" | "hubspot" | "stripe" | "mercury" | "paypal", connectionPayload: ConnectionDataPayload], {
169
+ tenantId: string;
170
+ connectionType: "revenue" | "payments";
171
+ connectionName: "chargebee" | "hubspot" | "stripe" | "mercury" | "paypal";
137
172
  connectionPayload: ConnectionDataPayload;
138
- }, "tenant/saveConnectorCredentialsSuccess", never, never>, saveConnectorCredentialsFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenantId: string, status: ZeniAPIStatus<Record<string, unknown>>], {
173
+ }, "tenant/saveConnectorCredentialsSuccess", never, never>, saveConnectorCredentialsFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenantId: string, connectionName: "chargebee" | "hubspot" | "stripe" | "mercury" | "paypal", status: ZeniAPIStatus<Record<string, unknown>>], {
139
174
  tenantId: string;
175
+ connectionName: "chargebee" | "hubspot" | "stripe" | "mercury" | "paypal";
140
176
  status: ZeniAPIStatus<Record<string, unknown>>;
141
177
  }, "tenant/saveConnectorCredentialsFailure", never, never>, deleteConnection: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenantId: string, connectionId: string, connectionType: "revenue" | "payments"], {
142
178
  tenantId: string;
@@ -357,7 +357,8 @@ const tenant = (0, toolkit_1.createSlice)({
357
357
  revenue: [],
358
358
  saveConnectionState: 'Not-Started',
359
359
  saveAPIKeyConnectionState: 'Not-Started',
360
- saveConnectorCredentialsState: 'Not-Started',
360
+ saveConnectorCredentialsStateBySlug: {},
361
+ saveConnectorCredentialsErrorBySlug: {},
361
362
  saveOAuthConnectionState: 'Not-Started',
362
363
  deleteConnectionState: 'Not-Started',
363
364
  error: undefined,
@@ -377,7 +378,8 @@ const tenant = (0, toolkit_1.createSlice)({
377
378
  revenue,
378
379
  saveConnectionState: 'Completed',
379
380
  saveAPIKeyConnectionState: 'Not-Started',
380
- saveConnectorCredentialsState: 'Not-Started',
381
+ saveConnectorCredentialsStateBySlug: {},
382
+ saveConnectorCredentialsErrorBySlug: {},
381
383
  saveOAuthConnectionState: 'Not-Started',
382
384
  deleteConnectionState: 'Not-Started',
383
385
  error: undefined,
@@ -397,7 +399,8 @@ const tenant = (0, toolkit_1.createSlice)({
397
399
  revenue: [],
398
400
  saveConnectionState: 'Error',
399
401
  saveAPIKeyConnectionState: 'Not-Started',
400
- saveConnectorCredentialsState: 'Not-Started',
402
+ saveConnectorCredentialsStateBySlug: {},
403
+ saveConnectorCredentialsErrorBySlug: {},
401
404
  saveOAuthConnectionState: 'Not-Started',
402
405
  deleteConnectionState: 'Not-Started',
403
406
  error: status,
@@ -555,46 +558,48 @@ const tenant = (0, toolkit_1.createSlice)({
555
558
  // ChargeBee + HubSpot continue using the legacy saveAPIKeyConnection /
556
559
  // saveOAuthConnection actions that POST to /1.0/connections/<id>.
557
560
  saveConnectorCredentials: {
558
- prepare(tenantId, connectionType, connectionName, credentials) {
561
+ prepare(tenantId, connectionType, args) {
559
562
  return {
560
- payload: { tenantId, connectionType, connectionName, credentials },
563
+ payload: { tenantId, connectionType, ...args },
561
564
  };
562
565
  },
563
566
  reducer(draft, action) {
564
567
  const existing = draft.externalConnectionsByTenant[action.payload.tenantId];
565
568
  if (existing != null) {
566
- existing.saveConnectorCredentialsState = 'In-Progress';
567
- existing.saveConnectorCredentialsError = undefined;
569
+ existing.saveConnectorCredentialsStateBySlug[action.payload.connectionName] = 'In-Progress';
570
+ delete existing.saveConnectorCredentialsErrorBySlug[action.payload.connectionName];
568
571
  }
569
572
  },
570
573
  },
571
574
  saveConnectorCredentialsSuccess: {
572
- prepare(tenantId, connectionType, connectionPayload) {
573
- return { payload: { tenantId, connectionType, connectionPayload } };
575
+ prepare(tenantId, connectionType, connectionName, connectionPayload) {
576
+ return {
577
+ payload: { tenantId, connectionType, connectionName, connectionPayload },
578
+ };
574
579
  },
575
580
  reducer(draft, action) {
576
581
  const existing = draft.externalConnectionsByTenant[action.payload.tenantId];
577
582
  if (existing != null) {
578
- existing.saveConnectorCredentialsState = 'Completed';
583
+ existing.saveConnectorCredentialsStateBySlug[action.payload.connectionName] = 'Completed';
579
584
  // Upsert by connection_name — see saveAPIKeyConnectionSuccess for
580
585
  // the rationale on lazy bucket init + replace-or-append.
581
586
  if (existing[action.payload.connectionType] == null) {
582
587
  existing[action.payload.connectionType] = [];
583
588
  }
584
589
  replaceOrAppendConnectionByName(existing[action.payload.connectionType], (0, exports.toConnection)(action.payload.connectionPayload));
585
- existing.saveConnectorCredentialsError = undefined;
590
+ delete existing.saveConnectorCredentialsErrorBySlug[action.payload.connectionName];
586
591
  }
587
592
  },
588
593
  },
589
594
  saveConnectorCredentialsFailure: {
590
- prepare(tenantId, status) {
591
- return { payload: { tenantId, status } };
595
+ prepare(tenantId, connectionName, status) {
596
+ return { payload: { tenantId, connectionName, status } };
592
597
  },
593
598
  reducer(draft, action) {
594
599
  const existing = draft.externalConnectionsByTenant[action.payload.tenantId];
595
600
  if (existing != null) {
596
- existing.saveConnectorCredentialsState = 'Error';
597
- existing.saveConnectorCredentialsError = action.payload.status;
601
+ existing.saveConnectorCredentialsStateBySlug[action.payload.connectionName] = 'Error';
602
+ existing.saveConnectorCredentialsErrorBySlug[action.payload.connectionName] = action.payload.status;
598
603
  }
599
604
  },
600
605
  },
@@ -9,7 +9,7 @@ import { MasterTOSInfo, UserReimbursementInfo } from '../company/companyStateTyp
9
9
  import { SubscriptionSummary } from '../subscription/subscriptionSummary/subscriptionSummaryState';
10
10
  import { InvitationStatus } from '../userRole/userRoleState';
11
11
  import { UserRoleType } from '../userRole/userRoleType';
12
- import { AuthProvider } from './tenantReducer';
12
+ import { AuthProvider, ExternalSupportedTool } from './tenantReducer';
13
13
  export interface TenantExternalConnections {
14
14
  accounting: Connection[];
15
15
  deleteConnectionState: FetchState;
@@ -18,12 +18,12 @@ export interface TenantExternalConnections {
18
18
  revenue: Connection[];
19
19
  saveAPIKeyConnectionState: FetchState;
20
20
  saveConnectionState: FetchState;
21
- saveConnectorCredentialsState: FetchState;
21
+ saveConnectorCredentialsErrorBySlug: Partial<Record<ExternalSupportedTool, ZeniAPIStatus>>;
22
+ saveConnectorCredentialsStateBySlug: Partial<Record<ExternalSupportedTool, FetchState>>;
22
23
  saveOAuthConnectionState: FetchState;
23
24
  deleteConnectionError?: ZeniAPIStatus;
24
25
  error?: ZeniAPIStatus;
25
26
  saveAPIKeyConnectionError?: ZeniAPIStatus;
26
- saveConnectorCredentialsError?: ZeniAPIStatus;
27
27
  saveOAuthConnectionError?: ZeniAPIStatus;
28
28
  }
29
29
  export interface TenantState extends FetchedState {
package/lib/epic.d.ts CHANGED
@@ -182,8 +182,6 @@ import { ActionType as FetchExpenseAutomationSaveTransactionCategorizationAction
182
182
  import { ActionType as TriggerReviewTabRefetchActionType } from './view/expenseAutomationView/epics/transactionCategorization/triggerReviewTabRefetchEpic';
183
183
  import { ActionType as FetchExpenseAutomationUpdateTransactionCategorizationEpicActionType } from './view/expenseAutomationView/epics/transactionCategorization/updateTransactionCategorizationEpic';
184
184
  import { ActionType as UploadTransactionReceiptSuccessEpicActionType } from './view/expenseAutomationView/epics/transactionCategorization/uploadTransactionReceiptSuccessEpic';
185
- import { ActionType as FetchRegisteredInterestsActionType } from './view/featureNotificationView/epics/fetchRegisteredInterestsEpic';
186
- import { ActionType as NotifyMeForFeatureActionType } from './view/featureNotificationView/epics/notifyMeForFeatureEpic';
187
185
  import { ActionType as DeleteFileActionType } from './view/fileView/epic/deleteFileEpic';
188
186
  import { ActionType as DeleteFileListActionType } from './view/fileView/epic/deleteFileListEpic';
189
187
  import { ActionType as FetchFileActionType } from './view/fileView/epic/fetchFileEpic';
@@ -209,6 +207,8 @@ import { ActionType as FetchNotificationUnreadCountActionType } from './view/not
209
207
  import { ActionType as FetchNotificationViewActionType } from './view/notificationView/epics/fetchNotificationViewEpic';
210
208
  import { ActionType as UpdateNotificationViewAllNotificationsStatusActionType } from './view/notificationView/epics/updateNotificationViewAllNotificationsStatusEpic';
211
209
  import { ActionType as UpdateNotificationViewNotificationStatusActionType } from './view/notificationView/epics/updateNotificationViewNotificationStatusEpic';
210
+ import { ActionType as FetchRegisteredInterestsActionType } from './view/featureNotificationView/epics/fetchRegisteredInterestsEpic';
211
+ import { ActionType as NotifyMeForFeatureActionType } from './view/featureNotificationView/epics/notifyMeForFeatureEpic';
212
212
  import { ActionType as FetchCompanyOnboardingViewActionType } from './view/onboardingView/cockpitView/epic/fetchCompanyOnboardingViewEpic';
213
213
  import { ActionType as FetchOnboardingCompletedCompaniesActionType } from './view/onboardingView/cockpitView/epic/fetchOnboardingCompletedCompaniesEpic';
214
214
  import { ActionType as FetchQBOConnectionPoolActionType } from './view/onboardingView/cockpitView/epic/fetchQBOConnectionPoolEpic';
@@ -495,18 +495,15 @@ import { ActionType as SaveSubscriptionUpdatesActionType } from './view/subscrip
495
495
  import { ActionType as CreateTagActionType } from './view/tagView/epics/createTagEpic';
496
496
  import { ActionType as DeleteTagActionType } from './view/tagView/epics/deleteTagEpic';
497
497
  import { ActionType as FetchAllTagsActionType } from './view/tagView/epics/fetchAllTagsEpic';
498
- import { ActionType as DeleteCannedResponseActionType } from './view/taskManager/cannedResponsesView/epics/deleteCannedResponseEpic';
499
- import { ActionType as FetchCannedResponsesActionType } from './view/taskManager/cannedResponsesView/epics/fetchCannedResponsesEpic';
500
- import { ActionType as SaveCannedResponseActionType } from './view/taskManager/cannedResponsesView/epics/saveCannedResponseEpic';
501
498
  import { ActionType as ArchiveTaskActionType } from './view/taskManager/taskDetailView/epics/archiveTaskEpic';
502
499
  import { ActionType as DeleteTaskActionType } from './view/taskManager/taskDetailView/epics/deleteTaskEpic';
500
+ import { ActionType as SnoozeTaskActionType } from './view/taskManager/taskDetailView/epics/snoozeTaskEpic';
501
+ import { ActionType as UnsnoozeTaskActionType } from './view/taskManager/taskDetailView/epics/unsnoozeTaskEpic';
503
502
  import { ActionType as FetchTaskDetailActionType } from './view/taskManager/taskDetailView/epics/fetchTaskDetailEpic';
504
503
  import { ActionType as FetchTaskDetailPageActionType } from './view/taskManager/taskDetailView/epics/fetchTaskDetailPageEpic';
505
504
  import { ActionType as FetchTaskHistoryActionType } from './view/taskManager/taskDetailView/epics/fetchTaskHistoryEpic';
506
505
  import { ActionType as InitializeTaskToLocalStoreActionType } from './view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic';
507
506
  import { ActionType as SaveTaskDetailActionType } from './view/taskManager/taskDetailView/epics/saveTaskDetailEpic';
508
- import { ActionType as SnoozeTaskActionType } from './view/taskManager/taskDetailView/epics/snoozeTaskEpic';
509
- import { ActionType as UnsnoozeTaskActionType } from './view/taskManager/taskDetailView/epics/unsnoozeTaskEpic';
510
507
  import { ActionType as CreateTaskFromTaskGroupTemplateActionType } from './view/taskManager/taskGroupTemplateView/epics/createTaskFromTaskGroupTemplateEpic';
511
508
  import { ActionType as FetchTaskGroupTemplatesActionType } from './view/taskManager/taskGroupTemplateView/epics/fetchTaskGroupTemplatesEpic';
512
509
  import { ActionType as CreateNewTaskGroupActionType } from './view/taskManager/taskGroupView/epics/createNewTaskGroupEpic';
@@ -518,6 +515,9 @@ import { ActionType as DragNDropTasksActionType } from './view/taskManager/taskL
518
515
  import { ActionType as FetchTaskListActionType } from './view/taskManager/taskListView/epics/fetchTaskListEpic';
519
516
  import { ActionType as FetchTaskListPageActionType } from './view/taskManager/taskListView/epics/fetchTaskListPageEpic';
520
517
  import { ActionType as UpdateTaskFromListViewActionType } from './view/taskManager/taskListView/epics/updateTaskFromListViewEpic';
518
+ import { ActionType as FetchCannedResponsesActionType } from './view/taskManager/cannedResponsesView/epics/fetchCannedResponsesEpic';
519
+ import { ActionType as SaveCannedResponseActionType } from './view/taskManager/cannedResponsesView/epics/saveCannedResponseEpic';
520
+ import { ActionType as DeleteCannedResponseActionType } from './view/taskManager/cannedResponsesView/epics/deleteCannedResponseEpic';
521
521
  import { ActionType as FetchTasksCardActionType } from './view/tasksCard/fetchTasksCardEpic';
522
522
  import { ActionType as TopExActionType } from './view/topEx/topExEpic';
523
523
  import { ActionType as FetchTransactionActivityLogActionType } from './view/transactionActivityLogView/fetchTransactionActivityLogEpic';
@@ -531,13 +531,13 @@ import { ActionType as UpdateTransactionDetailActionType } from './view/transact
531
531
  import { ActionType as UpdateTransactionOnUploadSuccessActionType } from './view/transactionDetail/epics/uploadMissingAttachmentSuccessEpic';
532
532
  import { ActionType as FetchTransactionListByAccountActionType } from './view/transactionList/fetchTransactionListByAccountEpic';
533
533
  import { ActionType as FetchTransactionListByClassActionType } from './view/transactionList/fetchTransactionListByClassEpic';
534
- import { ActionType as FetchTransactionListByEntityActionType } from './view/transactionList/fetchTransactionListByEntityEpic';
535
534
  import { ActionType as FetchTransactionListByProjectActionType } from './view/transactionList/fetchTransactionListByProjectEpic';
535
+ import { ActionType as FetchTransactionListByEntityActionType } from './view/transactionList/fetchTransactionListByEntityEpic';
536
536
  import { ActionType as FetchTransactionsListByCategoryTypeActionType } from './view/transactionList/fetchTransactionsListByCategoryTypeEpic';
537
537
  import { ActionType as ParallelFetchAccountTransactionListActionType } from './view/transactionList/parallelFetchAccountTransactionListEpic';
538
538
  import { ActionType as ParallelFetchClassTransactionListActionType } from './view/transactionList/parallelFetchClassTransactionListEpic';
539
- import { ActionType as ParallelFetchEntityTransactionListActionType } from './view/transactionList/parallelFetchEntityTransactionListEpic';
540
539
  import { ActionType as ParallelFetchProjectTransactionListActionType } from './view/transactionList/parallelFetchProjectTransactionListEpic';
540
+ import { ActionType as ParallelFetchEntityTransactionListActionType } from './view/transactionList/parallelFetchEntityTransactionListEpic';
541
541
  import { ActionType as ParallelFetchTransactionListByCategoryTypeActionType } from './view/transactionList/parallelFetchTransactionListByCategoryTypeEpic';
542
542
  import { ActionType as FetchExpenseTrendActionType } from './view/trend/fetchExpenseTrendEpic';
543
543
  import { ActionType as FetchIncomeTrendActionType } from './view/trend/fetchIncomeTrendEpic';
package/lib/epic.js CHANGED
@@ -9,7 +9,6 @@ const sectionAccountsViewEpic_1 = require("./entity/sectionAccountsView/sectionA
9
9
  const sectionClassesViewEpic_1 = require("./entity/sectionClassesViewV2/sectionClassesViewEpic");
10
10
  const sectionProjectViewEpic_1 = require("./entity/sectionProjectView/sectionProjectViewEpic");
11
11
  const clearAllEpic_1 = require("./entity/tenant/clearAllEpic");
12
- const deleteConnectionEpic_1 = require("./entity/tenant/epic/deleteConnectionEpic");
13
12
  const doMagicLinkSignInEpic_1 = require("./entity/tenant/epic/doMagicLinkSignInEpic");
14
13
  const fetchActiveTenantEpic_1 = require("./entity/tenant/epic/fetchActiveTenantEpic");
15
14
  const fetchAllTenantsEpic_1 = require("./entity/tenant/epic/fetchAllTenantsEpic");
@@ -17,6 +16,7 @@ const fetchExcludedResourcesEpic_1 = require("./entity/tenant/epic/fetchExcluded
17
16
  const fetchExternalConnectionsEpic_1 = require("./entity/tenant/epic/fetchExternalConnectionsEpic");
18
17
  const fetchSubscriptionSummaryForTenantEpic_1 = require("./entity/tenant/epic/fetchSubscriptionSummaryForTenantEpic");
19
18
  const resendVerifyDeviceOTPEpic_1 = require("./entity/tenant/epic/resendVerifyDeviceOTPEpic");
19
+ const deleteConnectionEpic_1 = require("./entity/tenant/epic/deleteConnectionEpic");
20
20
  const saveAPIKeyConnectionEpic_1 = require("./entity/tenant/epic/saveAPIKeyConnectionEpic");
21
21
  const saveConnectorCredentialsEpic_1 = require("./entity/tenant/epic/saveConnectorCredentialsEpic");
22
22
  const saveExternalConnectionEpic_1 = require("./entity/tenant/epic/saveExternalConnectionEpic");
@@ -190,8 +190,6 @@ const saveTransactionCategorizationEpic_1 = require("./view/expenseAutomationVie
190
190
  const triggerReviewTabRefetchEpic_1 = require("./view/expenseAutomationView/epics/transactionCategorization/triggerReviewTabRefetchEpic");
191
191
  const updateTransactionCategorizationEpic_1 = require("./view/expenseAutomationView/epics/transactionCategorization/updateTransactionCategorizationEpic");
192
192
  const uploadTransactionReceiptSuccessEpic_1 = require("./view/expenseAutomationView/epics/transactionCategorization/uploadTransactionReceiptSuccessEpic");
193
- const fetchRegisteredInterestsEpic_1 = require("./view/featureNotificationView/epics/fetchRegisteredInterestsEpic");
194
- const notifyMeForFeatureEpic_1 = require("./view/featureNotificationView/epics/notifyMeForFeatureEpic");
195
193
  const deleteFileEpic_1 = require("./view/fileView/epic/deleteFileEpic");
196
194
  const deleteFileListEpic_1 = require("./view/fileView/epic/deleteFileListEpic");
197
195
  const fetchFileEpic_1 = require("./view/fileView/epic/fetchFileEpic");
@@ -217,6 +215,8 @@ const fetchNotificationUnreadCountEpic_1 = require("./view/notificationView/epic
217
215
  const fetchNotificationViewEpic_1 = require("./view/notificationView/epics/fetchNotificationViewEpic");
218
216
  const updateNotificationViewAllNotificationsStatusEpic_1 = require("./view/notificationView/epics/updateNotificationViewAllNotificationsStatusEpic");
219
217
  const updateNotificationViewNotificationStatusEpic_1 = require("./view/notificationView/epics/updateNotificationViewNotificationStatusEpic");
218
+ const fetchRegisteredInterestsEpic_1 = require("./view/featureNotificationView/epics/fetchRegisteredInterestsEpic");
219
+ const notifyMeForFeatureEpic_1 = require("./view/featureNotificationView/epics/notifyMeForFeatureEpic");
220
220
  const fetchCompanyOnboardingViewEpic_1 = require("./view/onboardingView/cockpitView/epic/fetchCompanyOnboardingViewEpic");
221
221
  const fetchOnboardingCompletedCompaniesEpic_1 = require("./view/onboardingView/cockpitView/epic/fetchOnboardingCompletedCompaniesEpic");
222
222
  const fetchQBOConnectionPoolEpic_1 = require("./view/onboardingView/cockpitView/epic/fetchQBOConnectionPoolEpic");
@@ -506,18 +506,15 @@ const saveSubscriptionUpdatesEpic_1 = require("./view/subscriptionView/epic/save
506
506
  const createTagEpic_1 = require("./view/tagView/epics/createTagEpic");
507
507
  const deleteTagEpic_1 = require("./view/tagView/epics/deleteTagEpic");
508
508
  const fetchAllTagsEpic_1 = require("./view/tagView/epics/fetchAllTagsEpic");
509
- const deleteCannedResponseEpic_1 = require("./view/taskManager/cannedResponsesView/epics/deleteCannedResponseEpic");
510
- const fetchCannedResponsesEpic_1 = require("./view/taskManager/cannedResponsesView/epics/fetchCannedResponsesEpic");
511
- const saveCannedResponseEpic_1 = require("./view/taskManager/cannedResponsesView/epics/saveCannedResponseEpic");
512
509
  const archiveTaskEpic_1 = require("./view/taskManager/taskDetailView/epics/archiveTaskEpic");
513
510
  const deleteTaskEpic_1 = require("./view/taskManager/taskDetailView/epics/deleteTaskEpic");
511
+ const snoozeTaskEpic_1 = require("./view/taskManager/taskDetailView/epics/snoozeTaskEpic");
512
+ const unsnoozeTaskEpic_1 = require("./view/taskManager/taskDetailView/epics/unsnoozeTaskEpic");
514
513
  const fetchTaskDetailEpic_1 = require("./view/taskManager/taskDetailView/epics/fetchTaskDetailEpic");
515
514
  const fetchTaskDetailPageEpic_1 = require("./view/taskManager/taskDetailView/epics/fetchTaskDetailPageEpic");
516
515
  const fetchTaskHistoryEpic_1 = require("./view/taskManager/taskDetailView/epics/fetchTaskHistoryEpic");
517
516
  const initializeTaskToLocalStoreEpic_1 = require("./view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic");
518
517
  const saveTaskDetailEpic_1 = require("./view/taskManager/taskDetailView/epics/saveTaskDetailEpic");
519
- const snoozeTaskEpic_1 = require("./view/taskManager/taskDetailView/epics/snoozeTaskEpic");
520
- const unsnoozeTaskEpic_1 = require("./view/taskManager/taskDetailView/epics/unsnoozeTaskEpic");
521
518
  const createTaskFromTaskGroupTemplateEpic_1 = require("./view/taskManager/taskGroupTemplateView/epics/createTaskFromTaskGroupTemplateEpic");
522
519
  const fetchTaskGroupTemplatesEpic_1 = require("./view/taskManager/taskGroupTemplateView/epics/fetchTaskGroupTemplatesEpic");
523
520
  const createNewTaskGroupEpic_1 = require("./view/taskManager/taskGroupView/epics/createNewTaskGroupEpic");
@@ -529,6 +526,9 @@ const dragNDropTasksEpic_1 = require("./view/taskManager/taskListView/epics/drag
529
526
  const fetchTaskListEpic_1 = require("./view/taskManager/taskListView/epics/fetchTaskListEpic");
530
527
  const fetchTaskListPageEpic_1 = require("./view/taskManager/taskListView/epics/fetchTaskListPageEpic");
531
528
  const updateTaskFromListViewEpic_1 = require("./view/taskManager/taskListView/epics/updateTaskFromListViewEpic");
529
+ const fetchCannedResponsesEpic_1 = require("./view/taskManager/cannedResponsesView/epics/fetchCannedResponsesEpic");
530
+ const saveCannedResponseEpic_1 = require("./view/taskManager/cannedResponsesView/epics/saveCannedResponseEpic");
531
+ const deleteCannedResponseEpic_1 = require("./view/taskManager/cannedResponsesView/epics/deleteCannedResponseEpic");
532
532
  const fetchTasksCardEpic_1 = require("./view/tasksCard/fetchTasksCardEpic");
533
533
  const topExEpic_1 = require("./view/topEx/topExEpic");
534
534
  const fetchTransactionActivityLogEpic_1 = require("./view/transactionActivityLogView/fetchTransactionActivityLogEpic");
@@ -542,13 +542,13 @@ const updateTransactionDetailEpic_1 = require("./view/transactionDetail/epics/up
542
542
  const uploadMissingAttachmentSuccessEpic_1 = require("./view/transactionDetail/epics/uploadMissingAttachmentSuccessEpic");
543
543
  const fetchTransactionListByAccountEpic_1 = require("./view/transactionList/fetchTransactionListByAccountEpic");
544
544
  const fetchTransactionListByClassEpic_1 = require("./view/transactionList/fetchTransactionListByClassEpic");
545
- const fetchTransactionListByEntityEpic_1 = require("./view/transactionList/fetchTransactionListByEntityEpic");
546
545
  const fetchTransactionListByProjectEpic_1 = require("./view/transactionList/fetchTransactionListByProjectEpic");
546
+ const fetchTransactionListByEntityEpic_1 = require("./view/transactionList/fetchTransactionListByEntityEpic");
547
547
  const fetchTransactionsListByCategoryTypeEpic_1 = require("./view/transactionList/fetchTransactionsListByCategoryTypeEpic");
548
548
  const parallelFetchAccountTransactionListEpic_1 = require("./view/transactionList/parallelFetchAccountTransactionListEpic");
549
549
  const parallelFetchClassTransactionListEpic_1 = require("./view/transactionList/parallelFetchClassTransactionListEpic");
550
- const parallelFetchEntityTransactionListEpic_1 = require("./view/transactionList/parallelFetchEntityTransactionListEpic");
551
550
  const parallelFetchProjectTransactionListEpic_1 = require("./view/transactionList/parallelFetchProjectTransactionListEpic");
551
+ const parallelFetchEntityTransactionListEpic_1 = require("./view/transactionList/parallelFetchEntityTransactionListEpic");
552
552
  const parallelFetchTransactionListByCategoryTypeEpic_1 = require("./view/transactionList/parallelFetchTransactionListByCategoryTypeEpic");
553
553
  const fetchExpenseTrendEpic_1 = require("./view/trend/fetchExpenseTrendEpic");
554
554
  const fetchIncomeTrendEpic_1 = require("./view/trend/fetchIncomeTrendEpic");
@@ -9,25 +9,30 @@ import { saveConnectorCredentials, saveConnectorCredentialsFailure, saveConnecto
9
9
  // connector-specific (api_key, or client_id+client_secret) and is forwarded
10
10
  // verbatim to the BE — connector-side validation lives in
11
11
  // prepare_credential_update_args on the tenant service.
12
- export const saveConnectorCredentialsEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(saveConnectorCredentials.match), switchMap((action) => zeniAPI
13
- .postAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/connectors/${action.payload.connectionName}/credentials`, action.payload.credentials, Object.assign({ 'zeni-tenant-id': action.payload.tenantId }))
12
+ export const saveConnectorCredentialsEpic = (actions$,
13
+ // Underscore prefix marks the parameter as intentionally unused today but
14
+ // names what it will become — when we wire an in-progress guard (so a
15
+ // second save click can't `switchMap`-cancel an in-flight save and leave
16
+ // the BE in an indeterminate state), drop the underscore and read state
17
+ // here.
18
+ _state$, zeniAPI) => actions$.pipe(filter(saveConnectorCredentials.match), switchMap((action) => zeniAPI
19
+ .postAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/connectors/${action.payload.connectionName}/credentials`, action.payload.credentials, { 'zeni-tenant-id': action.payload.tenantId })
14
20
  .pipe(mergeMap((response) => {
15
- if (isSuccessResponse(response)) {
21
+ if (isSuccessResponse(response) && response.data != null) {
16
22
  return from([
17
- saveConnectorCredentialsSuccess(action.payload.tenantId, action.payload.connectionType, response.data // eslint-disable-line @typescript-eslint/no-non-null-assertion
18
- ),
23
+ saveConnectorCredentialsSuccess(action.payload.tenantId, action.payload.connectionType, action.payload.connectionName, response.data),
19
24
  ]);
20
25
  }
21
26
  const status = response.status ??
22
27
  createZeniAPIStatus('Failed to save connection. Please try again.');
23
28
  return from([
24
- saveConnectorCredentialsFailure(action.payload.tenantId, status),
29
+ saveConnectorCredentialsFailure(action.payload.tenantId, action.payload.connectionName, status),
25
30
  ]);
26
31
  }), catchError((error) => {
27
32
  const message = error instanceof Error
28
33
  ? error.message
29
34
  : 'Unexpected error saving connection.';
30
35
  return from([
31
- saveConnectorCredentialsFailure(action.payload.tenantId, createZeniAPIStatus(message)),
36
+ saveConnectorCredentialsFailure(action.payload.tenantId, action.payload.connectionName, createZeniAPIStatus(message)),
32
37
  ]);
33
38
  }))));
@@ -346,7 +346,8 @@ const tenant = createSlice({
346
346
  revenue: [],
347
347
  saveConnectionState: 'Not-Started',
348
348
  saveAPIKeyConnectionState: 'Not-Started',
349
- saveConnectorCredentialsState: 'Not-Started',
349
+ saveConnectorCredentialsStateBySlug: {},
350
+ saveConnectorCredentialsErrorBySlug: {},
350
351
  saveOAuthConnectionState: 'Not-Started',
351
352
  deleteConnectionState: 'Not-Started',
352
353
  error: undefined,
@@ -366,7 +367,8 @@ const tenant = createSlice({
366
367
  revenue,
367
368
  saveConnectionState: 'Completed',
368
369
  saveAPIKeyConnectionState: 'Not-Started',
369
- saveConnectorCredentialsState: 'Not-Started',
370
+ saveConnectorCredentialsStateBySlug: {},
371
+ saveConnectorCredentialsErrorBySlug: {},
370
372
  saveOAuthConnectionState: 'Not-Started',
371
373
  deleteConnectionState: 'Not-Started',
372
374
  error: undefined,
@@ -386,7 +388,8 @@ const tenant = createSlice({
386
388
  revenue: [],
387
389
  saveConnectionState: 'Error',
388
390
  saveAPIKeyConnectionState: 'Not-Started',
389
- saveConnectorCredentialsState: 'Not-Started',
391
+ saveConnectorCredentialsStateBySlug: {},
392
+ saveConnectorCredentialsErrorBySlug: {},
390
393
  saveOAuthConnectionState: 'Not-Started',
391
394
  deleteConnectionState: 'Not-Started',
392
395
  error: status,
@@ -544,46 +547,48 @@ const tenant = createSlice({
544
547
  // ChargeBee + HubSpot continue using the legacy saveAPIKeyConnection /
545
548
  // saveOAuthConnection actions that POST to /1.0/connections/<id>.
546
549
  saveConnectorCredentials: {
547
- prepare(tenantId, connectionType, connectionName, credentials) {
550
+ prepare(tenantId, connectionType, args) {
548
551
  return {
549
- payload: { tenantId, connectionType, connectionName, credentials },
552
+ payload: { tenantId, connectionType, ...args },
550
553
  };
551
554
  },
552
555
  reducer(draft, action) {
553
556
  const existing = draft.externalConnectionsByTenant[action.payload.tenantId];
554
557
  if (existing != null) {
555
- existing.saveConnectorCredentialsState = 'In-Progress';
556
- existing.saveConnectorCredentialsError = undefined;
558
+ existing.saveConnectorCredentialsStateBySlug[action.payload.connectionName] = 'In-Progress';
559
+ delete existing.saveConnectorCredentialsErrorBySlug[action.payload.connectionName];
557
560
  }
558
561
  },
559
562
  },
560
563
  saveConnectorCredentialsSuccess: {
561
- prepare(tenantId, connectionType, connectionPayload) {
562
- return { payload: { tenantId, connectionType, connectionPayload } };
564
+ prepare(tenantId, connectionType, connectionName, connectionPayload) {
565
+ return {
566
+ payload: { tenantId, connectionType, connectionName, connectionPayload },
567
+ };
563
568
  },
564
569
  reducer(draft, action) {
565
570
  const existing = draft.externalConnectionsByTenant[action.payload.tenantId];
566
571
  if (existing != null) {
567
- existing.saveConnectorCredentialsState = 'Completed';
572
+ existing.saveConnectorCredentialsStateBySlug[action.payload.connectionName] = 'Completed';
568
573
  // Upsert by connection_name — see saveAPIKeyConnectionSuccess for
569
574
  // the rationale on lazy bucket init + replace-or-append.
570
575
  if (existing[action.payload.connectionType] == null) {
571
576
  existing[action.payload.connectionType] = [];
572
577
  }
573
578
  replaceOrAppendConnectionByName(existing[action.payload.connectionType], toConnection(action.payload.connectionPayload));
574
- existing.saveConnectorCredentialsError = undefined;
579
+ delete existing.saveConnectorCredentialsErrorBySlug[action.payload.connectionName];
575
580
  }
576
581
  },
577
582
  },
578
583
  saveConnectorCredentialsFailure: {
579
- prepare(tenantId, status) {
580
- return { payload: { tenantId, status } };
584
+ prepare(tenantId, connectionName, status) {
585
+ return { payload: { tenantId, connectionName, status } };
581
586
  },
582
587
  reducer(draft, action) {
583
588
  const existing = draft.externalConnectionsByTenant[action.payload.tenantId];
584
589
  if (existing != null) {
585
- existing.saveConnectorCredentialsState = 'Error';
586
- existing.saveConnectorCredentialsError = action.payload.status;
590
+ existing.saveConnectorCredentialsStateBySlug[action.payload.connectionName] = 'Error';
591
+ existing.saveConnectorCredentialsErrorBySlug[action.payload.connectionName] = action.payload.status;
587
592
  }
588
593
  },
589
594
  },