@zeniai/client-epic-state 5.3.18 → 5.3.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/lib/commonStateTypes/coaBalance/coaBalance.d.ts +9 -0
  2. package/lib/commonStateTypes/coaBalance/coaBalance.js +11 -0
  3. package/lib/entity/tenant/epic/fetchAllTenantsEpic.d.ts +2 -4
  4. package/lib/entity/tenant/epic/fetchAllTenantsEpic.js +50 -42
  5. package/lib/entity/tenant/tenantPayload.d.ts +17 -1
  6. package/lib/entity/tenant/tenantReducer.d.ts +7 -2
  7. package/lib/entity/tenant/tenantReducer.js +48 -19
  8. package/lib/entity/tenant/tenantSelector.d.ts +26 -6
  9. package/lib/entity/tenant/tenantSelector.js +116 -93
  10. package/lib/entity/tenant/tenantState.d.ts +10 -0
  11. package/lib/epic.d.ts +2 -1
  12. package/lib/epic.js +3 -0
  13. package/lib/esm/commonStateTypes/coaBalance/coaBalance.js +10 -0
  14. package/lib/esm/entity/tenant/epic/fetchAllTenantsEpic.js +53 -45
  15. package/lib/esm/entity/tenant/tenantReducer.js +46 -17
  16. package/lib/esm/entity/tenant/tenantSelector.js +112 -92
  17. package/lib/esm/epic.js +4 -1
  18. package/lib/esm/index.js +7 -7
  19. package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +65 -3
  20. package/lib/esm/view/aiCfoView/aiCfoViewSelector.js +25 -0
  21. package/lib/esm/view/aiCfoView/epics/transcribeAudioEpic.js +60 -0
  22. package/lib/esm/view/balanceSheet/balanceSheetForTimeframeEpic.js +9 -4
  23. package/lib/esm/view/balanceSheet/balanceSheetReducer.js +2 -0
  24. package/lib/esm/view/cashFlow/cashFlowForTimeframeEpic.js +11 -5
  25. package/lib/esm/view/cashFlow/cashFlowReducer.js +2 -0
  26. package/lib/esm/view/dashboard/dashboardEpic.js +0 -4
  27. package/lib/esm/view/dashboard/dashboardSelector.js +2 -3
  28. package/lib/esm/view/financeStatement/financeStatementEpic.js +1 -5
  29. package/lib/esm/view/financeStatement/financeStatementSelector.js +18 -0
  30. package/lib/esm/view/people/peoplePageEpic.js +0 -4
  31. package/lib/esm/view/profitAndLoss/profitAndLossForTimeframeEpic.js +9 -4
  32. package/lib/esm/view/profitAndLoss/profitAndLossReducer.js +5 -1
  33. package/lib/esm/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.js +23 -3
  34. package/lib/esm/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.js +17 -4
  35. package/lib/esm/view/spendManagement/reimbursement/remiDetailView/epics/fetchRemiDetailEpic.js +1 -1
  36. package/lib/esm/view/transactionList/filterTransactionsByTimePeriod.js +18 -0
  37. package/lib/esm/view/transactionList/transactionListByAccountSelector.js +2 -1
  38. package/lib/esm/view/transactionList/transactionListByCategoryTypeSelector.js +2 -1
  39. package/lib/esm/view/transactionList/transactionListByClassSelector.js +2 -1
  40. package/lib/esm/view/transactionList/transactionListByProjectSelector.js +2 -1
  41. package/lib/index.d.ts +8 -8
  42. package/lib/index.js +56 -46
  43. package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +20 -0
  44. package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +2 -2
  45. package/lib/view/aiCfoView/aiCfoViewReducer.js +66 -4
  46. package/lib/view/aiCfoView/aiCfoViewSelector.d.ts +8 -1
  47. package/lib/view/aiCfoView/aiCfoViewSelector.js +27 -0
  48. package/lib/view/aiCfoView/aiCfoViewState.d.ts +9 -0
  49. package/lib/view/aiCfoView/epics/transcribeAudioEpic.d.ts +19 -0
  50. package/lib/view/aiCfoView/epics/transcribeAudioEpic.js +64 -0
  51. package/lib/view/balanceSheet/balanceSheetForTimeframeEpic.js +8 -3
  52. package/lib/view/balanceSheet/balanceSheetReducer.js +2 -0
  53. package/lib/view/balanceSheet/balanceSheetState.d.ts +2 -0
  54. package/lib/view/cashFlow/cashFlowForTimeframeEpic.js +10 -4
  55. package/lib/view/cashFlow/cashFlowReducer.js +2 -0
  56. package/lib/view/cashFlow/cashFlowState.d.ts +2 -0
  57. package/lib/view/dashboard/dashboardEpic.js +0 -4
  58. package/lib/view/dashboard/dashboardSelector.d.ts +0 -2
  59. package/lib/view/dashboard/dashboardSelector.js +1 -2
  60. package/lib/view/financeStatement/financeStatementEpic.js +1 -5
  61. package/lib/view/financeStatement/financeStatementSelector.d.ts +8 -0
  62. package/lib/view/financeStatement/financeStatementSelector.js +18 -0
  63. package/lib/view/people/peoplePageEpic.js +0 -4
  64. package/lib/view/profitAndLoss/profitAndLossForTimeframeEpic.js +8 -3
  65. package/lib/view/profitAndLoss/profitAndLossReducer.js +5 -1
  66. package/lib/view/profitAndLoss/profitAndLossState.d.ts +2 -1
  67. package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.d.ts +7 -2
  68. package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.js +24 -4
  69. package/lib/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.d.ts +7 -4
  70. package/lib/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.js +15 -1
  71. package/lib/view/spendManagement/reimbursement/remiDetailView/epics/fetchRemiDetailEpic.js +1 -1
  72. package/lib/view/transactionList/filterTransactionsByTimePeriod.d.ts +15 -0
  73. package/lib/view/transactionList/filterTransactionsByTimePeriod.js +22 -0
  74. package/lib/view/transactionList/transactionListByAccountSelector.js +2 -1
  75. package/lib/view/transactionList/transactionListByCategoryTypeSelector.js +2 -1
  76. package/lib/view/transactionList/transactionListByClassSelector.js +2 -1
  77. package/lib/view/transactionList/transactionListByProjectSelector.js +2 -1
  78. package/package.json +1 -1
