@zeniai/client-epic-state 5.1.68-beta0ND → 5.1.68-betaDI0

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 (39) hide show
  1. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  2. package/lib/entity/snackbar/snackbarTypes.js +0 -1
  3. package/lib/entity/tenant/tenantReducer.d.ts +1 -5
  4. package/lib/entity/tenant/tenantReducer.js +2 -19
  5. package/lib/epic.d.ts +1 -2
  6. package/lib/epic.js +1 -2
  7. package/lib/esm/entity/snackbar/snackbarTypes.js +0 -1
  8. package/lib/esm/entity/tenant/tenantReducer.js +1 -18
  9. package/lib/esm/epic.js +1 -2
  10. package/lib/esm/index.js +4 -4
  11. package/lib/esm/view/companyView/companyViewReducer.js +1 -26
  12. package/lib/esm/view/companyView/selector/companyManagementViewSelector.js +0 -6
  13. package/lib/esm/view/companyView/types/cockpitTypes.js +0 -1
  14. package/lib/esm/view/companyView/types/companyPassport/companyPassportViewState.js +0 -4
  15. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewPayload.js +7 -2
  16. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewReducer.js +47 -2
  17. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewSelector.js +9 -0
  18. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewState.js +1 -0
  19. package/lib/index.d.ts +4 -4
  20. package/lib/index.js +21 -21
  21. package/lib/view/companyView/companyViewReducer.d.ts +1 -11
  22. package/lib/view/companyView/companyViewReducer.js +3 -28
  23. package/lib/view/companyView/selector/companyManagementViewSelector.js +0 -6
  24. package/lib/view/companyView/types/cockpitTypes.d.ts +2 -2
  25. package/lib/view/companyView/types/cockpitTypes.js +0 -1
  26. package/lib/view/companyView/types/companyPassport/companyPassportViewState.d.ts +0 -1
  27. package/lib/view/companyView/types/companyPassport/companyPassportViewState.js +0 -4
  28. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  29. package/lib/view/notificationPreferencesView/notificationPreferencesViewPayload.d.ts +1 -0
  30. package/lib/view/notificationPreferencesView/notificationPreferencesViewPayload.js +7 -2
  31. package/lib/view/notificationPreferencesView/notificationPreferencesViewReducer.d.ts +6 -1
  32. package/lib/view/notificationPreferencesView/notificationPreferencesViewReducer.js +48 -3
  33. package/lib/view/notificationPreferencesView/notificationPreferencesViewSelector.js +9 -0
  34. package/lib/view/notificationPreferencesView/notificationPreferencesViewState.d.ts +1 -0
  35. package/lib/view/notificationPreferencesView/notificationPreferencesViewState.js +1 -0
  36. package/package.json +1 -1
  37. package/lib/esm/view/companyView/epic/companyPassport/updateCompanyProductServicesEpic.js +0 -81
  38. package/lib/view/companyView/epic/companyPassport/updateCompanyProductServicesEpic.d.ts +0 -10
  39. package/lib/view/companyView/epic/companyPassport/updateCompanyProductServicesEpic.js +0 -85
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.toggleEventChannel = exports.setGroupFrequency = exports.saveNotificationPreferencesSuccess = exports.saveNotificationPreferencesFailure = exports.saveNotificationPreferences = exports.fetchNotificationPreferencesSuccess = exports.clearNotificationPreferencesLocalOverrides = exports.clearAllNotificationPreferencesView = exports.initialState = void 0;
4
+ exports.toggleEventChannel = exports.setGroupFrequency = exports.setGroupChannelMaster = exports.saveNotificationPreferencesSuccess = exports.saveNotificationPreferencesFailure = exports.saveNotificationPreferences = exports.fetchNotificationPreferencesSuccess = exports.clearNotificationPreferencesLocalOverrides = exports.clearAllNotificationPreferencesView = exports.initialState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  const notificationPreferencesViewPayload_1 = require("./notificationPreferencesViewPayload");
7
7
  const notificationPreferencesViewState_1 = require("./notificationPreferencesViewState");
@@ -22,8 +22,18 @@ const mergePreferences = (base, patch) => {
22
22
  ...channels,
23
23
  };
24
24
  });
