@zeniai/client-epic-state 5.3.17 → 5.3.18-betaAK1
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 +2 -2
- package/lib/entity/tenant/tenantReducer.js +29 -18
- package/lib/entity/tenant/tenantSelector.d.ts +14 -6
- package/lib/entity/tenant/tenantSelector.js +98 -97
- 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 +28 -17
- package/lib/esm/entity/tenant/tenantSelector.js +94 -96
- package/lib/esm/epic.js +2 -0
- package/lib/esm/index.js +6 -6
- 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 +7 -7
- package/lib/index.js +54 -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
|
@@ -3,12 +3,10 @@ import { Observable } from 'rxjs';
|
|
|
3
3
|
import { ID } from '../../../commonStateTypes/common';
|
|
4
4
|
import { MonthYearPeriod } from '../../../commonStateTypes/timePeriod';
|
|
5
5
|
import { RootState } from '../../../rootStateTypes';
|
|
6
|
-
import { initializeSelectedPeriodForTenants } from '../../../view/expenseAutomationView/expenseAutomationViewReducer';
|
|
7
6
|
import { ZeniAPI } from '../../../zeniAPI';
|
|
8
|
-
import { updateCompanies } from '../../company/companyReducer';
|
|
9
7
|
import { TenantsData } from '../tenantPayload';
|
|
10
|
-
import { fetchAllTenants,
|
|
11
|
-
export type ActionType = ReturnType<typeof fetchAllTenants> | ReturnType<typeof
|
|
8
|
+
import { fetchActiveTenant, fetchAllTenants, updateTenantFailure, updateTenantSuccess, updateTenantSummariesSuccess, updateTenantsFailure } from '../tenantReducer';
|
|
9
|
+
export type ActionType = ReturnType<typeof fetchAllTenants> | ReturnType<typeof fetchActiveTenant> | ReturnType<typeof updateTenantSuccess> | ReturnType<typeof updateTenantFailure> | ReturnType<typeof updateTenantSummariesSuccess> | ReturnType<typeof updateTenantsFailure>;
|
|
12
10
|
export declare const fetchAllTenantsEpic: (actions$: ActionsObservable<ActionType>, state: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
13
11
|
export declare const defaultMonthYearPeriod: MonthYearPeriod;
|
|
14
12
|
export declare const getDefaultSelectedPeriodsForTenants: (tenantsData: TenantsData) => Record<ID, MonthYearPeriod>;
|
|
@@ -6,60 +6,63 @@ const operators_1 = require("rxjs/operators");
|
|
|
6
6
|
const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
|
|
7
7
|
const responsePayload_1 = require("../../../responsePayload");
|
|
8
8
|
const sessionEndpointsLoader_1 = require("../../../sessionEndpointsLoader");
|
|
9
|
-
const expenseAutomationViewReducer_1 = require("../../../view/expenseAutomationView/expenseAutomationViewReducer");
|
|
10
9
|
const zeniDayJS_1 = require("../../../zeniDayJS");
|
|
11
|
-
const companyReducer_1 = require("../../company/companyReducer");
|
|
12
10
|
const tenantReducer_1 = require("../tenantReducer");
|
|
11
|
+
// Only what the tenant switcher and tenant lookups read (~0.3 KB a tenant
|
|
12
|
+
// instead of ~18 KB with full records and companies). A tenant's full record
|
|
13
|
+
// comes from `fetchActiveTenant` when it is opened.
|
|
14
|
+
const TENANT_SUMMARIES_QUERY = {
|
|
15
|
+
is_full: false,
|
|
16
|
+
is_include_companies_in_response: false,
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The tenant the app lands on: the selected one, or the most recently opened
|
|
20
|
+
* when none is selected (sign-in, the root route).
|
|
21
|
+
*/
|
|
22
|
+
function getLandingTenantId(tenants, currentTenantId) {
|
|
23
|
+
if (currentTenantId != null &&
|
|
24
|
+
tenants.some((tenant) => tenant.tenant_id === currentTenantId)) {
|
|
25
|
+
return currentTenantId;
|
|
26
|
+
}
|
|
27
|
+
const lastCheckIn = (tenant) => tenant.user_last_check_in_time_into_tenant != null
|
|
28
|
+
? (0, zeniDayJS_1.date)(tenant.user_last_check_in_time_into_tenant).valueOf()
|
|
29
|
+
: 0;
|
|
30
|
+
return tenants.reduce((mostRecent, tenant) => mostRecent == null || lastCheckIn(tenant) > lastCheckIn(mostRecent)
|
|
31
|
+
? tenant
|
|
32
|
+
: mostRecent, undefined)?.tenant_id;
|
|
33
|
+
}
|
|
13
34
|
const fetchAllTenantsEpic = (actions$, state, zeniAPI) => {
|
|
14
|
-
const queryParam = {
|
|
15
|
-
is_include_companies_in_response: true,
|
|
16
|
-
};
|
|
17
35
|
return actions$.pipe((0, operators_1.filter)(tenantReducer_1.fetchAllTenants.match), (0, operators_1.switchMap)((action) => {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const currentTenantId = state.value.tenantState.currentTenantId;
|
|
22
|
-
if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
|
|
23
|
-
const defaultSelectedPeriodsForTenants = (0, exports.getDefaultSelectedPeriodsForTenants)(response.data);
|
|
24
|
-
let actions = [
|
|
25
|
-
(0, tenantReducer_1.updateTenantsSuccess)(response.data),
|
|
26
|
-
(0, expenseAutomationViewReducer_1.initializeSelectedPeriodForTenants)({
|
|
27
|
-
selectedPeriodByTenantId: defaultSelectedPeriodsForTenants,
|
|
28
|
-
}),
|
|
29
|
-
];
|
|
30
|
-
if (response.data.companies != null) {
|
|
31
|
-
let companiesPayload = response.data.companies;
|
|
32
|
-
if (currentTenantId != null) {
|
|
33
|
-
// filter out this tenant ID related company detail
|
|
34
|
-
// Find companyID for this tenant
|
|
35
|
-
const currentTenantPayload = response.data.tenants.find((tenant) => tenant.tenant_id === currentTenantId);
|
|
36
|
-
if (currentTenantPayload != null) {
|
|
37
|
-
companiesPayload = response.data.companies.filter((company) => company.company_id !== currentTenantPayload.company_id);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
console.warn('Selected tenant record not found in response', currentTenantId);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
actions = [
|
|
44
|
-
(0, companyReducer_1.updateCompanies)({
|
|
45
|
-
payload: companiesPayload,
|
|
46
|
-
schema: {},
|
|
47
|
-
}),
|
|
48
|
-
...actions,
|
|
49
|
-
];
|
|
50
|
-
}
|
|
51
|
-
return (0, rxjs_1.from)(actions);
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
36
|
+
const { userId, zeniSessionId } = action.payload;
|
|
37
|
+
const fetchTenants$ = (0, rxjs_1.defer)(() => zeniAPI.getJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/users/${userId}/tenants?query=${encodeURIComponent(JSON.stringify(TENANT_SUMMARIES_QUERY))}`, Object.assign({ 'zeni-user-id': userId }, { 'zeni-tenant-id': '' }, zeniSessionId != null ? { 'zeni-session-id': zeniSessionId } : {}))).pipe((0, operators_1.mergeMap)((response) => {
|
|
38
|
+
if (!(0, responsePayload_1.isSuccessResponse)(response) || response.data == null) {
|
|
54
39
|
return (0, rxjs_1.of)((0, tenantReducer_1.updateTenantsFailure)(response.status));
|
|
55
40
|
}
|
|
41
|
+
const { tenants } = response.data;
|
|
42
|
+
if (tenants.length === 0) {
|
|
43
|
+
return (0, rxjs_1.of)((0, tenantReducer_1.updateTenantsFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected error', 'Empty list of tenants')));
|
|
44
|
+
}
|
|
45
|
+
const tenantsLoaded = (0, tenantReducer_1.updateTenantSummariesSuccess)(tenants);
|
|
46
|
+
const { tenantState } = state.value;
|
|
47
|
+
const landingTenantId = getLandingTenantId(tenants, tenantState.currentTenantId);
|
|
48
|
+
const isLandingTenantLoadedOrLoading = landingTenantId == null ||
|
|
49
|
+
tenantState.tenantsById[landingTenantId] != null ||
|
|
50
|
+
tenantState.activeTenantFetchState.fetchState === 'In-Progress';
|
|
51
|
+
if (isLandingTenantLoadedOrLoading) {
|
|
52
|
+
return (0, rxjs_1.of)(tenantsLoaded);
|
|
53
|
+
}
|
|
54
|
+
// Screens that wait for this fetch (sign-in, the root route) read the
|
|
55
|
+
// landing tenant's roles and product settings, which the list does
|
|
56
|
+
// not carry, so it completes only once that tenant's record is in.
|
|
57
|
+
return (0, rxjs_1.merge)(actions$.pipe((0, operators_1.filter)((landingAction) => tenantReducer_1.updateTenantSuccess.match(landingAction) ||
|
|
58
|
+
tenantReducer_1.updateTenantFailure.match(landingAction)), (0, operators_1.take)(1), (0, operators_1.map)(() => tenantsLoaded)), (0, rxjs_1.of)((0, tenantReducer_1.fetchActiveTenant)(userId, landingTenantId, zeniSessionId)));
|
|
56
59
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, tenantReducer_1.updateTenantsFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected error', 'Fetch All Tenants REST API call errored out' +
|
|
57
60
|
JSON.stringify(error))))));
|
|
58
61
|
const sessionEndpointsLoader = (0, sessionEndpointsLoader_1.getSessionEndpointsLoader)();
|
|
59
62
|
if (sessionEndpointsLoader == null) {
|
|
60
63
|
return fetchTenants$;
|
|
61
64
|
}
|
|
62
|
-
return (0, rxjs_1.defer)(() => (0, rxjs_1.from)(sessionEndpointsLoader(
|
|
65
|
+
return (0, rxjs_1.defer)(() => (0, rxjs_1.from)(sessionEndpointsLoader(userId, zeniSessionId))).pipe((0, operators_1.switchMap)(() => fetchTenants$), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, tenantReducer_1.updateTenantsFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected error', 'Loading session endpoints errored out: ' +
|
|
63
66
|
JSON.stringify(error))))));
|
|
64
67
|
}));
|
|
65
68
|
};
|
|
@@ -7,6 +7,22 @@ import { SubscriptionSummaryPayload } from '../subscription/subscriptionSummary/
|
|
|
7
7
|
import { MasterTOSInfoPayload } from '../userRole/userRolePayload';
|
|
8
8
|
import { CapitalizableClassificationType, CapitalizableMatchPattern, CapitalizableThresholdSource } from './tenantState';
|
|
9
9
|
type TenantsResponse = ZeniAPIResponse<TenantsData>;
|
|
10
|
+
type TenantSummariesResponse = ZeniAPIResponse<TenantSummariesData>;
|
|
11
|
+
/**
|
|
12
|
+
* The tenants list requested with `is_full: false`: only what the tenant
|
|
13
|
+
* switcher and tenant lookups need. A tenant's full record comes from the
|
|
14
|
+
* active-tenant fetch.
|
|
15
|
+
*/
|
|
16
|
+
export interface TenantSummariesData {
|
|
17
|
+
tenants: TenantSummaryPayload[];
|
|
18
|
+
}
|
|
19
|
+
export interface TenantSummaryPayload {
|
|
20
|
+
company_id: ID;
|
|
21
|
+
company_name: string;
|
|
22
|
+
tenant_email_domain: string;
|
|
23
|
+
tenant_id: ID;
|
|
24
|
+
user_last_check_in_time_into_tenant: string | null;
|
|
25
|
+
}
|
|
10
26
|
export interface TenantsData {
|
|
11
27
|
tenants: TenantPayload[];
|
|
12
28
|
user: TenantUserPayload;
|
|
@@ -197,4 +213,4 @@ type SaveConnectionResponse = ZeniAPIResponse<ConnectionDataPayload>;
|
|
|
197
213
|
type SubscriptionSummaryForTenantResponse = ZeniAPIResponse<SubscriptionSummaryPayload>;
|
|
198
214
|
type OnboardingTenantResponse = ZeniAPIResponse<TenantPayload>;
|
|
199
215
|
/** Lets export interfaces and types */
|
|
200
|
-
export { TenantsResponse, TenantPayload, LoggedInUserPayload, UserData, SignInResponse, SignOutResponse, RoleResourcePayload, RoleResourcesResponse, ConnectionsPayload, ConnectionWithMetaPayload, ConnectionsResponse, SaveConnectionResponse, SubscriptionSummaryForTenantResponse, OnboardingTenantResponse, MagicLinkSignInResponse, sendEmailMagicLinkToUserResponse, VerifyDeviceWithTwoFAResponse, };
|
|
216
|
+
export { TenantSummariesResponse, TenantsResponse, TenantPayload, LoggedInUserPayload, UserData, SignInResponse, SignOutResponse, RoleResourcePayload, RoleResourcesResponse, ConnectionsPayload, ConnectionWithMetaPayload, ConnectionsResponse, SaveConnectionResponse, SubscriptionSummaryForTenantResponse, OnboardingTenantResponse, MagicLinkSignInResponse, sendEmailMagicLinkToUserResponse, VerifyDeviceWithTwoFAResponse, };
|
|
@@ -3,7 +3,7 @@ import { ZeniAPIStatus } from '../../responsePayload';
|
|
|
3
3
|
import ZeniUrl from '../../zeniUrl';
|
|
4
4
|
import { SubscriptionSummaryPayload } from '../subscription/subscriptionSummary/subscriptionSummaryPayload';
|
|
5
5
|
import { UserRolePayload } from '../userRole/userRolePayload';
|
|
6
|
-
import { CapitalizableAccountsPayload, ConnectionDataPayload, ConnectionWithMetaPayload, ConnectionsPayload, LoggedInUserPayload, RoleResourcePayload, TenantPayload, TenantUserPayload, TenantsData } from './tenantPayload';
|
|
6
|
+
import { CapitalizableAccountsPayload, ConnectionDataPayload, ConnectionWithMetaPayload, ConnectionsPayload, LoggedInUserPayload, RoleResourcePayload, TenantPayload, TenantSummaryPayload, TenantUserPayload, TenantsData } from './tenantPayload';
|
|
7
7
|
import { CapitalizableAccounts, Connection, RoleResource, TenantState } from './tenantState';
|
|
8
8
|
import { AuthProvider } from './tenantTypes';
|
|
9
9
|
export interface DoSignInPayload {
|
|
@@ -40,7 +40,7 @@ export declare const updateTenants: import("@reduxjs/toolkit").ActionCreatorWith
|
|
|
40
40
|
}, "tenant/updateTenants", never, never>, fetchAllTenants: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[userId: string, zeniSessionId?: string | undefined], {
|
|
41
41
|
userId: string;
|
|
42
42
|
zeniSessionId: string | undefined;
|
|
43
|
-
}, "tenant/fetchAllTenants", never, never>,
|
|
43
|
+
}, "tenant/fetchAllTenants", never, never>, updateTenantSummariesSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<TenantSummaryPayload[], "tenant/updateTenantSummariesSuccess">, updateTenantsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "tenant/updateTenantsFailure">, fetchActiveTenant: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[userId: string, tenantId: string, zeniSessionId?: string | undefined], {
|
|
44
44
|
userId: string;
|
|
45
45
|
tenantId: string;
|
|
46
46
|
zeniSessionId: string | undefined;
|
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
var _a;
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.updateSubscriptionSummaryForTenantSuccess = exports.fetchSubscriptionSummaryForTenant = exports.deleteConnectionFailure = exports.deleteConnectionSuccess = exports.deleteConnection = exports.initEmailConnectOAuthFailure = exports.initEmailConnectOAuthSuccess = exports.initEmailConnectOAuth = exports.saveConnectorCredentialsFailure = exports.saveConnectorCredentialsSuccess = exports.saveConnectorCredentials = exports.saveOAuthConnectionFailure = exports.saveOAuthConnectionSuccess = exports.saveOAuthConnection = exports.saveAPIKeyConnectionFailure = exports.saveAPIKeyConnectionSuccess = exports.saveAPIKeyConnection = exports.fetchExternalConnectionsSuccess = exports.fetchExternalConnectionsFailure = exports.saveExternalConnectionFailure = exports.saveExternalConnectionSuccess = exports.saveExternalConnection = exports.fetchExternalConnections = exports.updateLoggedInUser = exports.sessionHeartbeatFailure = exports.sessionHeartbeatSuccess = exports.sendSessionHeartbeat = exports.signOutSuccess = exports.doSignOut = exports.updateSignInState = exports.sendEmailMagicLinkToUserFailure = exports.sendEmailMagicLinkToUserSuccess = exports.sendEmailMagicLinkToUser = exports.magicLinkSignInFailure = exports.magicLinkSignInSuccess = exports.doMagicLinkSignIn = exports.doSignIn = exports.updateExcludedResourcesFailure = exports.updateExcludedResourcesSuccess = exports.fetchExcludedResources = exports.updateCurrentTenant = exports.updateTenantFailure = exports.updateTenantSuccess = exports.fetchActiveTenant = exports.updateTenantsFailure = exports.
|
|
7
|
+
exports.updateSubscriptionSummaryForTenantSuccess = exports.fetchSubscriptionSummaryForTenant = exports.deleteConnectionFailure = exports.deleteConnectionSuccess = exports.deleteConnection = exports.initEmailConnectOAuthFailure = exports.initEmailConnectOAuthSuccess = exports.initEmailConnectOAuth = exports.saveConnectorCredentialsFailure = exports.saveConnectorCredentialsSuccess = exports.saveConnectorCredentials = exports.saveOAuthConnectionFailure = exports.saveOAuthConnectionSuccess = exports.saveOAuthConnection = exports.saveAPIKeyConnectionFailure = exports.saveAPIKeyConnectionSuccess = exports.saveAPIKeyConnection = exports.fetchExternalConnectionsSuccess = exports.fetchExternalConnectionsFailure = exports.saveExternalConnectionFailure = exports.saveExternalConnectionSuccess = exports.saveExternalConnection = exports.fetchExternalConnections = exports.updateLoggedInUser = exports.sessionHeartbeatFailure = exports.sessionHeartbeatSuccess = exports.sendSessionHeartbeat = exports.signOutSuccess = exports.doSignOut = exports.updateSignInState = exports.sendEmailMagicLinkToUserFailure = exports.sendEmailMagicLinkToUserSuccess = exports.sendEmailMagicLinkToUser = exports.magicLinkSignInFailure = exports.magicLinkSignInSuccess = exports.doMagicLinkSignIn = exports.doSignIn = exports.updateExcludedResourcesFailure = exports.updateExcludedResourcesSuccess = exports.fetchExcludedResources = exports.updateCurrentTenant = exports.updateTenantFailure = exports.updateTenantSuccess = exports.fetchActiveTenant = exports.updateTenantsFailure = exports.updateTenantSummariesSuccess = exports.fetchAllTenants = exports.updateTenants = exports.initialState = exports.toExternalIntegrationType = void 0;
|
|
8
8
|
exports.toConnection = exports.toRoleResource = exports.resendVerifyDeviceOTPFailure = exports.resendVerifyDeviceOTPSuccess = exports.resendVerifyDeviceOTP = exports.updateTreasuryPromoIntroClosedByOutsideClickForLoggedInUser = exports.updateTreasuryPromoRemindMeLaterClickedForLoggedInUser = exports.updateTreasuryVideoViewedForLoggedInUser = exports.verifyDeviceWithTwoFAFailure = exports.verifyDeviceWithTwoFASuccess = exports.verifyDeviceWithTwoFA = exports.updateTenantMasterTOSInfo = exports.updateTenantCapitalizationAccountOverride = exports.updateTenantCapitalizationOnboardingDismissed = exports.updateTenantProductSettings = exports.updateTenantAutoReviewIncomeWithoutCustomer = exports.updateTenantAccountingProjectsEnabled = exports.updateTenantAccountingClassesEnabled = exports.trigger2FA = exports.resetSignInState = exports.updateReferViewedForLoggedInUser = exports.updateTenantReimbursementInfo = exports.removeOnboardingTenant = exports.updateOnboardingTenants = exports.updateSubscriptionSummaryForTenantFailure = void 0;
|
|
9
9
|
exports.mapCapitalizableAccountsPayload = mapCapitalizableAccountsPayload;
|
|
10
10
|
exports.mapConnectionsPayloadToState = mapConnectionsPayloadToState;
|
|
@@ -28,6 +28,7 @@ exports.initialState = {
|
|
|
28
28
|
error: undefined,
|
|
29
29
|
accountLocked: false,
|
|
30
30
|
tenantsById: {},
|
|
31
|
+
tenantSummariesById: {},
|
|
31
32
|
onboardingTenantsById: {},
|
|
32
33
|
tenantIds: [],
|
|
33
34
|
signInState: 'Not-Started',
|
|
@@ -118,26 +119,24 @@ const tenant = (0, toolkit_1.createSlice)({
|
|
|
118
119
|
});
|
|
119
120
|
},
|
|
120
121
|
},
|
|
121
|
-
|
|
122
|
-
const { tenants, user } = action.payload;
|
|
122
|
+
updateTenantSummariesSuccess(draft, action) {
|
|
123
123
|
draft.fetchState = 'Completed';
|
|
124
124
|
draft.error = undefined;
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
125
|
+
const tenantSummariesById = {};
|
|
126
|
+
action.payload.forEach((payload) => {
|
|
127
|
+
tenantSummariesById[payload.tenant_id] =
|
|
128
|
+
mapTenantSummaryPayloadToTenantSummary(payload);
|
|
129
|
+
});
|
|
130
|
+
draft.tenantSummariesById = tenantSummariesById;
|
|
131
|
+
draft.tenantIds = Object.keys(tenantSummariesById);
|
|
132
|
+
// A tenant missing from the list is no longer accessible to the user.
|
|
133
|
+
const accessibleTenantsById = {};
|
|
134
|
+
Object.values(draft.tenantsById).forEach((tenant) => {
|
|
135
|
+
if (tenantSummariesById[tenant.tenantId] != null) {
|
|
136
|
+
accessibleTenantsById[tenant.tenantId] = tenant;
|
|
136
137
|
}
|
|
137
138
|
});
|
|
138
|
-
draft.tenantsById =
|
|
139
|
-
draft.tenantIds = tenantIds;
|
|
140
|
-
draft.loggedInUser = (0, assignWith_1.default)(draft.loggedInUser ?? {}, firstUser, (objValue, srcValue) => srcValue ?? objValue);
|
|
139
|
+
draft.tenantsById = accessibleTenantsById;
|
|
141
140
|
},
|
|
142
141
|
updateTenantsFailure(draft, action) {
|
|
143
142
|
draft.fetchState = 'Error';
|
|
@@ -145,6 +144,7 @@ const tenant = (0, toolkit_1.createSlice)({
|
|
|
145
144
|
draft.error = action.payload;
|
|
146
145
|
draft.tenantIds = [];
|
|
147
146
|
draft.tenantsById = {};
|
|
147
|
+
draft.tenantSummariesById = {};
|
|
148
148
|
},
|
|
149
149
|
updateTenantSuccess(draft, action) {
|
|
150
150
|
const { tenants, user } = action.payload;
|
|
@@ -253,6 +253,7 @@ const tenant = (0, toolkit_1.createSlice)({
|
|
|
253
253
|
draft.signInState = 'Error';
|
|
254
254
|
draft.tenantIds = [];
|
|
255
255
|
draft.tenantsById = {};
|
|
256
|
+
draft.tenantSummariesById = {};
|
|
256
257
|
},
|
|
257
258
|
updateTenantReimbursementInfo(draft, action) {
|
|
258
259
|
const { tenant_id, reimbursement_info } = action.payload;
|
|
@@ -945,7 +946,7 @@ const tenant = (0, toolkit_1.createSlice)({
|
|
|
945
946
|
});
|
|
946
947
|
},
|
|
947
948
|
});
|
|
948
|
-
_a = tenant.actions, exports.updateTenants = _a.updateTenants, exports.fetchAllTenants = _a.fetchAllTenants, exports.
|
|
949
|
+
_a = tenant.actions, exports.updateTenants = _a.updateTenants, exports.fetchAllTenants = _a.fetchAllTenants, exports.updateTenantSummariesSuccess = _a.updateTenantSummariesSuccess, exports.updateTenantsFailure = _a.updateTenantsFailure, exports.fetchActiveTenant = _a.fetchActiveTenant, exports.updateTenantSuccess = _a.updateTenantSuccess, exports.updateTenantFailure = _a.updateTenantFailure, exports.updateCurrentTenant = _a.updateCurrentTenant, exports.fetchExcludedResources = _a.fetchExcludedResources, exports.updateExcludedResourcesSuccess = _a.updateExcludedResourcesSuccess, exports.updateExcludedResourcesFailure = _a.updateExcludedResourcesFailure, exports.doSignIn = _a.doSignIn, exports.doMagicLinkSignIn = _a.doMagicLinkSignIn, exports.magicLinkSignInSuccess = _a.magicLinkSignInSuccess, exports.magicLinkSignInFailure = _a.magicLinkSignInFailure, exports.sendEmailMagicLinkToUser = _a.sendEmailMagicLinkToUser, exports.sendEmailMagicLinkToUserSuccess = _a.sendEmailMagicLinkToUserSuccess, exports.sendEmailMagicLinkToUserFailure = _a.sendEmailMagicLinkToUserFailure, exports.updateSignInState = _a.updateSignInState, exports.doSignOut = _a.doSignOut, exports.signOutSuccess = _a.signOutSuccess, exports.sendSessionHeartbeat = _a.sendSessionHeartbeat, exports.sessionHeartbeatSuccess = _a.sessionHeartbeatSuccess, exports.sessionHeartbeatFailure = _a.sessionHeartbeatFailure, exports.updateLoggedInUser = _a.updateLoggedInUser, exports.fetchExternalConnections = _a.fetchExternalConnections, exports.saveExternalConnection = _a.saveExternalConnection, exports.saveExternalConnectionSuccess = _a.saveExternalConnectionSuccess, exports.saveExternalConnectionFailure = _a.saveExternalConnectionFailure, exports.fetchExternalConnectionsFailure = _a.fetchExternalConnectionsFailure, exports.fetchExternalConnectionsSuccess = _a.fetchExternalConnectionsSuccess, exports.saveAPIKeyConnection = _a.saveAPIKeyConnection, exports.saveAPIKeyConnectionSuccess = _a.saveAPIKeyConnectionSuccess, exports.saveAPIKeyConnectionFailure = _a.saveAPIKeyConnectionFailure, exports.saveOAuthConnection = _a.saveOAuthConnection, exports.saveOAuthConnectionSuccess = _a.saveOAuthConnectionSuccess, exports.saveOAuthConnectionFailure = _a.saveOAuthConnectionFailure, exports.saveConnectorCredentials = _a.saveConnectorCredentials, exports.saveConnectorCredentialsSuccess = _a.saveConnectorCredentialsSuccess, exports.saveConnectorCredentialsFailure = _a.saveConnectorCredentialsFailure, exports.initEmailConnectOAuth = _a.initEmailConnectOAuth, exports.initEmailConnectOAuthSuccess = _a.initEmailConnectOAuthSuccess, exports.initEmailConnectOAuthFailure = _a.initEmailConnectOAuthFailure, exports.deleteConnection = _a.deleteConnection, exports.deleteConnectionSuccess = _a.deleteConnectionSuccess, exports.deleteConnectionFailure = _a.deleteConnectionFailure, exports.fetchSubscriptionSummaryForTenant = _a.fetchSubscriptionSummaryForTenant, exports.updateSubscriptionSummaryForTenantSuccess = _a.updateSubscriptionSummaryForTenantSuccess, exports.updateSubscriptionSummaryForTenantFailure = _a.updateSubscriptionSummaryForTenantFailure, exports.updateOnboardingTenants = _a.updateOnboardingTenants, exports.removeOnboardingTenant = _a.removeOnboardingTenant, exports.updateTenantReimbursementInfo = _a.updateTenantReimbursementInfo, exports.updateReferViewedForLoggedInUser = _a.updateReferViewedForLoggedInUser, exports.resetSignInState = _a.resetSignInState, exports.trigger2FA = _a.trigger2FA, exports.updateTenantAccountingClassesEnabled = _a.updateTenantAccountingClassesEnabled, exports.updateTenantAccountingProjectsEnabled = _a.updateTenantAccountingProjectsEnabled, exports.updateTenantAutoReviewIncomeWithoutCustomer = _a.updateTenantAutoReviewIncomeWithoutCustomer, exports.updateTenantProductSettings = _a.updateTenantProductSettings, exports.updateTenantCapitalizationOnboardingDismissed = _a.updateTenantCapitalizationOnboardingDismissed, exports.updateTenantCapitalizationAccountOverride = _a.updateTenantCapitalizationAccountOverride, exports.updateTenantMasterTOSInfo = _a.updateTenantMasterTOSInfo, exports.verifyDeviceWithTwoFA = _a.verifyDeviceWithTwoFA, exports.verifyDeviceWithTwoFASuccess = _a.verifyDeviceWithTwoFASuccess, exports.verifyDeviceWithTwoFAFailure = _a.verifyDeviceWithTwoFAFailure, exports.updateTreasuryVideoViewedForLoggedInUser = _a.updateTreasuryVideoViewedForLoggedInUser, exports.updateTreasuryPromoRemindMeLaterClickedForLoggedInUser = _a.updateTreasuryPromoRemindMeLaterClickedForLoggedInUser, exports.updateTreasuryPromoIntroClosedByOutsideClickForLoggedInUser = _a.updateTreasuryPromoIntroClosedByOutsideClickForLoggedInUser, exports.resendVerifyDeviceOTP = _a.resendVerifyDeviceOTP, exports.resendVerifyDeviceOTPSuccess = _a.resendVerifyDeviceOTPSuccess, exports.resendVerifyDeviceOTPFailure = _a.resendVerifyDeviceOTPFailure;
|
|
949
950
|
exports.default = tenant.reducer;
|
|
950
951
|
/**
|
|
951
952
|
* Applies treasury promo user fields from the tenants API user block when present.
|
|
@@ -987,6 +988,16 @@ function mapTenantsPayloadToState(tenantsPayload, userTenantPayload) {
|
|
|
987
988
|
const firstUser = mapTenantPayloadToUser(tenantsPayload[0]);
|
|
988
989
|
return [tenantsById, tenantIds, firstUser];
|
|
989
990
|
}
|
|
991
|
+
function mapTenantSummaryPayloadToTenantSummary(payload) {
|
|
992
|
+
return {
|
|
993
|
+
companyId: payload.company_id,
|
|
994
|
+
companyName: payload.company_name,
|
|
995
|
+
tenantEmailDomain: payload.tenant_email_domain,
|
|
996
|
+
tenantId: payload.tenant_id,
|
|
997
|
+
// A tenant never opened sorts last, as in `mapTenantPayloadToTenant`.
|
|
998
|
+
userLastCheckInTime: (0, zeniDayJS_1.date)(payload.user_last_check_in_time_into_tenant ?? '1970-01-01'),
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
990
1001
|
function mapTenantPayloadToTenant(payload, userTenantPayload) {
|
|
991
1002
|
const tenant = {
|
|
992
1003
|
accountingClassIDs: payload.accounting_class_ids,
|
|
@@ -22,11 +22,14 @@ export interface TenantBaseView extends TenantCoreDetailsView {
|
|
|
22
22
|
}
|
|
23
23
|
export declare function getTenant(tenantState: TenantState, companyState: CompanyState, tenantId: ID): TenantView | undefined;
|
|
24
24
|
export declare function getTenantIdByCompanyId(tenantState: TenantState, companyId: ID): ID | undefined;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
/** Whether the tenant's full record is loaded, not just its list entry. */
|
|
26
|
+
export declare const isTenantLoaded: (state: RootState, tenantId: ID) => boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Whether the selected tenant's full record is loaded. Screens that act on
|
|
29
|
+
* roles or product settings wait for this rather than for either tenant fetch
|
|
30
|
+
* to complete: the tenants list alone carries neither.
|
|
31
|
+
*/
|
|
32
|
+
export declare const isCurrentTenantLoaded: (state: RootState) => boolean;
|
|
30
33
|
export declare const getTenantBaseViewForTenantId: (state: RootState, tenantId: ID) => TenantBaseView | undefined;
|
|
31
34
|
export type TenantsBaseOrdered = {
|
|
32
35
|
order: 'descending_last_check_in';
|
|
@@ -74,7 +77,12 @@ declare const getCurrentTenantHelper: (tenantState: TenantState, companyState: C
|
|
|
74
77
|
};
|
|
75
78
|
export type CurrentTenant = ReturnType<typeof getCurrentTenantHelper>;
|
|
76
79
|
export declare const getCurrentTenant: (state: RootState) => CurrentTenant;
|
|
77
|
-
|
|
80
|
+
/**
|
|
81
|
+
* The selected tenant's id as soon as it is chosen. Unlike `getCurrentTenant`,
|
|
82
|
+
* it is set before the tenant fetch lands (boot reads it from the cached
|
|
83
|
+
* tenant list).
|
|
84
|
+
*/
|
|
85
|
+
export declare const getCurrentTenantId: (state: RootState) => ID | undefined;
|
|
78
86
|
export declare function getOnboardingTenantByTenantId(tenantState: TenantState, tenantId: ID): Tenant | undefined;
|
|
79
87
|
export declare const getTenantBaseById: (state: RootState) => TenantBaseView[];
|
|
80
88
|
export declare const getTenantsBaseByCheckInDateSelector: (state: RootState) => TenantsBaseOrdered;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.DEFAULT_RECEIPTS_EMAIL = exports.isTenantTreasuryEnabled = exports.isOtherProductsEnabledForTenant = exports.isTenantBookkeepingEnabled = exports.getIsAutoReviewIncomeWithoutCustomerEnabled = exports.getIsAccountingProjectsEnabled = exports.getIsAccountingClassesEnabled = exports.isTenantAccountingServicesEnabled = exports.isTenantCardsOnly = exports.isTenantBankingOnly = exports.toTenantCoreDetailsView = exports.getCurrentTenantExternalConnections = exports.isTenantUsingZeniCOA = exports.isZeniDomainTenant = exports.getTenantBaseViewForTenantView = exports.getTenantsCoreDetailsByCheckInDateSelector = exports.getTenantsBaseByCheckInDateSelector = exports.getTenantBaseById = exports.
|
|
6
|
+
exports.DEFAULT_RECEIPTS_EMAIL = exports.isTenantTreasuryEnabled = exports.isOtherProductsEnabledForTenant = exports.isTenantBookkeepingEnabled = exports.getIsAutoReviewIncomeWithoutCustomerEnabled = exports.getIsAccountingProjectsEnabled = exports.getIsAccountingClassesEnabled = exports.isTenantAccountingServicesEnabled = exports.isTenantCardsOnly = exports.isTenantBankingOnly = exports.toTenantCoreDetailsView = exports.getCurrentTenantExternalConnections = exports.isTenantUsingZeniCOA = exports.isZeniDomainTenant = exports.getTenantBaseViewForTenantView = exports.getTenantsCoreDetailsByCheckInDateSelector = exports.getTenantsBaseByCheckInDateSelector = exports.getTenantBaseById = exports.getCurrentTenantId = exports.getCurrentTenant = exports.getTenantBaseViewForTenantId = exports.isCurrentTenantLoaded = exports.isTenantLoaded = void 0;
|
|
7
7
|
exports.getTenant = getTenant;
|
|
8
8
|
exports.getTenantIdByCompanyId = getTenantIdByCompanyId;
|
|
9
9
|
exports.getOnboardingTenantByTenantId = getOnboardingTenantByTenantId;
|
|
@@ -26,50 +26,77 @@ function getTenant(tenantState, companyState, tenantId) {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
function getTenantIdByCompanyId(tenantState, companyId) {
|
|
29
|
-
return Object.values(tenantState.tenantsById).find((tenant) => tenant.companyId === companyId)
|
|
29
|
+
return (Object.values(tenantState.tenantsById).find((tenant) => tenant.companyId === companyId) ??
|
|
30
|
+
Object.values(tenantState.tenantSummariesById).find((tenantSummary) => tenantSummary.companyId === companyId))?.tenantId;
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Every tenant in the list, most recently opened first. Roles are known only
|
|
34
|
+
* for tenants whose full record is loaded; the list itself carries none.
|
|
35
|
+
*/
|
|
36
|
+
function getTenantListEntriesByCheckInDate(tenantState) {
|
|
37
|
+
const entries = tenantState.tenantIds
|
|
38
|
+
.map((tenantId) => {
|
|
39
|
+
const tenant = tenantState.tenantsById[tenantId];
|
|
40
|
+
const tenantSummary = tenantState.tenantSummariesById[tenantId];
|
|
41
|
+
if (tenant != null) {
|
|
42
|
+
return {
|
|
43
|
+
companyId: tenant.companyId,
|
|
44
|
+
companyName: tenant.companyName,
|
|
45
|
+
tenantEmailDomain: tenant.tenantEmailDomain,
|
|
46
|
+
tenantId: tenant.tenantId,
|
|
47
|
+
userLastCheckInTime: tenant.userLastCheckInTime,
|
|
48
|
+
userRole: tenant.userRole,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return tenantSummary != null
|
|
52
|
+
? { ...tenantSummary, userRole: [] }
|
|
53
|
+
: undefined;
|
|
54
|
+
})
|
|
55
|
+
.filter((entry) => entry != null);
|
|
56
|
+
return (0, orderBy_1.default)(entries, (entry) => entry.userLastCheckInTime.valueOf(), 'desc');
|
|
40
57
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
companyName,
|
|
56
|
-
userRole,
|
|
57
|
-
companyLocaleInfo,
|
|
58
|
-
};
|
|
58
|
+
/**
|
|
59
|
+
* The selected tenant's full record. With no tenant selected, or one the user
|
|
60
|
+
* can no longer open, it is the most recently opened loaded tenant. A selected
|
|
61
|
+
* tenant that is in the list but not loaded yet reads as no tenant until its
|
|
62
|
+
* fetch lands, so nothing renders another tenant's record in its place.
|
|
63
|
+
*/
|
|
64
|
+
function getCurrentTenantView(tenantState, companyState) {
|
|
65
|
+
const { currentTenantId } = tenantState;
|
|
66
|
+
if (currentTenantId != null) {
|
|
67
|
+
const tenant = getTenant(tenantState, companyState, currentTenantId);
|
|
68
|
+
if (tenant != null ||
|
|
69
|
+
tenantState.tenantSummariesById[currentTenantId] != null) {
|
|
70
|
+
return tenant;
|
|
71
|
+
}
|
|
59
72
|
}
|
|
60
|
-
|
|
73
|
+
const mostRecentLoadedTenant = getTenantListEntriesByCheckInDate(tenantState).find((entry) => tenantState.tenantsById[entry.tenantId] != null);
|
|
74
|
+
return mostRecentLoadedTenant != null
|
|
75
|
+
? getTenant(tenantState, companyState, mostRecentLoadedTenant.tenantId)
|
|
76
|
+
: undefined;
|
|
77
|
+
}
|
|
78
|
+
/** Whether the tenant's full record is loaded, not just its list entry. */
|
|
79
|
+
const isTenantLoaded = (state, tenantId) => state.tenantState.tenantsById[tenantId] != null;
|
|
80
|
+
exports.isTenantLoaded = isTenantLoaded;
|
|
81
|
+
/**
|
|
82
|
+
* Whether the selected tenant's full record is loaded. Screens that act on
|
|
83
|
+
* roles or product settings wait for this rather than for either tenant fetch
|
|
84
|
+
* to complete: the tenants list alone carries neither.
|
|
85
|
+
*/
|
|
86
|
+
const isCurrentTenantLoaded = (state) => {
|
|
87
|
+
const { currentTenantId } = state.tenantState;
|
|
88
|
+
return currentTenantId != null && (0, exports.isTenantLoaded)(state, currentTenantId);
|
|
89
|
+
};
|
|
90
|
+
exports.isCurrentTenantLoaded = isCurrentTenantLoaded;
|
|
91
|
+
exports.getTenantBaseViewForTenantId = (0, toolkit_1.createSelector)((state) => state.tenantState, (state) => state.companyState, (_state, tenantId) => tenantId, (tenantState, companyState, tenantId) => {
|
|
92
|
+
const entry = getTenantListEntriesByCheckInDate(tenantState).find((listEntry) => listEntry.tenantId === tenantId);
|
|
93
|
+
return entry != null
|
|
94
|
+
? getTenantBaseViewForEntry(entry, companyState)
|
|
95
|
+
: undefined;
|
|
61
96
|
});
|
|
62
97
|
const getCurrentTenantHelper = (tenantState, companyState) => {
|
|
63
|
-
const {
|
|
64
|
-
|
|
65
|
-
if (currentTenantId != null) {
|
|
66
|
-
tenant = getTenant(tenantState, companyState, currentTenantId);
|
|
67
|
-
}
|
|
68
|
-
if (tenant == null && tenantIds.length > 0) {
|
|
69
|
-
const tenants = getTenantsByCheckInDate(tenantState, companyState);
|
|
70
|
-
tenant =
|
|
71
|
-
tenants.tenantsInOrder.length > 0 ? tenants.tenantsInOrder[0] : undefined;
|
|
72
|
-
}
|
|
98
|
+
const { currentTenantId, excludedResourcesByTenant, subscriptionSummaryByTenant, } = tenantState;
|
|
99
|
+
const tenant = getCurrentTenantView(tenantState, companyState);
|
|
73
100
|
let excludedResources = undefined;
|
|
74
101
|
if (tenant != null) {
|
|
75
102
|
excludedResources = excludedResourcesByTenant[tenant.tenantId];
|
|
@@ -130,9 +157,13 @@ const getCurrentTenantHelper = (tenantState, companyState) => {
|
|
|
130
157
|
exports.getCurrentTenant = (0, toolkit_1.createSelector)((state) => state.tenantState, (state) => state.companyState, (tenantState, companyState) => {
|
|
131
158
|
return getCurrentTenantHelper(tenantState, companyState);
|
|
132
159
|
});
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
160
|
+
/**
|
|
161
|
+
* The selected tenant's id as soon as it is chosen. Unlike `getCurrentTenant`,
|
|
162
|
+
* it is set before the tenant fetch lands (boot reads it from the cached
|
|
163
|
+
* tenant list).
|
|
164
|
+
*/
|
|
165
|
+
const getCurrentTenantId = (state) => state.tenantState.currentTenantId;
|
|
166
|
+
exports.getCurrentTenantId = getCurrentTenantId;
|
|
136
167
|
function getOnboardingTenantByTenantId(tenantState, tenantId) {
|
|
137
168
|
const tenant = tenantState.onboardingTenantsById[tenantId];
|
|
138
169
|
if (tenant != null) {
|
|
@@ -143,10 +174,7 @@ function getOnboardingTenantByTenantId(tenantState, tenantId) {
|
|
|
143
174
|
}
|
|
144
175
|
}
|
|
145
176
|
exports.getTenantBaseById = (0, toolkit_1.createSelector)((state) => state.tenantState, (state) => state.companyState, (tenantState, companyState) => {
|
|
146
|
-
return tenantState.
|
|
147
|
-
const tenant = tenantState.tenantsById[tenantId];
|
|
148
|
-
return getTenantBaseViewForTenant(tenant, companyState);
|
|
149
|
-
});
|
|
177
|
+
return getTenantListEntriesByCheckInDate(tenantState).map((entry) => getTenantBaseViewForEntry(entry, companyState));
|
|
150
178
|
});
|
|
151
179
|
exports.getTenantsBaseByCheckInDateSelector = (0, toolkit_1.createSelector)((state) => state.tenantState, (state) => state.companyState, (tenantState, companyState) => {
|
|
152
180
|
return getTenantsBaseByCheckInDate(tenantState, companyState);
|
|
@@ -178,16 +206,8 @@ const isTenantUsingZeniCOA = (currentTenant) => {
|
|
|
178
206
|
};
|
|
179
207
|
exports.isTenantUsingZeniCOA = isTenantUsingZeniCOA;
|
|
180
208
|
const getCurrentTenantExternalConnections = (tenantState, companyState) => {
|
|
181
|
-
const { externalConnectionsByTenant,
|
|
182
|
-
|
|
183
|
-
if (currentTenantId != null) {
|
|
184
|
-
tenant = getTenant(tenantState, companyState, currentTenantId);
|
|
185
|
-
}
|
|
186
|
-
if (tenant == null && tenantIds.length > 0) {
|
|
187
|
-
const tenants = getTenantsByCheckInDate(tenantState, companyState);
|
|
188
|
-
tenant =
|
|
189
|
-
tenants.tenantsInOrder.length > 0 ? tenants.tenantsInOrder[0] : undefined;
|
|
190
|
-
}
|
|
209
|
+
const { externalConnectionsByTenant, currentTenantId } = tenantState;
|
|
210
|
+
const tenant = getCurrentTenantView(tenantState, companyState);
|
|
191
211
|
let externalConnections = undefined;
|
|
192
212
|
if (tenant != null) {
|
|
193
213
|
externalConnections = externalConnectionsByTenant[tenant.tenantId];
|
|
@@ -202,58 +222,39 @@ exports.getCurrentTenantExternalConnections = getCurrentTenantExternalConnection
|
|
|
202
222
|
* Helpers
|
|
203
223
|
*/
|
|
204
224
|
function getTenantsBaseByCheckInDate(tenantState, companyState) {
|
|
205
|
-
const tenants = tenantState.tenantIds
|
|
206
|
-
.map((tenantId) => getTenant(tenantState, companyState, tenantId))
|
|
207
|
-
.filter((value) => value != null);
|
|
208
|
-
const tenantsOrdered = (0, orderBy_1.default)(tenants, (value) => value.userLastCheckInTime.valueOf(), 'desc');
|
|
209
|
-
const tenantsBaseOrdered = tenantsOrdered.map((tenant) => getTenantBaseViewForTenant(tenant, companyState));
|
|
210
225
|
return {
|
|
211
226
|
order: 'descending_last_check_in',
|
|
212
|
-
tenantsBaseInOrder:
|
|
227
|
+
tenantsBaseInOrder: getTenantListEntriesByCheckInDate(tenantState).map((entry) => getTenantBaseViewForEntry(entry, companyState)),
|
|
213
228
|
};
|
|
214
229
|
}
|
|
215
|
-
const
|
|
216
|
-
const
|
|
217
|
-
const companyId = tenant.companyId;
|
|
218
|
-
const companyName = companyState.companiesById[companyId]?.companyInfo.name;
|
|
219
|
-
const tenantName = tenant.companyName ?? companyName ?? tenant.tenantEmailDomain ?? '';
|
|
220
|
-
const tenantEmailDomain = tenant.tenantEmailDomain;
|
|
221
|
-
const userRole = tenant.userRole;
|
|
222
|
-
const companyLocaleInfo = companyState.companiesById[companyId]?.companyLocaleInfo;
|
|
230
|
+
const getTenantBaseViewForEntry = (entry, companyState) => {
|
|
231
|
+
const company = companyState.companiesById[entry.companyId];
|
|
223
232
|
return {
|
|
224
|
-
tenantId,
|
|
225
|
-
tenantName
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
233
|
+
tenantId: entry.tenantId,
|
|
234
|
+
tenantName: entry.companyName ??
|
|
235
|
+
company?.companyInfo.name ??
|
|
236
|
+
entry.tenantEmailDomain ??
|
|
237
|
+
'',
|
|
238
|
+
tenantEmailDomain: entry.tenantEmailDomain,
|
|
239
|
+
companyId: entry.companyId,
|
|
240
|
+
// Companies are loaded only for opened tenants; the list carries the name.
|
|
241
|
+
companyName: company?.companyInfo.name ?? entry.companyName,
|
|
242
|
+
userRole: entry.userRole,
|
|
243
|
+
companyLocaleInfo: company?.companyLocaleInfo,
|
|
231
244
|
};
|
|
232
245
|
};
|
|
233
246
|
function getTenantCoreDetailsByCheckInDate(tenantState, companyState) {
|
|
234
|
-
const tenants = tenantState.tenantIds
|
|
235
|
-
.map((tenantId) => getTenant(tenantState, companyState, tenantId))
|
|
236
|
-
.filter((value) => value != null);
|
|
237
|
-
const tenantsOrdered = (0, orderBy_1.default)(tenants, (value) => value.userLastCheckInTime.valueOf(), 'desc');
|
|
238
|
-
const tenantsCoreDetailsOrdered = tenantsOrdered.map((tenant) => getTenantCoreDetailsViewForTenant(tenant, companyState));
|
|
239
247
|
return {
|
|
240
248
|
order: 'descending_last_check_in',
|
|
241
|
-
tenantsCoreDetailsInOrder:
|
|
249
|
+
tenantsCoreDetailsInOrder: getTenantListEntriesByCheckInDate(tenantState).map((entry) => ({
|
|
250
|
+
tenantId: entry.tenantId,
|
|
251
|
+
tenantName: entry.companyName ??
|
|
252
|
+
companyState.companiesById[entry.companyId]?.companyInfo.name,
|
|
253
|
+
tenantEmailDomain: entry.tenantEmailDomain,
|
|
254
|
+
companyId: entry.companyId,
|
|
255
|
+
})),
|
|
242
256
|
};
|
|
243
257
|
}
|
|
244
|
-
const getTenantCoreDetailsViewForTenant = (tenant, companyState) => {
|
|
245
|
-
const tenantId = tenant.tenantId;
|
|
246
|
-
const companyId = tenant.companyId;
|
|
247
|
-
const companyName = companyState.companiesById[companyId]?.companyInfo.name;
|
|
248
|
-
const tenantName = tenant.companyName ?? companyName;
|
|
249
|
-
const tenantEmailDomain = tenant.tenantEmailDomain;
|
|
250
|
-
return {
|
|
251
|
-
tenantId,
|
|
252
|
-
tenantName,
|
|
253
|
-
tenantEmailDomain,
|
|
254
|
-
companyId,
|
|
255
|
-
};
|
|
256
|
-
};
|
|
257
258
|
const toTenantCoreDetailsView = (tenantsBaseView) => {
|
|
258
259
|
return tenantsBaseView.map(({ tenantId, tenantName, tenantEmailDomain, companyId }) => {
|
|
259
260
|
return {
|
|
@@ -46,7 +46,10 @@ export interface TenantState extends FetchedState {
|
|
|
46
46
|
summary?: SubscriptionSummary;
|
|
47
47
|
} | undefined>;
|
|
48
48
|
tenantIds: ID[];
|
|
49
|
+
/** Full records, loaded per tenant by the active-tenant fetch. */
|
|
49
50
|
tenantsById: Record<ID, Tenant>;
|
|
51
|
+
/** Every tenant the user can open, from the tenants list. */
|
|
52
|
+
tenantSummariesById: Record<ID, TenantSummary>;
|
|
50
53
|
verifyDeviceFetchState: FetchStateAndError;
|
|
51
54
|
accountLockTime?: ZeniDate;
|
|
52
55
|
accountUnlockTime?: ZeniDate;
|
|
@@ -58,6 +61,13 @@ export interface TenantState extends FetchedState {
|
|
|
58
61
|
sessionExpiresAt?: string;
|
|
59
62
|
twoFAPhoneNumber?: string;
|
|
60
63
|
}
|
|
64
|
+
export interface TenantSummary {
|
|
65
|
+
companyId: ID;
|
|
66
|
+
companyName: string;
|
|
67
|
+
tenantEmailDomain: string;
|
|
68
|
+
tenantId: ID;
|
|
69
|
+
userLastCheckInTime: ZeniDate;
|
|
70
|
+
}
|
|
61
71
|
export interface TenantProductSettings {
|
|
62
72
|
isBankingEnabled: boolean;
|
|
63
73
|
isBookkeepingEnabled: boolean;
|