@@ -29,6 +29,15 @@ export type COABalanceTimeFrame = NonNullable<ReturnType<typeof toCOABalanceTime
29
29
  export type COABalanceMonthQuarterTimeframe = Extract<COABalanceTimeFrame, 'month' | 'quarter'>;
30
30
  export type COABalanceMonthQuarterYearTimeframe = Exclude<COABalanceTimeFrame, 'free_range' | 'week'>;
31
31
  export type FetchStateByTimeframe = Record<COABalanceMonthQuarterYearTimeframe, FetchStateAndError>;
32
+ /**
33
+ * Custom start/end (YYYY-MM-DD) sent with the last fetch of each timeframe. A timeframe is missing
34
+ * when its last fetch used the default periods, so the stored balances cover full periods.
35
+ */
36
+ export type CustomDateRangeByTimeframe = Partial<Record<COABalanceMonthQuarterYearTimeframe, {
37
+ endDate: string;
38
+ startDate: string;
39
+ }>>;
40
+ export declare function withFetchedCustomDateRange(current: CustomDateRangeByTimeframe | undefined, timeframe: COABalanceMonthQuarterYearTimeframe, startDate: string | undefined, endDate: string | undefined): CustomDateRangeByTimeframe | undefined;
32
41
  export interface COABalanceGroupedByPeriod {
33
42
  months?: COABalance[];
34
43
  quarters?: COABalance[];
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toCOABalanceTimeframe = void 0;
4
+ exports.withFetchedCustomDateRange = withFetchedCustomDateRange;
4
5
  const stringToUnion_1 = require("../stringToUnion");
5
6
  /**
6
7
  * COA balance time frame
@@ -19,3 +20,13 @@ const ALL_COA_BALANCE_TIMEFRAME = [
19
20
  ];
20
21
  const toCOABalanceTimeframe = (v) => (0, stringToUnion_1.stringToUnionStrict)(v?.toLocaleLowerCase() ?? '', ALL_COA_BALANCE_TIMEFRAME);
21
22
  exports.toCOABalanceTimeframe = toCOABalanceTimeframe;
23
+ function withFetchedCustomDateRange(current, timeframe, startDate, endDate) {
24
+ const next = { ...current };
25
+ if (startDate != null && endDate != null) {
26
+ next[timeframe] = { startDate, endDate };
27
+ }
28
+ else {
29
+ delete next[timeframe];
30
+ }
31
+ return Object.keys(next).length > 0 ? next : undefined;
32
+ }
@@ -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, updateTenantsFailure, updateTenantsSuccess } from '../tenantReducer';
11
- export type ActionType = ReturnType<typeof fetchAllTenants> | ReturnType<typeof updateCompanies> | ReturnType<typeof updateTenantsSuccess> | ReturnType<typeof initializeSelectedPeriodForTenants> | ReturnType<typeof updateTenantsFailure>;
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,68 @@ 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 fetchTenants$ = (0, rxjs_1.defer)(() => zeniAPI.getJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/users/${action.payload.userId}/tenants?query=${encodeURIComponent(JSON.stringify(queryParam))}`, Object.assign({ 'zeni-user-id': action.payload.userId }, { 'zeni-tenant-id': '' }, action.payload.zeniSessionId != null
19
- ? { 'zeni-session-id': action.payload.zeniSessionId }
20
- : {}))).pipe((0, operators_1.mergeMap)((response) => {
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
+ // The wait is deliberately not scoped to the landing tenant:
58
+ // fetchActiveTenantEpic switches to the latest request, so another
59
+ // tenant's fetch dispatched meanwhile cancels this one and its answer
60
+ // is the only one that will come. Either way a full current tenant is
61
+ // in once any active-tenant fetch settles.
62
+ return (0, rxjs_1.merge)(actions$.pipe((0, operators_1.filter)((landingAction) => tenantReducer_1.updateTenantSuccess.match(landingAction) ||
63
+ 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
64
  }), (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
65
  JSON.stringify(error))))));
58
66
  const sessionEndpointsLoader = (0, sessionEndpointsLoader_1.getSessionEndpointsLoader)();
59
67
  if (sessionEndpointsLoader == null) {
60
68
  return fetchTenants$;
61
69
  }
62
- return (0, rxjs_1.defer)(() => (0, rxjs_1.from)(sessionEndpointsLoader(action.payload.userId, action.payload.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: ' +
70
+ 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
71
  JSON.stringify(error))))));
64
72
  }));
65
73
  };
@@ -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,12 @@ 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>, updateTenantsSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<TenantsData, "tenant/updateTenantsSuccess">, updateTenantsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "tenant/updateTenantsFailure">, fetchActiveTenant: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[userId: string, tenantId: string, zeniSessionId?: string | undefined], {
43
+ }, "tenant/fetchAllTenants", never, never>, updateTenantSummariesSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<TenantSummaryPayload[], "tenant/updateTenantSummariesSuccess">, seedTenantSummary: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
44
+ companyId: ID;
45
+ tenantEmailDomain: string;
46
+ tenantId: ID;
47
+ tenantName?: string;
48
+ }, "tenant/seedTenantSummary">, updateTenantsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "tenant/updateTenantsFailure">, fetchActiveTenant: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[userId: string, tenantId: string, zeniSessionId?: string | undefined], {
44
49
  userId: string;
45
50
  tenantId: string;
46
51
  zeniSessionId: string | undefined;
@@ -4,8 +4,8 @@ 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.updateTenantsSuccess = exports.fetchAllTenants = exports.updateTenants = exports.initialState = exports.toExternalIntegrationType = void 0;
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;
7
+ 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.seedTenantSummary = exports.updateTenantSummariesSuccess = exports.fetchAllTenants = exports.updateTenants = exports.initialState = exports.toExternalIntegrationType = void 0;
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 = exports.updateSubscriptionSummaryForTenantSuccess = void 0;
9
9
  exports.mapCapitalizableAccountsPayload = mapCapitalizableAccountsPayload;
10
10
  exports.mapConnectionsPayloadToState = mapConnectionsPayloadToState;
11
11
  const toolkit_1 = require("@reduxjs/toolkit");
@@ -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
- updateTenantsSuccess(draft, action) {
122
- const { tenants, user } = action.payload;
122
+ updateTenantSummariesSuccess(draft, action) {
123
123
  draft.fetchState = 'Completed';
124
124
  draft.error = undefined;
125
- const [tenantsbyId, tenantIds, firstUser] = mapTenantsPayloadToState(tenants, user);
126
- tenantIds.forEach((tenantId) => {
127
- const existingTenant = draft.tenantsById[tenantId];
128
- tenantsbyId[tenantId] = applyTreasuryPromoUserFieldsFromPayload(existingTenant, tenantsbyId[tenantId], user);
129
- if (existingTenant != null) {
130
- tenantsbyId[tenantId].capitalizableAccountOverrides =
131
- tenantsbyId[tenantId].capitalizableAccountOverrides ??
132
- existingTenant.capitalizableAccountOverrides;
133
- tenantsbyId[tenantId].capitalizationOnboardingDismissedAccounts =
134
- tenantsbyId[tenantId].capitalizationOnboardingDismissedAccounts ??
135
- existingTenant.capitalizationOnboardingDismissedAccounts;
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 = 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;
@@ -282,6 +283,24 @@ const tenant = (0, toolkit_1.createSlice)({
282
283
  updateCurrentTenant(draft, action) {
283
284
  draft.currentTenantId = action.payload;
284
285
  },
286
+ /**
287
+ * Records a tenant's ids known before the tenants list loads (the app's
288
+ * cached tenant list), so `getCurrentTenantIds` has them from the first
289
+ * render. The list is not changed and its own entries win.
290
+ */
291
+ seedTenantSummary(draft, action) {
292
+ const { companyId, tenantEmailDomain, tenantId, tenantName } = action.payload;
293
+ if (draft.tenantSummariesById[tenantId] == null) {
294
+ draft.tenantSummariesById[tenantId] = {
295
+ companyId,
296
+ companyName: tenantName ?? '',
297
+ tenantEmailDomain,
298
+ tenantId,
299
+ // Not in `tenantIds`, so it is never ordered or listed.
300
+ userLastCheckInTime: (0, zeniDayJS_1.date)('1970-01-01'),
301
+ };
302
+ }
303
+ },
285
304
  fetchExcludedResources: {
286
305
  prepare(userId, tenantId) {
287
306
  return { payload: { userId, tenantId } };
@@ -945,7 +964,7 @@ const tenant = (0, toolkit_1.createSlice)({
945
964
  });
946
965
  },
947
966
  });