25
+ const groupChannelEnabledByGroupId = {
26
+ ...base.groupChannelEnabledByGroupId,
27
+ };
28
+ Object.entries(patch.groupChannelEnabledByGroupId).forEach(([groupId, channels]) => {
29
+ groupChannelEnabledByGroupId[groupId] = {
30
+ ...(base.groupChannelEnabledByGroupId[groupId] ?? {}),
31
+ ...channels,
32
+ };
33
+ });
25
34
  return {
26
35
  eventEnabledByChannel,
36
+ groupChannelEnabledByGroupId,
27
37
  groupFrequencyByGroupId: {
28
38
  ...base.groupFrequencyByGroupId,
29
39
  ...patch.groupFrequencyByGroupId,
@@ -65,13 +75,38 @@ const subtractSavedOverrides = (current, saved) => {
65
75
  eventEnabledByChannel[eventId] = remainingChannels;
66
76
  }
67
77
  });
78
+ // Same value-equality subtraction as eventEnabledByChannel above — a
79
+ // group-channel master the user re-flipped while a PUT was in flight must
80
+ // survive so the next debounce cycle re-sends it.
81
+ const groupChannelEnabledByGroupId = {};
82
+ Object.entries(current.groupChannelEnabledByGroupId).forEach(([groupId, channels]) => {
83
+ const savedChannels = saved.groupChannelEnabledByGroupId[groupId];
84
+ if (savedChannels == null) {
85
+ groupChannelEnabledByGroupId[groupId] = channels;
86
+ return;
87
+ }
88
+ const remainingChannels = {};
89
+ Object.keys(channels).forEach((channel) => {
90
+ if (!(channel in savedChannels) ||
91
+ channels[channel] !== savedChannels[channel]) {
92
+ remainingChannels[channel] = channels[channel];
93
+ }
94
+ });
95
+ if (Object.keys(remainingChannels).length > 0) {
96
+ groupChannelEnabledByGroupId[groupId] = remainingChannels;
97
+ }
98
+ });
68
99
  const groupFrequencyByGroupId = {};
69
100
  Object.entries(current.groupFrequencyByGroupId).forEach(([groupId, frequency]) => {
70
101
  if (saved.groupFrequencyByGroupId[groupId] !== frequency) {
71
102
  groupFrequencyByGroupId[groupId] = frequency;
72
103
  }
73
104
  });
74
- return { eventEnabledByChannel, groupFrequencyByGroupId };
105
+ return {
106
+ eventEnabledByChannel,
107
+ groupChannelEnabledByGroupId,
108
+ groupFrequencyByGroupId,
109
+ };
75
110
  };
76
111
  const notificationPreferencesView = (0, toolkit_1.createSlice)({
77
112
  name: 'notificationPreferencesView',
@@ -208,6 +243,16 @@ const notificationPreferencesView = (0, toolkit_1.createSlice)({
208
243
  draft.preferences = mergePreferences(draft.preferences, patch);
209
244
  draft.localOverrides = subtractSavedOverrides(draft.localOverrides, action.payload.savedOverrides);
210
245
  },
246
+ setGroupChannelMaster(draft, action) {
247
+ // Mirror of `toggleEventChannel` but scoped to the group-channel master
248
+ // held under `groupChannelEnabledByGroupId[groupId][channel]`.
249
+ const { channel, enabled, groupId } = action.payload;
250
+ const groupMap = {
251
+ ...(draft.localOverrides.groupChannelEnabledByGroupId[groupId] ?? {}),
252
+ };
253
+ groupMap[channel] = enabled;
254
+ draft.localOverrides.groupChannelEnabledByGroupId[groupId] = groupMap;
255
+ },
211
256
  setGroupFrequency(draft, action) {
212
257
  draft.localOverrides.groupFrequencyByGroupId[action.payload.groupId] =
213
258
  action.payload.frequency;
@@ -222,5 +267,5 @@ const notificationPreferencesView = (0, toolkit_1.createSlice)({
222
267
  },
223
268
  },
224
269
  });
225
- _a = notificationPreferencesView.actions, exports.clearAllNotificationPreferencesView = _a.clearAllNotificationPreferencesView, exports.clearNotificationPreferencesLocalOverrides = _a.clearNotificationPreferencesLocalOverrides, exports.fetchNotificationPreferencesSuccess = _a.fetchNotificationPreferencesSuccess, exports.saveNotificationPreferences = _a.saveNotificationPreferences, exports.saveNotificationPreferencesFailure = _a.saveNotificationPreferencesFailure, exports.saveNotificationPreferencesSuccess = _a.saveNotificationPreferencesSuccess, exports.setGroupFrequency = _a.setGroupFrequency, exports.toggleEventChannel = _a.toggleEventChannel;
270
+ _a = notificationPreferencesView.actions, exports.clearAllNotificationPreferencesView = _a.clearAllNotificationPreferencesView, exports.clearNotificationPreferencesLocalOverrides = _a.clearNotificationPreferencesLocalOverrides, exports.fetchNotificationPreferencesSuccess = _a.fetchNotificationPreferencesSuccess, exports.saveNotificationPreferences = _a.saveNotificationPreferences, exports.saveNotificationPreferencesFailure = _a.saveNotificationPreferencesFailure, exports.saveNotificationPreferencesSuccess = _a.saveNotificationPreferencesSuccess, exports.setGroupChannelMaster = _a.setGroupChannelMaster, exports.setGroupFrequency = _a.setGroupFrequency, exports.toggleEventChannel = _a.toggleEventChannel;
226
271
  exports.default = notificationPreferencesView.reducer;
@@ -13,8 +13,16 @@ const getEffectiveNotificationPreferences = (state) => {
13
13
  ...channels,
14
14
  };
15
15
  });
