@eintrek/erp-shell 0.1.60 → 0.1.61
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/dist/http/axios.d.ts +8 -0
- package/dist/http/organization-fallback.d.ts +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.esm.js +249 -8
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +257 -7
- package/dist/index.js.map +1 -1
- package/dist/navigation/url-org-gate.d.ts +22 -0
- package/dist/organization/active-organization.d.ts +50 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/http/axios.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
import { AxiosInstance } from "axios";
|
|
2
|
+
declare module "axios" {
|
|
3
|
+
interface AxiosRequestConfig {
|
|
4
|
+
/** Send this request without X-Organization-ID. */
|
|
5
|
+
erpWithoutOrganization?: boolean;
|
|
6
|
+
/** Send this request for this organisation, whatever the tab has active. */
|
|
7
|
+
erpOrganizationId?: string;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
2
10
|
declare const instance: AxiosInstance;
|
|
3
11
|
export default instance;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function retryWithStoredOrganizations<T>(config: Record<string, unknown> | undefined, status: number | undefined, send: (config: Record<string, unknown>) => Promise<T>): Promise<T | undefined>;
|
package/dist/index.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export { OrganizationSwitcher, type OrganizationSwitcherProps, type Organization
|
|
|
23
23
|
export { SidebarHeader } from "./navigation/sidebar-header";
|
|
24
24
|
export { AppSidebar, type AppSidebarProps } from "./navigation/app-sidebar";
|
|
25
25
|
export { AppLayoutShell, type AppLayoutShellProps, type AppLayoutShellOrganization, } from "./navigation/app-layout-shell";
|
|
26
|
-
export { resolveUrlOrgGate, findOrganizationForCode, type UrlOrgGate, type UrlOrgGateInput, type OrganizationsStatus, } from "./navigation/url-org-gate";
|
|
26
|
+
export { resolveUrlOrgGate, findOrganizationForCode, resolveStaleOrganization, type StaleOrganizationRecovery, type UrlOrgGate, type UrlOrgGateInput, type OrganizationsStatus, } from "./navigation/url-org-gate";
|
|
27
27
|
export { type ShellChrome, type WorkspaceHeaderTone, WORKSPACE_HEADER_VARS, WORKSPACE_LIGHT_HEADER_VARS, } from "./navigation/chrome";
|
|
28
28
|
export { WorkspaceBrand, type WorkspaceBrandProps } from "./navigation/workspace-brand";
|
|
29
29
|
export { SidebarHelpCard, SidebarHelpLink, type SidebarHelpCardProps, type SidebarHelpLinkProps, } from "./navigation/sidebar-help-card";
|
|
@@ -54,6 +54,7 @@ export { unwrapApiResponse } from "./http/unwrap";
|
|
|
54
54
|
export { getAccessToken, clearAccessTokenCache, } from "./http/auth-token-manager";
|
|
55
55
|
export { runGlobalRequestPrecheck } from "./http/request-precheck";
|
|
56
56
|
export { getOrganizationId, setOrganizationId, clearOrganizationId, } from "./organization/organization-id";
|
|
57
|
-
export { getRequestOrganizationId, getTabOrganizationId, setTabOrganizationId, } from "./organization/active-organization";
|
|
57
|
+
export { getRequestOrganizationId, getTabOrganizationId, setTabOrganizationId, setKnownOrganizationIds, isKnownStaleOrganizationId, withoutOrganization, WITHOUT_ORGANIZATION_FLAG, FOR_ORGANIZATION_FIELD, getStoredOrganizationIds, clearStoredOrganization, } from "./organization/active-organization";
|
|
58
|
+
export { retryWithStoredOrganizations } from "./http/organization-fallback";
|
|
58
59
|
export declare const updateOrganizationId: (organizationId: string | null) => void;
|
|
59
60
|
export declare const getAxiosErrorMessage: (error: unknown) => string;
|
package/dist/index.esm.js
CHANGED
|
@@ -305,20 +305,154 @@ function readOrganizationStorage() {
|
|
|
305
305
|
return null;
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
|
+
/**
|
|
309
|
+
* The organisations the signed-in user belongs to, once their list has
|
|
310
|
+
* loaded (AppLayoutShell reports it); null until then.
|
|
311
|
+
*/
|
|
312
|
+
let knownOrganizationIds = null;
|
|
313
|
+
/**
|
|
314
|
+
* Record the user's organisations (browser only). From then on a stored or
|
|
315
|
+
* tab organisation that is not among them loses to one that is: a browser
|
|
316
|
+
* that still remembers a deleted organisation — or one the user has left —
|
|
317
|
+
* must not keep sending it while the cookie names a good one.
|
|
318
|
+
*/
|
|
319
|
+
function setKnownOrganizationIds(ids) {
|
|
320
|
+
if (!isBrowser$1())
|
|
321
|
+
return;
|
|
322
|
+
if (ids === null) {
|
|
323
|
+
knownOrganizationIds = null;
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
const set = new Set();
|
|
327
|
+
for (const id of ids) {
|
|
328
|
+
const value = normalise(id);
|
|
329
|
+
if (value)
|
|
330
|
+
set.add(value);
|
|
331
|
+
}
|
|
332
|
+
knownOrganizationIds = set;
|
|
333
|
+
}
|
|
334
|
+
/** Whether the loaded list says the user is NOT a member of `id`. */
|
|
335
|
+
function isKnownStaleOrganizationId(id) {
|
|
336
|
+
const value = normalise(id);
|
|
337
|
+
return (value !== null &&
|
|
338
|
+
knownOrganizationIds !== null &&
|
|
339
|
+
!knownOrganizationIds.has(value));
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Marks a request that must not carry X-Organization-ID: the user's own list
|
|
343
|
+
* of organisations is how a stale organisation id is found out, so it cannot
|
|
344
|
+
* depend on one. An app's interceptor honours it by passing the request's
|
|
345
|
+
* config to getRequestOrganizationId(config).
|
|
346
|
+
*
|
|
347
|
+
* axiosInstance.get("/organizations", withoutOrganization({ params }))
|
|
348
|
+
*/
|
|
349
|
+
const WITHOUT_ORGANIZATION_FLAG = "erpWithoutOrganization";
|
|
350
|
+
function withoutOrganization(config) {
|
|
351
|
+
return { ...(config ?? {}), [WITHOUT_ORGANIZATION_FLAG]: true };
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Marks a request for one particular organisation, whatever this tab has
|
|
355
|
+
* active. Used to retry the organisation list under each stored id when an
|
|
356
|
+
* API refuses it without one (see http/organization-fallback.ts).
|
|
357
|
+
*/
|
|
358
|
+
const FOR_ORGANIZATION_FIELD = "erpOrganizationId";
|
|
359
|
+
function isWithoutOrganization(config) {
|
|
360
|
+
return (!!config &&
|
|
361
|
+
typeof config === "object" &&
|
|
362
|
+
config[WITHOUT_ORGANIZATION_FLAG] === true);
|
|
363
|
+
}
|
|
364
|
+
function explicitOrganization(config) {
|
|
365
|
+
if (!config || typeof config !== "object")
|
|
366
|
+
return null;
|
|
367
|
+
const value = config[FOR_ORGANIZATION_FIELD];
|
|
368
|
+
return typeof value === "string" || typeof value === "number"
|
|
369
|
+
? normalise(value)
|
|
370
|
+
: null;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Every organisation id this browser has stored for the tab — the tab's
|
|
374
|
+
* own, localStorage, the cookie — distinct, in that order.
|
|
375
|
+
*/
|
|
376
|
+
function getStoredOrganizationIds() {
|
|
377
|
+
const ids = [
|
|
378
|
+
getTabOrganizationId(),
|
|
379
|
+
readOrganizationStorage(),
|
|
380
|
+
readOrganizationCookie(),
|
|
381
|
+
].filter((id) => id !== null);
|
|
382
|
+
return [...new Set(ids)];
|
|
383
|
+
}
|
|
308
384
|
/**
|
|
309
385
|
* The organisation a request from this tab belongs to: the tab's own, then
|
|
310
386
|
* localStorage, then the cookie. Use it for the X-Organization-ID header —
|
|
311
387
|
* and read it before any `await` in the interceptor, so the header names the
|
|
312
388
|
* organisation that was active when the request was made.
|
|
313
389
|
*
|
|
390
|
+
* Pass the request's config: a request marked withoutOrganization() gets
|
|
391
|
+
* null, so no header.
|
|
392
|
+
*
|
|
314
393
|
* localStorage before the cookie: setOrganizationId writes localStorage
|
|
315
394
|
* synchronously and then awaits a server action for the cookie, so during
|
|
316
395
|
* that round trip the cookie still names the previous organisation.
|
|
396
|
+
*
|
|
397
|
+
* Once the user's organisations are known (setKnownOrganizationIds), the
|
|
398
|
+
* first of those that is one of them wins: 0.1.60 let a deleted
|
|
399
|
+
* organisation's id left in localStorage beat a valid cookie, and every
|
|
400
|
+
* request — the organisation list included — was refused. If none is a
|
|
401
|
+
* member the first is still sent, as before: the list may simply be behind
|
|
402
|
+
* (an organisation created a moment ago).
|
|
403
|
+
*/
|
|
404
|
+
function getRequestOrganizationId(config) {
|
|
405
|
+
const explicit = explicitOrganization(config);
|
|
406
|
+
if (explicit)
|
|
407
|
+
return explicit;
|
|
408
|
+
if (isWithoutOrganization(config))
|
|
409
|
+
return null;
|
|
410
|
+
const candidates = [
|
|
411
|
+
getTabOrganizationId(),
|
|
412
|
+
readOrganizationStorage(),
|
|
413
|
+
readOrganizationCookie(),
|
|
414
|
+
];
|
|
415
|
+
if (knownOrganizationIds !== null) {
|
|
416
|
+
const member = candidates.find(id => id !== null && knownOrganizationIds.has(id));
|
|
417
|
+
if (member)
|
|
418
|
+
return member;
|
|
419
|
+
}
|
|
420
|
+
return candidates.find(id => id !== null) ?? null;
|
|
421
|
+
}
|
|
422
|
+
function expireOrganizationCookie() {
|
|
423
|
+
// The cookie is set by the host's server action, host-only or on a parent
|
|
424
|
+
// domain (AUTH_COOKIE_DOMAIN, e.g. .antniti.com). The browser does not say
|
|
425
|
+
// which, so expire it on the host and on every parent domain.
|
|
426
|
+
const base = `${ORGANIZATION_ID_KEY}=; Max-Age=0; path=/; SameSite=Lax`;
|
|
427
|
+
try {
|
|
428
|
+
document.cookie = base;
|
|
429
|
+
const labels = window.location.hostname.split(".");
|
|
430
|
+
for (let i = 0; i < labels.length - 1; i++) {
|
|
431
|
+
document.cookie = `${base}; domain=.${labels.slice(i).join(".")}`;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
catch {
|
|
435
|
+
// Cookies unavailable: nothing to clear.
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Forget the active organisation everywhere this browser keeps it: the tab,
|
|
440
|
+
* localStorage and the `erp.organizationId` cookie. Call on sign-out, so the
|
|
441
|
+
* next person to sign in on this browser does not start in the previous
|
|
442
|
+
* person's organisation.
|
|
317
443
|
*/
|
|
318
|
-
function
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
444
|
+
function clearStoredOrganization() {
|
|
445
|
+
if (!isBrowser$1())
|
|
446
|
+
return;
|
|
447
|
+
tabOrganizationId = null;
|
|
448
|
+
knownOrganizationIds = null;
|
|
449
|
+
try {
|
|
450
|
+
localStorage.removeItem(ORGANIZATION_ID_KEY);
|
|
451
|
+
}
|
|
452
|
+
catch {
|
|
453
|
+
// Storage unavailable: nothing to clear.
|
|
454
|
+
}
|
|
455
|
+
expireOrganizationCookie();
|
|
322
456
|
}
|
|
323
457
|
|
|
324
458
|
const SELECTED_ORG_STORAGE_KEY = "erp.organizationId";
|
|
@@ -1412,6 +1546,44 @@ const runGlobalRequestPrecheck = (config) => {
|
|
|
1412
1546
|
return validateGoodsReceiptChecks(config.data);
|
|
1413
1547
|
};
|
|
1414
1548
|
|
|
1549
|
+
/**
|
|
1550
|
+
* The organisation list is asked for without an organisation (see
|
|
1551
|
+
* withoutOrganization), but some APIs still refuse it without one: Peoplx's
|
|
1552
|
+
* GET /organizations sits behind its module.hr plan gate, which answers 400
|
|
1553
|
+
* "organization context required" to no header and 403 to an organisation
|
|
1554
|
+
* that does not exist. Until those routes stop needing one, a refused list is
|
|
1555
|
+
* asked again under each organisation this browser has stored — the tab's,
|
|
1556
|
+
* localStorage's, the cookie's — so one good id among stale ones still gets
|
|
1557
|
+
* the user their list, and with it the way back to a working organisation.
|
|
1558
|
+
*
|
|
1559
|
+
* `send` re-sends the request (an axios instance call). Returns the first
|
|
1560
|
+
* answer that succeeds, or undefined when none did or the request is not a
|
|
1561
|
+
* refused organisation-less one. Each retry is marked, so it never retries
|
|
1562
|
+
* itself.
|
|
1563
|
+
*/
|
|
1564
|
+
const RETRIED = "_erpOrganizationFallback";
|
|
1565
|
+
async function retryWithStoredOrganizations(config, status, send) {
|
|
1566
|
+
if (!config ||
|
|
1567
|
+
config[WITHOUT_ORGANIZATION_FLAG] !== true ||
|
|
1568
|
+
config[RETRIED] === true ||
|
|
1569
|
+
(status !== 400 && status !== 403)) {
|
|
1570
|
+
return undefined;
|
|
1571
|
+
}
|
|
1572
|
+
for (const id of getStoredOrganizationIds()) {
|
|
1573
|
+
try {
|
|
1574
|
+
return await send({
|
|
1575
|
+
...config,
|
|
1576
|
+
[RETRIED]: true,
|
|
1577
|
+
[FOR_ORGANIZATION_FIELD]: id,
|
|
1578
|
+
});
|
|
1579
|
+
}
|
|
1580
|
+
catch {
|
|
1581
|
+
// That one was refused too; try the next.
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
return undefined;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1415
1587
|
const isBrowser = () => typeof window !== "undefined";
|
|
1416
1588
|
const isAuthEndpoint = (url) => !!url && url.includes("/api/auth/");
|
|
1417
1589
|
const isAuthPage = () => isBrowser() && window.location.pathname.startsWith("/auth/");
|
|
@@ -1420,7 +1592,7 @@ const redirectToLogout = async () => {
|
|
|
1420
1592
|
return;
|
|
1421
1593
|
localStorage.clear();
|
|
1422
1594
|
sessionStorage.clear();
|
|
1423
|
-
|
|
1595
|
+
clearStoredOrganization();
|
|
1424
1596
|
clearAccessTokenCache();
|
|
1425
1597
|
await signOut({ callbackUrl: "/auth/signin" });
|
|
1426
1598
|
};
|
|
@@ -1452,7 +1624,7 @@ instance.interceptors.request.use(async (config) => {
|
|
|
1452
1624
|
// Read before the token await: the header must name the organisation that
|
|
1453
1625
|
// was active when the request was made (and under which its query is
|
|
1454
1626
|
// cached), not whatever is active once the token resolves.
|
|
1455
|
-
const organizationId = getRequestOrganizationId();
|
|
1627
|
+
const organizationId = getRequestOrganizationId(config);
|
|
1456
1628
|
const token = await getAccessToken(false);
|
|
1457
1629
|
if (token) {
|
|
1458
1630
|
config.headers.Authorization = `Bearer ${token}`;
|
|
@@ -1512,6 +1684,9 @@ instance.interceptors.response.use(response => {
|
|
|
1512
1684
|
window.dispatchEvent(new CustomEvent("erp:employee-record-required"));
|
|
1513
1685
|
}
|
|
1514
1686
|
}
|
|
1687
|
+
const listed = await retryWithStoredOrganizations(originalRequest, error.response?.status, config => instance(config));
|
|
1688
|
+
if (listed !== undefined)
|
|
1689
|
+
return listed;
|
|
1515
1690
|
return Promise.reject(toApiError(error));
|
|
1516
1691
|
});
|
|
1517
1692
|
|
|
@@ -1538,7 +1713,7 @@ function platformApiBase(app) {
|
|
|
1538
1713
|
* This package's version, attached to help messages so the back office can
|
|
1539
1714
|
* tell which shell a report came from. Keep in step with package.json.
|
|
1540
1715
|
*/
|
|
1541
|
-
const SHELL_VERSION = "0.1.
|
|
1716
|
+
const SHELL_VERSION = "0.1.61";
|
|
1542
1717
|
|
|
1543
1718
|
const HELP_APP_LABEL = {
|
|
1544
1719
|
platform: "แพลตฟอร์ม",
|
|
@@ -1861,6 +2036,9 @@ function NavUser({ organization, avatarSrc, profileHref, selectOrganizationHref
|
|
|
1861
2036
|
};
|
|
1862
2037
|
const handleSignOut = async () => {
|
|
1863
2038
|
setIsSigningOut(true);
|
|
2039
|
+
// The next person to sign in on this browser must not start in this
|
|
2040
|
+
// person's organisation: forget it in the tab, localStorage and cookie.
|
|
2041
|
+
clearStoredOrganization();
|
|
1864
2042
|
try {
|
|
1865
2043
|
await signOut({ callbackUrl: signInRedirectHref, redirect: true });
|
|
1866
2044
|
}
|
|
@@ -3254,6 +3432,31 @@ function resolveUrlOrgGate({ code, organizations, organizationsStatus, organizat
|
|
|
3254
3432
|
return { state: "unverified" };
|
|
3255
3433
|
}
|
|
3256
3434
|
}
|
|
3435
|
+
function resolveStaleOrganization({ code, organizations, organizationsStatus, organizationId, }) {
|
|
3436
|
+
const status = organizationsStatus ?? (organizations.length > 0 ? "success" : undefined);
|
|
3437
|
+
if (status !== "success")
|
|
3438
|
+
return { action: "none" };
|
|
3439
|
+
const activeId = organizationId === null || organizationId === undefined
|
|
3440
|
+
? ""
|
|
3441
|
+
: String(organizationId).trim();
|
|
3442
|
+
if (activeId === "")
|
|
3443
|
+
return { action: "none" };
|
|
3444
|
+
if (organizations.some(org => String(org.id) === activeId)) {
|
|
3445
|
+
return { action: "none" };
|
|
3446
|
+
}
|
|
3447
|
+
const urlOrg = findOrganizationForCode(code, organizations);
|
|
3448
|
+
if (urlOrg) {
|
|
3449
|
+
return { action: "use", targetId: String(urlOrg.id), fromUrl: true };
|
|
3450
|
+
}
|
|
3451
|
+
if (organizations.length === 1) {
|
|
3452
|
+
return {
|
|
3453
|
+
action: "use",
|
|
3454
|
+
targetId: String(organizations[0].id),
|
|
3455
|
+
fromUrl: false,
|
|
3456
|
+
};
|
|
3457
|
+
}
|
|
3458
|
+
return { action: "forget" };
|
|
3459
|
+
}
|
|
3257
3460
|
|
|
3258
3461
|
/**
|
|
3259
3462
|
* Top-level app chrome: sticky header, sidebar slot, content gutter and the
|
|
@@ -3315,6 +3518,44 @@ function AppLayoutShell({ children, sidebar, loadingComponent, breadcrumb, permi
|
|
|
3315
3518
|
requestedSwitchRef.current = switchTargetId;
|
|
3316
3519
|
void setOrganizationId(switchTargetId);
|
|
3317
3520
|
}, [switchTargetId, setOrganizationId]);
|
|
3521
|
+
// Once the user's organisations are known, requests prefer a stored
|
|
3522
|
+
// organisation that is one of them (getRequestOrganizationId).
|
|
3523
|
+
const organizationsLoaded = (organizationsStatus ??
|
|
3524
|
+
(organizations.length > 0 ? "success" : undefined)) === "success";
|
|
3525
|
+
useEffect(() => {
|
|
3526
|
+
if (organizationsLoaded) {
|
|
3527
|
+
setKnownOrganizationIds(organizations.map(org => org.id));
|
|
3528
|
+
}
|
|
3529
|
+
}, [organizationsLoaded, organizations]);
|
|
3530
|
+
// An active organisation that is not one of the user's — deleted, or left —
|
|
3531
|
+
// is replaced, so it stops being sent with every request. The URL's
|
|
3532
|
+
// organisation, when the user is a member, is the gate's switch above;
|
|
3533
|
+
// otherwise the user's only organisation, or none (they pick one: the
|
|
3534
|
+
// refusal below offers it, and a path without a code goes to the picker).
|
|
3535
|
+
// Once per stale id and target, so a setter that does not take cannot loop.
|
|
3536
|
+
const staleRecovery = resolveStaleOrganization({
|
|
3537
|
+
code,
|
|
3538
|
+
organizations,
|
|
3539
|
+
organizationsStatus,
|
|
3540
|
+
organizationId,
|
|
3541
|
+
});
|
|
3542
|
+
const staleRecoveryTarget = staleRecovery.action === "forget"
|
|
3543
|
+
? null
|
|
3544
|
+
: staleRecovery.action === "use" && !staleRecovery.fromUrl
|
|
3545
|
+
? staleRecovery.targetId
|
|
3546
|
+
: undefined;
|
|
3547
|
+
const staleRecoveryKey = staleRecoveryTarget === undefined
|
|
3548
|
+
? null
|
|
3549
|
+
: `${String(organizationId)}>${staleRecoveryTarget ?? ""}`;
|
|
3550
|
+
const handledStaleRecoveryRef = useRef(null);
|
|
3551
|
+
useEffect(() => {
|
|
3552
|
+
if (staleRecoveryKey === null || staleRecoveryTarget === undefined)
|
|
3553
|
+
return;
|
|
3554
|
+
if (handledStaleRecoveryRef.current === staleRecoveryKey)
|
|
3555
|
+
return;
|
|
3556
|
+
handledStaleRecoveryRef.current = staleRecoveryKey;
|
|
3557
|
+
void setOrganizationId(staleRecoveryTarget);
|
|
3558
|
+
}, [staleRecoveryKey, staleRecoveryTarget, setOrganizationId]);
|
|
3318
3559
|
// Key for the content subtree. It exists so switching organizations throws
|
|
3319
3560
|
// away the previous org's component state — but it must react ONLY to a real
|
|
3320
3561
|
// switch. organizationId legitimately passes through null while the context
|
|
@@ -4025,5 +4266,5 @@ const getAxiosErrorMessage = (error) => {
|
|
|
4025
4266
|
return String(error);
|
|
4026
4267
|
};
|
|
4027
4268
|
|
|
4028
|
-
export { AccessDenied, ApiError, AppBreadcrumb, AppLayoutShell, AppSidebar, EMPLOYEE_RECORD_OK_EVENT, EMPLOYEE_RECORD_REQUIRED, EMPLOYEE_RECORD_REQUIRED_EVENT, EmployeeRequiredGate, FeatureFlagsProvider, HeaderBackground, HelpButton, HelpDialogHost, NavMain, NavTools, NavUser, OWNER_CHIP, OrganizationSwitcher, PLAN_FEATURES, PermissionGateShell, PermissionProvider, PermissionRulesProvider, ReactQueryProvider, SHELL_VERSION, SessionBackedProfileCacheSeeder, SessionRefreshTrigger, SidebarContent, SidebarFooter, SidebarHeader, SidebarHelpCard, SidebarHelpLink, SidebarProvider, SidebarTrigger, TapMenu, ThemeProvider, WORKSPACE_HEADER_VARS, WORKSPACE_LIGHT_HEADER_VARS, WorkspaceBrand, instance as axiosInstance, buildSystemLinks, buildUrlWithCode, canAccessNavPermissionRoute, clearAccessTokenCache, clearOrganizationId, closeHelp, decodeJWT, describeAttached, describeBrowser, detectHelpApp, filterNavigationModulesByPermission, filterNavigationToolsByPermission, findOrganizationForCode, getAccessToken, getActiveModule, getActiveSubModule, getAxiosErrorMessage, getOrganizationId, getQueryClientConfig, getRequestOrganizationId, getRequiredChildGroups, getTabOrganizationId, hasPlanFeature, isLikelyTransientNetworkError, isPathActive, myRolesQueryKey, normalizePathnameForPermissionRules, openHelp, organizationScopedQueryHash, parseMyRoles, resolveActiveNav, resolveSidebarNav, resolveUiRoutePermission, resolveUrlOrgGate, roleSummary, runGlobalRequestPrecheck, runWithTransientRetry, setOrganizationId, setTabOrganizationId, shouldRetryQuery, toApiError, unwrapApiResponse, updateOrganizationId, useClearOrgOnUserChange, useFeatureFlag, useFeatureFlags, useInvalidateQueriesOnOrgChange, useKeycloakRoles, useMyRoles, useOrganizationIdState, usePermissionRules, useSessionRefresh, useSidebar, useSidebarToggle };
|
|
4269
|
+
export { AccessDenied, ApiError, AppBreadcrumb, AppLayoutShell, AppSidebar, EMPLOYEE_RECORD_OK_EVENT, EMPLOYEE_RECORD_REQUIRED, EMPLOYEE_RECORD_REQUIRED_EVENT, EmployeeRequiredGate, FOR_ORGANIZATION_FIELD, FeatureFlagsProvider, HeaderBackground, HelpButton, HelpDialogHost, NavMain, NavTools, NavUser, OWNER_CHIP, OrganizationSwitcher, PLAN_FEATURES, PermissionGateShell, PermissionProvider, PermissionRulesProvider, ReactQueryProvider, SHELL_VERSION, SessionBackedProfileCacheSeeder, SessionRefreshTrigger, SidebarContent, SidebarFooter, SidebarHeader, SidebarHelpCard, SidebarHelpLink, SidebarProvider, SidebarTrigger, TapMenu, ThemeProvider, WITHOUT_ORGANIZATION_FLAG, WORKSPACE_HEADER_VARS, WORKSPACE_LIGHT_HEADER_VARS, WorkspaceBrand, instance as axiosInstance, buildSystemLinks, buildUrlWithCode, canAccessNavPermissionRoute, clearAccessTokenCache, clearOrganizationId, clearStoredOrganization, closeHelp, decodeJWT, describeAttached, describeBrowser, detectHelpApp, filterNavigationModulesByPermission, filterNavigationToolsByPermission, findOrganizationForCode, getAccessToken, getActiveModule, getActiveSubModule, getAxiosErrorMessage, getOrganizationId, getQueryClientConfig, getRequestOrganizationId, getRequiredChildGroups, getStoredOrganizationIds, getTabOrganizationId, hasPlanFeature, isKnownStaleOrganizationId, isLikelyTransientNetworkError, isPathActive, myRolesQueryKey, normalizePathnameForPermissionRules, openHelp, organizationScopedQueryHash, parseMyRoles, resolveActiveNav, resolveSidebarNav, resolveStaleOrganization, resolveUiRoutePermission, resolveUrlOrgGate, retryWithStoredOrganizations, roleSummary, runGlobalRequestPrecheck, runWithTransientRetry, setKnownOrganizationIds, setOrganizationId, setTabOrganizationId, shouldRetryQuery, toApiError, unwrapApiResponse, updateOrganizationId, useClearOrgOnUserChange, useFeatureFlag, useFeatureFlags, useInvalidateQueriesOnOrgChange, useKeycloakRoles, useMyRoles, useOrganizationIdState, usePermissionRules, useSessionRefresh, useSidebar, useSidebarToggle, withoutOrganization };
|
|
4029
4270
|
//# sourceMappingURL=index.esm.js.map
|