948
- _a = tenant.actions, exports.updateTenants = _a.updateTenants, exports.fetchAllTenants = _a.fetchAllTenants, exports.updateTenantsSuccess = _a.updateTenantsSuccess, 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;
967
+ _a = tenant.actions, exports.updateTenants = _a.updateTenants, exports.fetchAllTenants = _a.fetchAllTenants, exports.updateTenantSummariesSuccess = _a.updateTenantSummariesSuccess, exports.seedTenantSummary = _a.seedTenantSummary, 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
968
  exports.default = tenant.reducer;
950
969
  /**
951
970
  * Applies treasury promo user fields from the tenants API user block when present.
@@ -987,6 +1006,16 @@ function mapTenantsPayloadToState(tenantsPayload, userTenantPayload) {
987
1006
  const firstUser = mapTenantPayloadToUser(tenantsPayload[0]);
988
1007
  return [tenantsById, tenantIds, firstUser];
989
1008
  }
1009
+ function mapTenantSummaryPayloadToTenantSummary(payload) {
1010
+ return {
1011
+ companyId: payload.company_id,
1012
+ companyName: payload.company_name,
1013
+ tenantEmailDomain: payload.tenant_email_domain,
1014
+ tenantId: payload.tenant_id,
1015
+ // A tenant never opened sorts last, as in `mapTenantPayloadToTenant`.
1016
+ userLastCheckInTime: (0, zeniDayJS_1.date)(payload.user_last_check_in_time_into_tenant ?? '1970-01-01'),
1017
+ };
1018
+ }
990
1019
  function mapTenantPayloadToTenant(payload, userTenantPayload) {
991
1020
  const tenant = {
992
1021
  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
- declare function getTenantsByCheckInDate(tenantState: TenantState, companyState: CompanyState): {
26
- order: "descending_last_check_in";
27
- tenantsInOrder: TenantView[];
28
- };
29
- export type TenantsOrdered = ReturnType<typeof getTenantsByCheckInDate>;
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,24 @@ 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
- export declare const getTenantsByCheckInDateSelector: (state: RootState) => TenantsOrdered;
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;
86
+ export interface CurrentTenantIds {
87
+ companyId: ID | undefined;
88
+ tenantId: ID | undefined;
89
+ }
90
+ /**
91
+ * The current tenant's ids before its record loads: from the record when
92
+ * loaded, otherwise from the tenants list or the entry seeded from the app's
93
+ * cache (`seedTenantSummary`). Providers keyed on them (Statsig, collaboration)
94
+ * then mount once with the final ids, on a reload and on a tenant switch.
95
+ * The result keeps its identity while the ids are unchanged.
96
+ */
97
+ export declare const getCurrentTenantIds: (state: RootState) => CurrentTenantIds;
78
98
  export declare function getOnboardingTenantByTenantId(tenantState: TenantState, tenantId: ID): Tenant | undefined;
79
99
  export declare const getTenantBaseById: (state: RootState) => TenantBaseView[];
80
100
  export declare const getTenantsBaseByCheckInDateSelector: (state: RootState) => TenantsBaseOrdered;