@zeniai/client-epic-state 5.3.17 → 5.3.18-betaAK2
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/tenant/epic/fetchAllTenantsEpic.d.ts +2 -4
- package/lib/entity/tenant/epic/fetchAllTenantsEpic.js +45 -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 +119 -96
- package/lib/entity/tenant/tenantState.d.ts +10 -0
- package/lib/epic.d.ts +2 -1
- package/lib/epic.js +2 -0
- package/lib/esm/entity/tenant/epic/fetchAllTenantsEpic.js +49 -46
- package/lib/esm/entity/tenant/tenantReducer.js +46 -17
- package/lib/esm/entity/tenant/tenantSelector.js +115 -95
- package/lib/esm/epic.js +2 -0
- 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/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/people/peoplePageEpic.js +0 -4
- package/lib/esm/view/transactionDetail/createTransaction/createTransactionPayload.js +19 -3
- package/lib/esm/view/transactionDetail/createTransaction/createTransactionState.js +2 -0
- 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/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/people/peoplePageEpic.js +0 -4
- package/lib/view/transactionDetail/createTransaction/createTransactionPayload.d.ts +6 -3
- package/lib/view/transactionDetail/createTransaction/createTransactionPayload.js +19 -3
- package/lib/view/transactionDetail/createTransaction/createTransactionState.d.ts +7 -2
- package/lib/view/transactionDetail/createTransaction/createTransactionState.js +2 -0
- package/lib/view/transactionDetail/transactionDetailReducer.d.ts +20 -20
- package/package.json +1 -1
|
@@ -12,6 +12,26 @@ export interface SubmitFeedbackPayload {
|
|
|
12
12
|
model?: string;
|
|
13
13
|
questionText?: string;
|
|
14
14
|
}
|
|
15
|
+
export interface TranscribeAudioPayload {
|
|
16
|
+
/** Recorded audio, already in a format the transcription model accepts. */
|
|
17
|
+
audio: Blob;
|
|
18
|
+
/**
|
|
19
|
+
* Session the recording was made in. Epics outlive the component, so without
|
|
20
|
+
* this a transcript that lands after the user switches sessions would append
|
|
21
|
+
* to whichever composer is open by then.
|
|
22
|
+
*/
|
|
23
|
+
chatSessionId?: ID;
|
|
24
|
+
/** BCP-47 dictation language. Omitted means the model auto-detects. */
|
|
25
|
+
language?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface TranscribeAudioSuccessPayload {
|
|
28
|
+
transcript: string;
|
|
29
|
+
chatSessionId?: ID;
|
|
30
|
+
}
|
|
31
|
+
/** Shape of the /1.0/transcriptions response body. */
|
|
32
|
+
export interface TranscriptionResponseData {
|
|
33
|
+
transcript: string;
|
|
34
|
+
}
|
|
15
35
|
export type ContextStatus = 'NONE' | 'NOT_FOUND' | 'PERMISSION_DENIED' | 'SUCCESS';
|
|
16
36
|
export interface CreateSessionResponseData {
|
|
17
37
|
chat_session_id: string;
|
|
@@ -4,7 +4,7 @@ import { PageToken } from '../../commonStateTypes/viewAndReport/viewAndReport';
|
|
|
4
4
|
import { ChatSessionPayload } from '../../entity/aiCfo/aiCfoPayload';
|
|
5
5
|
import { AiCfoAnswerResponseType } from '../../entity/aiCfo/aiCfoState';
|
|
6
6
|
import { ZeniAPIStatus } from '../../responsePayload';
|
|
7
|
-
import { ContextStatus, FeedbackType, SubmitFeedbackPayload } from './aiCfoViewPayload';
|
|
7
|
+
import { ContextStatus, FeedbackType, SubmitFeedbackPayload, TranscribeAudioPayload, TranscribeAudioSuccessPayload } from './aiCfoViewPayload';
|
|
8
8
|
import { AiCfoViewState, Routine, RoutineDraft, RoutineRun, Skill, SkillDetail, SkillDraft, SkillVersion, SkillVisibility } from './aiCfoViewState';
|
|
9
9
|
export declare const initialAiCfoViewState: AiCfoViewState;
|
|
10
10
|
export declare const acceptMasterTOS: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[userRoleId: string], {
|
|
@@ -220,7 +220,7 @@ export declare const acceptMasterTOS: import("@reduxjs/toolkit").ActionCreatorWi
|
|
|
220
220
|
}, "aiCfoView/submitQuestion", never, never>, submitQuestionFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
221
221
|
error: ZeniAPIStatus;
|
|
222
222
|
sessionId: ID;
|
|
223
|
-
}, "aiCfoView/submitQuestionFailure">, submitQuestionSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "aiCfoView/submitQuestionSuccess">, updateAiCfoViewScrollPosition: import("@reduxjs/toolkit").ActionCreatorWithPayload<number, "aiCfoView/updateAiCfoViewScrollPosition">, updateCotCollapsedState: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
223
|
+
}, "aiCfoView/submitQuestionFailure">, submitQuestionSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "aiCfoView/submitQuestionSuccess">, transcribeAudio: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[audio: Blob, language?: string | undefined, chatSessionId?: string | undefined], TranscribeAudioPayload, "aiCfoView/transcribeAudio", never, never>, transcribeAudioFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "aiCfoView/transcribeAudioFailure">, transcribeAudioSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transcript: string, chatSessionId?: string | undefined], TranscribeAudioSuccessPayload, "aiCfoView/transcribeAudioSuccess", never, never>, updateAiCfoViewScrollPosition: import("@reduxjs/toolkit").ActionCreatorWithPayload<number, "aiCfoView/updateAiCfoViewScrollPosition">, updateCotCollapsedState: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
224
224
|
isCollapsed: boolean;
|
|
225
225
|
questionAnswerId: ID;
|
|
226
226
|
}, "aiCfoView/updateCotCollapsedState">, updateCurrentInput: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "aiCfoView/updateCurrentInput">, updateResponseState: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.fetchSkillVersionBodySuccess = exports.fetchSkillVersionBodyFailure = exports.fetchSkillVersionBody = exports.fetchSkillsSuccess = exports.fetchSkillsFailure = exports.fetchSkills = exports.fetchSkillDetailSuccess = exports.fetchSkillDetailFailure = exports.fetchSkillDetail = exports.fetchRoutinesSuccess = exports.fetchRoutinesFailure = exports.fetchRoutines = exports.fetchRoutineRunsSuccess = exports.fetchRoutineRunsFailure = exports.fetchRoutineRuns = exports.fetchChatSessionsForUserSuccess = exports.fetchChatSessionsForUserFailure = exports.fetchChatSessionsForUser = exports.fetchChatHistorySuccess = exports.fetchChatHistoryFailure = exports.fetchChatHistory = exports.deleteSkillSuccess = exports.deleteSkillFailure = exports.deleteSkill = exports.deleteRoutineSuccess = exports.deleteRoutineFailure = exports.deleteRoutine = exports.deleteChatSessionSuccess = exports.deleteChatSessionFailure = exports.deleteChatSession = exports.createSessionSuccess = exports.createSessionFailure = exports.createSessionAndSubmitSuccess = exports.createSessionAndSubmitFailure = exports.createSessionAndSubmit = exports.createSession = exports.closeSkillsBrowser = exports.closeRoutinesBrowser = exports.closeRoutineRuns = exports.clearSkillMutation = exports.clearSkillDetail = exports.clearLastContextMessage = exports.clearDeleteChatSessionStatus = exports.clearCurrentSessionId = exports.clearAiCfoSidePanelHostPageContext = exports.applyAiCfoSidePanelHostPageTransition = exports.acceptMasterTOSSuccess = exports.acceptMasterTOSFailure = exports.acceptMasterTOS = exports.initialAiCfoViewState = void 0;
|
|
5
|
-
exports.updateResponseState = exports.updateCurrentInput = exports.updateCotCollapsedState = exports.updateAiCfoViewScrollPosition = exports.submitQuestionSuccess = exports.submitQuestionFailure = exports.submitQuestion = exports.submitFeedbackSuccess = exports.submitFeedbackFailure = exports.submitFeedback = exports.stopSubmitSuccess = exports.stopSubmitQuestionSuccess = exports.stopSubmitQuestionFailure = exports.stopSubmitQuestion = exports.stopSubmitFailure = exports.stopSubmit = exports.setSkillVisibilitySuccess = exports.setSkillVisibilityFailure = exports.setSkillVisibility = exports.setSession = exports.setRoutineEnabled = exports.saveSkillSuccess = exports.saveSkillFailure = exports.saveSkill = exports.saveRoutineSuccess = exports.saveRoutineFailure = exports.saveRoutine = exports.runRoutineSuccess = exports.runRoutineFailure = exports.runRoutine = exports.openSkillsBrowser = exports.openRoutinesBrowser = exports.initializeNewSessionState = exports.fetchSuggestedQuestionsSuccess = exports.fetchSuggestedQuestionsFailure = exports.fetchSuggestedQuestions = exports.fetchSkillVersionsSuccess = exports.fetchSkillVersionsFailure = exports.fetchSkillVersions = void 0;
|
|
5
|
+
exports.updateResponseState = exports.updateCurrentInput = exports.updateCotCollapsedState = exports.updateAiCfoViewScrollPosition = exports.transcribeAudioSuccess = exports.transcribeAudioFailure = exports.transcribeAudio = exports.submitQuestionSuccess = exports.submitQuestionFailure = exports.submitQuestion = exports.submitFeedbackSuccess = exports.submitFeedbackFailure = exports.submitFeedback = exports.stopSubmitSuccess = exports.stopSubmitQuestionSuccess = exports.stopSubmitQuestionFailure = exports.stopSubmitQuestion = exports.stopSubmitFailure = exports.stopSubmit = exports.setSkillVisibilitySuccess = exports.setSkillVisibilityFailure = exports.setSkillVisibility = exports.setSession = exports.setRoutineEnabled = exports.saveSkillSuccess = exports.saveSkillFailure = exports.saveSkill = exports.saveRoutineSuccess = exports.saveRoutineFailure = exports.saveRoutine = exports.runRoutineSuccess = exports.runRoutineFailure = exports.runRoutine = exports.openSkillsBrowser = exports.openRoutinesBrowser = exports.initializeNewSessionState = exports.fetchSuggestedQuestionsSuccess = exports.fetchSuggestedQuestionsFailure = exports.fetchSuggestedQuestions = exports.fetchSkillVersionsSuccess = exports.fetchSkillVersionsFailure = exports.fetchSkillVersions = void 0;
|
|
6
6
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
7
7
|
const rootActions_1 = require("../../rootActions");
|
|
8
8
|
function removeSessionIdFromPageKeyMap(draft, sessionId) {
|
|
@@ -52,6 +52,8 @@ exports.initialAiCfoViewState = {
|
|
|
52
52
|
fetchChatSessionHistoryByChatSessionId: {},
|
|
53
53
|
responseStateByChatSessionId: {},
|
|
54
54
|
stopSubmitStateByChatSessionId: {},
|
|
55
|
+
transcriptionState: { fetchState: 'Not-Started', error: undefined },
|
|
56
|
+
transcribingChatSessionId: undefined,
|
|
55
57
|
suggestedQuestionsByPageContext: {},
|
|
56
58
|
skillDetail: {
|
|
57
59
|
fetchState: 'Not-Started',
|
|
@@ -152,6 +154,19 @@ function closeSkillsBrowserState(draft) {
|
|
|
152
154
|
draft.uiState.isSkillsBrowserOpen = false;
|
|
153
155
|
clearOpenSkillState(draft);
|
|
154
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Clear a finished dictation attempt when the conversation moves on, so a failed one
|
|
159
|
+
* stops showing "Could not transcribe that recording" in every later chat. A running
|
|
160
|
+
* take keeps its state — the composer is showing a live "Transcribing…" for it.
|
|
161
|
+
*/
|
|
162
|
+
function resetFinishedTranscription(draft) {
|
|
163
|
+
if (draft.transcriptionState.fetchState === 'In-Progress') {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
draft.transcriptionState.fetchState = 'Not-Started';
|
|
167
|
+
draft.transcriptionState.error = undefined;
|
|
168
|
+
draft.transcribingChatSessionId = undefined;
|
|
169
|
+
}
|
|
155
170
|
const aiCfoView = (0, toolkit_1.createSlice)({
|
|
156
171
|
name: 'aiCfoView',
|
|
157
172
|
initialState: exports.initialAiCfoViewState,
|
|
@@ -159,6 +174,7 @@ const aiCfoView = (0, toolkit_1.createSlice)({
|
|
|
159
174
|
submitQuestion: {
|
|
160
175
|
reducer(draft, action) {
|
|
161
176
|
const { sessionId } = action.payload;
|
|
177
|
+
resetFinishedTranscription(draft);
|
|
162
178
|
// A turn is being sent, so the chat body has to be what the user sees. Doing this
|
|
163
179
|
// here rather than at each call site is deliberate: the composer, the sample
|
|
164
180
|
// chips, Run, and the `/` menu all submit, and every one of them was a separate
|
|
@@ -304,6 +320,7 @@ const aiCfoView = (0, toolkit_1.createSlice)({
|
|
|
304
320
|
setSession(draft, action) {
|
|
305
321
|
draft.uiState.currentChatSessionId = action.payload.sessionId;
|
|
306
322
|
draft.uiState.agentId = action.payload.agentId;
|
|
323
|
+
resetFinishedTranscription(draft);
|
|
307
324
|
// Picking a session means wanting to see that chat, so the browser cannot stay over
|
|
308
325
|
// it. In the reducer because there are six dispatch sites across three separate
|
|
309
326
|
// rails, and covering them one at a time missed half of them.
|
|
@@ -356,6 +373,7 @@ const aiCfoView = (0, toolkit_1.createSlice)({
|
|
|
356
373
|
createSessionAndSubmit: {
|
|
357
374
|
reducer(draft, action) {
|
|
358
375
|
draft.uiState.agentId = action.payload.agentId;
|
|
376
|
+
resetFinishedTranscription(draft);
|
|
359
377
|
draft.createSessionAndSubmitState.fetchState = 'In-Progress';
|
|
360
378
|
draft.createSessionAndSubmitState.error = undefined;
|
|
361
379
|
},
|
|
@@ -556,7 +574,49 @@ const aiCfoView = (0, toolkit_1.createSlice)({
|
|
|
556
574
|
return { payload: { chatMessageId, error } };
|
|
557
575
|
},
|
|
558
576
|
},
|
|
577
|
+
transcribeAudio: {
|
|
578
|
+
reducer(draft, action) {
|
|
579
|
+
draft.transcriptionState.fetchState = 'In-Progress';
|
|
580
|
+
draft.transcriptionState.error = undefined;
|
|
581
|
+
draft.transcribingChatSessionId = action.payload.chatSessionId;
|
|
582
|
+
},
|
|
583
|
+
prepare(audio, language, chatSessionId) {
|
|
584
|
+
return { payload: { audio, chatSessionId, language } };
|
|
585
|
+
},
|
|
586
|
+
},
|
|
587
|
+
transcribeAudioSuccess: {
|
|
588
|
+
reducer(draft, action) {
|
|
589
|
+
draft.transcriptionState.fetchState = 'Completed';
|
|
590
|
+
draft.transcriptionState.error = undefined;
|
|
591
|
+
// The user moved to another session while this was in flight — dropping it
|
|
592
|
+
// is the only safe option, since appending would put their words in a
|
|
593
|
+
// conversation they did not dictate into.
|
|
594
|
+
if (action.payload.chatSessionId !== draft.uiState.currentChatSessionId) {
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
const transcript = action.payload.transcript.trim();
|
|
598
|
+
if (transcript === '') {
|
|
599
|
+
// Silence, not a failure: leave the composer untouched so the user can
|
|
600
|
+
// simply speak again rather than hunting for what went wrong.
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
// Append to whatever is in the box now rather than to a snapshot taken when
|
|
604
|
+
// recording began — a take produces exactly one result, so there is nothing
|
|
605
|
+
// to reconcile, and anything typed while transcribing survives.
|
|
606
|
+
const existing = draft.uiState.currentInput.trim();
|
|
607
|
+
draft.uiState.currentInput =
|
|
608
|
+
existing === '' ? transcript : `${existing} ${transcript}`;
|
|
609
|
+
},
|
|
610
|
+
prepare(transcript, chatSessionId) {
|
|
611
|
+
return { payload: { chatSessionId, transcript } };
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
transcribeAudioFailure(draft, action) {
|
|
615
|
+
draft.transcriptionState.fetchState = 'Error';
|
|
616
|
+
draft.transcriptionState.error = action.payload;
|
|
617
|
+
},
|
|
559
618
|
clearCurrentSessionId(draft) {
|
|
619
|
+
resetFinishedTranscription(draft);
|
|
560
620
|
// New Chat: the empty composer is the point, so the browser cannot stay over it.
|
|
561
621
|
if (draft.uiState.isSkillsBrowserOpen === true) {
|
|
562
622
|
closeSkillsBrowserState(draft);
|
|
@@ -840,7 +900,8 @@ const aiCfoView = (0, toolkit_1.createSlice)({
|
|
|
840
900
|
// The server has it. Nothing it sends from here on will contain this row,
|
|
841
901
|
// so the tombstone has done its job and holding it any longer is what
|
|
842
902
|
// makes a routine recreated under the same id invisible forever.
|
|
843
|
-
draft.routines.deletedScheduleIds =
|
|
903
|
+
draft.routines.deletedScheduleIds =
|
|
904
|
+
draft.routines.deletedScheduleIds.filter((id) => id !== action.payload.scheduleId);
|
|
844
905
|
draft.routineMutation = {
|
|
845
906
|
fetchState: 'Completed',
|
|
846
907
|
error: undefined,
|
|
@@ -852,7 +913,8 @@ const aiCfoView = (0, toolkit_1.createSlice)({
|
|
|
852
913
|
// is what lets the refetch put the row back — leaving it hidden would
|
|
853
914
|
// tell the user they had stopped something they had not, which is the
|
|
854
915
|
// worst outcome this list can produce.
|
|
855
|
-
draft.routines.deletedScheduleIds =
|
|
916
|
+
draft.routines.deletedScheduleIds =
|
|
917
|
+
draft.routines.deletedScheduleIds.filter((id) => id !== action.payload.scheduleId);
|
|
856
918
|
// Its own slice: the refetch that puts the row back would otherwise wipe
|
|
857
919
|
// this error, leaving the row silently reappearing with no explanation.
|
|
858
920
|
draft.routineMutation = {
|
|
@@ -1188,5 +1250,5 @@ const aiCfoView = (0, toolkit_1.createSlice)({
|
|
|
1188
1250
|
});
|
|
1189
1251
|
},
|
|
1190
1252
|
});
|
|
1191
|
-
_a = aiCfoView.actions, exports.acceptMasterTOS = _a.acceptMasterTOS, exports.acceptMasterTOSFailure = _a.acceptMasterTOSFailure, exports.acceptMasterTOSSuccess = _a.acceptMasterTOSSuccess, exports.applyAiCfoSidePanelHostPageTransition = _a.applyAiCfoSidePanelHostPageTransition, exports.clearAiCfoSidePanelHostPageContext = _a.clearAiCfoSidePanelHostPageContext, exports.clearCurrentSessionId = _a.clearCurrentSessionId, exports.clearDeleteChatSessionStatus = _a.clearDeleteChatSessionStatus, exports.clearLastContextMessage = _a.clearLastContextMessage, exports.clearSkillDetail = _a.clearSkillDetail, exports.clearSkillMutation = _a.clearSkillMutation, exports.closeRoutineRuns = _a.closeRoutineRuns, exports.closeRoutinesBrowser = _a.closeRoutinesBrowser, exports.closeSkillsBrowser = _a.closeSkillsBrowser, exports.createSession = _a.createSession, exports.createSessionAndSubmit = _a.createSessionAndSubmit, exports.createSessionAndSubmitFailure = _a.createSessionAndSubmitFailure, exports.createSessionAndSubmitSuccess = _a.createSessionAndSubmitSuccess, exports.createSessionFailure = _a.createSessionFailure, exports.createSessionSuccess = _a.createSessionSuccess, exports.deleteChatSession = _a.deleteChatSession, exports.deleteChatSessionFailure = _a.deleteChatSessionFailure, exports.deleteChatSessionSuccess = _a.deleteChatSessionSuccess, exports.deleteRoutine = _a.deleteRoutine, exports.deleteRoutineFailure = _a.deleteRoutineFailure, exports.deleteRoutineSuccess = _a.deleteRoutineSuccess, exports.deleteSkill = _a.deleteSkill, exports.deleteSkillFailure = _a.deleteSkillFailure, exports.deleteSkillSuccess = _a.deleteSkillSuccess, exports.fetchChatHistory = _a.fetchChatHistory, exports.fetchChatHistoryFailure = _a.fetchChatHistoryFailure, exports.fetchChatHistorySuccess = _a.fetchChatHistorySuccess, exports.fetchChatSessionsForUser = _a.fetchChatSessionsForUser, exports.fetchChatSessionsForUserFailure = _a.fetchChatSessionsForUserFailure, exports.fetchChatSessionsForUserSuccess = _a.fetchChatSessionsForUserSuccess, exports.fetchRoutineRuns = _a.fetchRoutineRuns, exports.fetchRoutineRunsFailure = _a.fetchRoutineRunsFailure, exports.fetchRoutineRunsSuccess = _a.fetchRoutineRunsSuccess, exports.fetchRoutines = _a.fetchRoutines, exports.fetchRoutinesFailure = _a.fetchRoutinesFailure, exports.fetchRoutinesSuccess = _a.fetchRoutinesSuccess, exports.fetchSkillDetail = _a.fetchSkillDetail, exports.fetchSkillDetailFailure = _a.fetchSkillDetailFailure, exports.fetchSkillDetailSuccess = _a.fetchSkillDetailSuccess, exports.fetchSkills = _a.fetchSkills, exports.fetchSkillsFailure = _a.fetchSkillsFailure, exports.fetchSkillsSuccess = _a.fetchSkillsSuccess, exports.fetchSkillVersionBody = _a.fetchSkillVersionBody, exports.fetchSkillVersionBodyFailure = _a.fetchSkillVersionBodyFailure, exports.fetchSkillVersionBodySuccess = _a.fetchSkillVersionBodySuccess, exports.fetchSkillVersions = _a.fetchSkillVersions, exports.fetchSkillVersionsFailure = _a.fetchSkillVersionsFailure, exports.fetchSkillVersionsSuccess = _a.fetchSkillVersionsSuccess, exports.fetchSuggestedQuestions = _a.fetchSuggestedQuestions, exports.fetchSuggestedQuestionsFailure = _a.fetchSuggestedQuestionsFailure, exports.fetchSuggestedQuestionsSuccess = _a.fetchSuggestedQuestionsSuccess, exports.initializeNewSessionState = _a.initializeNewSessionState, exports.openRoutinesBrowser = _a.openRoutinesBrowser, exports.openSkillsBrowser = _a.openSkillsBrowser, exports.runRoutine = _a.runRoutine, exports.runRoutineFailure = _a.runRoutineFailure, exports.runRoutineSuccess = _a.runRoutineSuccess, exports.saveRoutine = _a.saveRoutine, exports.saveRoutineFailure = _a.saveRoutineFailure, exports.saveRoutineSuccess = _a.saveRoutineSuccess, exports.saveSkill = _a.saveSkill, exports.saveSkillFailure = _a.saveSkillFailure, exports.saveSkillSuccess = _a.saveSkillSuccess, exports.setRoutineEnabled = _a.setRoutineEnabled, exports.setSession = _a.setSession, exports.setSkillVisibility = _a.setSkillVisibility, exports.setSkillVisibilityFailure = _a.setSkillVisibilityFailure, exports.setSkillVisibilitySuccess = _a.setSkillVisibilitySuccess, exports.stopSubmit = _a.stopSubmit, exports.stopSubmitFailure = _a.stopSubmitFailure, exports.stopSubmitQuestion = _a.stopSubmitQuestion, exports.stopSubmitQuestionFailure = _a.stopSubmitQuestionFailure, exports.stopSubmitQuestionSuccess = _a.stopSubmitQuestionSuccess, exports.stopSubmitSuccess = _a.stopSubmitSuccess, exports.submitFeedback = _a.submitFeedback, exports.submitFeedbackFailure = _a.submitFeedbackFailure, exports.submitFeedbackSuccess = _a.submitFeedbackSuccess, exports.submitQuestion = _a.submitQuestion, exports.submitQuestionFailure = _a.submitQuestionFailure, exports.submitQuestionSuccess = _a.submitQuestionSuccess, exports.updateAiCfoViewScrollPosition = _a.updateAiCfoViewScrollPosition, exports.updateCotCollapsedState = _a.updateCotCollapsedState, exports.updateCurrentInput = _a.updateCurrentInput, exports.updateResponseState = _a.updateResponseState;
|
|
1253
|
+
_a = aiCfoView.actions, exports.acceptMasterTOS = _a.acceptMasterTOS, exports.acceptMasterTOSFailure = _a.acceptMasterTOSFailure, exports.acceptMasterTOSSuccess = _a.acceptMasterTOSSuccess, exports.applyAiCfoSidePanelHostPageTransition = _a.applyAiCfoSidePanelHostPageTransition, exports.clearAiCfoSidePanelHostPageContext = _a.clearAiCfoSidePanelHostPageContext, exports.clearCurrentSessionId = _a.clearCurrentSessionId, exports.clearDeleteChatSessionStatus = _a.clearDeleteChatSessionStatus, exports.clearLastContextMessage = _a.clearLastContextMessage, exports.clearSkillDetail = _a.clearSkillDetail, exports.clearSkillMutation = _a.clearSkillMutation, exports.closeRoutineRuns = _a.closeRoutineRuns, exports.closeRoutinesBrowser = _a.closeRoutinesBrowser, exports.closeSkillsBrowser = _a.closeSkillsBrowser, exports.createSession = _a.createSession, exports.createSessionAndSubmit = _a.createSessionAndSubmit, exports.createSessionAndSubmitFailure = _a.createSessionAndSubmitFailure, exports.createSessionAndSubmitSuccess = _a.createSessionAndSubmitSuccess, exports.createSessionFailure = _a.createSessionFailure, exports.createSessionSuccess = _a.createSessionSuccess, exports.deleteChatSession = _a.deleteChatSession, exports.deleteChatSessionFailure = _a.deleteChatSessionFailure, exports.deleteChatSessionSuccess = _a.deleteChatSessionSuccess, exports.deleteRoutine = _a.deleteRoutine, exports.deleteRoutineFailure = _a.deleteRoutineFailure, exports.deleteRoutineSuccess = _a.deleteRoutineSuccess, exports.deleteSkill = _a.deleteSkill, exports.deleteSkillFailure = _a.deleteSkillFailure, exports.deleteSkillSuccess = _a.deleteSkillSuccess, exports.fetchChatHistory = _a.fetchChatHistory, exports.fetchChatHistoryFailure = _a.fetchChatHistoryFailure, exports.fetchChatHistorySuccess = _a.fetchChatHistorySuccess, exports.fetchChatSessionsForUser = _a.fetchChatSessionsForUser, exports.fetchChatSessionsForUserFailure = _a.fetchChatSessionsForUserFailure, exports.fetchChatSessionsForUserSuccess = _a.fetchChatSessionsForUserSuccess, exports.fetchRoutineRuns = _a.fetchRoutineRuns, exports.fetchRoutineRunsFailure = _a.fetchRoutineRunsFailure, exports.fetchRoutineRunsSuccess = _a.fetchRoutineRunsSuccess, exports.fetchRoutines = _a.fetchRoutines, exports.fetchRoutinesFailure = _a.fetchRoutinesFailure, exports.fetchRoutinesSuccess = _a.fetchRoutinesSuccess, exports.fetchSkillDetail = _a.fetchSkillDetail, exports.fetchSkillDetailFailure = _a.fetchSkillDetailFailure, exports.fetchSkillDetailSuccess = _a.fetchSkillDetailSuccess, exports.fetchSkills = _a.fetchSkills, exports.fetchSkillsFailure = _a.fetchSkillsFailure, exports.fetchSkillsSuccess = _a.fetchSkillsSuccess, exports.fetchSkillVersionBody = _a.fetchSkillVersionBody, exports.fetchSkillVersionBodyFailure = _a.fetchSkillVersionBodyFailure, exports.fetchSkillVersionBodySuccess = _a.fetchSkillVersionBodySuccess, exports.fetchSkillVersions = _a.fetchSkillVersions, exports.fetchSkillVersionsFailure = _a.fetchSkillVersionsFailure, exports.fetchSkillVersionsSuccess = _a.fetchSkillVersionsSuccess, exports.fetchSuggestedQuestions = _a.fetchSuggestedQuestions, exports.fetchSuggestedQuestionsFailure = _a.fetchSuggestedQuestionsFailure, exports.fetchSuggestedQuestionsSuccess = _a.fetchSuggestedQuestionsSuccess, exports.initializeNewSessionState = _a.initializeNewSessionState, exports.openRoutinesBrowser = _a.openRoutinesBrowser, exports.openSkillsBrowser = _a.openSkillsBrowser, exports.runRoutine = _a.runRoutine, exports.runRoutineFailure = _a.runRoutineFailure, exports.runRoutineSuccess = _a.runRoutineSuccess, exports.saveRoutine = _a.saveRoutine, exports.saveRoutineFailure = _a.saveRoutineFailure, exports.saveRoutineSuccess = _a.saveRoutineSuccess, exports.saveSkill = _a.saveSkill, exports.saveSkillFailure = _a.saveSkillFailure, exports.saveSkillSuccess = _a.saveSkillSuccess, exports.setRoutineEnabled = _a.setRoutineEnabled, exports.setSession = _a.setSession, exports.setSkillVisibility = _a.setSkillVisibility, exports.setSkillVisibilityFailure = _a.setSkillVisibilityFailure, exports.setSkillVisibilitySuccess = _a.setSkillVisibilitySuccess, exports.stopSubmit = _a.stopSubmit, exports.stopSubmitFailure = _a.stopSubmitFailure, exports.stopSubmitQuestion = _a.stopSubmitQuestion, exports.stopSubmitQuestionFailure = _a.stopSubmitQuestionFailure, exports.stopSubmitQuestionSuccess = _a.stopSubmitQuestionSuccess, exports.stopSubmitSuccess = _a.stopSubmitSuccess, exports.submitFeedback = _a.submitFeedback, exports.submitFeedbackFailure = _a.submitFeedbackFailure, exports.submitFeedbackSuccess = _a.submitFeedbackSuccess, exports.submitQuestion = _a.submitQuestion, exports.submitQuestionFailure = _a.submitQuestionFailure, exports.submitQuestionSuccess = _a.submitQuestionSuccess, exports.transcribeAudio = _a.transcribeAudio, exports.transcribeAudioFailure = _a.transcribeAudioFailure, exports.transcribeAudioSuccess = _a.transcribeAudioSuccess, exports.updateAiCfoViewScrollPosition = _a.updateAiCfoViewScrollPosition, exports.updateCotCollapsedState = _a.updateCotCollapsedState, exports.updateCurrentInput = _a.updateCurrentInput, exports.updateResponseState = _a.updateResponseState;
|
|
1192
1254
|
exports.default = aiCfoView.reducer;
|
|
@@ -4,7 +4,7 @@ import { FetchStateAndError } from '../../commonStateTypes/common';
|
|
|
4
4
|
import { SelectorView } from '../../commonStateTypes/viewAndReport/viewAndReport';
|
|
5
5
|
import { AiCfoSelectorView } from '../../entity/aiCfo/aiCfoSelector';
|
|
6
6
|
import { RootState } from '../../rootStateTypes';
|
|
7
|
-
import { AiCfoViewUIState,
|
|
7
|
+
import { AiCfoViewUIState, RoutineMutationState, RoutineRunsState, RoutinesState, SkillDetailState, SkillMutationState, SkillVersionBodyState, SkillVersionsState, SkillsState, SuggestedQuestionsForPageContext } from './aiCfoViewState';
|
|
8
8
|
export interface AiCfoViewSelector extends SelectorView, AiCfoSelectorView {
|
|
9
9
|
createSessionAndSubmitState: FetchStateAndError;
|
|
10
10
|
createSessionState: FetchStateAndError;
|
|
@@ -42,3 +42,10 @@ export declare function getSkillVersionBody(state: RootState): SkillVersionBodyS
|
|
|
42
42
|
export declare function getSkillMutation(state: RootState): SkillMutationState;
|
|
43
43
|
/** True only when the server says the feature is on for this tenant. */
|
|
44
44
|
export declare function getSkillsEnabled(state: RootState): boolean;
|
|
45
|
+
export declare function getIsTranscribing(state: RootState): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Set when a transcription request failed. Without surfacing this the composer
|
|
48
|
+
* would just drop the "Transcribing…" label and sit there silently, leaving the
|
|
49
|
+
* user with no sign their recording went nowhere.
|
|
50
|
+
*/
|
|
51
|
+
export declare function getTranscriptionFailed(state: RootState): boolean;
|
|
@@ -13,6 +13,8 @@ exports.getSkillVersions = getSkillVersions;
|
|
|
13
13
|
exports.getSkillVersionBody = getSkillVersionBody;
|
|
14
14
|
exports.getSkillMutation = getSkillMutation;
|
|
15
15
|
exports.getSkillsEnabled = getSkillsEnabled;
|
|
16
|
+
exports.getIsTranscribing = getIsTranscribing;
|
|
17
|
+
exports.getTranscriptionFailed = getTranscriptionFailed;
|
|
16
18
|
const aiCfoReducer_1 = require("../../entity/aiCfo/aiCfoReducer");
|
|
17
19
|
const aiCfoSelector_1 = require("../../entity/aiCfo/aiCfoSelector");
|
|
18
20
|
const aiCfoViewReducer_1 = require("./aiCfoViewReducer");
|
|
@@ -149,3 +151,28 @@ function getSkillMutation(state) {
|
|
|
149
151
|
function getSkillsEnabled(state) {
|
|
150
152
|
return getSkills(state).skillsEnabled;
|
|
151
153
|
}
|
|
154
|
+
/** True while a finished voice recording is being transcribed server-side. */
|
|
155
|
+
/**
|
|
156
|
+
* A take belongs to the chat it was dictated into. A new chat has no session id yet on
|
|
157
|
+
* either side, which is a match rather than a mismatch.
|
|
158
|
+
*/
|
|
159
|
+
function isTranscribingCurrentSession(state) {
|
|
160
|
+
if (state.aiCfoViewState == null) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
return (state.aiCfoViewState.transcribingChatSessionId ===
|
|
164
|
+
state.aiCfoViewState.uiState.currentChatSessionId);
|
|
165
|
+
}
|
|
166
|
+
function getIsTranscribing(state) {
|
|
167
|
+
return (state.aiCfoViewState?.transcriptionState?.fetchState === 'In-Progress' &&
|
|
168
|
+
isTranscribingCurrentSession(state));
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Set when a transcription request failed. Without surfacing this the composer
|
|
172
|
+
* would just drop the "Transcribing…" label and sit there silently, leaving the
|
|
173
|
+
* user with no sign their recording went nowhere.
|
|
174
|
+
*/
|
|
175
|
+
function getTranscriptionFailed(state) {
|
|
176
|
+
return (state.aiCfoViewState?.transcriptionState?.fetchState === 'Error' &&
|
|
177
|
+
isTranscribingCurrentSession(state));
|
|
178
|
+
}
|
|
@@ -378,5 +378,14 @@ export interface AiCfoViewState extends FetchStateAndError {
|
|
|
378
378
|
stopSubmitStateByChatSessionId: Record<ID, FetchStateAndError>;
|
|
379
379
|
/** Keyed by `page_context` query value (e.g. balance_sheet). */
|
|
380
380
|
suggestedQuestionsByPageContext: Partial<Record<AiCfoSuggestedQuestionsPageContext, SuggestedQuestionsForPageContext>>;
|
|
381
|
+
/** Voice dictation: in-flight while a recording is being transcribed. */
|
|
382
|
+
transcriptionState: FetchStateAndError;
|
|
381
383
|
uiState: AiCfoViewUIState;
|
|
384
|
+
/**
|
|
385
|
+
* Conversation the take in `transcriptionState` was dictated into. The spinner and
|
|
386
|
+
* the failure message belong to that chat alone — an epic outlives the component, so
|
|
387
|
+
* without this a take started in one session locks the composer, or shows its error,
|
|
388
|
+
* in whichever session the user has moved to.
|
|
389
|
+
*/
|
|
390
|
+
transcribingChatSessionId?: ID;
|
|
382
391
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { clearAll } from '../../../rootActions';
|
|
4
|
+
import { RootState } from '../../../rootStateTypes';
|
|
5
|
+
import { ZeniAPI } from '../../../zeniAPI';
|
|
6
|
+
import { transcribeAudio, transcribeAudioFailure, transcribeAudioSuccess } from '../aiCfoViewReducer';
|
|
7
|
+
export type ActionType = ReturnType<typeof clearAll> | ReturnType<typeof transcribeAudio> | ReturnType<typeof transcribeAudioSuccess> | ReturnType<typeof transcribeAudioFailure>;
|
|
8
|
+
/**
|
|
9
|
+
* Voice dictation for the AI CFO composer. Dispatch `transcribeAudio(blob, language)` with a
|
|
10
|
+
* finished recording to POST it to the AI CFO micro-service `/1.0/transcriptions` endpoint;
|
|
11
|
+
* on success the transcript is appended to the composer input for the user to edit and send.
|
|
12
|
+
*
|
|
13
|
+
* `switchMap` (not `mergeMap`): a newer recording supersedes an older in-flight one, so a
|
|
14
|
+
* slow response can never append a stale transcript after a fresh one has already landed.
|
|
15
|
+
* The AbortController makes that cancellation real — `fetch` wrapped in a promise ignores
|
|
16
|
+
* an RxJS unsubscribe, so without the signal the superseded request would run to completion
|
|
17
|
+
* and still bill a transcription call whose result nothing wants.
|
|
18
|
+
*/
|
|
19
|
+
export declare const transcribeAudioEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.transcribeAudioEpic = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const responsePayload_1 = require("../../../responsePayload");
|
|
7
|
+
const rootActions_1 = require("../../../rootActions");
|
|
8
|
+
const aiCfoViewReducer_1 = require("../aiCfoViewReducer");
|
|
9
|
+
const AUDIO_FIELD = 'audio';
|
|
10
|
+
const LANGUAGE_FIELD = 'language';
|
|
11
|
+
/** Extension only has to match the recorded format; the server reads the part's MIME type. */
|
|
12
|
+
const AUDIO_FILE_NAME = 'dictation.wav';
|
|
13
|
+
/**
|
|
14
|
+
* A hung request would otherwise pin `isTranscribing` true forever, and the composer
|
|
15
|
+
* gates both submit and the mic on it — leaving the user unable to send even typed
|
|
16
|
+
* text until something else resolved it.
|
|
17
|
+
*/
|
|
18
|
+
const TRANSCRIPTION_TIMEOUT_MS = 30000;
|
|
19
|
+
/**
|
|
20
|
+
* Voice dictation for the AI CFO composer. Dispatch `transcribeAudio(blob, language)` with a
|
|
21
|
+
* finished recording to POST it to the AI CFO micro-service `/1.0/transcriptions` endpoint;
|
|
22
|
+
* on success the transcript is appended to the composer input for the user to edit and send.
|
|
23
|
+
*
|
|
24
|
+
* `switchMap` (not `mergeMap`): a newer recording supersedes an older in-flight one, so a
|
|
25
|
+
* slow response can never append a stale transcript after a fresh one has already landed.
|
|
26
|
+
* The AbortController makes that cancellation real — `fetch` wrapped in a promise ignores
|
|
27
|
+
* an RxJS unsubscribe, so without the signal the superseded request would run to completion
|
|
28
|
+
* and still bill a transcription call whose result nothing wants.
|
|
29
|
+
*/
|
|
30
|
+
const transcribeAudioEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(aiCfoViewReducer_1.transcribeAudio.match), (0, operators_1.switchMap)((action) => {
|
|
31
|
+
const { audio, chatSessionId, language } = action.payload;
|
|
32
|
+
const abortController = new AbortController();
|
|
33
|
+
const formData = new FormData();
|
|
34
|
+
formData.append(AUDIO_FIELD, audio, AUDIO_FILE_NAME);
|
|
35
|
+
if (language != null && language !== '') {
|
|
36
|
+
formData.append(LANGUAGE_FIELD, language);
|
|
37
|
+
}
|
|
38
|
+
return zeniAPI
|
|
39
|
+
.postFormData(`${zeniAPI.apiEndPoints.aiCfoMicroServiceBaseUrl}/1.0/transcriptions`, formData, abortController.signal)
|
|
40
|
+
.pipe((0, operators_1.timeout)(TRANSCRIPTION_TIMEOUT_MS),
|
|
41
|
+
// A tenant switch clears the store; a transcript still in flight must not
|
|
42
|
+
// land in the next tenant's composer (both sessions can be `undefined`, so
|
|
43
|
+
// the reducer's session guard would let it through).
|
|
44
|
+
(0, operators_1.takeUntil)(actions$.pipe((0, operators_1.filter)(rootActions_1.clearAll.match))), (0, operators_1.map)((response) => {
|
|
45
|
+
if (!(0, responsePayload_1.isSuccessResponse)(response)) {
|
|
46
|
+
return (0, aiCfoViewReducer_1.transcribeAudioFailure)(response.status);
|
|
47
|
+
}
|
|
48
|
+
// An EMPTY transcript is a success (the mic caught silence) and the
|
|
49
|
+
// reducer leaves the composer alone. A MISSING one breaks the response
|
|
50
|
+
// contract, so it surfaces as an error rather than being coerced to
|
|
51
|
+
// silence the user cannot distinguish from a quiet room.
|
|
52
|
+
if (response.data?.transcript == null) {
|
|
53
|
+
return (0, aiCfoViewReducer_1.transcribeAudioFailure)((0, responsePayload_1.createZeniAPIStatus)('Transcription succeeded but the response carried no transcript', 'Unexpected Error'));
|
|
54
|
+
}
|
|
55
|
+
// The session id rides along so a transcript that lands after the user
|
|
56
|
+
// switched sessions is dropped rather than misfiled.
|
|
57
|
+
return (0, aiCfoViewReducer_1.transcribeAudioSuccess)(response.data.transcript, chatSessionId);
|
|
58
|
+
}), (0, operators_1.finalize)(() => abortController.abort()), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, aiCfoViewReducer_1.transcribeAudioFailure)((0, responsePayload_1.createZeniAPIStatus)(
|
|
59
|
+
// message (detailed) first, then the short title — per createZeniAPIStatus(message, title).
|
|
60
|
+
// JSON.stringify(Error) drops the (non-enumerable) message — extract it explicitly.
|
|
61
|
+
'Transcription REST API call errored out: ' +
|
|
62
|
+
(error instanceof Error ? error.message : String(error)), 'Unexpected Error')))));
|
|
63
|
+
}));
|
|
64
|
+
exports.transcribeAudioEpic = transcribeAudioEpic;
|
|
@@ -91,10 +91,6 @@ const fetchDashboardEpic = (actions$, state$) => actions$.pipe((0, operators_1.f
|
|
|
91
91
|
const revenueState = (0, revenueSelector_1.getRevenueReportFetchState)(state.revenueState.uiState.selectedForecast?.id, state.revenueState);
|
|
92
92
|
const opExState = (0, opExSelector_1.getOperatingExpensesReportFetchState)(state.opExState.uiState.selectedForecast?.id, state.opExState);
|
|
93
93
|
const netBurnOrIncomeReportFetchState = (0, netBurnOrIncomeSelector_1.getNetBurnOrIncomeReportFetchState)(state.netBurnOrIncomeState.uiState.selectedForecast?.id, state.netBurnOrIncomeState);
|
|
94
|
-
if (state.tenantState.fetchState !== 'In-Progress' &&
|
|
95
|
-
!state.tenantState.hasValidState()) {
|
|
96
|
-
fetchActions.push((0, tenantReducer_1.fetchAllTenants)(userId));
|
|
97
|
-
}
|
|
98
94
|
if (state.cardBalanceState.fetchState !== 'In-Progress' &&
|
|
99
95
|
!state.cardBalanceState.hasValidState()) {
|
|
100
96
|
fetchActions.push((0, cardBalanceReducer_1.fetchCardBalance)());
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ReportID, SelectorReport, SelectorView } from '../../commonStateTypes/viewAndReport/viewAndReport';
|
|
2
|
-
import { TenantsOrdered } from '../../entity/tenant/tenantSelector';
|
|
3
2
|
import { Tenant } from '../../entity/tenant/tenantState';
|
|
4
3
|
import { RootState } from '../../rootStateTypes';
|
|
5
4
|
import { CardType } from './dashboardState';
|
|
@@ -7,7 +6,6 @@ export interface DashboardReport extends SelectorReport {
|
|
|
7
6
|
cardsForDashboardUI: CardType[];
|
|
8
7
|
cardsOrdered: CardType[];
|
|
9
8
|
reportsInOrder: (SelectorReport | SelectorView)[];
|
|
10
|
-
tenantsOrdered: TenantsOrdered;
|
|
11
9
|
currentTenant?: Tenant;
|
|
12
10
|
}
|
|
13
11
|
export declare const getDashboard: (state: RootState, additionalExcludedReports: ReportID[]) => DashboardReport;
|
|
@@ -37,8 +37,7 @@ const getCashInCashOutLast4Periods = (state) => (0, cashInCashOutSelector_1.getC
|
|
|
37
37
|
const getNetBurnOrIncomeStoryCard = (state) => (0, netBurnOrIncomeStoryCardSelector_1.getNetBurnOrIncomeStoryCardReport)(state);
|
|
38
38
|
const apAgingSelector = (state) => (0, apAgingSelector_1.getApAgingReport)(state);
|
|
39
39
|
const arAgingSelector = (state) => (0, arAgingSelector_1.getArAgingReport)(state);
|
|
40
|
-
const tenantSelector = (0, toolkit_1.createSelector)(tenantSelector_1.
|
|
41
|
-
tenantsOrdered,
|
|
40
|
+
const tenantSelector = (0, toolkit_1.createSelector)(tenantSelector_1.getCurrentTenant, (currentTenant) => ({
|
|
42
41
|
currentTenant,
|
|
43
42
|
}));
|
|
44
43
|
exports.getDashboard = (0, toolkit_1.createSelector)(tenantSelector, cardBalanceSelector_1.getCardBalance, cashBalanceSelector_1.getCashBalance, getOperatingExpensesForLast5Periods, getRevenueForLast4Periods, topExSelector_1.getTop6Expenses, getNetBurnOrIncomeForLast4Periods, getNetBurnOrIncomeStoryCard, getCashPositionLast5Periods, getCashInCashOutLast4Periods, insightsCardSelector_1.getInsights, companyPassportViewSelector_1.getCompanyPassportView, tasksCardSelector_1.getTasksCardReport, billPayCardSelector_1.getBillPayCardReport, reimbursementCardSelector_1.getReimbursementCardReport, apAgingSelector, arAgingSelector, referralSelector_1.getRewardsPlanCard, dashboardLayoutSelector_1.getDashboardCardsOrdered, (state) => {
|
|
@@ -18,12 +18,8 @@ const fetchFinanceStatementEpic = (actions$, state$) => actions$.pipe((0, operat
|
|
|
18
18
|
return (0, rxjs_1.of)((0, tenantReducer_1.fetchAllTenants)(userId), (0, profitAndLossReducer_1.fetchProfitAndLoss)(), (0, balanceSheetReducer_1.fetchBalanceSheet)(), (0, cashFlowReducer_1.fetchCashFlow)());
|
|
19
19
|
}
|
|
20
20
|
else {
|
|
21
|
-
const {
|
|
21
|
+
const { financeStatementState } = state;
|
|
22
22
|
const fetchActions = [];
|
|
23
|
-
if (tenantState.fetchState !== 'In-Progress' &&
|
|
24
|
-
!tenantState.hasValidState()) {
|
|
25
|
-
fetchActions.push((0, tenantReducer_1.fetchAllTenants)(userId));
|
|
26
|
-
}
|
|
27
23
|
const pandLFetchState = (0, profitAndLossSelector_1.getPandLReportFetchState)(undefined, state.profitAndLossState);
|
|
28
24
|
const balanceSheetFetchState = (0, balanceSheetSelector_1.getBalanceSheetFetchState)(state.balanceSheetState);
|
|
29
25
|
const cashFlowFetchState = (0, cashFlowSelector_1.getCashFlowReportFetchState)(state.cashFlowState);
|
|
@@ -13,10 +13,6 @@ const fetchPeoplePageEpic = (actions$, state$) => actions$.pipe((0, operators_1.
|
|
|
13
13
|
else {
|
|
14
14
|
const state = state$.value;
|
|
15
15
|
const fetchActions = [];
|
|
16
|
-
if (state.tenantState.fetchState !== 'In-Progress' &&
|
|
17
|
-
!state.tenantState.hasValidState()) {
|
|
18
|
-
fetchActions.push((0, tenantReducer_1.fetchAllTenants)(userId));
|
|
19
|
-
}
|
|
20
16
|
if (state.peopleState.fetchState != 'In-Progress' &&
|
|
21
17
|
!state.peopleState.hasValidState()) {
|
|
22
18
|
fetchActions.push((0, peopleReducer_1.fetchPeople)());
|
|
@@ -13,8 +13,9 @@ import { CreateTransactionLocalData } from './createTransactionState';
|
|
|
13
13
|
* constant NAMES; ZENI_LINE_DETAIL_TYPE_TO_QBO_LINE_DETAIL_TYPE_MAP converts them for the
|
|
14
14
|
* body the backend sends on to QuickBooks, never for ours.
|
|
15
15
|
* 2. The QBO Purchases (check, credit_card_credit) send their reference number as
|
|
16
|
-
* `document_number`; a journal entry sends its entry name
|
|
17
|
-
*
|
|
16
|
+
* `document_number`; a journal entry sends its entry name, a bill its bill number and a
|
|
17
|
+
* vendor credit its reference number as `document_id`. All land on QBO's DocNumber, but
|
|
18
|
+
* QBOJournalEntry reads only `document_id`.
|
|
18
19
|
*/
|
|
19
20
|
export interface CreateTransactionAccountPayload {
|
|
20
21
|
qbo_id: ID;
|
|
@@ -53,10 +54,12 @@ export interface CreateTransactionRemitToAddressPayload {
|
|
|
53
54
|
export interface CreateTransactionRequest extends Record<string, unknown> {
|
|
54
55
|
transaction_date: string;
|
|
55
56
|
transaction_type: string;
|
|
56
|
-
/** journal_entry entry name (QBO DocNumber). */
|
|
57
|
+
/** journal_entry entry name, bill number or vendor_credit reference number (QBO DocNumber). */
|
|
57
58
|
document_id?: string;
|
|
58
59
|
/** check / credit_card_credit reference number (QBO Purchase). */
|
|
59
60
|
document_number?: string;
|
|
61
|
+
/** bill only. */
|
|
62
|
+
due_date?: string;
|
|
60
63
|
from_account_id?: ID;
|
|
61
64
|
/** credit_card_credit is modelled as a Purchase with Credit: true. */
|
|
62
65
|
is_credit?: boolean;
|
|
@@ -135,13 +135,29 @@ const prepareCreateTransactionPayload = (state, localData) => {
|
|
|
135
135
|
};
|
|
136
136
|
}
|
|
137
137
|
const lines = localData.lines.map((line) => toLinePayload(state, line, transactionType));
|
|
138
|
+
const documentIdField = localData.documentNumber != null && localData.documentNumber !== ''
|
|
139
|
+
? { document_id: localData.documentNumber }
|
|
140
|
+
: {};
|
|
138
141
|
if (transactionType === 'journal_entry') {
|
|
142
|
+
return { ...base, ...documentIdField, lines };
|
|
143
|
+
}
|
|
144
|
+
// Both post to accounts payable, so they carry no header account or payment type.
|
|
145
|
+
if (transactionType === 'vendor_credit') {
|
|
146
|
+
return {
|
|
147
|
+
...base,
|
|
148
|
+
vendor_id: toQboVendorId(state, localData.vendorId),
|
|
149
|
+
...documentIdField,
|
|
150
|
+
lines,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (transactionType === 'bill') {
|
|
139
154
|
return {
|
|
140
155
|
...base,
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
156
|
+
vendor_id: toQboVendorId(state, localData.vendorId),
|
|
157
|
+
...(localData.dueDate != null && {
|
|
158
|
+
due_date: localData.dueDate.format(timePeriod_1.DEFAULT_DATE_FORMAT),
|
|
144
159
|
}),
|
|
160
|
+
...documentIdField,
|
|
145
161
|
lines,
|
|
146
162
|
};
|
|
147
163
|
}
|
|
@@ -9,7 +9,7 @@ import { ZeniDate } from '../../../zeniDayJS';
|
|
|
9
9
|
* The transaction types the Create Transaction flow can originate. A narrow subset of
|
|
10
10
|
* TransactionType -- everything else is read-only and arrives via sync.
|
|
11
11
|
*/
|
|
12
|
-
export declare const ALL_CREATABLE_TRANSACTION_TYPES: readonly ["expense", "check", "credit_card_credit", "transfer", "journal_entry"];
|
|
12
|
+
export declare const ALL_CREATABLE_TRANSACTION_TYPES: readonly ["expense", "check", "credit_card_credit", "transfer", "journal_entry", "bill", "vendor_credit"];
|
|
13
13
|
export type CreatableTransactionType = (typeof ALL_CREATABLE_TRANSACTION_TYPES)[number];
|
|
14
14
|
/**
|
|
15
15
|
* The wire shape the create endpoint expects for a check's remit-to address. Deliberately not
|
|
@@ -54,8 +54,13 @@ export interface CreateTransactionLocalData {
|
|
|
54
54
|
/** Empty for transfer, which has no lines at all. */
|
|
55
55
|
lines: CreateTransactionLineLocalData[];
|
|
56
56
|
transactionType: CreatableTransactionType;
|
|
57
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* check / credit_card_credit / vendor_credit reference number, journal_entry entry name, or
|
|
59
|
+
* bill number.
|
|
60
|
+
*/
|
|
58
61
|
documentNumber?: string;
|
|
62
|
+
/** bill only. */
|
|
63
|
+
dueDate?: ZeniDate;
|
|
59
64
|
/** transfer */
|
|
60
65
|
fromAccountId?: ID;
|
|
61
66
|
paymentType?: PaymentType;
|
|
@@ -177,39 +177,39 @@ export declare const downloadAccountingProviderAttachment: import("@reduxjs/tool
|
|
|
177
177
|
}, "transactionDetail/deleteSplitLine", never, never>, toggleSplitEditMode: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionId: TransactionID, editMode: boolean], {
|
|
178
178
|
transactionId: TransactionID;
|
|
179
179
|
editMode: boolean;
|
|
180
|
-
}, "transactionDetail/toggleSplitEditMode", never, never>, initializeCreateTransactionLocalData: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry"], {
|
|
181
|
-
transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
182
|
-
}, "transactionDetail/initializeCreateTransactionLocalData", never, never>, updateCreateTransactionLocalData: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry", localData: Partial<CreateTransactionLocalData>], {
|
|
183
|
-
transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
180
|
+
}, "transactionDetail/toggleSplitEditMode", never, never>, initializeCreateTransactionLocalData: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry"], {
|
|
181
|
+
transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
182
|
+
}, "transactionDetail/initializeCreateTransactionLocalData", never, never>, updateCreateTransactionLocalData: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry", localData: Partial<CreateTransactionLocalData>], {
|
|
183
|
+
transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
184
184
|
localData: Partial<CreateTransactionLocalData>;
|
|
185
|
-
}, "transactionDetail/updateCreateTransactionLocalData", never, never>, updateCreateTransactionLineLocalData: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry", lineId: string, lineUpdates: Partial<CreateTransactionLineLocalData>], {
|
|
186
|
-
transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
185
|
+
}, "transactionDetail/updateCreateTransactionLocalData", never, never>, updateCreateTransactionLineLocalData: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry", lineId: string, lineUpdates: Partial<CreateTransactionLineLocalData>], {
|
|
186
|
+
transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
187
187
|
lineId: string;
|
|
188
188
|
lineUpdates: Partial<CreateTransactionLineLocalData>;
|
|
189
|
-
}, "transactionDetail/updateCreateTransactionLineLocalData", never, never>, addCreateTransactionLine: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry", line?: Partial<CreateTransactionLineLocalData> | undefined], {
|
|
190
|
-
transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
189
|
+
}, "transactionDetail/updateCreateTransactionLineLocalData", never, never>, addCreateTransactionLine: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry", line?: Partial<CreateTransactionLineLocalData> | undefined], {
|
|
190
|
+
transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
191
191
|
line: Partial<CreateTransactionLineLocalData> | undefined;
|
|
192
|
-
}, "transactionDetail/addCreateTransactionLine", never, never>, removeCreateTransactionLine: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry", lineId: string], {
|
|
193
|
-
transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
192
|
+
}, "transactionDetail/addCreateTransactionLine", never, never>, removeCreateTransactionLine: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry", lineId: string], {
|
|
193
|
+
transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
194
194
|
lineId: string;
|
|
195
|
-
}, "transactionDetail/removeCreateTransactionLine", never, never>, resetCreateTransactionLocalData: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry"], {
|
|
196
|
-
transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
197
|
-
}, "transactionDetail/resetCreateTransactionLocalData", never, never>, createTransaction: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry"], {
|
|
198
|
-
transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
195
|
+
}, "transactionDetail/removeCreateTransactionLine", never, never>, resetCreateTransactionLocalData: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry"], {
|
|
196
|
+
transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
197
|
+
}, "transactionDetail/resetCreateTransactionLocalData", never, never>, createTransaction: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry"], {
|
|
198
|
+
transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
199
199
|
}, "transactionDetail/createTransaction", never, never>, createTransactionSuccessOrFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[fetchState: FetchState, createdTransactionId?: TransactionID | undefined, error?: ZeniAPIStatus<Record<string, unknown>> | undefined], {
|
|
200
200
|
fetchState: FetchState;
|
|
201
201
|
createdTransactionId: TransactionID | undefined;
|
|
202
202
|
error: ZeniAPIStatus<Record<string, unknown>> | undefined;
|
|
203
|
-
}, "transactionDetail/createTransactionSuccessOrFailure", never, never>, setRecommendationsForCreateTransactionLines: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry", lineIds: string[], recommendations: Recommendation[], isAccountingClassesEnabled: boolean], {
|
|
204
|
-
transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
203
|
+
}, "transactionDetail/createTransactionSuccessOrFailure", never, never>, setRecommendationsForCreateTransactionLines: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry", lineIds: string[], recommendations: Recommendation[], isAccountingClassesEnabled: boolean], {
|
|
204
|
+
transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
205
205
|
lineIds: string[];
|
|
206
206
|
recommendations: Recommendation[];
|
|
207
207
|
isAccountingClassesEnabled: boolean;
|
|
208
|
-
}, "transactionDetail/setRecommendationsForCreateTransactionLines", never, never>, clearRecommendationsForCreateTransactionLines: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry", lineIds: string[]], {
|
|
209
|
-
transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
208
|
+
}, "transactionDetail/setRecommendationsForCreateTransactionLines", never, never>, clearRecommendationsForCreateTransactionLines: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry", lineIds: string[]], {
|
|
209
|
+
transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
210
210
|
lineIds: string[];
|
|
211
|
-
}, "transactionDetail/clearRecommendationsForCreateTransactionLines", never, never>, fetchVendorRecommendationsForCreateTransaction: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry", lineIds: string[], entity?: Entity | undefined], {
|
|
212
|
-
transactionType: "expense" | "check" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
211
|
+
}, "transactionDetail/clearRecommendationsForCreateTransactionLines", never, never>, fetchVendorRecommendationsForCreateTransaction: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry", lineIds: string[], entity?: Entity | undefined], {
|
|
212
|
+
transactionType: "expense" | "check" | "bill" | "vendor_credit" | "credit_card_credit" | "transfer" | "journal_entry";
|
|
213
213
|
lineIds: string[];
|
|
214
214
|
entity: Entity | undefined;
|
|
215
215
|
}, "transactionDetail/fetchVendorRecommendationsForCreateTransaction", never, never>, createTransactionAttachmentUploadFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[failedAttachmentFileNames: string[]], {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.18-betaAK2",
|
|
4
4
|
"description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/esm/index.js",
|