@the-portland-company/shell 0.80.2 → 0.81.1

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.
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { S as StandardNavIconKey, f as NavIcon, N as NavItem, g as NavBreadcrumb, h as StandardNavMode, i as NavLinkComponent, j as NavChromeFetcher, k as NavMode, l as NavUserMenu, m as NavOrgOption, b as NotificationsAdapter, o as NavFooter, p as NavDisplayMode } from './index-fydj5EU2.cjs';
3
+ import { S as StandardNavIconKey, f as NavIcon, N as NavItem, g as NavBreadcrumb, h as StandardNavMode, i as NavLinkComponent, j as NavChromeFetcher, k as NavMode, l as NavUserMenu, m as NavOrgOption, b as NotificationsAdapter, o as NavFooterLink, p as NavFooter, q as NavDisplayMode } from './index-_Y7jOKPN.cjs';
4
4
  import './theme-preference.cjs';
5
5
 
6
6
  /**
@@ -375,6 +375,14 @@ type ChromeState = {
375
375
  * account and flashes as the wrong organization.
376
376
  */
377
377
  orgsLoading: boolean;
378
+ /**
379
+ * An org switch is in flight: the pill already shows the new org, but the
380
+ * app's token (and so every chrome read made with it) still carries the old
381
+ * one until `onReexchange` settles. Readers whose answer depends on the org
382
+ * wait for this to clear instead of caching the old org's answer under the
383
+ * new org's key.
384
+ */
385
+ orgPending: boolean;
378
386
  navDisplay: NavDisplayMode;
379
387
  setNavDisplay: (m: NavDisplayMode) => void;
380
388
  };
