@zeniai/client-epic-state 5.2.47 → 5.2.49-beta0ND
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.
- package/lib/entity/notificationRegistry/notificationRegistryReducer.d.ts +2 -1
- package/lib/entity/notificationRegistry/notificationRegistryReducer.js +20 -9
- package/lib/entity/notificationRegistry/notificationRegistrySelector.d.ts +2 -1
- package/lib/entity/notificationRegistry/notificationRegistrySelector.js +7 -1
- package/lib/entity/notificationRegistry/notificationRegistryState.d.ts +5 -0
- package/lib/entity/notificationRegistry/notificationRegistryState.js +7 -1
- package/lib/entity/sectionProjectView/sectionProjectViewReducer.js +3 -1
- package/lib/epic.js +4 -4
- package/lib/esm/entity/notificationRegistry/notificationRegistryReducer.js +20 -9
- package/lib/esm/entity/notificationRegistry/notificationRegistrySelector.js +5 -0
- package/lib/esm/entity/notificationRegistry/notificationRegistryState.js +5 -0
- package/lib/esm/entity/sectionProjectView/sectionProjectViewReducer.js +3 -1
- package/lib/esm/epic.js +4 -4
- package/lib/esm/index.js +4 -4
- package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +4 -2
- package/lib/esm/view/aiCfoView/epics/fetchRoutineRunsEpic.js +3 -1
- package/lib/esm/view/expenseAutomationView/reducers/reconciliationViewReducer.js +80 -53
- package/lib/esm/view/notificationPreferencesView/epics/saveNotificationPreferencesEpic.js +20 -7
- package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewReducer.js +43 -17
- package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewSelector.js +24 -4
- package/lib/esm/view/settingsView/epic/fetchNotificationSettingsEpic.js +12 -2
- package/lib/index.d.ts +4 -4
- package/lib/index.js +21 -14
- package/lib/view/aiCfoView/aiCfoViewReducer.js +4 -2
- package/lib/view/aiCfoView/aiCfoViewSelector.d.ts +1 -1
- package/lib/view/aiCfoView/epics/fetchRoutineRunsEpic.js +3 -1
- package/lib/view/expenseAutomationView/reducers/reconciliationViewReducer.js +80 -53
- package/lib/view/notificationPreferencesView/epics/saveNotificationPreferencesEpic.js +19 -6
- package/lib/view/notificationPreferencesView/notificationPreferencesViewReducer.d.ts +8 -5
- package/lib/view/notificationPreferencesView/notificationPreferencesViewReducer.js +43 -17
- package/lib/view/notificationPreferencesView/notificationPreferencesViewSelector.d.ts +4 -0
- package/lib/view/notificationPreferencesView/notificationPreferencesViewSelector.js +30 -5
- package/lib/view/notificationPreferencesView/notificationPreferencesViewState.d.ts +4 -3
- package/lib/view/settingsView/epic/fetchNotificationSettingsEpic.js +12 -2
- package/lib/view/settingsView/settingsViewPayload.d.ts +2 -0
- package/package.json +1 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { NotificationRegistryPayload } from './notificationRegistryPayload';
|
|
2
|
-
import { NotificationRegistryState } from './notificationRegistryState';
|
|
2
|
+
import { NotificationDomain, NotificationRegistryState } from './notificationRegistryState';
|
|
3
3
|
export declare const initialState: NotificationRegistryState;
|
|
4
4
|
export interface UpdateNotificationRegistryPayload {
|
|
5
5
|
registry: NotificationRegistryPayload | undefined;
|
|
6
6
|
registryEpochAtDispatch: number;
|
|
7
|
+
registriesByDomain?: Partial<Record<NotificationDomain, NotificationRegistryPayload | undefined>>;
|
|
7
8
|
}
|
|
8
9
|
export declare const updateNotificationRegistry: import("@reduxjs/toolkit").ActionCreatorWithPayload<UpdateNotificationRegistryPayload, "notificationRegistry/updateNotificationRegistry">;
|
|
9
10
|
declare const _default: import("redux").Reducer<NotificationRegistryState>;
|
|
@@ -4,6 +4,7 @@ exports.updateNotificationRegistry = exports.initialState = void 0;
|
|
|
4
4
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
5
5
|
const rootActions_1 = require("../../rootActions");
|
|
6
6
|
const notificationRegistryPayload_1 = require("./notificationRegistryPayload");
|
|
7
|
+
const notificationRegistryState_1 = require("./notificationRegistryState");
|
|
7
8
|
exports.initialState = { registryEpoch: 0 };
|
|
8
9
|
const notificationRegistry = (0, toolkit_1.createSlice)({
|
|
9
10
|
name: 'notificationRegistry',
|
|
@@ -22,16 +23,24 @@ const notificationRegistry = (0, toolkit_1.createSlice)({
|
|
|
22
23
|
// `task_checklist_registry` CLEARS so tenant B doesn't inherit A's
|
|
23
24
|
// Task Checklist section. Guarded by the epoch check above so a stale
|
|
24
25
|
// absent-response can't wipe a fresh registry.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
const { registriesByDomain } = action.payload;
|
|
27
|
+
// Absent `registriesByDomain` means a pre-domain caller: treat `registry`
|
|
28
|
+
// as the task_checklist snapshot so their behaviour is unchanged.
|
|
29
|
+
const snapshots = registriesByDomain ?? { task_checklist: action.payload.registry };
|
|
30
|
+
draft.registryByDomain = {};
|
|
31
|
+
for (const domain of notificationRegistryState_1.NOTIFICATION_DOMAINS) {
|
|
32
|
+
const payload = snapshots[domain];
|
|
33
|
+
// Full-replace per domain, and an absent snapshot CLEARS that domain so
|
|
34
|
+
// tenant B never inherits A's section. The gates are independent
|
|
35
|
+
// server-side, so one domain clearing must not touch the other.
|
|
36
|
+
if (payload != null) {
|
|
37
|
+
draft.registryByDomain[domain] =
|
|
38
|
+
(0, notificationRegistryPayload_1.mapNotificationRegistryPayloadToRegistry)(payload);
|
|
39
|
+
}
|
|
28
40
|
}
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// the preferences slice's `mergePreferences`). Do not assume the
|
|
33
|
-
// current payload is partial without also updating this reducer.
|
|
34
|
-
draft.registry = (0, notificationRegistryPayload_1.mapNotificationRegistryPayloadToRegistry)(action.payload.registry);
|
|
41
|
+
// Mirrored for consumers that predate the domain-keyed map.
|
|
42
|
+
draft.registry = draft.registryByDomain.task_checklist;
|
|
43
|
+
return;
|
|
35
44
|
},
|
|
36
45
|
},
|
|
37
46
|
extraReducers: (builder) => {
|
|
@@ -44,6 +53,8 @@ const notificationRegistry = (0, toolkit_1.createSlice)({
|
|
|
44
53
|
// — Cursor Bugbot 67d6918e. Returning `initialState` verbatim would
|
|
45
54
|
// rewind the counter and let a stale in-flight GET restore A's
|
|
46
55
|
// registry over B's.
|
|
56
|
+
// Drops `registry` and `registryByDomain` together: a tenant switch must
|
|
57
|
+
// not leave one domain's section behind.
|
|
47
58
|
return { registryEpoch: draft.registryEpoch + 1 };
|
|
48
59
|
});
|
|
49
60
|
},
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { NotificationRegistry, NotificationRegistryState } from './notificationRegistryState';
|
|
1
|
+
import { NotificationDomain, NotificationRegistry, NotificationRegistryState } from './notificationRegistryState';
|
|
2
2
|
export declare const getNotificationRegistry: (slice: NotificationRegistryState) => NotificationRegistry | undefined;
|
|
3
|
+
export declare const getNotificationRegistryForDomain: (slice: NotificationRegistryState, domain: NotificationDomain) => NotificationRegistry | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getNotificationRegistry = void 0;
|
|
3
|
+
exports.getNotificationRegistryForDomain = exports.getNotificationRegistry = void 0;
|
|
4
4
|
// Current behavior: a null / undefined registry means the whole notification
|
|
5
5
|
// section is hidden by consumers. This conflates two distinct states —
|
|
6
6
|
// "user has no saved preferences yet" vs "the Task Checklist feature gate is
|
|
@@ -8,3 +8,9 @@ exports.getNotificationRegistry = void 0;
|
|
|
8
8
|
// them (e.g. an explicit `gate_off` signal from the server) is a follow-up.
|
|
9
9
|
const getNotificationRegistry = (slice) => slice.registry;
|
|
10
10
|
exports.getNotificationRegistry = getNotificationRegistry;
|
|
11
|
+
// `undefined` conflates gate-off with no-preferences-yet; consumers hide the
|
|
12
|
+
// section either way. Falls back to `registry` for task_checklist so state built
|
|
13
|
+
// in the pre-domain shape (consumer mocks, older callers) still resolves.
|
|
14
|
+
const getNotificationRegistryForDomain = (slice, domain) => slice.registryByDomain?.[domain] ??
|
|
15
|
+
(domain === 'task_checklist' ? slice.registry : undefined);
|
|
16
|
+
exports.getNotificationRegistryForDomain = getNotificationRegistryForDomain;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export declare const NOTIFICATION_DOMAINS: readonly ["task_checklist", "commenting"];
|
|
2
|
+
export type NotificationDomain = (typeof NOTIFICATION_DOMAINS)[number];
|
|
3
|
+
export declare const DEFAULT_NOTIFICATION_DOMAIN: NotificationDomain;
|
|
4
|
+
export declare const toNotificationDomain: (raw: string) => NotificationDomain;
|
|
1
5
|
export declare const NOTIFICATION_CHANNELS: readonly ["email", "slack", "in_app"];
|
|
2
6
|
export type NotificationChannel = (typeof NOTIFICATION_CHANNELS)[number];
|
|
3
7
|
export declare const toNotificationChannel: (raw: string) => NotificationChannel;
|
|
@@ -30,4 +34,5 @@ export interface NotificationRegistry {
|
|
|
30
34
|
export interface NotificationRegistryState {
|
|
31
35
|
registryEpoch: number;
|
|
32
36
|
registry?: NotificationRegistry;
|
|
37
|
+
registryByDomain?: Partial<Record<NotificationDomain, NotificationRegistry>>;
|
|
33
38
|
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toNotificationFrequency = exports.NOTIFICATION_FREQUENCIES = exports.toNotificationChannel = exports.NOTIFICATION_CHANNELS = void 0;
|
|
3
|
+
exports.toNotificationFrequency = exports.NOTIFICATION_FREQUENCIES = exports.toNotificationChannel = exports.NOTIFICATION_CHANNELS = exports.toNotificationDomain = exports.DEFAULT_NOTIFICATION_DOMAIN = exports.NOTIFICATION_DOMAINS = void 0;
|
|
4
4
|
const stringToUnion_1 = require("../../commonStateTypes/stringToUnion");
|
|
5
|
+
// Wire vocabulary owned by the notifications service, not by this slice.
|
|
6
|
+
exports.NOTIFICATION_DOMAINS = ['task_checklist', 'commenting'];
|
|
7
|
+
// Callers that predate the domain split mean Task Checklist.
|
|
8
|
+
exports.DEFAULT_NOTIFICATION_DOMAIN = 'task_checklist';
|
|
9
|
+
const toNotificationDomain = (raw) => (0, stringToUnion_1.stringToUnion)(raw, exports.NOTIFICATION_DOMAINS);
|
|
10
|
+
exports.toNotificationDomain = toNotificationDomain;
|
|
5
11
|
exports.NOTIFICATION_CHANNELS = ['email', 'slack', 'in_app'];
|
|
6
12
|
const toNotificationChannel = (raw) => (0, stringToUnion_1.stringToUnion)(raw, exports.NOTIFICATION_CHANNELS);
|
|
7
13
|
exports.toNotificationChannel = toNotificationChannel;
|
|
@@ -35,7 +35,9 @@ const sectionProjectView = (0, toolkit_1.createSlice)({
|
|
|
35
35
|
Object.keys(sectionPayload.projects).forEach((projectId) => {
|
|
36
36
|
const projectPayload = sectionPayload.projects[projectId];
|
|
37
37
|
// A calculated section is grouped by project with no accounts under it.
|
|
38
|
-
const projectAccounts = 'accounts' in projectPayload
|
|
38
|
+
const projectAccounts = 'accounts' in projectPayload
|
|
39
|
+
? projectPayload.accounts
|
|
40
|
+
: undefined;
|
|
39
41
|
const nestedAccountIds = projectAccounts != null
|
|
40
42
|
? (0, getNestedAccountIDHierarchyForSection_1.getNestedAccountIDHierarchyForAccounts)(Object.keys(projectAccounts), accountsMetadata)
|
|
41
43
|
: [];
|
package/lib/epic.js
CHANGED
|
@@ -53,21 +53,21 @@ const acceptMasterTOSEpic_1 = require("./view/aiCfoView/epics/acceptMasterTOSEpi
|
|
|
53
53
|
const createSessionAndSubmitEpic_1 = require("./view/aiCfoView/epics/createSessionAndSubmitEpic");
|
|
54
54
|
const createSessionEpic_1 = require("./view/aiCfoView/epics/createSessionEpic");
|
|
55
55
|
const deleteChatSessionEpic_1 = require("./view/aiCfoView/epics/deleteChatSessionEpic");
|
|
56
|
+
const deleteRoutineEpic_1 = require("./view/aiCfoView/epics/deleteRoutineEpic");
|
|
56
57
|
const deleteSkillEpic_1 = require("./view/aiCfoView/epics/deleteSkillEpic");
|
|
57
58
|
const fetchChatHistoryEpic_1 = require("./view/aiCfoView/epics/fetchChatHistoryEpic");
|
|
58
59
|
const fetchChatSessionsForUserEpic_1 = require("./view/aiCfoView/epics/fetchChatSessionsForUserEpic");
|
|
60
|
+
const fetchRoutineRunsEpic_1 = require("./view/aiCfoView/epics/fetchRoutineRunsEpic");
|
|
61
|
+
const fetchRoutinesEpic_1 = require("./view/aiCfoView/epics/fetchRoutinesEpic");
|
|
59
62
|
const fetchSkillDetailEpic_1 = require("./view/aiCfoView/epics/fetchSkillDetailEpic");
|
|
60
63
|
const fetchSkillVersionBodyEpic_1 = require("./view/aiCfoView/epics/fetchSkillVersionBodyEpic");
|
|
61
64
|
const fetchSkillVersionsEpic_1 = require("./view/aiCfoView/epics/fetchSkillVersionsEpic");
|
|
62
65
|
const fetchSkillsEpic_1 = require("./view/aiCfoView/epics/fetchSkillsEpic");
|
|
63
66
|
const fetchSuggestedQuestionsEpic_1 = require("./view/aiCfoView/epics/fetchSuggestedQuestionsEpic");
|
|
64
|
-
const deleteRoutineEpic_1 = require("./view/aiCfoView/epics/deleteRoutineEpic");
|
|
65
|
-
const fetchRoutineRunsEpic_1 = require("./view/aiCfoView/epics/fetchRoutineRunsEpic");
|
|
66
|
-
const fetchRoutinesEpic_1 = require("./view/aiCfoView/epics/fetchRoutinesEpic");
|
|
67
67
|
const runRoutineEpic_1 = require("./view/aiCfoView/epics/runRoutineEpic");
|
|
68
68
|
const saveRoutineEpic_1 = require("./view/aiCfoView/epics/saveRoutineEpic");
|
|
69
|
-
const setRoutineEnabledEpic_1 = require("./view/aiCfoView/epics/setRoutineEnabledEpic");
|
|
70
69
|
const saveSkillEpic_1 = require("./view/aiCfoView/epics/saveSkillEpic");
|
|
70
|
+
const setRoutineEnabledEpic_1 = require("./view/aiCfoView/epics/setRoutineEnabledEpic");
|
|
71
71
|
const setSkillVisibilityEpic_1 = require("./view/aiCfoView/epics/setSkillVisibilityEpic");
|
|
72
72
|
const stopSubmitEpic_1 = require("./view/aiCfoView/epics/stopSubmitEpic");
|
|
73
73
|
const stopSubmitQuestionEpic_1 = require("./view/aiCfoView/epics/stopSubmitQuestionEpic");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { clearAll } from '../../rootActions';
|
|
3
3
|
import { mapNotificationRegistryPayloadToRegistry, } from './notificationRegistryPayload';
|
|
4
|
+
import { NOTIFICATION_DOMAINS, } from './notificationRegistryState';
|
|
4
5
|
export const initialState = { registryEpoch: 0 };
|
|
5
6
|
const notificationRegistry = createSlice({
|
|
6
7
|
name: 'notificationRegistry',
|
|
@@ -19,16 +20,24 @@ const notificationRegistry = createSlice({
|
|
|
19
20
|
// `task_checklist_registry` CLEARS so tenant B doesn't inherit A's
|
|
20
21
|
// Task Checklist section. Guarded by the epoch check above so a stale
|
|
21
22
|
// absent-response can't wipe a fresh registry.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const { registriesByDomain } = action.payload;
|
|
24
|
+
// Absent `registriesByDomain` means a pre-domain caller: treat `registry`
|
|
25
|
+
// as the task_checklist snapshot so their behaviour is unchanged.
|
|
26
|
+
const snapshots = registriesByDomain ?? { task_checklist: action.payload.registry };
|
|
27
|
+
draft.registryByDomain = {};
|
|
28
|
+
for (const domain of NOTIFICATION_DOMAINS) {
|
|
29
|
+
const payload = snapshots[domain];
|
|
30
|
+
// Full-replace per domain, and an absent snapshot CLEARS that domain so
|
|
31
|
+
// tenant B never inherits A's section. The gates are independent
|
|
32
|
+
// server-side, so one domain clearing must not touch the other.
|
|
33
|
+
if (payload != null) {
|
|
34
|
+
draft.registryByDomain[domain] =
|
|
35
|
+
mapNotificationRegistryPayloadToRegistry(payload);
|
|
36
|
+
}
|
|
25
37
|
}
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// the preferences slice's `mergePreferences`). Do not assume the
|
|
30
|
-
// current payload is partial without also updating this reducer.
|
|
31
|
-
draft.registry = mapNotificationRegistryPayloadToRegistry(action.payload.registry);
|
|
38
|
+
// Mirrored for consumers that predate the domain-keyed map.
|
|
39
|
+
draft.registry = draft.registryByDomain.task_checklist;
|
|
40
|
+
return;
|
|
32
41
|
},
|
|
33
42
|
},
|
|
34
43
|
extraReducers: (builder) => {
|
|
@@ -41,6 +50,8 @@ const notificationRegistry = createSlice({
|
|
|
41
50
|
// — Cursor Bugbot 67d6918e. Returning `initialState` verbatim would
|
|
42
51
|
// rewind the counter and let a stale in-flight GET restore A's
|
|
43
52
|
// registry over B's.
|
|
53
|
+
// Drops `registry` and `registryByDomain` together: a tenant switch must
|
|
54
|
+
// not leave one domain's section behind.
|
|
44
55
|
return { registryEpoch: draft.registryEpoch + 1 };
|
|
45
56
|
});
|
|
46
57
|
},
|
|
@@ -4,3 +4,8 @@
|
|
|
4
4
|
// off for this tenant". Both currently surface as `undefined`. Distinguishing
|
|
5
5
|
// them (e.g. an explicit `gate_off` signal from the server) is a follow-up.
|
|
6
6
|
export const getNotificationRegistry = (slice) => slice.registry;
|
|
7
|
+
// `undefined` conflates gate-off with no-preferences-yet; consumers hide the
|
|
8
|
+
// section either way. Falls back to `registry` for task_checklist so state built
|
|
9
|
+
// in the pre-domain shape (consumer mocks, older callers) still resolves.
|
|
10
|
+
export const getNotificationRegistryForDomain = (slice, domain) => slice.registryByDomain?.[domain] ??
|
|
11
|
+
(domain === 'task_checklist' ? slice.registry : undefined);
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { stringToUnion } from '../../commonStateTypes/stringToUnion';
|
|
2
|
+
// Wire vocabulary owned by the notifications service, not by this slice.
|
|
3
|
+
export const NOTIFICATION_DOMAINS = ['task_checklist', 'commenting'];
|
|
4
|
+
// Callers that predate the domain split mean Task Checklist.
|
|
5
|
+
export const DEFAULT_NOTIFICATION_DOMAIN = 'task_checklist';
|
|
6
|
+
export const toNotificationDomain = (raw) => stringToUnion(raw, NOTIFICATION_DOMAINS);
|
|
2
7
|
export const NOTIFICATION_CHANNELS = ['email', 'slack', 'in_app'];
|
|
3
8
|
export const toNotificationChannel = (raw) => stringToUnion(raw, NOTIFICATION_CHANNELS);
|
|
4
9
|
export const NOTIFICATION_FREQUENCIES = ['instant', 'daily'];
|
|
@@ -32,7 +32,9 @@ const sectionProjectView = createSlice({
|
|
|
32
32
|
Object.keys(sectionPayload.projects).forEach((projectId) => {
|
|
33
33
|
const projectPayload = sectionPayload.projects[projectId];
|
|
34
34
|
// A calculated section is grouped by project with no accounts under it.
|
|
35
|
-
const projectAccounts = 'accounts' in projectPayload
|
|
35
|
+
const projectAccounts = 'accounts' in projectPayload
|
|
36
|
+
? projectPayload.accounts
|
|
37
|
+
: undefined;
|
|
36
38
|
const nestedAccountIds = projectAccounts != null
|
|
37
39
|
? getNestedAccountIDHierarchyForAccounts(Object.keys(projectAccounts), accountsMetadata)
|
|
38
40
|
: [];
|
package/lib/esm/epic.js
CHANGED
|
@@ -50,21 +50,21 @@ import { acceptMasterTOSEpic, } from './view/aiCfoView/epics/acceptMasterTOSEpic
|
|
|
50
50
|
import { createSessionAndSubmitEpic, } from './view/aiCfoView/epics/createSessionAndSubmitEpic';
|
|
51
51
|
import { createSessionEpic, } from './view/aiCfoView/epics/createSessionEpic';
|
|
52
52
|
import { deleteChatSessionEpic, } from './view/aiCfoView/epics/deleteChatSessionEpic';
|
|
53
|
+
import { deleteRoutineEpic } from './view/aiCfoView/epics/deleteRoutineEpic';
|
|
53
54
|
import { deleteSkillEpic } from './view/aiCfoView/epics/deleteSkillEpic';
|
|
54
55
|
import { fetchChatHistoryEpic, } from './view/aiCfoView/epics/fetchChatHistoryEpic';
|
|
55
56
|
import { fetchChatSessionsForUserEpic, } from './view/aiCfoView/epics/fetchChatSessionsForUserEpic';
|
|
57
|
+
import { fetchRoutineRunsEpic } from './view/aiCfoView/epics/fetchRoutineRunsEpic';
|
|
58
|
+
import { fetchRoutinesEpic } from './view/aiCfoView/epics/fetchRoutinesEpic';
|
|
56
59
|
import { fetchSkillDetailEpic } from './view/aiCfoView/epics/fetchSkillDetailEpic';
|
|
57
60
|
import { fetchSkillVersionBodyEpic } from './view/aiCfoView/epics/fetchSkillVersionBodyEpic';
|
|
58
61
|
import { fetchSkillVersionsEpic } from './view/aiCfoView/epics/fetchSkillVersionsEpic';
|
|
59
62
|
import { fetchSkillsEpic, } from './view/aiCfoView/epics/fetchSkillsEpic';
|
|
60
63
|
import { fetchSuggestedQuestionsEpic, } from './view/aiCfoView/epics/fetchSuggestedQuestionsEpic';
|
|
61
|
-
import { deleteRoutineEpic } from './view/aiCfoView/epics/deleteRoutineEpic';
|
|
62
|
-
import { fetchRoutineRunsEpic } from './view/aiCfoView/epics/fetchRoutineRunsEpic';
|
|
63
|
-
import { fetchRoutinesEpic } from './view/aiCfoView/epics/fetchRoutinesEpic';
|
|
64
64
|
import { runRoutineEpic } from './view/aiCfoView/epics/runRoutineEpic';
|
|
65
65
|
import { saveRoutineEpic } from './view/aiCfoView/epics/saveRoutineEpic';
|
|
66
|
-
import { setRoutineEnabledEpic } from './view/aiCfoView/epics/setRoutineEnabledEpic';
|
|
67
66
|
import { saveSkillEpic } from './view/aiCfoView/epics/saveSkillEpic';
|
|
67
|
+
import { setRoutineEnabledEpic } from './view/aiCfoView/epics/setRoutineEnabledEpic';
|
|
68
68
|
import { setSkillVisibilityEpic } from './view/aiCfoView/epics/setSkillVisibilityEpic';
|
|
69
69
|
import { stopSubmitEpic, } from './view/aiCfoView/epics/stopSubmitEpic';
|
|
70
70
|
import { stopSubmitQuestionEpic, } from './view/aiCfoView/epics/stopSubmitQuestionEpic';
|
package/lib/esm/index.js
CHANGED
|
@@ -64,8 +64,8 @@ import { ALL_JE_SCHEDULE_IGNORE_REASONS, ALL_JE_SCHEDULE_REVERT_REASONS, ALL_ONE
|
|
|
64
64
|
import { ALL_MONTH_END_CLOSE_CHECKS_FREQUENCY, } from './entity/monthEndCloseChecks/monthEndCloseChecksState';
|
|
65
65
|
import { updateCommentsNotifications, updateCommentsNotificationsStatuses, } from './entity/notification/notificationReducer';
|
|
66
66
|
import { toNotificationModeStrict, } from './entity/notification/types/notificationTypes';
|
|
67
|
-
import { getNotificationRegistry } from './entity/notificationRegistry/notificationRegistrySelector';
|
|
68
|
-
import { toNotificationChannel, toNotificationFrequency, } from './entity/notificationRegistry/notificationRegistryState';
|
|
67
|
+
import { getNotificationRegistry, getNotificationRegistryForDomain, } from './entity/notificationRegistry/notificationRegistrySelector';
|
|
68
|
+
import { DEFAULT_NOTIFICATION_DOMAIN, NOTIFICATION_DOMAINS, toNotificationChannel, toNotificationDomain, toNotificationFrequency, } from './entity/notificationRegistry/notificationRegistryState';
|
|
69
69
|
import { getPlaidPaymentAccounts } from './entity/paymentAccount/paymentAccountSelector';
|
|
70
70
|
import { VERIFIED_PAYMENT_ACCOUNT_PROVIDER_VERIFICATION_STATUS, } from './entity/paymentAccount/paymentAccountState';
|
|
71
71
|
import { closeSnackbar, openSnackbar } from './entity/snackbar/snackbarReducer';
|
|
@@ -236,7 +236,7 @@ import { toAverageMonthsCount } from './view/netBurnOrIncomeStoryCard/epic/updat
|
|
|
236
236
|
import { fetchNetBurnOrIncomeStoryCard, updateNetBurnOrIncomeStoryCardSettings, } from './view/netBurnOrIncomeStoryCard/netBurnOrIncomeStoryCardReducer';
|
|
237
237
|
import { getNetBurnOrIncomeStoryCardReport } from './view/netBurnOrIncomeStoryCard/netBurnOrIncomeStoryCardSelector';
|
|
238
238
|
import { clearAllNotificationPreferencesView, clearNotificationPreferencesLocalOverrides, saveNotificationPreferences, setGroupChannelMaster, setGroupFrequency, toggleEventChannel, } from './view/notificationPreferencesView/notificationPreferencesViewReducer';
|
|
239
|
-
import { getEffectiveNotificationPreferences, getNotificationLocalOverrides, getNotificationPreferencesSaveState, hasUnsavedNotificationPreferences, } from './view/notificationPreferencesView/notificationPreferencesViewSelector';
|
|
239
|
+
import { getEffectiveNotificationPreferences, getEffectiveNotificationPreferencesForDomain, getNotificationLocalOverrides, getNotificationLocalOverridesForDomain, getNotificationPreferencesSaveState, hasUnsavedNotificationPreferences, hasUnsavedNotificationPreferencesForDomain, } from './view/notificationPreferencesView/notificationPreferencesViewSelector';
|
|
240
240
|
import { fetchNotificationUnreadCount, fetchNotificationUnreadCountSuccess, fetchNotificationView, updateNotificationViewAllNotificationsStatus, updateNotificationViewCurrentTabAndSubTab, updateNotificationViewNotificationStatus, updateNotificationViewSubTab, updateNotificationViewTabState, updateNotificationViewUIState, } from './view/notificationView/notificationViewReducer';
|
|
241
241
|
import { getExternalNotificationsForSelectedSubTab, getNotificationView, getNotificationsForSelectedSubTab, } from './view/notificationView/notificationViewSelector';
|
|
242
242
|
import { toNotificationSubTabTypeStrict, toNotificationTabTypeStrict, } from './view/notificationView/notificationViewState';
|
|
@@ -680,7 +680,7 @@ export { toNotificationModeStrict, updateCommentsNotifications, updateCommentsNo
|
|
|
680
680
|
export { toNotificationSubTabTypeStrict, toNotificationTabTypeStrict, fetchNotificationView, fetchNotificationUnreadCount, fetchNotificationUnreadCountSuccess, updateNotificationViewAllNotificationsStatus, updateNotificationViewNotificationStatus, updateNotificationViewTabState, updateNotificationViewCurrentTabAndSubTab, updateNotificationViewSubTab, updateNotificationViewUIState, getNotificationView, getExternalNotificationsForSelectedSubTab, getNotificationsForSelectedSubTab, };
|
|
681
681
|
export { fetchRegisteredInterests, notifyMeForFeature, getFeatureNotificationView, getRegisteredInterests, getRegisteredInterestsByFeature, isFeatureInterestRegistered, };
|
|
682
682
|
export { pushToastNotification, getLastNotificationTime, getNotifications, };
|
|
683
|
-
export { getEffectiveNotificationPreferences, getNotificationLocalOverrides, getNotificationPreferencesSaveState, getNotificationRegistry, hasUnsavedNotificationPreferences, clearAllNotificationPreferencesView, clearNotificationPreferencesLocalOverrides, saveNotificationPreferences, setGroupChannelMaster, setGroupFrequency, toggleEventChannel, toNotificationChannel, toNotificationFrequency, };
|
|
683
|
+
export { getEffectiveNotificationPreferences, getEffectiveNotificationPreferencesForDomain, getNotificationLocalOverrides, getNotificationLocalOverridesForDomain, getNotificationPreferencesSaveState, getNotificationRegistry, getNotificationRegistryForDomain, hasUnsavedNotificationPreferences, hasUnsavedNotificationPreferencesForDomain, NOTIFICATION_DOMAINS, DEFAULT_NOTIFICATION_DOMAIN, clearAllNotificationPreferencesView, clearNotificationPreferencesLocalOverrides, saveNotificationPreferences, setGroupChannelMaster, setGroupFrequency, toggleEventChannel, toNotificationChannel, toNotificationDomain, toNotificationFrequency, };
|
|
684
684
|
export { getReferralListView, getInviteFormView, toReferralListViewSortKeyType, StatusTypes, AmountStatusTypes, DEFAULT_REFERRER_AMOUNT, fetchReferrals, sendReferralInvite, clearReferrals, saveReferralFormDataInLocalStore, updateReferralListSortUiState, resendReferralInvite, fetchRewardsPlan, getRewardsPlanCard, updateReferViewed, };
|
|
685
685
|
export { ALL_WEEK_DAYS, SEMI_WEEKLY_REQUIRED_DAYS_COUNT, getMinAllowedEndDate, getRecurringEndDateFromCount, toDayOfWeek, toRecurringFrequency, };
|
|
686
686
|
export { fetchCockpitContext, fetchCompanyTaskManagerView, fetchTaskManagerMetrics, getCompanyTaskManagerView, createTaskFromTaskGroupTemplate, };
|
|
@@ -835,7 +835,8 @@ const aiCfoView = createSlice({
|
|
|
835
835
|
// The server has it. Nothing it sends from here on will contain this row,
|
|
836
836
|
// so the tombstone has done its job and holding it any longer is what
|
|
837
837
|
// makes a routine recreated under the same id invisible forever.
|
|
838
|
-
draft.routines.deletedScheduleIds =
|
|
838
|
+
draft.routines.deletedScheduleIds =
|
|
839
|
+
draft.routines.deletedScheduleIds.filter((id) => id !== action.payload.scheduleId);
|
|
839
840
|
draft.routineMutation = {
|
|
840
841
|
fetchState: 'Completed',
|
|
841
842
|
error: undefined,
|
|
@@ -847,7 +848,8 @@ const aiCfoView = createSlice({
|
|
|
847
848
|
// is what lets the refetch put the row back — leaving it hidden would
|
|
848
849
|
// tell the user they had stopped something they had not, which is the
|
|
849
850
|
// worst outcome this list can produce.
|
|
850
|
-
draft.routines.deletedScheduleIds =
|
|
851
|
+
draft.routines.deletedScheduleIds =
|
|
852
|
+
draft.routines.deletedScheduleIds.filter((id) => id !== action.payload.scheduleId);
|
|
851
853
|
// Its own slice: the refetch that puts the row back would otherwise wipe
|
|
852
854
|
// this error, leaving the row silently reappearing with no explanation.
|
|
853
855
|
draft.routineMutation = {
|
|
@@ -27,7 +27,9 @@ export const fetchRoutineRunsEpic = (actions$, _state$, zeniAPI) => actions$.pip
|
|
|
27
27
|
// Filtered, not trusted: one malformed row must not take the
|
|
28
28
|
// whole history down, and a run without an id is not addressable
|
|
29
29
|
// by anything the UI does with it.
|
|
30
|
-
runs: (data.runs ?? [])
|
|
30
|
+
runs: (data.runs ?? [])
|
|
31
|
+
.filter(isRoutineRunPayload)
|
|
32
|
+
.map(toRoutineRun),
|
|
31
33
|
scheduleId,
|
|
32
34
|
sessionId: data.session_id ?? null,
|
|
33
35
|
});
|
|
@@ -102,32 +102,27 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
102
102
|
draft.selectedTab = 'review';
|
|
103
103
|
draft.selectedAccountId = action.payload.accountId;
|
|
104
104
|
}
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(action.payload.selectedPeriod)]?.reconciliationByAccountID[action.payload.accountId];
|
|
106
|
+
if (accountRecon == null) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (accountRecon.transactionFetchState.fetchState !== 'Completed' ||
|
|
108
110
|
action.payload.cacheOverride === true) {
|
|
109
|
-
const data = accountReconciliationRecords.reconciliationByAccountID[action.payload.accountId];
|
|
110
111
|
if (action.payload.refreshViewInBackground === true) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
fetchState: 'In-Progress',
|
|
115
|
-
error: undefined,
|
|
116
|
-
},
|
|
117
|
-
accountId: action.payload.accountId,
|
|
118
|
-
reconciliationId: undefined,
|
|
112
|
+
accountRecon.refreshStatus = {
|
|
113
|
+
fetchState: 'In-Progress',
|
|
114
|
+
error: undefined,
|
|
119
115
|
};
|
|
116
|
+
accountRecon.accountId = action.payload.accountId;
|
|
117
|
+
accountRecon.reconciliationId = undefined;
|
|
120
118
|
}
|
|
121
119
|
else {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
fetchState: 'In-Progress',
|
|
126
|
-
error: undefined,
|
|
127
|
-
},
|
|
128
|
-
accountId: action.payload.accountId,
|
|
129
|
-
reconciliationId: undefined,
|
|
120
|
+
accountRecon.transactionFetchState = {
|
|
121
|
+
fetchState: 'In-Progress',
|
|
122
|
+
error: undefined,
|
|
130
123
|
};
|
|
124
|
+
accountRecon.accountId = action.payload.accountId;
|
|
125
|
+
accountRecon.reconciliationId = undefined;
|
|
131
126
|
}
|
|
132
127
|
}
|
|
133
128
|
}
|
|
@@ -179,14 +174,17 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
179
174
|
}
|
|
180
175
|
}
|
|
181
176
|
else {
|
|
182
|
-
const
|
|
177
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(action.payload.selectedPeriod)]?.reconciliationByAccountID[action.payload.accountId];
|
|
178
|
+
if (accountRecon == null) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
183
181
|
if (action.payload.refreshViewInBackground === true) {
|
|
184
|
-
|
|
185
|
-
|
|
182
|
+
accountRecon.refreshStatus.error = action.payload.error;
|
|
183
|
+
accountRecon.refreshStatus.fetchState = 'Error';
|
|
186
184
|
}
|
|
187
185
|
else {
|
|
188
|
-
|
|
189
|
-
|
|
186
|
+
accountRecon.transactionFetchState.error = action.payload.error;
|
|
187
|
+
accountRecon.transactionFetchState.fetchState = 'Error';
|
|
190
188
|
}
|
|
191
189
|
}
|
|
192
190
|
},
|
|
@@ -391,8 +389,11 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
391
389
|
},
|
|
392
390
|
setStatementParseInProgress: (draft, action) => {
|
|
393
391
|
const { accountId, selectedPeriod, statementParseInProgress } = action.payload;
|
|
394
|
-
draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]
|
|
395
|
-
|
|
392
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
393
|
+
if (accountRecon == null) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
accountRecon.statementParseInProgress = statementParseInProgress;
|
|
396
397
|
},
|
|
397
398
|
setStatementProcessingDismissedToBackground: (draft, action) => {
|
|
398
399
|
const { accountId, selectedPeriod, dismissedToBackground } = action.payload;
|
|
@@ -476,15 +477,23 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
476
477
|
},
|
|
477
478
|
uploadAccountStatementSuccess: (draft, action) => {
|
|
478
479
|
const { accountId, selectedPeriod } = action.payload;
|
|
479
|
-
draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]
|
|
480
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
481
|
+
if (accountRecon == null) {
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
accountRecon.statementUploadStatus = {
|
|
480
485
|
fetchState: 'Completed',
|
|
481
486
|
error: undefined,
|
|
482
487
|
};
|
|
483
|
-
|
|
488
|
+
accountRecon.statementParseInProgress = true;
|
|
484
489
|
},
|
|
485
490
|
uploadAccountStatementFailure: (draft, action) => {
|
|
486
491
|
const { accountId, selectedPeriod } = action.payload;
|
|
487
|
-
draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]
|
|
492
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
493
|
+
if (accountRecon == null) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
accountRecon.statementUploadStatus = {
|
|
488
497
|
fetchState: 'Error',
|
|
489
498
|
error: action.payload.error,
|
|
490
499
|
};
|
|
@@ -677,23 +686,34 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
677
686
|
},
|
|
678
687
|
reparseStatementFailure: (draft, action) => {
|
|
679
688
|
const { accountId, selectedPeriod } = action.payload;
|
|
680
|
-
draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]
|
|
689
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
690
|
+
if (accountRecon == null) {
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
accountRecon.reparseStatementStatus = {
|
|
681
694
|
fetchState: 'Error',
|
|
682
695
|
error: action.payload.error,
|
|
683
696
|
};
|
|
684
|
-
|
|
697
|
+
accountRecon.statementProcessingFailed = true;
|
|
685
698
|
},
|
|
686
699
|
resetReparseStatementStatus: (draft, action) => {
|
|
687
700
|
const { accountId, selectedPeriod } = action.payload;
|
|
688
|
-
draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]
|
|
701
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
702
|
+
if (accountRecon == null) {
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
accountRecon.reparseStatementStatus = {
|
|
689
706
|
fetchState: 'Not-Started',
|
|
690
707
|
error: undefined,
|
|
691
708
|
};
|
|
692
709
|
},
|
|
693
710
|
updateParsedStatementData: (draft, action) => {
|
|
694
711
|
const { accountId, selectedPeriod, parsedStatementData } = action.payload;
|
|
695
|
-
draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]
|
|
696
|
-
|
|
712
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
713
|
+
if (accountRecon == null) {
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
accountRecon.parsedStatementData = parsedStatementData;
|
|
697
717
|
},
|
|
698
718
|
updateStatementUpdateLocalData: (draft, action) => {
|
|
699
719
|
const { accountId, selectedPeriod, statementUpdateLocalData, statementUploadId, } = action.payload;
|
|
@@ -819,17 +839,21 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
819
839
|
},
|
|
820
840
|
updateAccountReconciliationLocalData: (draft, action) => {
|
|
821
841
|
const { accountId, selectedPeriod, localData } = action.payload;
|
|
822
|
-
const
|
|
842
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
843
|
+
if (accountRecon == null) {
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
const oldLocalData = accountRecon.localData;
|
|
823
847
|
if (oldLocalData == null) {
|
|
824
|
-
|
|
848
|
+
accountRecon.localData = localData;
|
|
825
849
|
}
|
|
826
850
|
else {
|
|
827
|
-
|
|
851
|
+
accountRecon.localData = {
|
|
828
852
|
...oldLocalData,
|
|
829
853
|
...localData,
|
|
830
854
|
};
|
|
831
855
|
}
|
|
832
|
-
|
|
856
|
+
accountRecon.localData = {
|
|
833
857
|
...oldLocalData,
|
|
834
858
|
...localData,
|
|
835
859
|
};
|
|
@@ -1119,7 +1143,10 @@ function updateAllReconciliation(draft, accounts, selectedPeriod, reconciliation
|
|
|
1119
1143
|
}
|
|
1120
1144
|
}
|
|
1121
1145
|
function updateReconciliationByAccountID(draft, accounts, selectedPeriod, accountId, reconciliationData, refreshViewInBackground) {
|
|
1122
|
-
const
|
|
1146
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
1147
|
+
if (accountRecon == null) {
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1123
1150
|
const oldConnectionStatus = draft.accountConnectionStatusByAccountID[accountId];
|
|
1124
1151
|
draft.accountConnectionStatusByAccountID[accountId] = {
|
|
1125
1152
|
status: toBankStatusCodeType(reconciliationData.bank_status.code),
|
|
@@ -1129,21 +1156,17 @@ function updateReconciliationByAccountID(draft, accounts, selectedPeriod, accoun
|
|
|
1129
1156
|
: false,
|
|
1130
1157
|
paymentAccountId: accounts.payment_account_id ?? undefined,
|
|
1131
1158
|
};
|
|
1132
|
-
const statementParseInProgress = resolveStatementParseInProgressAfterFetch(
|
|
1159
|
+
const statementParseInProgress = resolveStatementParseInProgressAfterFetch(accountRecon, reconciliationData);
|
|
1160
|
+
accountRecon.reconciliationId =
|
|
1161
|
+
reconciliationData.reconciliation_id ?? undefined;
|
|
1162
|
+
accountRecon.statementParseInProgress = statementParseInProgress;
|
|
1133
1163
|
if (refreshViewInBackground === true) {
|
|
1134
|
-
|
|
1135
|
-
...oldRecord,
|
|
1136
|
-
reconciliationId: reconciliationData.reconciliation_id ?? undefined,
|
|
1137
|
-
refreshStatus: { fetchState: 'Completed', error: undefined },
|
|
1138
|
-
statementParseInProgress,
|
|
1139
|
-
};
|
|
1164
|
+
accountRecon.refreshStatus = { fetchState: 'Completed', error: undefined };
|
|
1140
1165
|
}
|
|
1141
1166
|
else {
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
reconciliationId: reconciliationData.reconciliation_id ?? undefined,
|
|
1146
|
-
transactionFetchState: { fetchState: 'Completed', error: undefined },
|
|
1167
|
+
accountRecon.transactionFetchState = {
|
|
1168
|
+
fetchState: 'Completed',
|
|
1169
|
+
error: undefined,
|
|
1147
1170
|
};
|
|
1148
1171
|
}
|
|
1149
1172
|
}
|
|
@@ -1173,7 +1196,11 @@ const updateExcludedAccountExclusionInfo = (draft, account) => {
|
|
|
1173
1196
|
};
|
|
1174
1197
|
};
|
|
1175
1198
|
const updateReconciliationByAccountIDOnIncludeAccount = (draft, accountId, reconciliation, monthYearPeriodId) => {
|
|
1176
|
-
draft.accountReconciliationRecordsBySelectedPeriod[monthYearPeriodId]
|
|
1199
|
+
const accountReconciliationRecords = draft.accountReconciliationRecordsBySelectedPeriod[monthYearPeriodId];
|
|
1200
|
+
if (accountReconciliationRecords == null) {
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
accountReconciliationRecords.reconciliationByAccountID[accountId] = {
|
|
1177
1204
|
accountId,
|
|
1178
1205
|
reconciliationId: reconciliation.reconciliation_id ?? undefined,
|
|
1179
1206
|
transactionFetchState: { fetchState: 'Not-Started', error: undefined },
|