@burdenoff/fe-libs 2026.1021.3 → 2026.1021.4
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/chrome/contextSwitcher/contextSwitch.d.ts +84 -0
- package/dist/chrome/contextSwitcher/contextSwitch.js +31 -0
- package/dist/chrome/contextSwitcher/resolveSwitchTarget.d.ts +51 -0
- package/dist/chrome/contextSwitcher/resolveSwitchTarget.js +26 -0
- package/dist/chrome/contextSwitcher/useContextSwitchController.d.ts +50 -0
- package/dist/chrome/contextSwitcher/useContextSwitchController.js +62 -0
- package/dist/chrome/index.d.ts +6 -0
- package/dist/chrome.js +26 -23
- package/package.json +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Header organization / workspace switches (BOFF-8078), shared by every shell
|
|
3
|
+
* through `useContextSwitchController` (lifted from fluidgrids-app, where the
|
|
4
|
+
* same file was copied into bigconsole-app and healthybowl-app).
|
|
5
|
+
*
|
|
6
|
+
* `selectWorkspace` (microfe-auth) issues a token for the workspace it is
|
|
7
|
+
* given and then lists that workspace's projects. The list request does NOT
|
|
8
|
+
* carry the workspace it was asked about: fe-libs `graphqlFetch` derives the
|
|
9
|
+
* `x-workspace-id` header, and the context the fresh workspace token is
|
|
10
|
+
* validated against, from the stored ActiveContext (`bf-p-<uid>-context`, with
|
|
11
|
+
* the `?workspace=` URL param taking precedence). When the handler calls
|
|
12
|
+
* `selectWorkspace(B)` while ActiveContext still names workspace A, the new
|
|
13
|
+
* token is dropped as "invalid for context A", a token for A is minted in its
|
|
14
|
+
* place, and the request lists A's projects. The handler then selected A's
|
|
15
|
+
* first project, so the stored context paired workspace B with a project from
|
|
16
|
+
* workspace A, and kept that pair across reloads.
|
|
17
|
+
*
|
|
18
|
+
* Measured in prod on 2026-09-28 with the header switcher, A = f423fce9 and
|
|
19
|
+
* B = 089761cb: `MyProjectsForContext` went out with `x-workspace-id: f423fce9`
|
|
20
|
+
* and A's workspace token right after `IssueWorkspaceToken` returned B's token,
|
|
21
|
+
* and answered A's only project (e35d7c3b). VibeControls, which publishes the
|
|
22
|
+
* new workspace first, ends on B's project (e6febd92).
|
|
23
|
+
*
|
|
24
|
+
* So both switches publish the target context to ActiveContext first — the
|
|
25
|
+
* organization and workspace, with the project cleared — and only then ask
|
|
26
|
+
* microfe-auth to select it. Only a project that belongs to the target
|
|
27
|
+
* workspace is ever selected, and a switch that a later switch has superseded
|
|
28
|
+
* is discarded instead of applied.
|
|
29
|
+
*/
|
|
30
|
+
export interface SwitchableOrganization {
|
|
31
|
+
id: string;
|
|
32
|
+
tenantId?: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface SwitchableWorkspace {
|
|
35
|
+
id: string;
|
|
36
|
+
organizationId?: string | null;
|
|
37
|
+
tenantId?: unknown;
|
|
38
|
+
}
|
|
39
|
+
export interface SwitchableProject {
|
|
40
|
+
id: string;
|
|
41
|
+
workspaceId?: string | null;
|
|
42
|
+
}
|
|
43
|
+
export interface WorkspaceSelection<P extends SwitchableProject> {
|
|
44
|
+
success: boolean;
|
|
45
|
+
projects?: ReadonlyArray<P>;
|
|
46
|
+
}
|
|
47
|
+
export interface ContextSwitchDeps<O extends SwitchableOrganization, W extends SwitchableWorkspace, P extends SwitchableProject> {
|
|
48
|
+
/**
|
|
49
|
+
* Monotonic switch counter (a React ref), shared by the organization and
|
|
50
|
+
* workspace switches: the most recent switch of either kind wins.
|
|
51
|
+
*/
|
|
52
|
+
requests: {
|
|
53
|
+
current: number;
|
|
54
|
+
};
|
|
55
|
+
setOrganization: (organizationId: string | null) => void;
|
|
56
|
+
setWorkspace: (workspaceId: string | null) => void;
|
|
57
|
+
setProject: (projectId: string | null) => void;
|
|
58
|
+
setTenant: (tenantId: string | null) => void;
|
|
59
|
+
selectOrganization: (organization: O) => Promise<ReadonlyArray<W>>;
|
|
60
|
+
selectWorkspace: (workspace: W) => Promise<WorkspaceSelection<P>>;
|
|
61
|
+
selectProject: (project: P) => void;
|
|
62
|
+
}
|
|
63
|
+
export type ContextSwitchOutcome = {
|
|
64
|
+
status: 'project-selected';
|
|
65
|
+
workspaceId: string;
|
|
66
|
+
projectId: string;
|
|
67
|
+
} | {
|
|
68
|
+
status: 'no-project';
|
|
69
|
+
workspaceId: string;
|
|
70
|
+
} | {
|
|
71
|
+
status: 'no-workspace';
|
|
72
|
+
} | {
|
|
73
|
+
status: 'superseded';
|
|
74
|
+
};
|
|
75
|
+
/** The first project the selection returned that belongs to `workspaceId`. */
|
|
76
|
+
export declare function firstProjectOfWorkspace<P extends SwitchableProject>(selection: WorkspaceSelection<P>, workspaceId: string): P | null;
|
|
77
|
+
/** Header workspace switch: enter `workspace` and select its first project. */
|
|
78
|
+
export declare function switchWorkspace<O extends SwitchableOrganization, W extends SwitchableWorkspace, P extends SwitchableProject>(deps: ContextSwitchDeps<O, W, P>, workspace: W): Promise<ContextSwitchOutcome>;
|
|
79
|
+
/**
|
|
80
|
+
* Header organization switch: clear the workspace and project, load the
|
|
81
|
+
* organization's workspaces, then enter the first one exactly as a workspace
|
|
82
|
+
* switch would.
|
|
83
|
+
*/
|
|
84
|
+
export declare function switchOrganization<O extends SwitchableOrganization, W extends SwitchableWorkspace, P extends SwitchableProject>(deps: ContextSwitchDeps<O, W, P>, organization: O): Promise<ContextSwitchOutcome>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/chrome/contextSwitcher/contextSwitch.ts
|
|
2
|
+
function e(e, t) {
|
|
3
|
+
return e.success ? e.projects?.find((e) => e.workspaceId === t) ?? null : null;
|
|
4
|
+
}
|
|
5
|
+
async function t(t, n, r) {
|
|
6
|
+
n.organizationId && t.setOrganization(n.organizationId), typeof n.tenantId == "string" && t.setTenant(n.tenantId), t.setWorkspace(n.id), t.setProject(null);
|
|
7
|
+
let i = await t.selectWorkspace(n);
|
|
8
|
+
if (r !== t.requests.current) return { status: "superseded" };
|
|
9
|
+
let a = e(i, n.id);
|
|
10
|
+
return a ? (t.selectProject(a), t.setProject(a.id), {
|
|
11
|
+
status: "project-selected",
|
|
12
|
+
workspaceId: n.id,
|
|
13
|
+
projectId: a.id
|
|
14
|
+
}) : {
|
|
15
|
+
status: "no-project",
|
|
16
|
+
workspaceId: n.id
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function n(e, n) {
|
|
20
|
+
return t(e, n, ++e.requests.current);
|
|
21
|
+
}
|
|
22
|
+
async function r(e, n) {
|
|
23
|
+
let r = ++e.requests.current;
|
|
24
|
+
e.setOrganization(n.id), typeof n.tenantId == "string" && e.setTenant(n.tenantId), e.setWorkspace(null), e.setProject(null);
|
|
25
|
+
let i = await e.selectOrganization(n);
|
|
26
|
+
if (r !== e.requests.current) return { status: "superseded" };
|
|
27
|
+
let a = i[0];
|
|
28
|
+
return a ? t(e, a, r) : { status: "no-workspace" };
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { e as firstProjectOfWorkspace, r as switchOrganization, n as switchWorkspace };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* resolveSwitchTarget — where to land when the active org/workspace changes.
|
|
3
|
+
*
|
|
4
|
+
* The workspace token is re-issued on every context switch (BOFF-2821). A route
|
|
5
|
+
* that holds a *resource id belonging to the old workspace* (a workflow, a run,
|
|
6
|
+
* an agent, a file …) would then fire queries the new token cannot authorize —
|
|
7
|
+
* the "Unexpected error" banners — or show the old workspace's record under the
|
|
8
|
+
* new workspace. So when the switch starts on such a resource-deep route the
|
|
9
|
+
* shell replace-navigates to that section's list page; the stale id is dropped.
|
|
10
|
+
*
|
|
11
|
+
* List/section pages (no resource id) are NOT redirected: they re-scope in place
|
|
12
|
+
* through the new selection. Each product passes its own rule table, because the
|
|
13
|
+
* route shapes are product-specific (VibeControls' `/vibecontrols/<section>/<id>`,
|
|
14
|
+
* FluidGrids' `/workflows/workflow/<key>/<version>` and `/workflows/runs/<id>`).
|
|
15
|
+
*
|
|
16
|
+
* Lifted from vibecontrols-app `src/routes/resolveSwitchTarget.ts` (BOFF-2821),
|
|
17
|
+
* with VibeControls' hard-coded tables turned into a parameter.
|
|
18
|
+
*/
|
|
19
|
+
/** One resource-deep route and the list/landing route that replaces it. */
|
|
20
|
+
export interface ContextSwitchRedirectRule {
|
|
21
|
+
/**
|
|
22
|
+
* Matches a pathname that carries a resource id of the old context. Rules are
|
|
23
|
+
* tried in order; the first match wins. A `g`/`y` flag is ignored (the match
|
|
24
|
+
* is always made from the start of a fresh state), so a shared rule table
|
|
25
|
+
* gives the same answer on every call.
|
|
26
|
+
*/
|
|
27
|
+
match: RegExp;
|
|
28
|
+
/** The landing to go to: a fixed path, or one computed from the match. */
|
|
29
|
+
to: string | ((match: RegExpExecArray) => string);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The target pathname to replace-navigate to after a context switch, or `null`
|
|
33
|
+
* to stay on `pathname` (only the context query params change).
|
|
34
|
+
*
|
|
35
|
+
* Returns `null` when no rule matches, and when the matching rule's landing is
|
|
36
|
+
* `pathname` itself, so a rule can never loop on its own landing page.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveSwitchTarget(pathname: string, rules: ReadonlyArray<ContextSwitchRedirectRule>): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* A rule for a family of `<prefix>/<section>/<id…>` detail routes: anything
|
|
41
|
+
* deeper than a `<prefix>/<section>` landing redirects back to that landing, so
|
|
42
|
+
* current and future detail routes are covered without enumerating each one.
|
|
43
|
+
* The bare `<prefix>/<section>` page and `<prefix>` itself stay in place.
|
|
44
|
+
*
|
|
45
|
+
* `sectionLandingRule('/vibecontrols')` is VibeControls' rule:
|
|
46
|
+
* `/vibecontrols/agents/a1` → `/vibecontrols/agents`,
|
|
47
|
+
* `/vibecontrols/calendar/task/t1` → `/vibecontrols/calendar`.
|
|
48
|
+
*
|
|
49
|
+
* @param prefix a rooted path without a trailing slash, e.g. `/vibecontrols`
|
|
50
|
+
*/
|
|
51
|
+
export declare function sectionLandingRule(prefix: string): ContextSwitchRedirectRule;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/chrome/contextSwitcher/resolveSwitchTarget.ts
|
|
2
|
+
function e(e, n) {
|
|
3
|
+
for (let r of n) {
|
|
4
|
+
let n = t(r.match).exec(e);
|
|
5
|
+
if (!n) continue;
|
|
6
|
+
let i = typeof r.to == "string" ? r.to : r.to(n);
|
|
7
|
+
return i === e ? null : i;
|
|
8
|
+
}
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
function t(e) {
|
|
12
|
+
return !e.global && !e.sticky ? e : new RegExp(e.source, e.flags.replace(/[gy]/g, ""));
|
|
13
|
+
}
|
|
14
|
+
function n(e) {
|
|
15
|
+
return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
16
|
+
}
|
|
17
|
+
function r(e) {
|
|
18
|
+
if (!/^\/[^/]/.test(e) || e.endsWith("/")) throw Error(`sectionLandingRule: prefix must be a rooted path without a trailing slash, got "${e}"`);
|
|
19
|
+
let t = n(e);
|
|
20
|
+
return {
|
|
21
|
+
match: RegExp(`^${t}/([^/]+)/[^/]+`),
|
|
22
|
+
to: (t) => `${e}/${t[1]}`
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { e as resolveSwitchTarget, r as sectionLandingRule };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ContextSwitchOutcome, SwitchableOrganization, SwitchableProject, SwitchableWorkspace, WorkspaceSelection } from './contextSwitch';
|
|
2
|
+
import { ContextSwitchRedirectRule } from './resolveSwitchTarget';
|
|
3
|
+
/** Which header switch produced an outcome. */
|
|
4
|
+
export type ContextSwitchKind = 'organization' | 'workspace';
|
|
5
|
+
export interface ContextSwitchEvent {
|
|
6
|
+
kind: ContextSwitchKind;
|
|
7
|
+
/** The organization or workspace the user picked. */
|
|
8
|
+
id: string;
|
|
9
|
+
outcome: ContextSwitchOutcome;
|
|
10
|
+
}
|
|
11
|
+
export interface UseContextSwitchControllerOptions<O extends SwitchableOrganization, W extends SwitchableWorkspace, P extends SwitchableProject> {
|
|
12
|
+
/** The switcher's lists; a pick is resolved to its full record here. */
|
|
13
|
+
organizations: ReadonlyArray<O>;
|
|
14
|
+
workspaces: ReadonlyArray<W>;
|
|
15
|
+
projects: ReadonlyArray<P>;
|
|
16
|
+
/** microfe-auth: select the organization and list its workspaces. */
|
|
17
|
+
selectOrganization: (organization: O) => Promise<ReadonlyArray<W>>;
|
|
18
|
+
/** microfe-auth: issue the workspace token and list the workspace's projects. */
|
|
19
|
+
selectWorkspace: (workspace: W) => Promise<WorkspaceSelection<P>>;
|
|
20
|
+
/** microfe-auth: select a project. */
|
|
21
|
+
selectProject: (project: P) => void;
|
|
22
|
+
/**
|
|
23
|
+
* The product's resource-deep routes and their list pages. Omitted or empty:
|
|
24
|
+
* a switch never navigates.
|
|
25
|
+
*/
|
|
26
|
+
redirectRules?: ReadonlyArray<ContextSwitchRedirectRule>;
|
|
27
|
+
/** Called with every switch's outcome, superseded ones included. */
|
|
28
|
+
onSwitch?: (event: ContextSwitchEvent) => void;
|
|
29
|
+
}
|
|
30
|
+
export interface ContextSwitchController {
|
|
31
|
+
/**
|
|
32
|
+
* Switch to `organization` and enter its first workspace. Resolves to the
|
|
33
|
+
* outcome, or `null` when the id is not in `organizations`.
|
|
34
|
+
*/
|
|
35
|
+
onOrganizationChange: (organization: {
|
|
36
|
+
id: string;
|
|
37
|
+
}) => Promise<ContextSwitchOutcome | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Switch to `workspace` and select its first project. Resolves to the
|
|
40
|
+
* outcome, or `null` when the id is not in `workspaces`.
|
|
41
|
+
*/
|
|
42
|
+
onWorkspaceChange: (workspace: {
|
|
43
|
+
id: string;
|
|
44
|
+
}) => Promise<ContextSwitchOutcome | null>;
|
|
45
|
+
/** Select `project` (an id missing from `projects` still becomes active). */
|
|
46
|
+
onProjectChange: (project: {
|
|
47
|
+
id: string;
|
|
48
|
+
}) => void;
|
|
49
|
+
}
|
|
50
|
+
export declare function useContextSwitchController<O extends SwitchableOrganization, W extends SwitchableWorkspace, P extends SwitchableProject>(options: UseContextSwitchControllerOptions<O, W, P>): ContextSwitchController;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { useActiveContext as e } from "../../shared/providers/shell/ActiveContextProvider.js";
|
|
2
|
+
import { useLogger as t } from "../../shared/logger/useLogger.js";
|
|
3
|
+
import { switchOrganization as n, switchWorkspace as r } from "./contextSwitch.js";
|
|
4
|
+
import { resolveSwitchTarget as i } from "./resolveSwitchTarget.js";
|
|
5
|
+
import { useRef as a } from "react";
|
|
6
|
+
import { useLocation as o, useNavigate as s } from "react-router";
|
|
7
|
+
//#region src/chrome/contextSwitcher/useContextSwitchController.ts
|
|
8
|
+
function c(c) {
|
|
9
|
+
let { organizations: l, workspaces: u, projects: d, selectOrganization: f, selectWorkspace: p, selectProject: m, redirectRules: h, onSwitch: g } = c, _ = t("ContextSwitcher"), v = s(), { pathname: y } = o(), b = e(), x = {
|
|
10
|
+
requests: a(0),
|
|
11
|
+
setOrganization: b.setOrganization,
|
|
12
|
+
setWorkspace: b.setWorkspace,
|
|
13
|
+
setProject: b.setProject,
|
|
14
|
+
setTenant: b.setTenant,
|
|
15
|
+
selectOrganization: f,
|
|
16
|
+
selectWorkspace: p,
|
|
17
|
+
selectProject: m
|
|
18
|
+
}, S = () => {
|
|
19
|
+
if (!h || h.length === 0) return;
|
|
20
|
+
let e = i(y, h);
|
|
21
|
+
e && (_.info("Leaving a resource of the previous context", {
|
|
22
|
+
from: y,
|
|
23
|
+
to: e
|
|
24
|
+
}), v({
|
|
25
|
+
pathname: e,
|
|
26
|
+
search: typeof window > "u" ? "" : window.location.search
|
|
27
|
+
}, { replace: !0 }));
|
|
28
|
+
}, C = (e, t, n) => {
|
|
29
|
+
n.status === "superseded" && _.info(`Discarding stale ${e}-switch result`, { [`${e}Id`]: t }), g?.({
|
|
30
|
+
kind: e,
|
|
31
|
+
id: t,
|
|
32
|
+
outcome: n
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
onOrganizationChange: async (e) => {
|
|
37
|
+
let t = l.find((t) => t.id === e.id);
|
|
38
|
+
if (!t) return _.warn("Organization switch ignored: not in the switcher list", { organizationId: e.id }), null;
|
|
39
|
+
_.info("Changing organization", { organizationId: t.id });
|
|
40
|
+
let r = t.id !== b.organizationId, i = n(x, t);
|
|
41
|
+
r && S();
|
|
42
|
+
let a = await i;
|
|
43
|
+
return C("organization", t.id, a), a;
|
|
44
|
+
},
|
|
45
|
+
onWorkspaceChange: async (e) => {
|
|
46
|
+
let t = u.find((t) => t.id === e.id);
|
|
47
|
+
if (!t) return _.warn("Workspace switch ignored: not in the switcher list", { workspaceId: e.id }), null;
|
|
48
|
+
_.info("Changing workspace", { workspaceId: t.id });
|
|
49
|
+
let n = t.id !== b.workspaceId, i = r(x, t);
|
|
50
|
+
n && S();
|
|
51
|
+
let a = await i;
|
|
52
|
+
return C("workspace", t.id, a), a;
|
|
53
|
+
},
|
|
54
|
+
onProjectChange: (e) => {
|
|
55
|
+
_.info("Changing project", { projectId: e.id });
|
|
56
|
+
let t = d.find((t) => t.id === e.id);
|
|
57
|
+
t && m(t), b.setProject(e.id);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { c as useContextSwitchController };
|
package/dist/chrome/index.d.ts
CHANGED
|
@@ -84,6 +84,12 @@ export type { LanguageSwitcherProps, Language } from './LanguageSwitcher';
|
|
|
84
84
|
export type { GeographySwitcherProps } from './GeographySwitcher';
|
|
85
85
|
export type { NotificationCenterProps } from './NotificationCenter';
|
|
86
86
|
export type { ContextSwitcherProps, Organization, Workspace, Project, } from './ContextSwitcher';
|
|
87
|
+
export { useContextSwitchController } from './contextSwitcher/useContextSwitchController';
|
|
88
|
+
export type { ContextSwitchController, ContextSwitchEvent, ContextSwitchKind, UseContextSwitchControllerOptions, } from './contextSwitcher/useContextSwitchController';
|
|
89
|
+
export { firstProjectOfWorkspace, switchOrganization, switchWorkspace, } from './contextSwitcher/contextSwitch';
|
|
90
|
+
export type { ContextSwitchDeps, ContextSwitchOutcome, SwitchableOrganization, SwitchableProject, SwitchableWorkspace, WorkspaceSelection, } from './contextSwitcher/contextSwitch';
|
|
91
|
+
export { resolveSwitchTarget, sectionLandingRule, } from './contextSwitcher/resolveSwitchTarget';
|
|
92
|
+
export type { ContextSwitchRedirectRule } from './contextSwitcher/resolveSwitchTarget';
|
|
87
93
|
export type { LanguagePickerSheetProps } from './LanguagePickerSheet';
|
|
88
94
|
export type { ProductPickerSheetProps } from './ProductPickerSheet';
|
|
89
95
|
export type { AccountSwitcherProps, Account } from './AccountSwitcher';
|
package/dist/chrome.js
CHANGED
|
@@ -23,26 +23,29 @@ import { NotificationCenter as D } from "./chrome/NotificationCenter.js";
|
|
|
23
23
|
import { LanguagePickerSheet as O } from "./chrome/LanguagePickerSheet.js";
|
|
24
24
|
import { ProductPickerSheet as k } from "./chrome/ProductPickerSheet.js";
|
|
25
25
|
import { AccountSwitcher as A } from "./chrome/AccountSwitcher.js";
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
|
|
26
|
+
import { firstProjectOfWorkspace as j, switchOrganization as M, switchWorkspace as N } from "./chrome/contextSwitcher/contextSwitch.js";
|
|
27
|
+
import { resolveSwitchTarget as P, sectionLandingRule as F } from "./chrome/contextSwitcher/resolveSwitchTarget.js";
|
|
28
|
+
import { useContextSwitchController as I } from "./chrome/contextSwitcher/useContextSwitchController.js";
|
|
29
|
+
import { AutoBreadcrumbs as L, registerBreadcrumbName as R, unregisterBreadcrumbName as z } from "./chrome/AutoBreadcrumbs.js";
|
|
30
|
+
import { NavCustomizeDialog as B } from "./chrome/NavCustomizeDialog.js";
|
|
31
|
+
import { PersonaSimulationPill as V, PersonaSurfaceControls as H } from "./chrome/PersonaSurfaceControls.js";
|
|
32
|
+
import { ProductSideNav as U } from "./chrome/ProductSideNav.js";
|
|
33
|
+
import { BrandMark as W } from "./chrome/BrandMark.js";
|
|
34
|
+
import { DynamicFooter as G } from "./chrome/DynamicFooter.js";
|
|
35
|
+
import { PanelTabs as K } from "./chrome/PanelTabs.js";
|
|
36
|
+
import { PanelContainer as q } from "./chrome/PanelContainer.js";
|
|
37
|
+
import { StatusBar as J } from "./chrome/StatusBar.js";
|
|
38
|
+
import { PluginRoutes as Y } from "./chrome/PluginRoutes.js";
|
|
39
|
+
import { PluginSettingsPage as X } from "./chrome/PluginSettingsPage.js";
|
|
40
|
+
import { PluginToolbar as Z } from "./chrome/PluginToolbar.js";
|
|
41
|
+
import { PluginWidgetGrid as Q } from "./chrome/PluginWidgetGrid.js";
|
|
42
|
+
import { PluginContextMenuTarget as $ } from "./chrome/PluginContextMenuTarget.js";
|
|
43
|
+
import { ThemePreferences as ee } from "./chrome/ThemePreferences.js";
|
|
44
|
+
import { selectMobileTabs as te } from "./chrome/mobileTabBar/selectTabs.js";
|
|
45
|
+
import { useMobileTabBarVisible as ne } from "./chrome/mobileTabBar/useMobileTabBarVisible.js";
|
|
46
|
+
import { MobileTabBar as re } from "./chrome/MobileTabBar.js";
|
|
47
|
+
import { NativeTopBar as ie } from "./chrome/NativeTopBar.js";
|
|
48
|
+
import { SwipeNavigation as ae } from "./chrome/SwipeNavigation.js";
|
|
49
|
+
import { NativePageTransition as oe } from "./chrome/NativePageTransition.js";
|
|
50
|
+
import { findNavTitle as se, useNativeTopBarTitle as ce } from "./chrome/nativeTopBarTitle.js";
|
|
51
|
+
export { A as AccountSwitcher, o as AppShellLayout, L as AutoBreadcrumbs, W as BrandMark, _ as Breadcrumbs, g as CommandPalette, w as ContextSwitcher, d as DEFAULT_FOOTER_COLUMNS, f as DEFAULT_SOCIAL_LINKS, G as DynamicFooter, p as Footer, l as FooterBar, T as GeographySwitcher, h as GlobalSearch, c as HeaderBar, O as LanguagePickerSheet, C as LanguageSwitcher, re as MobileTabBar, t as NAV_MORE_ID_PREFIX, oe as NativePageTransition, ie as NativeTopBar, B as NavCustomizeDialog, v as NavLink, D as NotificationCenter, s as PageHeader, q as PanelContainer, K as PanelTabs, V as PersonaSimulationPill, H as PersonaSurfaceControls, $ as PluginContextMenuTarget, u as PluginFooterStrip, Y as PluginRoutes, X as PluginSettingsPage, Z as PluginToolbar, Q as PluginWidgetGrid, k as ProductPickerSheet, U as ProductSideNav, S as ProductSwitcher, x as ProfileSwitcher, E as PushOptInToggle, e as ShortcutHelpDialog, m as SideNavigation, b as Sidebar, J as StatusBar, ae as SwipeNavigation, y as Tabs, ee as ThemePreferences, n as applyNavVisibility, r as applyPermissionFilter, i as applySurfaceVisibility, se as findNavTitle, j as firstProjectOfWorkspace, a as isItemEffectivelyShown, R as registerBreadcrumbName, P as resolveSwitchTarget, F as sectionLandingRule, te as selectMobileTabs, M as switchOrganization, N as switchWorkspace, z as unregisterBreadcrumbName, I as useContextSwitchController, ne as useMobileTabBarVisible, ce as useNativeTopBarTitle };
|