@@ -478,6 +486,12 @@ declare function PolitogyAppChrome({ storagePrefix, proxyBasePath, fetchJson: fe
478
486
  declare function ChromeTopBarActions(): react_jsx_runtime.JSX.Element | null;
479
487
  /** True when any core-org membership carries a super-admin tier. */
480
488
  declare function useIsSuperAdmin(): boolean;
489
+ /**
490
+ * The legal pages live on Politogy ID (Reference/UI-Platform "Retirement of
491
+ * app.politogyvrm.com": legal pages → `auth.politogyvrm.com`). Resolved per
492
+ * call so a staging host links to the staging IdP.
493
+ */
494
+ declare function footerLinks(): NavFooterLink[];
481
495
  /**
482
496
  * Sidebar footer: legal links AND build metadata (env / commit / version /
483
497
  * date / author) for every user. Reference/UI-Platform "Left bar — required
@@ -500,9 +514,10 @@ declare function useChromeIdentity(fallback?: {
500
514
  }): ResolvedIdentity;
501
515
 
502
516
  /**
503
- * The My Account menu config — profile/org links into VRM core, real roles
504
- * from the user's core organizations and the signed-in account. No theme
505
- * control: the product is light only (Reference/UI-Platform).
517
+ * The My Account menu config — the profile link into Politogy ID, the
518
+ * organization link into the Settings app, real roles from the user's
519
+ * organizations and the signed-in account. No theme control: the product is
520
+ * light only (Reference/UI-Platform).
506
521
  */
507
522
  declare function useChromeUserMenu({ userId, userName, email, }: {
508
523
  userId: string;
@@ -550,4 +565,4 @@ type UseChromeModeArg = ModeId | {
550
565
  */
551
566
  declare function useChromeMode(arg?: UseChromeModeArg): NavMode;
552
567
 
553
- export { type BootPhase, type BootProgress, type BootStageId, type ChromeDevNotesConfig, type ChromeIdentity, ChromeTopBarActions, type ControlledOrgState, LoadingScreen, POLITOGY_APPS, PolitogyAppChrome, PolitogyAppFrame, type PolitogyAppKey, type PolitogyAppMode, type PolitogyAppSession, type PolitogyBuildMeta, type PolitogyFrameData, type PolitogyFrameGrant, type PolitogyGrantedFrame, type ResolvedIdentity, type TokenOrgState, deriveBreadcrumbs, looksLikeEmail, modeLandingHref, resolveIdentity, standardNavIcons, useChromeFooter, useChromeIdentity, useChromeMode, useChromeState, useChromeUserMenu, useIsSuperAdmin };
568
+ export { type BootPhase, type BootProgress, type BootStageId, type ChromeDevNotesConfig, type ChromeIdentity, ChromeTopBarActions, type ControlledOrgState, LoadingScreen, POLITOGY_APPS, PolitogyAppChrome, PolitogyAppFrame, type PolitogyAppKey, type PolitogyAppMode, type PolitogyAppSession, type PolitogyBuildMeta, type PolitogyFrameData, type PolitogyFrameGrant, type PolitogyGrantedFrame, type ResolvedIdentity, type TokenOrgState, deriveBreadcrumbs, footerLinks, looksLikeEmail, modeLandingHref, resolveIdentity, standardNavIcons, useChromeFooter, useChromeIdentity, useChromeMode, useChromeState, useChromeUserMenu, useIsSuperAdmin };
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { S as StandardNavIconKey, f as NavIcon, N as NavItem, g as NavBreadcrumb, h as StandardNavMode, i as NavLinkComponent, j as NavChromeFetcher, k as NavMode, l as NavUserMenu, m as NavOrgOption, b as NotificationsAdapter, o as NavFooter, p as NavDisplayMode } from './index-KGYMc_1i.js';
3
+ import { S as StandardNavIconKey, f as NavIcon, N as NavItem, g as NavBreadcrumb, h as StandardNavMode, i as NavLinkComponent, j as NavChromeFetcher, k as NavMode, l as NavUserMenu, m as NavOrgOption, b as NotificationsAdapter, o as NavFooterLink, p as NavFooter, q as NavDisplayMode } from './index-bYu6DxNt.js';
4
4
  import './theme-preference.js';
5
5
 
6
6
  /**
@@ -375,6 +375,14 @@ type ChromeState = {
375
375
  * account and flashes as the wrong organization.
376
376
  */
377
377
  orgsLoading: boolean;
378
+ /**
379
+ * An org switch is in flight: the pill already shows the new org, but the
380
+ * app's token (and so every chrome read made with it) still carries the old
381
+ * one until `onReexchange` settles. Readers whose answer depends on the org
382
+ * wait for this to clear instead of caching the old org's answer under the
383
+ * new org's key.
384
+ */
385
+ orgPending: boolean;
378
386
  navDisplay: NavDisplayMode;
379
387
  setNavDisplay: (m: NavDisplayMode) => void;
380
388
  };
@@ -478,6 +486,12 @@ declare function PolitogyAppChrome({ storagePrefix, proxyBasePath, fetchJson: fe
478
486
  declare function ChromeTopBarActions(): react_jsx_runtime.JSX.Element | null;
479
487
  /** True when any core-org membership carries a super-admin tier. */
480
488
  declare function useIsSuperAdmin(): boolean;
489
+ /**
490
+ * The legal pages live on Politogy ID (Reference/UI-Platform "Retirement of
491
+ * app.politogyvrm.com": legal pages → `auth.politogyvrm.com`). Resolved per
492
+ * call so a staging host links to the staging IdP.
493
+ */
494
+ declare function footerLinks(): NavFooterLink[];
481
495
  /**
482
496
  * Sidebar footer: legal links AND build metadata (env / commit / version /
483
497
  * date / author) for every user. Reference/UI-Platform "Left bar — required
@@ -500,9 +514,10 @@ declare function useChromeIdentity(fallback?: {
500
514
  }): ResolvedIdentity;
501
515
 
502
516
  /**
503
- * The My Account menu config — profile/org links into VRM core, real roles
504
- * from the user's core organizations and the signed-in account. No theme
505
- * control: the product is light only (Reference/UI-Platform).
517
+ * The My Account menu config — the profile link into Politogy ID, the
518
+ * organization link into the Settings app, real roles from the user's
519
+ * organizations and the signed-in account. No theme control: the product is
520
+ * light only (Reference/UI-Platform).
506
521
  */
507
522
  declare function useChromeUserMenu({ userId, userName, email, }: {
508
523
  userId: string;
@@ -550,4 +565,4 @@ type UseChromeModeArg = ModeId | {
550
565
  */
551
566
  declare function useChromeMode(arg?: UseChromeModeArg): NavMode;
552
567
 
553
- export { type BootPhase, type BootProgress, type BootStageId, type ChromeDevNotesConfig, type ChromeIdentity, ChromeTopBarActions, type ControlledOrgState, LoadingScreen, POLITOGY_APPS, PolitogyAppChrome, PolitogyAppFrame, type PolitogyAppKey, type PolitogyAppMode, type PolitogyAppSession, type PolitogyBuildMeta, type PolitogyFrameData, type PolitogyFrameGrant, type PolitogyGrantedFrame, type ResolvedIdentity, type TokenOrgState, deriveBreadcrumbs, looksLikeEmail, modeLandingHref, resolveIdentity, standardNavIcons, useChromeFooter, useChromeIdentity, useChromeMode, useChromeState, useChromeUserMenu, useIsSuperAdmin };
568
+ export { type BootPhase, type BootProgress, type BootStageId, type ChromeDevNotesConfig, type ChromeIdentity, ChromeTopBarActions, type ControlledOrgState, LoadingScreen, POLITOGY_APPS, PolitogyAppChrome, PolitogyAppFrame, type PolitogyAppKey, type PolitogyAppMode, type PolitogyAppSession, type PolitogyBuildMeta, type PolitogyFrameData, type PolitogyFrameGrant, type PolitogyGrantedFrame, type ResolvedIdentity, type TokenOrgState, deriveBreadcrumbs, footerLinks, looksLikeEmail, modeLandingHref, resolveIdentity, standardNavIcons, useChromeFooter, useChromeIdentity, useChromeMode, useChromeState, useChromeUserMenu, useIsSuperAdmin };
@@ -1,11 +1,11 @@
1
1
  "use client";
2
2
  import { broadcastLogout, watchLogout } from './chunk-LL6LSJAH.js';
3
- import { clearBetaBannerDismissal, standardPolitogyNav, standardNavIcons, isNavItemActive, NavAppShell } from './chunk-DXJOADNV.js';
4
- export { standardNavIcons } from './chunk-DXJOADNV.js';
5
- import { warnDeprecated, NavChromeProvider, TopBarWidgetSlot, FuelAction, SpecOverlayAction, NotificationsAction, SupportAction, useChromeMe, useNavChromeDedupedFetch, useChromeOrgs, useNavChromeFetcher } from './chunk-TUK2IEL5.js';
3
+ import { clearBetaBannerDismissal, standardPolitogyNav, standardNavIcons, isNavItemActive, NavAppShell } from './chunk-BU4NXTLF.js';
4
+ export { standardNavIcons } from './chunk-BU4NXTLF.js';
5
+ import { warnDeprecated, NavChromeProvider, TopBarWidgetSlot, FuelAction, SpecOverlayAction, NotificationsAction, SupportAction, useChromeMe, useNavChromeDedupedFetch, useChromeOrgs, useNavChromeFetcher } from './chunk-L73FZKGE.js';
6
6
  import './chunk-BHRVZPZ7.js';
7
7
  import { NAV_DISPLAY_DEFAULT, resolveNavDisplay, writeNavDisplayLocal, writeNavDisplayCookie, isNavDisplayPreference, NAV_DISPLAY_STORAGE_KEY, readNavDisplayCookie } from './chunk-7YVJ7HQG.js';
8
- import { readOrgSelectorFromUrl, matchOrgSelector, isOrgId, switchActiveOrg, ACTIVE_ORG_QUERY_PARAM, ORG_ID_QUERY_PARAM, orgIdTail, syncOrgIdInUrl, writeActiveOrgCookie, resolveActiveOrg, readActiveOrgCookie } from './chunk-FBUF7LUE.js';
8
+ import { authBaseUrl, orgIdTail, settingsBaseUrl, ORG_ID_QUERY_PARAM, readOrgSelectorFromUrl, matchOrgSelector, syncOrgIdInUrl, isOrgId, switchActiveOrg, ACTIVE_ORG_QUERY_PARAM, writeActiveOrgCookie, resolveActiveOrg, readActiveOrgCookie } from './chunk-5LO5W7W5.js';
9
9
  import { createContext, useMemo, useRef, useEffect, useState, useCallback, useContext } from 'react';
10
10
  import { DevNotesMenu, createDevNotesClient, DevNotesProvider, DevNotesTaskListModal, DevNotesOverlay } from '@the-portland-company/devnotes';
11
11
  import { LuNotebookPen, LuContactRound, LuMegaphone, LuFilePenLine } from 'react-icons/lu';
@@ -889,16 +889,6 @@ function FrameBody({
889
889
  }
890
890
  var ORG_STORAGE_KEY = "vrm.activeOrg";
891
891
  var MODE_STORAGE_KEY = "vrm.activeMode";
892
- var CORE_BASE_URL = "https://app.politogyvrm.com";
893
- var CORE_BASE_URL_STAGING = "https://staging-app.politogyvrm.com";
894
- function getCoreBaseUrl() {
895
- if (typeof window !== "undefined") {
896
- if (window.location.hostname.toLowerCase().includes("staging")) {
897
- return CORE_BASE_URL_STAGING;
898
- }
899
- }
900
- return CORE_BASE_URL;
901
- }
902
892
  var ChromeStateContext = createContext(null);
903
893
  function useChromeState() {
904
894
  return useContext(ChromeStateContext);
@@ -953,7 +943,13 @@ function TokenChromeStateProvider({
953
943
  );
954
944
  }, [overrideOrg, tokenOrg.orgId]);
955
945
  useEffect(() => {
956
- if (pendingOrg && tokenOrg.orgId === pendingOrg) setPendingOrg(null);
946
+ if (!pendingOrg || tokenOrg.orgId !== pendingOrg) return;
947
+ setPendingOrg(null);
948
+ try {
949
+ const next = syncOrgIdInUrl(window.location.href, pendingOrg);
950
+ if (next) window.history.replaceState(window.history.state, "", next);
951
+ } catch {
952
+ }
957
953
  }, [pendingOrg, tokenOrg.orgId]);
958
954
  const setOrgId = useCallback((id) => {
959
955
  const current = tokenOrgRef.current;
@@ -1016,10 +1012,11 @@ function TokenChromeStateProvider({
1016
1012
  setOrgId,
1017
1013
  orgs,
1018
1014
  orgsLoading: !tokenOrg.orgs && orgsFetching && !orgsError && !fetchedOrgs,
1015
+ orgPending: pendingOrg !== null,
1019
1016
  navDisplay,
1020
1017
  setNavDisplay
1021
1018
  }),
1022
- [orgId, setOrgId, orgs, tokenOrg.orgs, orgsFetching, orgsError, fetchedOrgs, navDisplay, setNavDisplay]
1019
+ [orgId, setOrgId, orgs, tokenOrg.orgs, orgsFetching, orgsError, fetchedOrgs, pendingOrg, navDisplay, setNavDisplay]
1023
1020
  );
1024
1021
  return /* @__PURE__ */ jsx(ChromeStateContext.Provider, { value, children });
1025
1022
  }
@@ -1162,6 +1159,7 @@ function ChromeStateProvider({
1162
1159
  rawRole: o.rawRole ?? null
1163
1160
  })),
1164
1161
  orgsLoading: false,
1162
+ orgPending: false,
1165
1163
  navDisplay,
1166
1164
  setNavDisplay
1167
1165
  };
@@ -1180,6 +1178,7 @@ function ChromeStateProvider({
1180
1178
  // Loading until the fetch settles. On error we stop loading so the frame
1181
1179
  // falls back to the app label rather than shimmering forever.
1182
1180
  orgsLoading: orgsFetching && !orgsError && !orgs,
1181
+ orgPending: false,
1183
1182
  navDisplay,
1184
1183
  setNavDisplay
1185
1184
  };
@@ -1386,9 +1385,15 @@ function useIsSuperAdmin() {
1386
1385
  const state = useChromeState();
1387
1386
  return (state?.orgs ?? []).some((o) => /super/i.test(o.rawRole ?? ""));
1388
1387
  }
1389
- var FOOTER_LINKS = [
1390
- { label: "Privacy", href: `${CORE_BASE_URL}/privacy-policy`, external: true },
1391
- { label: "Terms", href: `${CORE_BASE_URL}/terms-and-conditions`, external: true },
1388
+ function footerLinks() {
1389
+ const auth = authBaseUrl();
1390
+ return [
1391
+ { label: "Privacy", href: `${auth}/privacy-policy`, external: true },
1392
+ { label: "Terms", href: `${auth}/terms-and-conditions`, external: true },
1393
+ ...FOOTER_LINKS_STATIC
1394
+ ];
1395
+ }
1396
+ var FOOTER_LINKS_STATIC = [
1392
1397
  {
1393
1398
  label: "Subscriptions",
1394
1399
  href: "https://politogyvrm.com/subscription-cancellation-policy",
@@ -1397,7 +1402,7 @@ var FOOTER_LINKS = [
1397
1402
  ];
1398
1403
  function useChromeFooter(meta) {
1399
1404
  return useMemo(
1400
- () => ({ links: FOOTER_LINKS, ...meta }),
1405
+ () => ({ links: footerLinks(), ...meta }),
1401
1406
  [meta.envLabel, meta.version, meta.commit, meta.commitDate, meta.commitAuthor]
1402
1407
  );
1403
1408
  }
@@ -1418,15 +1423,17 @@ function useChromeUserMenu({
1418
1423
  }) {
1419
1424
  const state = useChromeState();
1420
1425
  const activeOrg = state?.orgs.find((o) => o.id === state.orgId) ?? null;
1421
- const orgSuffix = activeOrg ? `?org=${activeOrg.id}` : "";
1422
- const coreBase = getCoreBaseUrl();
1426
+ const tail = orgIdTail(activeOrg?.id);
1427
+ const orgSuffix = tail ? `?${ORG_ID_QUERY_PARAM}=${tail}` : "";
1428
+ const auth = authBaseUrl();
1429
+ const settings = settingsBaseUrl();
1423
1430
  return {
1424
- // My Profile is global — NOT org-suffixed (main-app ShellChromeBridge).
1425
- myProfileHref: `${coreBase}/my-profile`,
1426
- organizationSettingsHref: `${coreBase}/organization-settings${orgSuffix}`,
1431
+ // My Profile is global — NOT org-suffixed.
1432
+ myProfileHref: `${auth}/my-profile`,
1433
+ organizationSettingsHref: `${settings}/organization-settings${orgSuffix}`,
1427
1434
  roles: (state?.orgs ?? []).filter((o) => o.rawRole || o.role).map((o) => ({ role: o.rawRole ?? o.role, orgName: o.name })),
1428
1435
  accounts: [{ id: userId, name: userName, email, avatarUrl: null, active: true }],
1429
- addAccountHref: `${coreBase}/my-profile#accounts`,
1436
+ addAccountHref: `${auth}/my-profile#accounts`,
1430
1437
  // No theme control: the product is light only (Reference/UI-Platform
1431
1438
  // "Theme — light only"; shell 0.73.0 stopped applying dark). The account
1432
1439
  // menu rendered an "Appearance" radio with one option until 0.77.0.
@@ -1477,6 +1484,7 @@ function useChromeMode(arg = {}) {
1477
1484
  const dedupedFetch = useNavChromeDedupedFetch();
1478
1485
  const { me, loaded: meLoaded } = useChromeMe();
1479
1486
  const orgId = ctx?.orgId ?? null;
1487
+ const orgPending = ctx?.orgPending ?? false;
1480
1488
  const [entitled, setEntitled] = useState(null);
1481
1489
  const [selectedModeId, setSelectedModeId] = useState(null);
1482
1490
  useEffect(() => {
@@ -1488,6 +1496,7 @@ function useChromeMode(arg = {}) {
1488
1496
  }, []);
1489
1497
  useEffect(() => {
1490
1498
  if (!dedupedFetch || !orgId || !meLoaded) return;
1499
+ if (orgPending) return;
1491
1500
  const bootMe = me;
1492
1501
  if (bootMe && bootMe.account === orgId && bootMe.modes !== void 0) {
1493
1502
  setEntitled(bootMe.modes ?? null);
@@ -1503,7 +1512,7 @@ function useChromeMode(arg = {}) {
1503
1512
  return () => {
1504
1513
  cancelled = true;
1505
1514
  };
1506
- }, [dedupedFetch, me, meLoaded, orgId]);
1515
+ }, [dedupedFetch, me, meLoaded, orgId, orgPending]);
1507
1516
  const options = MODE_DEFS.filter((m) => entitled?.[m.id]);
1508
1517
  const pinned = pinnedModeId ? MODE_DEFS.find((m) => m.id === pinnedModeId) ?? null : null;
1509
1518
  const selected = selectedModeId ? options.find((m) => m.id === selectedModeId) ?? null : null;
@@ -1539,6 +1548,6 @@ function useChromeMode(arg = {}) {
1539
1548
  };
1540
1549
  }
1541
1550
 
1542
- export { ChromeTopBarActions, LoadingScreen, POLITOGY_APPS, PolitogyAppChrome, PolitogyAppFrame, deriveBreadcrumbs, looksLikeEmail, modeLandingHref, resolveIdentity, useChromeFooter, useChromeIdentity, useChromeMode, useChromeState, useChromeUserMenu, useIsSuperAdmin };
1551
+ export { ChromeTopBarActions, LoadingScreen, POLITOGY_APPS, PolitogyAppChrome, PolitogyAppFrame, deriveBreadcrumbs, footerLinks, looksLikeEmail, modeLandingHref, resolveIdentity, useChromeFooter, useChromeIdentity, useChromeMode, useChromeState, useChromeUserMenu, useIsSuperAdmin };
1543
1552
  //# sourceMappingURL=app-chrome.js.map
1544
1553
  //# sourceMappingURL=app-chrome.js.map