16
+ const mergedGroupChannelEnabledByGroupId = { ...view.preferences.groupChannelEnabledByGroupId };
17
+ Object.entries(view.localOverrides.groupChannelEnabledByGroupId).forEach(([groupId, channels]) => {
18
+ mergedGroupChannelEnabledByGroupId[groupId] = {
19
+ ...(view.preferences.groupChannelEnabledByGroupId[groupId] ?? {}),
20
+ ...channels,
21
+ };
22
+ });
16
23
  return {
17
24
  eventEnabledByChannel: mergedEventEnabledByChannel,
25
+ groupChannelEnabledByGroupId: mergedGroupChannelEnabledByGroupId,
18
26
  groupFrequencyByGroupId: {
19
27
  ...view.preferences.groupFrequencyByGroupId,
20
28
  ...view.localOverrides.groupFrequencyByGroupId,
@@ -27,6 +35,7 @@ exports.getNotificationLocalOverrides = getNotificationLocalOverrides;
27
35
  const hasUnsavedNotificationPreferences = (state) => {
28
36
  const overrides = getView(state).localOverrides;
29
37
  return (Object.keys(overrides.eventEnabledByChannel).length > 0 ||
38
+ Object.keys(overrides.groupChannelEnabledByGroupId).length > 0 ||
30
39
  Object.keys(overrides.groupFrequencyByGroupId).length > 0);
31
40
  };
32
41
  exports.hasUnsavedNotificationPreferences = hasUnsavedNotificationPreferences;
@@ -2,6 +2,7 @@ import { FetchStateAndError } from '../../commonStateTypes/common';
2
2
  import { NotificationChannel, NotificationFrequency } from '../../entity/notificationRegistry/notificationRegistryState';
3
3
  export interface NotificationPreferences {
4
4
  eventEnabledByChannel: Record<string, Partial<Record<NotificationChannel, boolean>>>;
5
+ groupChannelEnabledByGroupId: Record<string, Partial<Record<NotificationChannel, boolean>>>;
5
6
  groupFrequencyByGroupId: Record<string, NotificationFrequency>;
6
7
  }
7
8
  export interface NotificationPreferencesViewState {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.emptyNotificationPreferences = void 0;
4
4
  const emptyNotificationPreferences = () => ({
5
5
  eventEnabledByChannel: {},
6
+ groupChannelEnabledByGroupId: {},
6
7
  groupFrequencyByGroupId: {},
7
8
  });
8
9
  exports.emptyNotificationPreferences = emptyNotificationPreferences;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.1.68-beta0ND",
3
+ "version": "5.1.68-betaDI0",
4
4
  "description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/esm/index.js",
@@ -1,81 +0,0 @@
1
- import { from } from 'rxjs';
2
- import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
- import { updateCompanies } from '../../../../entity/company/companyReducer';
4
- import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
5
- import { updateTenantProductSettings } from '../../../../entity/tenant/tenantReducer';
6
- import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
7
- import { updateCompanyProductServices, updateCompanyProductServicesFailure, updateCompanyProductServicesSuccess, } from '../../companyViewReducer';
8
- export const updateCompanyProductServicesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(updateCompanyProductServices.match), switchMap((action) => {
9
- const { companyId, services } = action.payload;
10
- const { isBookkeepingEnabled, isBillPayEnabled, isReimbursementEnabled } = services;
11
- const tenantId = Object.values(state$.value.tenantState.tenantsById).find((tenant) => tenant?.companyId === companyId)?.tenantId;
12
- // Send only the service-enable fields so the backend routes this through
13
- // its isolated "enable services" path. Bookkeeping is a Tenant product
14
- // flag and implies spend management; bill pay / reimbursement are Company
15
- // feature flags.
16
- const requestBody = {};
17
- if (isBookkeepingEnabled != null) {
18
- requestBody.is_book_keeping_enabled = isBookkeepingEnabled;
19
- requestBody.is_spend_management_enabled = isBookkeepingEnabled;
20
- }
21
- if (isBillPayEnabled != null) {
22
- requestBody.is_bill_pay_feature_enabled = isBillPayEnabled;
23
- }
24
- if (isReimbursementEnabled != null) {
25
- requestBody.is_reimbursement_feature_enabled = isReimbursementEnabled;
26
- }
27
- return zeniAPI
28
- .putAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/companies/${companyId}`, requestBody)
29
- .pipe(mergeMap((response) => {
30
- if (isSuccessResponse(response)) {
31
- const companies = response.data?.companies ?? [];
32
- if (companies.length > 0) {
33
- const actions = [
34
- updateCompanies({
35
- payload: companies,
36
- schema: {},
37
- }),
38
- ];
39
- // The company response carries the company feature flags; the
40
- // tenant product flags are not part of it, so merge them from
41
- // the (now-succeeded) request values.
42
- if (isBookkeepingEnabled != null && tenantId != null) {
43
- actions.push(updateTenantProductSettings({
44
- tenantId,
45
- isBookkeepingEnabled,
46
- isSpendManagementEnabled: isBookkeepingEnabled,
47
- }));
48
- }
49
- actions.push(updateCompanyProductServicesSuccess());
50
- actions.push(openSnackbar({
51
- messageSection: 'product_services_update',
52
- messageText: 'success',
53
- type: 'success',
54
- }));
55
- return from(actions);
56
- }
57
- }
58
- return from([
59
- updateCompanyProductServicesFailure({
60
- status: response.status,
61
- }),
62
- openSnackbar({
63
- messageSection: 'product_services_update',
64
- messageText: 'failed',
65
- type: 'error',
66
- }),
67
- ]);
68
- }), catchError((error) => from([
69
- updateCompanyProductServicesFailure({
70
- status: createZeniAPIStatus('Unexpected error', 'Update Company Product Services errored out' +
71
- (error instanceof Error
72
- ? error.message
73
- : JSON.stringify(error))),
74
- }),
75
- openSnackbar({
76
- messageSection: 'product_services_update',
77
- messageText: 'failed',
78
- type: 'error',
79
- }),
80
- ])));
81
- }));
@@ -1,10 +0,0 @@
1
- import { ActionsObservable, StateObservable } from 'redux-observable';
2
- import { Observable } from 'rxjs';
3
- import { updateCompanies } from '../../../../entity/company/companyReducer';
4
- import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
5
- import { updateTenantProductSettings } from '../../../../entity/tenant/tenantReducer';
6
- import { RootState } from '../../../../reducer';
7
- import { ZeniAPI } from '../../../../zeniAPI';
8
- import { updateCompanyProductServices, updateCompanyProductServicesFailure, updateCompanyProductServicesSuccess } from '../../companyViewReducer';
9
- export type ActionType = ReturnType<typeof updateCompanies> | ReturnType<typeof updateTenantProductSettings> | ReturnType<typeof openSnackbar> | ReturnType<typeof updateCompanyProductServices> | ReturnType<typeof updateCompanyProductServicesSuccess> | ReturnType<typeof updateCompanyProductServicesFailure>;
10
- export declare const updateCompanyProductServicesEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -1,85 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.updateCompanyProductServicesEpic = void 0;
4
- const rxjs_1 = require("rxjs");
5
- const operators_1 = require("rxjs/operators");
6
- const companyReducer_1 = require("../../../../entity/company/companyReducer");
7
- const snackbarReducer_1 = require("../../../../entity/snackbar/snackbarReducer");
8
- const tenantReducer_1 = require("../../../../entity/tenant/tenantReducer");
9
- const responsePayload_1 = require("../../../../responsePayload");
10
- const companyViewReducer_1 = require("../../companyViewReducer");
11
- const updateCompanyProductServicesEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(companyViewReducer_1.updateCompanyProductServices.match), (0, operators_1.switchMap)((action) => {
12
- const { companyId, services } = action.payload;
13
- const { isBookkeepingEnabled, isBillPayEnabled, isReimbursementEnabled } = services;
14
- const tenantId = Object.values(state$.value.tenantState.tenantsById).find((tenant) => tenant?.companyId === companyId)?.tenantId;
15
- // Send only the service-enable fields so the backend routes this through
16
- // its isolated "enable services" path. Bookkeeping is a Tenant product
17
- // flag and implies spend management; bill pay / reimbursement are Company
18
- // feature flags.
19
- const requestBody = {};
20
- if (isBookkeepingEnabled != null) {
21
- requestBody.is_book_keeping_enabled = isBookkeepingEnabled;
22
- requestBody.is_spend_management_enabled = isBookkeepingEnabled;
23
- }
24
- if (isBillPayEnabled != null) {
25
- requestBody.is_bill_pay_feature_enabled = isBillPayEnabled;
26
- }
27
- if (isReimbursementEnabled != null) {
28
- requestBody.is_reimbursement_feature_enabled = isReimbursementEnabled;
29
- }
30
- return zeniAPI
31
- .putAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/companies/${companyId}`, requestBody)
32
- .pipe((0, operators_1.mergeMap)((response) => {
33
- if ((0, responsePayload_1.isSuccessResponse)(response)) {
34
- const companies = response.data?.companies ?? [];
35
- if (companies.length > 0) {
36
- const actions = [
37
- (0, companyReducer_1.updateCompanies)({
38
- payload: companies,
39
- schema: {},
40
- }),
41
- ];
42
- // The company response carries the company feature flags; the
43
- // tenant product flags are not part of it, so merge them from
44
- // the (now-succeeded) request values.
45
- if (isBookkeepingEnabled != null && tenantId != null) {
46
- actions.push((0, tenantReducer_1.updateTenantProductSettings)({
47
- tenantId,
48
- isBookkeepingEnabled,
49
- isSpendManagementEnabled: isBookkeepingEnabled,
50
- }));
51
- }
52
- actions.push((0, companyViewReducer_1.updateCompanyProductServicesSuccess)());
53
- actions.push((0, snackbarReducer_1.openSnackbar)({
54
- messageSection: 'product_services_update',
55
- messageText: 'success',
56
- type: 'success',
57
- }));
58
- return (0, rxjs_1.from)(actions);
59
- }
60
- }
61
- return (0, rxjs_1.from)([
62
- (0, companyViewReducer_1.updateCompanyProductServicesFailure)({
63
- status: response.status,
64
- }),
65
- (0, snackbarReducer_1.openSnackbar)({
66
- messageSection: 'product_services_update',
67
- messageText: 'failed',
68
- type: 'error',
69
- }),
70
- ]);
71
- }), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
72
- (0, companyViewReducer_1.updateCompanyProductServicesFailure)({
73
- status: (0, responsePayload_1.createZeniAPIStatus)('Unexpected error', 'Update Company Product Services errored out' +
74
- (error instanceof Error
75
- ? error.message
76
- : JSON.stringify(error))),
77
- }),
78
- (0, snackbarReducer_1.openSnackbar)({
79
- messageSection: 'product_services_update',
80
- messageText: 'failed',
81
- type: 'error',
82
- }),
83
- ])));
84
- }));
85
- exports.updateCompanyProductServicesEpic = updateCompanyProductServicesEpic;