@zeniai/client-epic-state 5.3.18 → 5.3.20
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/commonStateTypes/coaBalance/coaBalance.d.ts +9 -0
- package/lib/commonStateTypes/coaBalance/coaBalance.js +11 -0
- package/lib/entity/tenant/epic/fetchAllTenantsEpic.d.ts +2 -4
- package/lib/entity/tenant/epic/fetchAllTenantsEpic.js +50 -42
- package/lib/entity/tenant/tenantPayload.d.ts +17 -1
- package/lib/entity/tenant/tenantReducer.d.ts +7 -2
- package/lib/entity/tenant/tenantReducer.js +48 -19
- package/lib/entity/tenant/tenantSelector.d.ts +26 -6
- package/lib/entity/tenant/tenantSelector.js +116 -93
- package/lib/entity/tenant/tenantState.d.ts +10 -0
- package/lib/epic.d.ts +2 -1
- package/lib/epic.js +3 -0
- package/lib/esm/commonStateTypes/coaBalance/coaBalance.js +10 -0
- package/lib/esm/entity/tenant/epic/fetchAllTenantsEpic.js +53 -45
- package/lib/esm/entity/tenant/tenantReducer.js +46 -17
- package/lib/esm/entity/tenant/tenantSelector.js +112 -92
- package/lib/esm/epic.js +4 -1
- package/lib/esm/index.js +7 -7
- package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +65 -3
- package/lib/esm/view/aiCfoView/aiCfoViewSelector.js +25 -0
- package/lib/esm/view/aiCfoView/epics/transcribeAudioEpic.js +60 -0
- package/lib/esm/view/balanceSheet/balanceSheetForTimeframeEpic.js +9 -4
- package/lib/esm/view/balanceSheet/balanceSheetReducer.js +2 -0
- package/lib/esm/view/cashFlow/cashFlowForTimeframeEpic.js +11 -5
- package/lib/esm/view/cashFlow/cashFlowReducer.js +2 -0
- package/lib/esm/view/dashboard/dashboardEpic.js +0 -4
- package/lib/esm/view/dashboard/dashboardSelector.js +2 -3
- package/lib/esm/view/financeStatement/financeStatementEpic.js +1 -5
- package/lib/esm/view/financeStatement/financeStatementSelector.js +18 -0
- package/lib/esm/view/people/peoplePageEpic.js +0 -4
- package/lib/esm/view/profitAndLoss/profitAndLossForTimeframeEpic.js +9 -4
- package/lib/esm/view/profitAndLoss/profitAndLossReducer.js +5 -1
- package/lib/esm/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.js +23 -3
- package/lib/esm/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.js +17 -4
- package/lib/esm/view/spendManagement/reimbursement/remiDetailView/epics/fetchRemiDetailEpic.js +1 -1
- package/lib/esm/view/transactionList/filterTransactionsByTimePeriod.js +18 -0
- package/lib/esm/view/transactionList/transactionListByAccountSelector.js +2 -1
- package/lib/esm/view/transactionList/transactionListByCategoryTypeSelector.js +2 -1
- package/lib/esm/view/transactionList/transactionListByClassSelector.js +2 -1
- package/lib/esm/view/transactionList/transactionListByProjectSelector.js +2 -1
- package/lib/index.d.ts +8 -8
- package/lib/index.js +56 -46
- package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +20 -0
- package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +2 -2
- package/lib/view/aiCfoView/aiCfoViewReducer.js +66 -4
- package/lib/view/aiCfoView/aiCfoViewSelector.d.ts +8 -1
- package/lib/view/aiCfoView/aiCfoViewSelector.js +27 -0
- package/lib/view/aiCfoView/aiCfoViewState.d.ts +9 -0
- package/lib/view/aiCfoView/epics/transcribeAudioEpic.d.ts +19 -0
- package/lib/view/aiCfoView/epics/transcribeAudioEpic.js +64 -0
- package/lib/view/balanceSheet/balanceSheetForTimeframeEpic.js +8 -3
- package/lib/view/balanceSheet/balanceSheetReducer.js +2 -0
- package/lib/view/balanceSheet/balanceSheetState.d.ts +2 -0
- package/lib/view/cashFlow/cashFlowForTimeframeEpic.js +10 -4
- package/lib/view/cashFlow/cashFlowReducer.js +2 -0
- package/lib/view/cashFlow/cashFlowState.d.ts +2 -0
- package/lib/view/dashboard/dashboardEpic.js +0 -4
- package/lib/view/dashboard/dashboardSelector.d.ts +0 -2
- package/lib/view/dashboard/dashboardSelector.js +1 -2
- package/lib/view/financeStatement/financeStatementEpic.js +1 -5
- package/lib/view/financeStatement/financeStatementSelector.d.ts +8 -0
- package/lib/view/financeStatement/financeStatementSelector.js +18 -0
- package/lib/view/people/peoplePageEpic.js +0 -4
- package/lib/view/profitAndLoss/profitAndLossForTimeframeEpic.js +8 -3
- package/lib/view/profitAndLoss/profitAndLossReducer.js +5 -1
- package/lib/view/profitAndLoss/profitAndLossState.d.ts +2 -1
- package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.d.ts +7 -2
- package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.js +24 -4
- package/lib/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.d.ts +7 -4
- package/lib/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.js +15 -1
- package/lib/view/spendManagement/reimbursement/remiDetailView/epics/fetchRemiDetailEpic.js +1 -1
- package/lib/view/transactionList/filterTransactionsByTimePeriod.d.ts +15 -0
- package/lib/view/transactionList/filterTransactionsByTimePeriod.js +22 -0
- package/lib/view/transactionList/transactionListByAccountSelector.js +2 -1
- package/lib/view/transactionList/transactionListByCategoryTypeSelector.js +2 -1
- package/lib/view/transactionList/transactionListByClassSelector.js +2 -1
- package/lib/view/transactionList/transactionListByProjectSelector.js +2 -1
- package/package.json +1 -1
|
@@ -133,3 +133,28 @@ export function getSkillMutation(state) {
|
|
|
133
133
|
export function getSkillsEnabled(state) {
|
|
134
134
|
return getSkills(state).skillsEnabled;
|
|
135
135
|
}
|
|
136
|
+
/** True while a finished voice recording is being transcribed server-side. */
|
|
137
|
+
/**
|
|
138
|
+
* A take belongs to the chat it was dictated into. A new chat has no session id yet on
|
|
139
|
+
* either side, which is a match rather than a mismatch.
|
|
140
|
+
*/
|
|
141
|
+
function isTranscribingCurrentSession(state) {
|
|
142
|
+
if (state.aiCfoViewState == null) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return (state.aiCfoViewState.transcribingChatSessionId ===
|
|
146
|
+
state.aiCfoViewState.uiState.currentChatSessionId);
|
|
147
|
+
}
|
|
148
|
+
export function getIsTranscribing(state) {
|
|
149
|
+
return (state.aiCfoViewState?.transcriptionState?.fetchState === 'In-Progress' &&
|
|
150
|
+
isTranscribingCurrentSession(state));
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Set when a transcription request failed. Without surfacing this the composer
|
|
154
|
+
* would just drop the "Transcribing…" label and sit there silently, leaving the
|
|
155
|
+
* user with no sign their recording went nowhere.
|
|
156
|
+
*/
|
|
157
|
+
export function getTranscriptionFailed(state) {
|
|
158
|
+
return (state.aiCfoViewState?.transcriptionState?.fetchState === 'Error' &&
|
|
159
|
+
isTranscribingCurrentSession(state));
|
|
160
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, finalize, map, switchMap, takeUntil, timeout, } from 'rxjs/operators';
|
|
3
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../responsePayload';
|
|
4
|
+
import { clearAll } from '../../../rootActions';
|
|
5
|
+
import { transcribeAudio, transcribeAudioFailure, transcribeAudioSuccess, } from '../aiCfoViewReducer';
|
|
6
|
+
const AUDIO_FIELD = 'audio';
|
|
7
|
+
const LANGUAGE_FIELD = 'language';
|
|
8
|
+
/** Extension only has to match the recorded format; the server reads the part's MIME type. */
|
|
9
|
+
const AUDIO_FILE_NAME = 'dictation.wav';
|
|
10
|
+
/**
|
|
11
|
+
* A hung request would otherwise pin `isTranscribing` true forever, and the composer
|
|
12
|
+
* gates both submit and the mic on it — leaving the user unable to send even typed
|
|
13
|
+
* text until something else resolved it.
|
|
14
|
+
*/
|
|
15
|
+
const TRANSCRIPTION_TIMEOUT_MS = 30000;
|
|
16
|
+
/**
|
|
17
|
+
* Voice dictation for the AI CFO composer. Dispatch `transcribeAudio(blob, language)` with a
|
|
18
|
+
* finished recording to POST it to the AI CFO micro-service `/1.0/transcriptions` endpoint;
|
|
19
|
+
* on success the transcript is appended to the composer input for the user to edit and send.
|
|
20
|
+
*
|
|
21
|
+
* `switchMap` (not `mergeMap`): a newer recording supersedes an older in-flight one, so a
|
|
22
|
+
* slow response can never append a stale transcript after a fresh one has already landed.
|
|
23
|
+
* The AbortController makes that cancellation real — `fetch` wrapped in a promise ignores
|
|
24
|
+
* an RxJS unsubscribe, so without the signal the superseded request would run to completion
|
|
25
|
+
* and still bill a transcription call whose result nothing wants.
|
|
26
|
+
*/
|
|
27
|
+
export const transcribeAudioEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(transcribeAudio.match), switchMap((action) => {
|
|
28
|
+
const { audio, chatSessionId, language } = action.payload;
|
|
29
|
+
const abortController = new AbortController();
|
|
30
|
+
const formData = new FormData();
|
|
31
|
+
formData.append(AUDIO_FIELD, audio, AUDIO_FILE_NAME);
|
|
32
|
+
if (language != null && language !== '') {
|
|
33
|
+
formData.append(LANGUAGE_FIELD, language);
|
|
34
|
+
}
|
|
35
|
+
return zeniAPI
|
|
36
|
+
.postFormData(`${zeniAPI.apiEndPoints.aiCfoMicroServiceBaseUrl}/1.0/transcriptions`, formData, abortController.signal)
|
|
37
|
+
.pipe(timeout(TRANSCRIPTION_TIMEOUT_MS),
|
|
38
|
+
// A tenant switch clears the store; a transcript still in flight must not
|
|
39
|
+
// land in the next tenant's composer (both sessions can be `undefined`, so
|
|
40
|
+
// the reducer's session guard would let it through).
|
|
41
|
+
takeUntil(actions$.pipe(filter(clearAll.match))), map((response) => {
|
|
42
|
+
if (!isSuccessResponse(response)) {
|
|
43
|
+
return transcribeAudioFailure(response.status);
|
|
44
|
+
}
|
|
45
|
+
// An EMPTY transcript is a success (the mic caught silence) and the
|
|
46
|
+
// reducer leaves the composer alone. A MISSING one breaks the response
|
|
47
|
+
// contract, so it surfaces as an error rather than being coerced to
|
|
48
|
+
// silence the user cannot distinguish from a quiet room.
|
|
49
|
+
if (response.data?.transcript == null) {
|
|
50
|
+
return transcribeAudioFailure(createZeniAPIStatus('Transcription succeeded but the response carried no transcript', 'Unexpected Error'));
|
|
51
|
+
}
|
|
52
|
+
// The session id rides along so a transcript that lands after the user
|
|
53
|
+
// switched sessions is dropped rather than misfiled.
|
|
54
|
+
return transcribeAudioSuccess(response.data.transcript, chatSessionId);
|
|
55
|
+
}), finalize(() => abortController.abort()), catchError((error) => of(transcribeAudioFailure(createZeniAPIStatus(
|
|
56
|
+
// message (detailed) first, then the short title — per createZeniAPIStatus(message, title).
|
|
57
|
+
// JSON.stringify(Error) drops the (non-enumerable) message — extract it explicitly.
|
|
58
|
+
'Transcription REST API call errored out: ' +
|
|
59
|
+
(error instanceof Error ? error.message : String(error)), 'Unexpected Error')))));
|
|
60
|
+
}));
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
2
|
+
import { catchError, filter, groupBy, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { updateCalculatedSectionAccountsView, updateSectionAccountsView, } from '../../entity/sectionAccountsView/sectionAccountsViewReducer';
|
|
4
4
|
import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
|
|
5
5
|
import { ALL_ASSETS_SECTIONS, ALL_CURRENT_ASSETS_SECTIONS, ALL_CURRENT_LIABILITIES_SECTIONS, ALL_LIABILITIES_SECTIONS, toSectionId, } from './balanceSheetPayload';
|
|
6
6
|
import { fetchBalanceSheetForTimeframe, updateBalanceSheetForTimeframe, updateBalanceSheetForTimeframeFailure, } from './balanceSheetReducer';
|
|
7
7
|
export const reportIdUniqueKey = () => 'balance_sheet';
|
|
8
|
-
export const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchBalanceSheetForTimeframe.match),
|
|
8
|
+
export const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchBalanceSheetForTimeframe.match),
|
|
9
|
+
// One stream per timeframe: a newer request for the same timeframe (e.g. a
|
|
10
|
+
// custom-date-range change, or a dated fetch right after a default one)
|
|
11
|
+
// cancels the older in-flight request so a stale response can't land last.
|
|
12
|
+
groupBy((action) => action.payload.timeframe), mergeMap((group$) => group$.pipe(switchMap((action) => {
|
|
9
13
|
const getTimeSeriesGroup = (timeframe) => {
|
|
10
14
|
switch (timeframe) {
|
|
11
15
|
case 'month':
|
|
@@ -20,7 +24,8 @@ export const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actio
|
|
|
20
24
|
is_full_response: action.payload.fetchFullReport,
|
|
21
25
|
time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
|
|
22
26
|
};
|
|
23
|
-
if (action.payload.startDate != null &&
|
|
27
|
+
if (action.payload.startDate != null &&
|
|
28
|
+
action.payload.endDate != null) {
|
|
24
29
|
queryValue.custom_start_date = action.payload.startDate;
|
|
25
30
|
queryValue.custom_end_date = action.payload.endDate;
|
|
26
31
|
}
|
|
@@ -73,4 +78,4 @@ export const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actio
|
|
|
73
78
|
}
|
|
74
79
|
}), catchError((error) => of(updateBalanceSheetForTimeframeFailure(createZeniAPIStatus('Unexpected Error', 'Balance Sheet REST API call errored out' +
|
|
75
80
|
JSON.stringify(error)), action.payload.timeframe))));
|
|
76
|
-
}));
|
|
81
|
+
}))));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { mapReportPayloadV2ToReportV2 } from '../../commonPayloadTypes/v2/viewAndReportPayloadv2';
|
|
3
|
+
import { withFetchedCustomDateRange } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
3
4
|
import { clearAll } from '../../rootActions';
|
|
4
5
|
export const initialState = {
|
|
5
6
|
bookCloseDate: undefined,
|
|
@@ -62,6 +63,7 @@ const balanceSheet = createSlice({
|
|
|
62
63
|
fetchState: 'In-Progress',
|
|
63
64
|
error: undefined,
|
|
64
65
|
};
|
|
66
|
+
draft.customDateRangeByTimeframe = withFetchedCustomDateRange(draft.customDateRangeByTimeframe, timeframe, action.payload.startDate, action.payload.endDate);
|
|
65
67
|
},
|
|
66
68
|
},
|
|
67
69
|
updateBalanceSheetForTimeframe(draft, action) {
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
2
|
+
import { catchError, filter, groupBy, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { updateCalculatedSectionAccountsView, updateSectionAccountsView, } from '../../entity/sectionAccountsView/sectionAccountsViewReducer';
|
|
4
4
|
import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
|
|
5
5
|
import { toCashFlowReportViewID, } from './cashFlowPayload';
|
|
6
6
|
import { fetchCashFlowForTimeframe, updateCashFlowForTimeframe, updateCashFlowForTimeframeFailure, } from './cashFlowReducer';
|
|
7
7
|
export const reportIdUniqueKey = () => 'cash_flow';
|
|
8
|
-
export const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchCashFlowForTimeframe.match),
|
|
8
|
+
export const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchCashFlowForTimeframe.match),
|
|
9
|
+
// One stream per timeframe: a newer request for the same timeframe (e.g. a
|
|
10
|
+
// custom-date-range change, or a dated fetch right after a default one)
|
|
11
|
+
// cancels the older in-flight request so a stale response can't land last.
|
|
12
|
+
groupBy((action) => action.payload.timeframe), mergeMap((group$) => group$.pipe(switchMap((action) => {
|
|
9
13
|
const getTimeSeriesGroup = (timeframe) => {
|
|
10
14
|
switch (timeframe) {
|
|
11
15
|
case 'month':
|
|
@@ -20,7 +24,8 @@ export const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.
|
|
|
20
24
|
is_full_response: action.payload.fetchFullReport,
|
|
21
25
|
time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
|
|
22
26
|
};
|
|
23
|
-
if (action.payload.startDate != null &&
|
|
27
|
+
if (action.payload.startDate != null &&
|
|
28
|
+
action.payload.endDate != null) {
|
|
24
29
|
queryValue.custom_start_date = action.payload.startDate;
|
|
25
30
|
queryValue.custom_end_date = action.payload.endDate;
|
|
26
31
|
}
|
|
@@ -48,5 +53,6 @@ export const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.
|
|
|
48
53
|
else {
|
|
49
54
|
return of(updateCashFlowForTimeframeFailure(response.status, action.payload.timeframe));
|
|
50
55
|
}
|
|
51
|
-
}), catchError((error) => of(updateCashFlowForTimeframeFailure(createZeniAPIStatus('Unexpected Error', 'Cash Flow REST API call errored out' +
|
|
52
|
-
|
|
56
|
+
}), catchError((error) => of(updateCashFlowForTimeframeFailure(createZeniAPIStatus('Unexpected Error', 'Cash Flow REST API call errored out' +
|
|
57
|
+
JSON.stringify(error)), action.payload.timeframe))));
|
|
58
|
+
}))));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { mapReportPayloadV2ToReportV2 } from '../../commonPayloadTypes/v2/viewAndReportPayloadv2';
|
|
3
|
+
import { withFetchedCustomDateRange } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
3
4
|
import { clearAll } from '../../rootActions';
|
|
4
5
|
export const initialState = {
|
|
5
6
|
fetchState: {
|
|
@@ -54,6 +55,7 @@ const cashFlow = createSlice({
|
|
|
54
55
|
fetchState: 'In-Progress',
|
|
55
56
|
error: undefined,
|
|
56
57
|
};
|
|
58
|
+
draft.customDateRangeByTimeframe = withFetchedCustomDateRange(draft.customDateRangeByTimeframe, timeframe, action.payload.startDate, action.payload.endDate);
|
|
57
59
|
},
|
|
58
60
|
},
|
|
59
61
|
updateCashFlowForTimeframe(draft, action) {
|
|
@@ -88,10 +88,6 @@ export const fetchDashboardEpic = (actions$, state$) => actions$.pipe(filter(fet
|
|
|
88
88
|
const revenueState = getRevenueReportFetchState(state.revenueState.uiState.selectedForecast?.id, state.revenueState);
|
|
89
89
|
const opExState = getOperatingExpensesReportFetchState(state.opExState.uiState.selectedForecast?.id, state.opExState);
|
|
90
90
|
const netBurnOrIncomeReportFetchState = getNetBurnOrIncomeReportFetchState(state.netBurnOrIncomeState.uiState.selectedForecast?.id, state.netBurnOrIncomeState);
|
|
91
|
-
if (state.tenantState.fetchState !== 'In-Progress' &&
|
|
92
|
-
!state.tenantState.hasValidState()) {
|
|
93
|
-
fetchActions.push(fetchAllTenants(userId));
|
|
94
|
-
}
|
|
95
91
|
if (state.cardBalanceState.fetchState !== 'In-Progress' &&
|
|
96
92
|
!state.cardBalanceState.hasValidState()) {
|
|
97
93
|
fetchActions.push(fetchCardBalance());
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createSelector } from '@reduxjs/toolkit';
|
|
2
2
|
import { newBalancesFilter } from '../../commonStateTypes/coaBalance/coaBalancesFilter';
|
|
3
3
|
import { reduceFetchState } from '../../commonStateTypes/reduceFetchState';
|
|
4
|
-
import { getCurrentTenant
|
|
4
|
+
import { getCurrentTenant } from '../../entity/tenant/tenantSelector';
|
|
5
5
|
import { hasAdminLevelAccess, hasInvestorBankerLevelAccess, } from '../../entity/userRole/userRoleType';
|
|
6
6
|
import { getApAgingReport } from '../apAgingView/apAgingReport/apAgingSelector';
|
|
7
7
|
import { getArAgingReport } from '../arAgingView/arAgingReport/arAgingSelector';
|
|
@@ -34,8 +34,7 @@ const getCashInCashOutLast4Periods = (state) => getCashInCashOut(state.accountSt
|
|
|
34
34
|
const getNetBurnOrIncomeStoryCard = (state) => getNetBurnOrIncomeStoryCardReport(state);
|
|
35
35
|
const apAgingSelector = (state) => getApAgingReport(state);
|
|
36
36
|
const arAgingSelector = (state) => getArAgingReport(state);
|
|
37
|
-
const tenantSelector = createSelector(
|
|
38
|
-
tenantsOrdered,
|
|
37
|
+
const tenantSelector = createSelector(getCurrentTenant, (currentTenant) => ({
|
|
39
38
|
currentTenant,
|
|
40
39
|
}));
|
|
41
40
|
export const getDashboard = createSelector(tenantSelector, getCardBalance, getCashBalance, getOperatingExpensesForLast5Periods, getRevenueForLast4Periods, getTop6Expenses, getNetBurnOrIncomeForLast4Periods, getNetBurnOrIncomeStoryCard, getCashPositionLast5Periods, getCashInCashOutLast4Periods, getInsights, getCompanyPassportView, getTasksCardReport, getBillPayCardReport, getReimbursementCardReport, apAgingSelector, arAgingSelector, getRewardsPlanCard, getDashboardCardsOrdered, (state) => {
|
|
@@ -15,12 +15,8 @@ export const fetchFinanceStatementEpic = (actions$, state$) => actions$.pipe(fil
|
|
|
15
15
|
return of(fetchAllTenants(userId), fetchProfitAndLoss(), fetchBalanceSheet(), fetchCashFlow());
|
|
16
16
|
}
|
|
17
17
|
else {
|
|
18
|
-
const {
|
|
18
|
+
const { financeStatementState } = state;
|
|
19
19
|
const fetchActions = [];
|
|
20
|
-
if (tenantState.fetchState !== 'In-Progress' &&
|
|
21
|
-
!tenantState.hasValidState()) {
|
|
22
|
-
fetchActions.push(fetchAllTenants(userId));
|
|
23
|
-
}
|
|
24
20
|
const pandLFetchState = getPandLReportFetchState(undefined, state.profitAndLossState);
|
|
25
21
|
const balanceSheetFetchState = getBalanceSheetFetchState(state.balanceSheetState);
|
|
26
22
|
const cashFlowFetchState = getCashFlowReportFetchState(state.cashFlowState);
|
|
@@ -161,6 +161,23 @@ export const getFinanceStatement = createSelector((state) => state.accountState,
|
|
|
161
161
|
default:
|
|
162
162
|
break;
|
|
163
163
|
}
|
|
164
|
+
let customDateRangeByTimeframe;
|
|
165
|
+
switch (financeStatementState.selectedReportId) {
|
|
166
|
+
case 'profit_and_loss':
|
|
167
|
+
customDateRangeByTimeframe =
|
|
168
|
+
profitAndLossState.pandL.customDateRangeByTimeframe;
|
|
169
|
+
break;
|
|
170
|
+
case 'balance_sheet':
|
|
171
|
+
customDateRangeByTimeframe =
|
|
172
|
+
balanceSheetState.customDateRangeByTimeframe;
|
|
173
|
+
break;
|
|
174
|
+
case 'cash_flow':
|
|
175
|
+
customDateRangeByTimeframe = cashFlowState.customDateRangeByTimeframe;
|
|
176
|
+
break;
|
|
177
|
+
default:
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
const selectedReportCustomDateRange = customDateRangeByTimeframe?.[financeStatementState.timeframe];
|
|
164
181
|
return {
|
|
165
182
|
reportId: 'finance_statement',
|
|
166
183
|
reportTitle: '',
|
|
@@ -170,6 +187,7 @@ export const getFinanceStatement = createSelector((state) => state.accountState,
|
|
|
170
187
|
allTimeframeTicks,
|
|
171
188
|
balancesInTimeframe,
|
|
172
189
|
selectedReportAndTimeframeFetchState,
|
|
190
|
+
selectedReportCustomDateRange,
|
|
173
191
|
displayOrder: financeStatementState.displayOrder,
|
|
174
192
|
reportFormat: financeStatementState.reportFormat,
|
|
175
193
|
firstMonthOfFY,
|
|
@@ -10,10 +10,6 @@ export const fetchPeoplePageEpic = (actions$, state$) => actions$.pipe(filter(fe
|
|
|
10
10
|
else {
|
|
11
11
|
const state = state$.value;
|
|
12
12
|
const fetchActions = [];
|
|
13
|
-
if (state.tenantState.fetchState !== 'In-Progress' &&
|
|
14
|
-
!state.tenantState.hasValidState()) {
|
|
15
|
-
fetchActions.push(fetchAllTenants(userId));
|
|
16
|
-
}
|
|
17
13
|
if (state.peopleState.fetchState != 'In-Progress' &&
|
|
18
14
|
!state.peopleState.hasValidState()) {
|
|
19
15
|
fetchActions.push(fetchPeople());
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
2
|
+
import { catchError, filter, groupBy, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { updateCalculatedSectionAccountsView, updateSectionAccountsView, } from '../../entity/sectionAccountsView/sectionAccountsViewReducer';
|
|
4
4
|
import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
|
|
5
5
|
import { fetchProfitAndLossForTimeframe, updateProfitAndLossForTimeframe, updateProfitAndLossForTimeframeFailure, } from './profitAndLossReducer';
|
|
6
6
|
export const reportIdUniqueKey = (forecastId) => forecastId != null
|
|
7
7
|
? `profit_and_loss+${forecastId}`
|
|
8
8
|
: 'profit_and_loss';
|
|
9
|
-
export const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchProfitAndLossForTimeframe.match),
|
|
9
|
+
export const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchProfitAndLossForTimeframe.match),
|
|
10
|
+
// One stream per timeframe: a newer request for the same timeframe (e.g. a
|
|
11
|
+
// custom-date-range change, or a dated fetch right after a default one)
|
|
12
|
+
// cancels the older in-flight request so a stale response can't land last.
|
|
13
|
+
groupBy((action) => `${action.payload.forecastId ?? ''}_${action.payload.timeframe}`), mergeMap((group$) => group$.pipe(switchMap((action) => {
|
|
10
14
|
const getTimeSeriesGroup = (timeframe) => {
|
|
11
15
|
switch (timeframe) {
|
|
12
16
|
case 'month':
|
|
@@ -25,7 +29,8 @@ export const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => acti
|
|
|
25
29
|
queryValue.forecast_id = action.payload.forecastId;
|
|
26
30
|
queryValue.is_forecast_vs_actual = true;
|
|
27
31
|
}
|
|
28
|
-
if (action.payload.startDate != null &&
|
|
32
|
+
if (action.payload.startDate != null &&
|
|
33
|
+
action.payload.endDate != null) {
|
|
29
34
|
queryValue.custom_start_date = action.payload.startDate;
|
|
30
35
|
queryValue.custom_end_date = action.payload.endDate;
|
|
31
36
|
}
|
|
@@ -55,4 +60,4 @@ export const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => acti
|
|
|
55
60
|
return of(updateProfitAndLossForTimeframeFailure(response.status, action.payload.forecastId, action.payload.timeframe));
|
|
56
61
|
}
|
|
57
62
|
}), catchError((error) => of(updateProfitAndLossForTimeframeFailure(createZeniAPIStatus('Unexpected Error', 'P&L REST API call errored out' + JSON.stringify(error)), action.payload.forecastId, action.payload.timeframe))));
|
|
58
|
-
}));
|
|
63
|
+
}))));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { mapReportPayloadV2ToReportV2 } from '../../commonPayloadTypes/v2/viewAndReportPayloadv2';
|
|
3
|
+
import { withFetchedCustomDateRange } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
3
4
|
import { clearAll } from '../../rootActions';
|
|
4
5
|
export const initialPandLState = {
|
|
5
6
|
bookCloseDate: undefined,
|
|
@@ -71,7 +72,10 @@ const profitAndLoss = createSlice({
|
|
|
71
72
|
fetchState: 'In-Progress',
|
|
72
73
|
error: undefined,
|
|
73
74
|
};
|
|
74
|
-
updateState(draft, action.payload.forecastId, {
|
|
75
|
+
updateState(draft, action.payload.forecastId, {
|
|
76
|
+
fetchState,
|
|
77
|
+
customDateRangeByTimeframe: withFetchedCustomDateRange(pAndLState.customDateRangeByTimeframe, timeframe, action.payload.startDate, action.payload.endDate),
|
|
78
|
+
});
|
|
75
79
|
},
|
|
76
80
|
},
|
|
77
81
|
updateProfitAndLossForTimeframe(draft, action) {
|
|
@@ -30,8 +30,13 @@ const editRemiView = createSlice({
|
|
|
30
30
|
};
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
|
-
indicateReadyToInitializeRemiLocalStore
|
|
34
|
-
|
|
33
|
+
indicateReadyToInitializeRemiLocalStore: {
|
|
34
|
+
reducer() {
|
|
35
|
+
// do nothing
|
|
36
|
+
},
|
|
37
|
+
prepare(reimbursementId) {
|
|
38
|
+
return { payload: { reimbursementId } };
|
|
39
|
+
},
|
|
35
40
|
},
|
|
36
41
|
fetchRecommendationsAndUpdateMerchantRecommendations: {
|
|
37
42
|
reducer() {
|
|
@@ -137,6 +142,21 @@ const editRemiView = createSlice({
|
|
|
137
142
|
return { payload: { reimbursementId } };
|
|
138
143
|
},
|
|
139
144
|
},
|
|
145
|
+
initializeRemiToLocalStoreFailure: {
|
|
146
|
+
reducer(draft, action) {
|
|
147
|
+
const { reimbursementId, error } = action.payload;
|
|
148
|
+
draft.editRemiStateById[reimbursementId] = {
|
|
149
|
+
...draft.editRemiStateById[reimbursementId],
|
|
150
|
+
fetchStatus: {
|
|
151
|
+
fetchState: 'Error',
|
|
152
|
+
error,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
prepare(reimbursementId, error) {
|
|
157
|
+
return { payload: { reimbursementId, error } };
|
|
158
|
+
},
|
|
159
|
+
},
|
|
140
160
|
saveRemiUpdatesToLocalStore(draft, action) {
|
|
141
161
|
if (action.payload.reimbursementId != null) {
|
|
142
162
|
const reimbursementId = action.payload.reimbursementId;
|
|
@@ -387,7 +407,7 @@ const editRemiView = createSlice({
|
|
|
387
407
|
});
|
|
388
408
|
},
|
|
389
409
|
});
|
|
390
|
-
export const { fetchEditRemiDetailPage, fetchRemiAndInitializeLocalStore, initializeRemiToLocalStore, fetchRecommendationsAndUpdateMerchantRecommendations, saveRemiUpdatesToLocalStore, updatesPaymentToInLocalStore, discardRemiUpdatesInLocalStore, removeFileFromRemiUpdatesInLocalStore, saveRemiDetail, saveRemiSuccessOrFailure, parseReceiptsToRemi, fetchCurrencyConversionValue, updateReimbursementType, updateHomeCurrencyConversion, currencyConversionValueSuccessOrFailure, waitForRemiDetailThenInitializeLocalStore, waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant, updateAddRemiAutoFields, indicateReadyToInitializeRemiLocalStore, updateUploadFetchState, updateRecommendationInMerchant, updateTentativeMerchantNames, clearTentativeMerchantName, clearAddRemiAutoFields, } = editRemiView.actions;
|
|
410
|
+
export const { fetchEditRemiDetailPage, fetchRemiAndInitializeLocalStore, initializeRemiToLocalStore, fetchRecommendationsAndUpdateMerchantRecommendations, saveRemiUpdatesToLocalStore, updatesPaymentToInLocalStore, discardRemiUpdatesInLocalStore, removeFileFromRemiUpdatesInLocalStore, saveRemiDetail, saveRemiSuccessOrFailure, parseReceiptsToRemi, fetchCurrencyConversionValue, updateReimbursementType, updateHomeCurrencyConversion, currencyConversionValueSuccessOrFailure, waitForRemiDetailThenInitializeLocalStore, initializeRemiToLocalStoreFailure, waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant, updateAddRemiAutoFields, indicateReadyToInitializeRemiLocalStore, updateUploadFetchState, updateRecommendationInMerchant, updateTentativeMerchantNames, clearTentativeMerchantName, clearAddRemiAutoFields, } = editRemiView.actions;
|
|
391
411
|
export default editRemiView.reducer;
|
|
392
412
|
const doUpdateRecommendationForEntity = (draft, lineId, recommendations, shouldAutofill, reimbursementId, reimbursementStageCode) => {
|
|
393
413
|
if (reimbursementId != null) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import recordGet from 'lodash/get';
|
|
2
|
-
import { from } from 'rxjs';
|
|
3
|
-
import { filter, mergeMap } from 'rxjs/operators';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { from, merge } from 'rxjs';
|
|
3
|
+
import { filter, map, mergeMap, take, takeUntil, takeWhile, } from 'rxjs/operators';
|
|
4
|
+
import { clearAll } from '../../../../../rootActions';
|
|
5
|
+
import { fetchRemiDetail, updateRemiDetailFetchState, } from '../../remiDetailView/remiDetailViewReducer';
|
|
6
|
+
import { fetchRemiAndInitializeLocalStore, indicateReadyToInitializeRemiLocalStore, initializeRemiToLocalStore, initializeRemiToLocalStoreFailure, waitForRemiDetailThenInitializeLocalStore, } from '../editRemiViewReducer';
|
|
6
7
|
export const fetchRemiAndInitializeLocalStoreEpic = (actions$, state$) => actions$.pipe(filter(fetchRemiAndInitializeLocalStore.match), mergeMap((action) => {
|
|
7
8
|
const { reimbursementId, cacheOverride, isShowDeletedReimbursementEnabled, } = action.payload;
|
|
8
9
|
const state = state$.value;
|
|
@@ -35,3 +36,15 @@ export const fetchRemiAndInitializeLocalStoreEpic = (actions$, state$) => action
|
|
|
35
36
|
}
|
|
36
37
|
return from(remiDetailActions);
|
|
37
38
|
}));
|
|
39
|
+
export const waitForRemiDetailThenInitializeLocalStoreEpic = (actions$) => actions$.pipe(filter(waitForRemiDetailThenInitializeLocalStore.match), mergeMap((action) => {
|
|
40
|
+
const { reimbursementId } = action.payload;
|
|
41
|
+
const ready$ = actions$.pipe(filter(indicateReadyToInitializeRemiLocalStore.match), filter((readyAction) => readyAction.payload.reimbursementId === reimbursementId), take(1), map(() => initializeRemiToLocalStore(reimbursementId)));
|
|
42
|
+
const failed$ = actions$.pipe(filter(updateRemiDetailFetchState.match), filter((fetchStateAction) => fetchStateAction.payload.reimbursementId === reimbursementId &&
|
|
43
|
+
fetchStateAction.payload.fetchState === 'Error'), map((fetchStateAction) => initializeRemiToLocalStoreFailure(reimbursementId, fetchStateAction.payload.error)));
|
|
44
|
+
const supersededOrCleared$ = actions$.pipe(filter((nextAction) => clearAll.match(nextAction) ||
|
|
45
|
+
(waitForRemiDetailThenInitializeLocalStore.match(nextAction) &&
|
|
46
|
+
nextAction.payload.reimbursementId === reimbursementId)));
|
|
47
|
+
// An Error does not end the wait: a newer request for the same id may still succeed.
|
|
48
|
+
// After an Error, supersededOrCleared$ is what ends it.
|
|
49
|
+
return merge(ready$, failed$).pipe(takeWhile((resultAction) => !initializeRemiToLocalStore.match(resultAction), true), takeUntil(supersededOrCleared$));
|
|
50
|
+
}));
|
package/lib/esm/view/spendManagement/reimbursement/remiDetailView/epics/fetchRemiDetailEpic.js
CHANGED
|
@@ -75,7 +75,7 @@ export const fetchRemiDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(
|
|
|
75
75
|
}));
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
|
-
actions.push(indicateReadyToInitializeRemiLocalStore());
|
|
78
|
+
actions.push(indicateReadyToInitializeRemiLocalStore(reimbursementId));
|
|
79
79
|
if (response.data.transaction?.lines != null &&
|
|
80
80
|
response.data.transaction.lines.length > 0) {
|
|
81
81
|
actions.push(fetchDuplicateReimbursement(response.data.transaction.created_by_user_id, false, response.data.transaction.transaction_id));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DEFAULT_DATE_FORMAT, toString, } from '../../commonStateTypes/timePeriod';
|
|
2
|
+
/**
|
|
3
|
+
* Transaction lists are fetched and cached in month buckets: `splitPeriod`
|
|
4
|
+
* snaps the first bucket back to the 1st of the month, while the last bucket
|
|
5
|
+
* is fetched with the real end date. So a period that starts mid-month (e.g. a
|
|
6
|
+
* drill-down from the custom-date-range column "Jun 17-30 2026") pulls in the
|
|
7
|
+
* days before its start. Drop those so the list reconciles to the clicked
|
|
8
|
+
* figure. Periods starting on the 1st (every pre-existing caller) are returned
|
|
9
|
+
* untouched. Compares calendar days as `YYYY-MM-DD` strings so the viewer's
|
|
10
|
+
* timezone can't shift the boundary.
|
|
11
|
+
*/
|
|
12
|
+
export const filterTransactionsByTimePeriod = (transactions, period) => {
|
|
13
|
+
if (period.start.day === 1) {
|
|
14
|
+
return transactions;
|
|
15
|
+
}
|
|
16
|
+
const start = toString(period.start);
|
|
17
|
+
return transactions.filter((transaction) => transaction.date.format(DEFAULT_DATE_FORMAT) >= start);
|
|
18
|
+
};
|
|
@@ -2,6 +2,7 @@ import flatMap from 'lodash/flatMap';
|
|
|
2
2
|
import recordGet from 'lodash/get';
|
|
3
3
|
import orderBy from 'lodash/orderBy';
|
|
4
4
|
import { getSupportedTransactionById } from '../../entity/transaction/transactionSelector';
|
|
5
|
+
import { filterTransactionsByTimePeriod } from './filterTransactionsByTimePeriod';
|
|
5
6
|
import { splitPeriod } from './parallelFetchAccountTransactionListEpic';
|
|
6
7
|
import { isAnyFetchCompleted, reduceFetchState, } from './reduceTransactionListFetchState';
|
|
7
8
|
import { getAcKey, getAcTranKey, } from './transactionListState';
|
|
@@ -29,7 +30,7 @@ export const getTransactionListByAccount = (transactionState, transactionListSta
|
|
|
29
30
|
}
|
|
30
31
|
return value != null;
|
|
31
32
|
});
|
|
32
|
-
transactions = orderBy(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
33
|
+
transactions = orderBy(filterTransactionsByTimePeriod(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
33
34
|
}
|
|
34
35
|
const key = getAcKey(accountId, accountType);
|
|
35
36
|
const uiState = recordGet(transactionListState.byAccount.transactionListUIStateByAccountKey, key, {});
|
|
@@ -2,6 +2,7 @@ import flatMap from 'lodash/flatMap';
|
|
|
2
2
|
import recordGet from 'lodash/get';
|
|
3
3
|
import orderBy from 'lodash/orderBy';
|
|
4
4
|
import { getSupportedTransactionById } from '../../entity/transaction/transactionSelector';
|
|
5
|
+
import { filterTransactionsByTimePeriod } from './filterTransactionsByTimePeriod';
|
|
5
6
|
import { splitPeriod } from './parallelFetchAccountTransactionListEpic';
|
|
6
7
|
import { isAnyFetchCompleted, reduceFetchState, } from './reduceTransactionListFetchState';
|
|
7
8
|
import { getCategoryTypeTranKey, } from './transactionListState';
|
|
@@ -26,7 +27,7 @@ export const getTransactionsListByCategoryType = (transactionState, transactionL
|
|
|
26
27
|
}
|
|
27
28
|
return value != null;
|
|
28
29
|
});
|
|
29
|
-
transactions = orderBy(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
30
|
+
transactions = orderBy(filterTransactionsByTimePeriod(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
30
31
|
}
|
|
31
32
|
const uiState = transactionListState.byType[transactionCategoryType].transactionListUIState;
|
|
32
33
|
return {
|
|
@@ -2,6 +2,7 @@ import flatMap from 'lodash/flatMap';
|
|
|
2
2
|
import recordGet from 'lodash/get';
|
|
3
3
|
import orderBy from 'lodash/orderBy';
|
|
4
4
|
import { getSupportedTransactionById } from '../../entity/transaction/transactionSelector';
|
|
5
|
+
import { filterTransactionsByTimePeriod } from './filterTransactionsByTimePeriod';
|
|
5
6
|
import { splitPeriod } from './parallelFetchAccountTransactionListEpic';
|
|
6
7
|
import { isAnyFetchCompleted, reduceFetchState, } from './reduceTransactionListFetchState';
|
|
7
8
|
import { getClassAcKey, getClassAcTranKey, } from './transactionListState';
|
|
@@ -29,7 +30,7 @@ export const getTransactionListByClass = (transactionState, transactionListState
|
|
|
29
30
|
}
|
|
30
31
|
return value != null;
|
|
31
32
|
});
|
|
32
|
-
transactions = orderBy(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
33
|
+
transactions = orderBy(filterTransactionsByTimePeriod(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
33
34
|
}
|
|
34
35
|
const key = getClassAcKey(accountId, accountType, classId);
|
|
35
36
|
const uiState = recordGet(transactionListState.byClass.transactionListUIStateByClassKey, key, {});
|
|
@@ -2,6 +2,7 @@ import flatMap from 'lodash/flatMap';
|
|
|
2
2
|
import recordGet from 'lodash/get';
|
|
3
3
|
import orderBy from 'lodash/orderBy';
|
|
4
4
|
import { getSupportedTransactionById } from '../../entity/transaction/transactionSelector';
|
|
5
|
+
import { filterTransactionsByTimePeriod } from './filterTransactionsByTimePeriod';
|
|
5
6
|
import { splitPeriod } from './parallelFetchAccountTransactionListEpic';
|
|
6
7
|
import { isAnyFetchCompleted, reduceFetchState, } from './reduceTransactionListFetchState';
|
|
7
8
|
import { getProjectAcKey, getProjectAcTranKey, } from './transactionListState';
|
|
@@ -29,7 +30,7 @@ export const getTransactionListByProject = (transactionState, transactionListSta
|
|
|
29
30
|
}
|
|
30
31
|
return value != null;
|
|
31
32
|
});
|
|
32
|
-
transactions = orderBy(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
33
|
+
transactions = orderBy(filterTransactionsByTimePeriod(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
33
34
|
}
|
|
34
35
|
const key = getProjectAcKey(accountId, accountType, projectId);
|
|
35
36
|
const uiState = recordGet(transactionListState.byProject.transactionListUIStateByProjectKey, key, {});
|
package/lib/index.d.ts
CHANGED
|
@@ -146,8 +146,8 @@ import { ALL_WEEK_DAYS, DayOfWeek, PriorityCodeType, Task, TaskCodeType, TaskPri
|
|
|
146
146
|
import { getTaskGroupById } from './entity/taskGroup/taskGroupSelector';
|
|
147
147
|
import { TaskGroupState } from './entity/taskGroup/taskGroupState';
|
|
148
148
|
import { TaskGroupTemplate } from './entity/taskGroupTemplate/taskGroupTemplateState';
|
|
149
|
-
import { DoSignInPayload, deleteConnection, doMagicLinkSignIn, doSignIn, doSignOut, fetchActiveTenant, fetchAllTenants, fetchExcludedResources as fetchExcludedResourcesForTenant, fetchExternalConnections as fetchExternalConnectionsForTenant, fetchSubscriptionSummaryForTenant, initEmailConnectOAuth, resendVerifyDeviceOTP, resetSignInState, saveAPIKeyConnection, saveConnectorCredentials, saveExternalConnection as saveExternalConnectionForTenant, saveOAuthConnection, sendEmailMagicLinkToUser, sendSessionHeartbeat, toExternalIntegrationType, updateCurrentTenant, updateSignInState, verifyDeviceWithTwoFA } from './entity/tenant/tenantReducer';
|
|
150
|
-
import { CurrentTenant, DEFAULT_RECEIPTS_EMAIL, TenantBaseView, TenantCoreDetailsView, TenantView, TenantsBaseOrdered,
|
|
149
|
+
import { DoSignInPayload, deleteConnection, doMagicLinkSignIn, doSignIn, doSignOut, fetchActiveTenant, fetchAllTenants, fetchExcludedResources as fetchExcludedResourcesForTenant, fetchExternalConnections as fetchExternalConnectionsForTenant, fetchSubscriptionSummaryForTenant, initEmailConnectOAuth, resendVerifyDeviceOTP, resetSignInState, saveAPIKeyConnection, saveConnectorCredentials, saveExternalConnection as saveExternalConnectionForTenant, saveOAuthConnection, seedTenantSummary, sendEmailMagicLinkToUser, sendSessionHeartbeat, toExternalIntegrationType, updateCurrentTenant, updateSignInState, verifyDeviceWithTwoFA } from './entity/tenant/tenantReducer';
|
|
150
|
+
import { CurrentTenant, CurrentTenantIds, DEFAULT_RECEIPTS_EMAIL, TenantBaseView, TenantCoreDetailsView, TenantView, TenantsBaseOrdered, getCurrentTenant, getCurrentTenantId, getCurrentTenantIds, getIsAccountingClassesEnabled, getIsAccountingProjectsEnabled, getIsAutoReviewIncomeWithoutCustomerEnabled, getReceiptsEmail, getTenantBaseById, getTenantBaseViewForTenantId, getTenantBaseViewForTenantView, getTenantsBaseByCheckInDateSelector, getTenantsCoreDetailsByCheckInDateSelector, isCurrentTenantLoaded, isOtherProductsEnabledForTenant, isTenantBankingOnly, isTenantBookkeepingEnabled, isTenantCardsOnly, isTenantLoaded, isTenantUsingZeniCOA, isZeniDomainTenant, toTenantCoreDetailsView } from './entity/tenant/tenantSelector';
|
|
151
151
|
import { CapitalizableAccount, CapitalizableAccounts, CapitalizableClassificationType, CapitalizableMatchPattern, Connection, LoggedInUser, RoleResource, Tenant, TenantProductSettings } from './entity/tenant/tenantState';
|
|
152
152
|
import { toExternalSupportedTool } from './entity/tenant/tenantTypes';
|
|
153
153
|
import { ToastNotificationPayload } from './entity/toastNotification/toastNotificationPayload';
|
|
@@ -512,7 +512,7 @@ import { InternationalWireSelectorView, getInternationalWireView } from './view/
|
|
|
512
512
|
import { fetchInternationalVerificationForm, submitInternationalVerificationForm, updateVerificationFormLocalData } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationReducer';
|
|
513
513
|
import { InternationalWireVerificationView, getIntlWireVerificationView } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSelector';
|
|
514
514
|
import { FieldValueType, InternationalWireVerificationState, VerificationFormField, VerificationFormLocalData } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationState';
|
|
515
|
-
import { fetchBillAttachment, fetchMagicLinkBankNameByRouting, fetchMagicLinkBankNameBySwift, fetchMagicLinkTenant, saveBankAccount, saveMagicLinkAddressInLocalStore, updateMagicLinkBankAccountLocalStoreData, updateMagicLinkInternationalBankAccountLocalStoreData } from './view/spendManagement/billPay/magicLinkView/magicLinkViewReducer';
|
|
515
|
+
import { fetchBillAttachment, fetchMagicLinkBankNameByRouting, fetchMagicLinkBankNameBySwift, fetchMagicLinkTenant, saveBankAccount, saveMagicLinkAddressInLocalStore, updateMagicLinkBankAccountLocalStoreData, updateMagicLinkInternationalBankAccountLocalStoreData, updateMagicLinkTenantFailure, updateMagicLinkTenantSuccess } from './view/spendManagement/billPay/magicLinkView/magicLinkViewReducer';
|
|
516
516
|
import { MagicLinkView, getMagicLinkBankAccountView, getMagicLinkCurrentAddressState, getMagicLinkView } from './view/spendManagement/billPay/magicLinkView/magicLinkViewSelector';
|
|
517
517
|
import { PreviousBillsSelectorView } from './view/spendManagement/billPay/previousBills/previousBillsSelector';
|
|
518
518
|
import { fetchWiseRedirectStatus } from './view/spendManagement/billPay/wiseRedirectView/wiseRedirectReducer';
|
|
@@ -754,7 +754,7 @@ export { TimeframeTick, TimeframeTickWithMetaData, toTimeframeTick, mapTimePerio
|
|
|
754
754
|
export { VendorSpendTrendFilterTabType, toVendorSpendTrendFilterTabsTypeStrict, } from './entity/vendorExpense/vendorSpendTrendFilterTabType';
|
|
755
755
|
export { getNumberOfPeriods };
|
|
756
756
|
export { SCHEDULE_DAYS_OF_MONTH, ScheduleDaysOfMonth, toScheduleDaysOfMonth, Day, Month, toMonth, toMonthStrict, Quarter, toQuarter, toQuarterStrict, AbsoluteDay, TimePeriod, };
|
|
757
|
-
export { CapitalizableAccount, CapitalizableAccounts, CapitalizableClassificationType, CapitalizableMatchPattern, Tenant, TenantView, LoggedInUser, TenantBaseView, CurrentTenant, TenantProductSettings, getTenantBaseById, getCurrentTenant, getIsAccountingClassesEnabled, getIsAccountingProjectsEnabled, getIsAutoReviewIncomeWithoutCustomerEnabled,
|
|
757
|
+
export { CapitalizableAccount, CapitalizableAccounts, CapitalizableClassificationType, CapitalizableMatchPattern, Tenant, TenantView, LoggedInUser, TenantBaseView, CurrentTenant, CurrentTenantIds, TenantProductSettings, getTenantBaseById, getCurrentTenant, getCurrentTenantId, getCurrentTenantIds, isCurrentTenantLoaded, isTenantLoaded, getIsAccountingClassesEnabled, getIsAccountingProjectsEnabled, getIsAutoReviewIncomeWithoutCustomerEnabled, getTenantsBaseByCheckInDateSelector, getTenantsCoreDetailsByCheckInDateSelector, toTenantCoreDetailsView, getTenantBaseViewForTenantView, getTenantBaseViewForTenantId, isZeniDomainTenant, isTenantUsingZeniCOA, TenantsBaseOrdered, TenantCoreDetailsView, fetchActiveTenant, fetchAllTenants, seedTenantSummary, updateCurrentTenant, clearAll, doMagicLinkSignIn, verifyDeviceWithTwoFA, resendVerifyDeviceOTP, sendEmailMagicLinkToUser, doSignIn, updateSignInState, DoSignInPayload, doSignOut, sendSessionHeartbeat, resetSignInState, RoleResource, Connection, fetchExcludedResourcesForTenant, fetchExternalConnectionsForTenant, saveExternalConnectionForTenant, deleteConnection, saveAPIKeyConnection, saveConnectorCredentials, saveOAuthConnection, initEmailConnectOAuth, toExternalIntegrationType, toExternalSupportedTool, fetchSubscriptionSummaryForTenant, isTenantBankingOnly, isTenantCardsOnly, isTenantBookkeepingEnabled, isOtherProductsEnabledForTenant, DEFAULT_RECEIPTS_EMAIL, getReceiptsEmail, };
|
|
758
758
|
export { Account, AccountType, AccountBase, StatementCloseDay, toAccountType, AccountReport, NestedAccountReport, AccountWithBalanceReport, AccountGroup, AccountGroupReportV2, AccountGroupType, toAccountGroupType, AccountGroupReport, getAccountGroupKey, AccountGroupKey, RecommendedAccountBase, AccountFilterOption, getAllAccounts, getTransactionFilterAccountOptions, };
|
|
759
759
|
export { Class, ClassBase, RecommendedClassBase, } from './entity/class/classState';
|
|
760
760
|
export { ClassFilterOption, getAllClasses, getClassById, getClassFilterOptions, } from './entity/class/classSelector';
|
|
@@ -952,7 +952,7 @@ export { isZeniClearingAccountReport, ZENI_CLEARING_ACCOUNT, isZeniClearingAccou
|
|
|
952
952
|
export { fetchOnboardingCustomerView, fetchOnboardingCustomerSetupView, getOnboardingPlaidLinkToken, establishOnboardingPlaidConnection, updateOnboardingCustomerViewAccountDetails, updateOnboardingCustomerViewCompleteStatus, updateOnboardingCustomerViewDashboardLoaded, updateOnboardingPaymentAccountLoginStatus, updateOnboardingPaymentAccountStatus, updateOnboardingCustomerView, updateOnboardingCustomerViewLocalStoreData, updateCurrentStep, updateCurrentSubStep, updateOnboardingCustomerViewUIState, saveOnboardingCompnayOfficerPhoneInLocalStore, saveOnboardingCustomerViewDataInLocalStore, clearOnboardingCustomerViewDataInLocalStore, applyKycDocumentAutofillForOnboarding, applyKybDocumentAutofillForOnboarding, clearKycKybAutofillForOnboarding, acknowledgeOnboardingAiActivationViewed, acknowledgeOnboardingAiFinanceTeam, fetchAiAgentsActivationStatus, aiAgentsActivationCountsUpdated, aiAgentsActivationPhaseChanged, getAiAgentsActivationCounts, getAiAgentsActivationPhases, getAiAgentsActivationSubview, getOnboardingCustomerView, getProductSettingsString, OnboardingCustomerView, OnboardingStep, OnboardingSubStep, ALL_ONBOARDING_STEPS, ALL_ONBOARDING_SUB_STEPS, toOnboardingStepType, toOnboardingSubStepType, OnboardingCustomerViewUIState, OnboardingCustomerViewLocalData, OnboardingBusinessProfileUpdate, AiAgentsActivationCounts, AiAgentsActivationPhase, AiAgentsActivationPhaseStatus, AiAgentsActivationSubview, };
|
|
953
953
|
export { saveAccountMapping, saveAccountMappingLocalData, clearAccountMappingLocalData, AccountMappingLocalData, AccountMappingView, VendorAccountMappingView, getAccountMappingView, initializeAccountMappingView, ExpenseCategory1099Filing, };
|
|
954
954
|
export { MagicLinkView, getMagicLinkView, getMagicLinkBankAccountView, getMagicLinkCurrentAddressState, };
|
|
955
|
-
export { fetchMagicLinkTenant, fetchBillAttachment, saveBankAccount, updateMagicLinkBankAccountLocalStoreData, updateMagicLinkInternationalBankAccountLocalStoreData, fetchMagicLinkBankNameByRouting, fetchMagicLinkBankNameBySwift, saveMagicLinkAddressInLocalStore, };
|
|
955
|
+
export { fetchMagicLinkTenant, updateMagicLinkTenantSuccess, updateMagicLinkTenantFailure, fetchBillAttachment, saveBankAccount, updateMagicLinkBankAccountLocalStoreData, updateMagicLinkInternationalBankAccountLocalStoreData, fetchMagicLinkBankNameByRouting, fetchMagicLinkBankNameBySwift, saveMagicLinkAddressInLocalStore, };
|
|
956
956
|
export { getWiseRedirect, fetchWiseRedirectStatus };
|
|
957
957
|
export { getInternationalWireView, InternationalWireSelectorView, DynamicFormField, CreateInternationalWireDetailsLocalData, SupportedAccountType, VendorCurrency, initializeInternationalWireLocalData, updateInternationalWireLocalStoreData, initializeDynamicForm, fetchInternationalWireDynamicForm, createPaymentInstrument, createPaymentInstrumentUpdateStatus, deletePaymentInstrument, clearInternationalWire, };
|
|
958
958
|
export { fetchUserRoleConfig, getUserRoleConfig };
|
|
@@ -1002,12 +1002,12 @@ export { AiAccountantCustomerViewState, AiAccountantSortKey, AiAccountantUIState
|
|
|
1002
1002
|
export { AiAccountantFilterCategoryField } from './view/companyView/types/cockpitTypes';
|
|
1003
1003
|
export { cancelAiAccountantOnboarding, fetchAiAccountantCustomers, fetchAiAccountantJobs, setSelectedTenantIdsForJobTrigger, triggerAiAccountantJob, updateAiAccountantUIState, } from './view/aiAccountantView/aiAccountantViewReducer';
|
|
1004
1004
|
export { AiAccountantCockpitView, getAiAccountantCockpitView, } from './view/aiAccountantView/aiAccountantViewSelector';
|
|
1005
|
-
export { acceptMasterTOS, applyAiCfoSidePanelHostPageTransition, clearAiCfoSidePanelHostPageContext, clearCurrentSessionId, clearDeleteChatSessionStatus, clearLastContextMessage, clearSkillDetail, clearSkillMutation, closeRoutineRuns, closeRoutinesBrowser, closeSkillsBrowser, createSession, createSessionAndSubmit, deleteChatSession, deleteRoutine, deleteSkill, fetchChatHistory, fetchChatSessionsForUser, fetchRoutineRuns, fetchRoutines, fetchSkillDetail, fetchSkills, fetchSkillsFailure, fetchSkillsSuccess, fetchSkillVersionBody, fetchSkillVersions, fetchSuggestedQuestions, fetchSuggestedQuestionsFailure, fetchSuggestedQuestionsSuccess, openRoutinesBrowser, openSkillsBrowser, runRoutine, saveRoutine, saveSkill, setRoutineEnabled, setSession, setSkillVisibility, stopSubmit, stopSubmitQuestion, submitFeedback, submitQuestion, updateAiCfoViewScrollPosition, updateCotCollapsedState, updateCurrentInput, updateResponseState, } from './view/aiCfoView/aiCfoViewReducer';
|
|
1005
|
+
export { acceptMasterTOS, applyAiCfoSidePanelHostPageTransition, clearAiCfoSidePanelHostPageContext, clearCurrentSessionId, clearDeleteChatSessionStatus, clearLastContextMessage, clearSkillDetail, clearSkillMutation, closeRoutineRuns, closeRoutinesBrowser, closeSkillsBrowser, createSession, createSessionAndSubmit, deleteChatSession, deleteRoutine, deleteSkill, fetchChatHistory, fetchChatSessionsForUser, fetchRoutineRuns, fetchRoutines, fetchSkillDetail, fetchSkills, fetchSkillsFailure, fetchSkillsSuccess, fetchSkillVersionBody, fetchSkillVersions, fetchSuggestedQuestions, fetchSuggestedQuestionsFailure, fetchSuggestedQuestionsSuccess, openRoutinesBrowser, openSkillsBrowser, runRoutine, saveRoutine, saveSkill, setRoutineEnabled, setSession, setSkillVisibility, stopSubmit, stopSubmitQuestion, submitFeedback, submitQuestion, transcribeAudio, updateAiCfoViewScrollPosition, updateCotCollapsedState, updateCurrentInput, updateResponseState, } from './view/aiCfoView/aiCfoViewReducer';
|
|
1006
1006
|
export { AiCfoViewState, AiCfoViewUIState, Routine, RoutineDraft, RoutineMutationState, RoutineRecurrence, RoutineRun, RoutineRunsState, RoutineRunStatus, RoutinesState, RoutineStatus, Skill, SkillDetail, SkillDetailState, SkillDraft, SkillMutationState, SkillsState, SkillVersion, SkillVersionBodyState, SkillVersionsState, SkillVisibility, SuggestedQuestionsForPageContext, } from './view/aiCfoView/aiCfoViewState';
|
|
1007
1007
|
export { FetchSuggestedQuestionsResponse, SuggestedQuestionsDataPayload, FetchSkillsResponse, SkillSummaryPayload, SkillListDataPayload, } from './view/aiCfoView/aiCfoViewPayload';
|
|
1008
|
-
export type { FeedbackType, SubmitFeedbackPayload, } from './view/aiCfoView/aiCfoViewPayload';
|
|
1008
|
+
export type { FeedbackType, SubmitFeedbackPayload, TranscribeAudioPayload, TranscriptionResponseData, } from './view/aiCfoView/aiCfoViewPayload';
|
|
1009
1009
|
export type { AiCfoSuggestedQuestionsPageContext } from './common/aiCfo/aiCfoSuggestedQuestionsPageContext';
|
|
1010
|
-
export { AiCfoViewSelector, canCreateRoutine, getAiCfoView, getRoutineMutation, getRoutineRuns, getRoutines, getRoutinesEnabled, getSkillDetail, getSkillMutation, getSkills, getSkillsEnabled, getSkillVersionBody, getSkillVersions, getSuggestedQuestionsForPageContext, } from './view/aiCfoView/aiCfoViewSelector';
|
|
1010
|
+
export { AiCfoViewSelector, canCreateRoutine, getAiCfoView, getIsTranscribing, getRoutineMutation, getRoutineRuns, getRoutines, getRoutinesEnabled, getSkillDetail, getSkillMutation, getSkills, getSkillsEnabled, getSkillVersionBody, getSkillVersions, getSuggestedQuestionsForPageContext, getTranscriptionFailed, } from './view/aiCfoView/aiCfoViewSelector';
|
|
1011
1011
|
export { MessagePayload, ChatSessionPayload, AiCfoAnswerPayload, } from './entity/aiCfo/aiCfoPayload';
|
|
1012
1012
|
export { setNewSession, setSessions, updateAiCfoAnswerCardPolicyWizardPlan, upsertAnswerPayload, upsertOrAddQuestionAnswerPayload, addQuestionPayload, clearSession, toAiCfoExports, toAiCfoVisualization, appendSyntheticAiCfoAnswer, updateSyntheticAiCfoAnswer, removeSyntheticAiCfoAnswer, } from './entity/aiCfo/aiCfoReducer';
|
|
1013
1013
|
export { AiCfoSelectorView, getAllQuestionAnswersForChatSession, getQuestionAnswerByIdForChatSession, getAllQuestionsForChatSession, getAiCfoSelectorView, getSyntheticAiCfoAnswersForChatSession, getSyntheticAiCfoAnswerByQuestionAnswerId, ChatSessionWithOrderedQuestionAnswers, } from './entity/aiCfo/aiCfoSelector';
|