@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/index.js
CHANGED
|
@@ -324,20 +324,154 @@ function readOrganizationStorage() {
|
|
|
324
324
|
return null;
|
|
325
325
|
}
|
|
326
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* The organisations the signed-in user belongs to, once their list has
|
|
329
|
+
* loaded (AppLayoutShell reports it); null until then.
|
|
330
|
+
*/
|
|
331
|
+
let knownOrganizationIds = null;
|
|
332
|
+
/**
|
|
333
|
+
* Record the user's organisations (browser only). From then on a stored or
|
|
334
|
+
* tab organisation that is not among them loses to one that is: a browser
|
|
335
|
+
* that still remembers a deleted organisation — or one the user has left —
|
|
336
|
+
* must not keep sending it while the cookie names a good one.
|
|
337
|
+
*/
|
|
338
|
+
function setKnownOrganizationIds(ids) {
|
|
339
|
+
if (!isBrowser$1())
|
|
340
|
+
return;
|
|
341
|
+
if (ids === null) {
|
|
342
|
+
knownOrganizationIds = null;
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const set = new Set();
|
|
346
|
+
for (const id of ids) {
|
|
347
|
+
const value = normalise(id);
|
|
348
|
+
if (value)
|
|
349
|
+
set.add(value);
|
|
350
|
+
}
|
|
351
|
+
knownOrganizationIds = set;
|
|
352
|
+
}
|
|
353
|
+
/** Whether the loaded list says the user is NOT a member of `id`. */
|
|
354
|
+
function isKnownStaleOrganizationId(id) {
|
|
355
|
+
const value = normalise(id);
|
|
356
|
+
return (value !== null &&
|
|
357
|
+
knownOrganizationIds !== null &&
|
|
358
|
+
!knownOrganizationIds.has(value));
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Marks a request that must not carry X-Organization-ID: the user's own list
|
|
362
|
+
* of organisations is how a stale organisation id is found out, so it cannot
|
|
363
|
+
* depend on one. An app's interceptor honours it by passing the request's
|
|
364
|
+
* config to getRequestOrganizationId(config).
|
|
365
|
+
*
|
|
366
|
+
* axiosInstance.get("/organizations", withoutOrganization({ params }))
|
|
367
|
+
*/
|
|
368
|
+
const WITHOUT_ORGANIZATION_FLAG = "erpWithoutOrganization";
|
|
369
|
+
function withoutOrganization(config) {
|
|
370
|
+
return { ...(config ?? {}), [WITHOUT_ORGANIZATION_FLAG]: true };
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Marks a request for one particular organisation, whatever this tab has
|
|
374
|
+
* active. Used to retry the organisation list under each stored id when an
|
|
375
|
+
* API refuses it without one (see http/organization-fallback.ts).
|
|
376
|
+
*/
|
|
377
|
+
const FOR_ORGANIZATION_FIELD = "erpOrganizationId";
|
|
378
|
+
function isWithoutOrganization(config) {
|
|
379
|
+
return (!!config &&
|
|
380
|
+
typeof config === "object" &&
|
|
381
|
+
config[WITHOUT_ORGANIZATION_FLAG] === true);
|
|
382
|
+
}
|
|
383
|
+
function explicitOrganization(config) {
|
|
384
|
+
if (!config || typeof config !== "object")
|
|
385
|
+
return null;
|
|
386
|
+
const value = config[FOR_ORGANIZATION_FIELD];
|
|
387
|
+
return typeof value === "string" || typeof value === "number"
|
|
388
|
+
? normalise(value)
|
|
389
|
+
: null;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Every organisation id this browser has stored for the tab — the tab's
|
|
393
|
+
* own, localStorage, the cookie — distinct, in that order.
|
|
394
|
+
*/
|
|
395
|
+
function getStoredOrganizationIds() {
|
|
396
|
+
const ids = [
|
|
397
|
+
getTabOrganizationId(),
|
|
398
|
+
readOrganizationStorage(),
|
|
399
|
+
readOrganizationCookie(),
|
|
400
|
+
].filter((id) => id !== null);
|
|
401
|
+
return [...new Set(ids)];
|
|
402
|
+
}
|
|
327
403
|
/**
|
|
328
404
|
* The organisation a request from this tab belongs to: the tab's own, then
|
|
329
405
|
* localStorage, then the cookie. Use it for the X-Organization-ID header —
|
|
330
406
|
* and read it before any `await` in the interceptor, so the header names the
|
|
331
407
|
* organisation that was active when the request was made.
|
|
332
408
|
*
|
|
409
|
+
* Pass the request's config: a request marked withoutOrganization() gets
|
|
410
|
+
* null, so no header.
|
|
411
|
+
*
|
|
333
412
|
* localStorage before the cookie: setOrganizationId writes localStorage
|
|
334
413
|
* synchronously and then awaits a server action for the cookie, so during
|
|
335
414
|
* that round trip the cookie still names the previous organisation.
|
|
415
|
+
*
|
|
416
|
+
* Once the user's organisations are known (setKnownOrganizationIds), the
|
|
417
|
+
* first of those that is one of them wins: 0.1.60 let a deleted
|
|
418
|
+
* organisation's id left in localStorage beat a valid cookie, and every
|
|
419
|
+
* request — the organisation list included — was refused. If none is a
|
|
420
|
+
* member the first is still sent, as before: the list may simply be behind
|
|
421
|
+
* (an organisation created a moment ago).
|
|
422
|
+
*/
|
|
423
|
+
function getRequestOrganizationId(config) {
|
|
424
|
+
const explicit = explicitOrganization(config);
|
|
425
|
+
if (explicit)
|
|
426
|
+
return explicit;
|
|
427
|
+
if (isWithoutOrganization(config))
|
|
428
|
+
return null;
|
|
429
|
+
const candidates = [
|
|
430
|
+
getTabOrganizationId(),
|
|
431
|
+
readOrganizationStorage(),
|
|
432
|
+
readOrganizationCookie(),
|
|
433
|
+
];
|
|
434
|
+
if (knownOrganizationIds !== null) {
|
|
435
|
+
const member = candidates.find(id => id !== null && knownOrganizationIds.has(id));
|
|
436
|
+
if (member)
|
|
437
|
+
return member;
|
|
438
|
+
}
|
|
439
|
+
return candidates.find(id => id !== null) ?? null;
|
|
440
|
+
}
|
|
441
|
+
function expireOrganizationCookie() {
|
|
442
|
+
// The cookie is set by the host's server action, host-only or on a parent
|
|
443
|
+
// domain (AUTH_COOKIE_DOMAIN, e.g. .antniti.com). The browser does not say
|
|
444
|
+
// which, so expire it on the host and on every parent domain.
|
|
445
|
+
const base = `${ORGANIZATION_ID_KEY}=; Max-Age=0; path=/; SameSite=Lax`;
|
|
446
|
+
try {
|
|
447
|
+
document.cookie = base;
|
|
448
|
+
const labels = window.location.hostname.split(".");
|
|
449
|
+
for (let i = 0; i < labels.length - 1; i++) {
|
|
450
|
+
document.cookie = `${base}; domain=.${labels.slice(i).join(".")}`;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
catch {
|
|
454
|
+
// Cookies unavailable: nothing to clear.
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Forget the active organisation everywhere this browser keeps it: the tab,
|
|
459
|
+
* localStorage and the `erp.organizationId` cookie. Call on sign-out, so the
|
|
460
|
+
* next person to sign in on this browser does not start in the previous
|
|
461
|
+
* person's organisation.
|
|
336
462
|
*/
|
|
337
|
-
function
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
463
|
+
function clearStoredOrganization() {
|
|
464
|
+
if (!isBrowser$1())
|
|
465
|
+
return;
|
|
466
|
+
tabOrganizationId = null;
|
|
467
|
+
knownOrganizationIds = null;
|
|
468
|
+
try {
|
|
469
|
+
localStorage.removeItem(ORGANIZATION_ID_KEY);
|
|
470
|
+
}
|
|
471
|
+
catch {
|
|
472
|
+
// Storage unavailable: nothing to clear.
|
|
473
|
+
}
|
|
474
|
+
expireOrganizationCookie();
|
|
341
475
|
}
|
|
342
476
|
|
|
343
477
|
const SELECTED_ORG_STORAGE_KEY = "erp.organizationId";
|
|
@@ -1431,6 +1565,44 @@ const runGlobalRequestPrecheck = (config) => {
|
|
|
1431
1565
|
return validateGoodsReceiptChecks(config.data);
|
|
1432
1566
|
};
|
|
1433
1567
|
|
|
1568
|
+
/**
|
|
1569
|
+
* The organisation list is asked for without an organisation (see
|
|
1570
|
+
* withoutOrganization), but some APIs still refuse it without one: Peoplx's
|
|
1571
|
+
* GET /organizations sits behind its module.hr plan gate, which answers 400
|
|
1572
|
+
* "organization context required" to no header and 403 to an organisation
|
|
1573
|
+
* that does not exist. Until those routes stop needing one, a refused list is
|
|
1574
|
+
* asked again under each organisation this browser has stored — the tab's,
|
|
1575
|
+
* localStorage's, the cookie's — so one good id among stale ones still gets
|
|
1576
|
+
* the user their list, and with it the way back to a working organisation.
|
|
1577
|
+
*
|
|
1578
|
+
* `send` re-sends the request (an axios instance call). Returns the first
|
|
1579
|
+
* answer that succeeds, or undefined when none did or the request is not a
|
|
1580
|
+
* refused organisation-less one. Each retry is marked, so it never retries
|
|
1581
|
+
* itself.
|
|
1582
|
+
*/
|
|
1583
|
+
const RETRIED = "_erpOrganizationFallback";
|
|
1584
|
+
async function retryWithStoredOrganizations(config, status, send) {
|
|
1585
|
+
if (!config ||
|
|
1586
|
+
config[WITHOUT_ORGANIZATION_FLAG] !== true ||
|
|
1587
|
+
config[RETRIED] === true ||
|
|
1588
|
+
(status !== 400 && status !== 403)) {
|
|
1589
|
+
return undefined;
|
|
1590
|
+
}
|
|
1591
|
+
for (const id of getStoredOrganizationIds()) {
|
|
1592
|
+
try {
|
|
1593
|
+
return await send({
|
|
1594
|
+
...config,
|
|
1595
|
+
[RETRIED]: true,
|
|
1596
|
+
[FOR_ORGANIZATION_FIELD]: id,
|
|
1597
|
+
});
|
|
1598
|
+
}
|
|
1599
|
+
catch {
|
|
1600
|
+
// That one was refused too; try the next.
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
return undefined;
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1434
1606
|
const isBrowser = () => typeof window !== "undefined";
|
|
1435
1607
|
const isAuthEndpoint = (url) => !!url && url.includes("/api/auth/");
|
|
1436
1608
|
const isAuthPage = () => isBrowser() && window.location.pathname.startsWith("/auth/");
|
|
@@ -1439,7 +1611,7 @@ const redirectToLogout = async () => {
|
|
|
1439
1611
|
return;
|
|
1440
1612
|
localStorage.clear();
|
|
1441
1613
|
sessionStorage.clear();
|
|
1442
|
-
|
|
1614
|
+
clearStoredOrganization();
|
|
1443
1615
|
clearAccessTokenCache();
|
|
1444
1616
|
await react.signOut({ callbackUrl: "/auth/signin" });
|
|
1445
1617
|
};
|
|
@@ -1471,7 +1643,7 @@ instance.interceptors.request.use(async (config) => {
|
|
|
1471
1643
|
// Read before the token await: the header must name the organisation that
|
|
1472
1644
|
// was active when the request was made (and under which its query is
|
|
1473
1645
|
// cached), not whatever is active once the token resolves.
|
|
1474
|
-
const organizationId = getRequestOrganizationId();
|
|
1646
|
+
const organizationId = getRequestOrganizationId(config);
|
|
1475
1647
|
const token = await getAccessToken(false);
|
|
1476
1648
|
if (token) {
|
|
1477
1649
|
config.headers.Authorization = `Bearer ${token}`;
|
|
@@ -1531,6 +1703,9 @@ instance.interceptors.response.use(response => {
|
|
|
1531
1703
|
window.dispatchEvent(new CustomEvent("erp:employee-record-required"));
|
|
1532
1704
|
}
|
|
1533
1705
|
}
|
|
1706
|
+
const listed = await retryWithStoredOrganizations(originalRequest, error.response?.status, config => instance(config));
|
|
1707
|
+
if (listed !== undefined)
|
|
1708
|
+
return listed;
|
|
1534
1709
|
return Promise.reject(toApiError(error));
|
|
1535
1710
|
});
|
|
1536
1711
|
|
|
@@ -1557,7 +1732,7 @@ function platformApiBase(app) {
|
|
|
1557
1732
|
* This package's version, attached to help messages so the back office can
|
|
1558
1733
|
* tell which shell a report came from. Keep in step with package.json.
|
|
1559
1734
|
*/
|
|
1560
|
-
const SHELL_VERSION = "0.1.
|
|
1735
|
+
const SHELL_VERSION = "0.1.61";
|
|
1561
1736
|
|
|
1562
1737
|
const HELP_APP_LABEL = {
|
|
1563
1738
|
platform: "แพลตฟอร์ม",
|
|
@@ -1880,6 +2055,9 @@ function NavUser({ organization, avatarSrc, profileHref, selectOrganizationHref
|
|
|
1880
2055
|
};
|
|
1881
2056
|
const handleSignOut = async () => {
|
|
1882
2057
|
setIsSigningOut(true);
|
|
2058
|
+
// The next person to sign in on this browser must not start in this
|
|
2059
|
+
// person's organisation: forget it in the tab, localStorage and cookie.
|
|
2060
|
+
clearStoredOrganization();
|
|
1883
2061
|
try {
|
|
1884
2062
|
await react.signOut({ callbackUrl: signInRedirectHref, redirect: true });
|
|
1885
2063
|
}
|
|
@@ -3273,6 +3451,31 @@ function resolveUrlOrgGate({ code, organizations, organizationsStatus, organizat
|
|
|
3273
3451
|
return { state: "unverified" };
|
|
3274
3452
|
}
|
|
3275
3453
|
}
|
|
3454
|
+
function resolveStaleOrganization({ code, organizations, organizationsStatus, organizationId, }) {
|
|
3455
|
+
const status = organizationsStatus ?? (organizations.length > 0 ? "success" : undefined);
|
|
3456
|
+
if (status !== "success")
|
|
3457
|
+
return { action: "none" };
|
|
3458
|
+
const activeId = organizationId === null || organizationId === undefined
|
|
3459
|
+
? ""
|
|
3460
|
+
: String(organizationId).trim();
|
|
3461
|
+
if (activeId === "")
|
|
3462
|
+
return { action: "none" };
|
|
3463
|
+
if (organizations.some(org => String(org.id) === activeId)) {
|
|
3464
|
+
return { action: "none" };
|
|
3465
|
+
}
|
|
3466
|
+
const urlOrg = findOrganizationForCode(code, organizations);
|
|
3467
|
+
if (urlOrg) {
|
|
3468
|
+
return { action: "use", targetId: String(urlOrg.id), fromUrl: true };
|
|
3469
|
+
}
|
|
3470
|
+
if (organizations.length === 1) {
|
|
3471
|
+
return {
|
|
3472
|
+
action: "use",
|
|
3473
|
+
targetId: String(organizations[0].id),
|
|
3474
|
+
fromUrl: false,
|
|
3475
|
+
};
|
|
3476
|
+
}
|
|
3477
|
+
return { action: "forget" };
|
|
3478
|
+
}
|
|
3276
3479
|
|
|
3277
3480
|
/**
|
|
3278
3481
|
* Top-level app chrome: sticky header, sidebar slot, content gutter and the
|
|
@@ -3334,6 +3537,44 @@ function AppLayoutShell({ children, sidebar, loadingComponent, breadcrumb, permi
|
|
|
3334
3537
|
requestedSwitchRef.current = switchTargetId;
|
|
3335
3538
|
void setOrganizationId(switchTargetId);
|
|
3336
3539
|
}, [switchTargetId, setOrganizationId]);
|
|
3540
|
+
// Once the user's organisations are known, requests prefer a stored
|
|
3541
|
+
// organisation that is one of them (getRequestOrganizationId).
|
|
3542
|
+
const organizationsLoaded = (organizationsStatus ??
|
|
3543
|
+
(organizations.length > 0 ? "success" : undefined)) === "success";
|
|
3544
|
+
React.useEffect(() => {
|
|
3545
|
+
if (organizationsLoaded) {
|
|
3546
|
+
setKnownOrganizationIds(organizations.map(org => org.id));
|
|
3547
|
+
}
|
|
3548
|
+
}, [organizationsLoaded, organizations]);
|
|
3549
|
+
// An active organisation that is not one of the user's — deleted, or left —
|
|
3550
|
+
// is replaced, so it stops being sent with every request. The URL's
|
|
3551
|
+
// organisation, when the user is a member, is the gate's switch above;
|
|
3552
|
+
// otherwise the user's only organisation, or none (they pick one: the
|
|
3553
|
+
// refusal below offers it, and a path without a code goes to the picker).
|
|
3554
|
+
// Once per stale id and target, so a setter that does not take cannot loop.
|
|
3555
|
+
const staleRecovery = resolveStaleOrganization({
|
|
3556
|
+
code,
|
|
3557
|
+
organizations,
|
|
3558
|
+
organizationsStatus,
|
|
3559
|
+
organizationId,
|
|
3560
|
+
});
|
|
3561
|
+
const staleRecoveryTarget = staleRecovery.action === "forget"
|
|
3562
|
+
? null
|
|
3563
|
+
: staleRecovery.action === "use" && !staleRecovery.fromUrl
|
|
3564
|
+
? staleRecovery.targetId
|
|
3565
|
+
: undefined;
|
|
3566
|
+
const staleRecoveryKey = staleRecoveryTarget === undefined
|
|
3567
|
+
? null
|
|
3568
|
+
: `${String(organizationId)}>${staleRecoveryTarget ?? ""}`;
|
|
3569
|
+
const handledStaleRecoveryRef = React.useRef(null);
|
|
3570
|
+
React.useEffect(() => {
|
|
3571
|
+
if (staleRecoveryKey === null || staleRecoveryTarget === undefined)
|
|
3572
|
+
return;
|
|
3573
|
+
if (handledStaleRecoveryRef.current === staleRecoveryKey)
|
|
3574
|
+
return;
|
|
3575
|
+
handledStaleRecoveryRef.current = staleRecoveryKey;
|
|
3576
|
+
void setOrganizationId(staleRecoveryTarget);
|
|
3577
|
+
}, [staleRecoveryKey, staleRecoveryTarget, setOrganizationId]);
|
|
3337
3578
|
// Key for the content subtree. It exists so switching organizations throws
|
|
3338
3579
|
// away the previous org's component state — but it must react ONLY to a real
|
|
3339
3580
|
// switch. organizationId legitimately passes through null while the context
|
|
@@ -4057,6 +4298,7 @@ exports.EMPLOYEE_RECORD_OK_EVENT = EMPLOYEE_RECORD_OK_EVENT;
|
|
|
4057
4298
|
exports.EMPLOYEE_RECORD_REQUIRED = EMPLOYEE_RECORD_REQUIRED;
|
|
4058
4299
|
exports.EMPLOYEE_RECORD_REQUIRED_EVENT = EMPLOYEE_RECORD_REQUIRED_EVENT;
|
|
4059
4300
|
exports.EmployeeRequiredGate = EmployeeRequiredGate;
|
|
4301
|
+
exports.FOR_ORGANIZATION_FIELD = FOR_ORGANIZATION_FIELD;
|
|
4060
4302
|
exports.FeatureFlagsProvider = FeatureFlagsProvider;
|
|
4061
4303
|
exports.HeaderBackground = HeaderBackground;
|
|
4062
4304
|
exports.HelpButton = HelpButton;
|
|
@@ -4083,6 +4325,7 @@ exports.SidebarProvider = SidebarProvider;
|
|
|
4083
4325
|
exports.SidebarTrigger = SidebarTrigger;
|
|
4084
4326
|
exports.TapMenu = TapMenu;
|
|
4085
4327
|
exports.ThemeProvider = ThemeProvider;
|
|
4328
|
+
exports.WITHOUT_ORGANIZATION_FLAG = WITHOUT_ORGANIZATION_FLAG;
|
|
4086
4329
|
exports.WORKSPACE_HEADER_VARS = WORKSPACE_HEADER_VARS;
|
|
4087
4330
|
exports.WORKSPACE_LIGHT_HEADER_VARS = WORKSPACE_LIGHT_HEADER_VARS;
|
|
4088
4331
|
exports.WorkspaceBrand = WorkspaceBrand;
|
|
@@ -4092,6 +4335,7 @@ exports.buildUrlWithCode = buildUrlWithCode;
|
|
|
4092
4335
|
exports.canAccessNavPermissionRoute = canAccessNavPermissionRoute;
|
|
4093
4336
|
exports.clearAccessTokenCache = clearAccessTokenCache;
|
|
4094
4337
|
exports.clearOrganizationId = clearOrganizationId;
|
|
4338
|
+
exports.clearStoredOrganization = clearStoredOrganization;
|
|
4095
4339
|
exports.closeHelp = closeHelp;
|
|
4096
4340
|
exports.decodeJWT = decodeJWT;
|
|
4097
4341
|
exports.describeAttached = describeAttached;
|
|
@@ -4108,8 +4352,10 @@ exports.getOrganizationId = getOrganizationId;
|
|
|
4108
4352
|
exports.getQueryClientConfig = getQueryClientConfig;
|
|
4109
4353
|
exports.getRequestOrganizationId = getRequestOrganizationId;
|
|
4110
4354
|
exports.getRequiredChildGroups = getRequiredChildGroups;
|
|
4355
|
+
exports.getStoredOrganizationIds = getStoredOrganizationIds;
|
|
4111
4356
|
exports.getTabOrganizationId = getTabOrganizationId;
|
|
4112
4357
|
exports.hasPlanFeature = hasPlanFeature;
|
|
4358
|
+
exports.isKnownStaleOrganizationId = isKnownStaleOrganizationId;
|
|
4113
4359
|
exports.isLikelyTransientNetworkError = isLikelyTransientNetworkError;
|
|
4114
4360
|
exports.isPathActive = isPathActive;
|
|
4115
4361
|
exports.myRolesQueryKey = myRolesQueryKey;
|
|
@@ -4119,11 +4365,14 @@ exports.organizationScopedQueryHash = organizationScopedQueryHash;
|
|
|
4119
4365
|
exports.parseMyRoles = parseMyRoles;
|
|
4120
4366
|
exports.resolveActiveNav = resolveActiveNav;
|
|
4121
4367
|
exports.resolveSidebarNav = resolveSidebarNav;
|
|
4368
|
+
exports.resolveStaleOrganization = resolveStaleOrganization;
|
|
4122
4369
|
exports.resolveUiRoutePermission = resolveUiRoutePermission;
|
|
4123
4370
|
exports.resolveUrlOrgGate = resolveUrlOrgGate;
|
|
4371
|
+
exports.retryWithStoredOrganizations = retryWithStoredOrganizations;
|
|
4124
4372
|
exports.roleSummary = roleSummary;
|
|
4125
4373
|
exports.runGlobalRequestPrecheck = runGlobalRequestPrecheck;
|
|
4126
4374
|
exports.runWithTransientRetry = runWithTransientRetry;
|
|
4375
|
+
exports.setKnownOrganizationIds = setKnownOrganizationIds;
|
|
4127
4376
|
exports.setOrganizationId = setOrganizationId;
|
|
4128
4377
|
exports.setTabOrganizationId = setTabOrganizationId;
|
|
4129
4378
|
exports.shouldRetryQuery = shouldRetryQuery;
|
|
@@ -4141,4 +4390,5 @@ exports.usePermissionRules = usePermissionRules;
|
|
|
4141
4390
|
exports.useSessionRefresh = useSessionRefresh;
|
|
4142
4391
|
exports.useSidebar = useSidebar;
|
|
4143
4392
|
exports.useSidebarToggle = useSidebarToggle;
|
|
4393
|
+
exports.withoutOrganization = withoutOrganization;
|
|
4144
4394
|
//# sourceMappingURL=index.js.map
|