@the-portland-company/shell 0.96.0 → 0.96.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## 0.96.2
2
+
3
+ The org switcher list shows each organization's icon (Specs/Left-Navigation §6: each org "with its icon mark, name and short ID"; Ben 2026-11-04: the Primary logo showed in the card, but the list did not show the icon).
4
+
5
+ - **Switcher rows use `iconUrl`.** A row shows the org's Brand Kit icon on a white tile, uncropped (`object-contain`). Without an icon it shows the Primary logo as before, then initials. Each row's mark carries `data-org-option-mark="icon" | "logo" | "initials"`.
6
+ - **`iconUrl` reaches the switcher and the collapsed rail.** `ChromeOrgSummary` gains optional `iconUrl` (sent by the chrome API `/api/orgs` from contacts#425). Every org-list copy in the chrome state (token, controlled and uncontrolled providers) and the active org card in `PolitogyAppFrame` now carry it, so the collapsed rail's `OrgIconMark` gets the icon too. Apps that pass their own `tokenOrg.orgs` or controlled `orgs` should include `iconUrl` from `/api/orgs`.
7
+ - Tests: `__tests__/orgSwitcherIcon.test.tsx`.
8
+
9
+ ## 0.96.1
10
+
11
+ Privacy, Terms and Subscriptions open in a new tab (Ben 2026-11-04: clicking Privacy replaced the app with the public Politogy ID page, with no left bar or top bar).
12
+
13
+ - **Left-bar footer links honor `external`.** `NavFooterLink.external` was documented as "opens in a new tab" but the rail footer ignored it, so every app sent the user away from the app in the same tab. External links now get `target="_blank"` and `rel="noopener noreferrer"`; links without `external` keep opening in the same tab. Every app on the frame gets this with a version bump and no code change.
14
+ - **Privacy and Terms point at the website** (Ben 2026-11-04: "Yes, point them now"): Privacy `https://politogyvrm.com/privacy` (was Politogy ID `/privacy-policy`), Terms `https://politogyvrm.com/terms-of-service` (was `/terms-and-conditions`). Subscriptions is unchanged. `footerLinks()` no longer depends on the host, so staging links to the same public pages.
15
+ - Tests: `__tests__/native.test.tsx` ("opens external legal links in a new tab"), `__tests__/retiredHostLinks.test.tsx` (the three addresses).
16
+
1
17
  ## 0.96.0
2
18
 
3
19
  One shared "⋯" row menu for list rows (Ben 2026-10-26: Email's broadcast menu stuck open, and on the last row Archive and Delete were cut off by the table frame).
@@ -2985,6 +2985,8 @@ function NavSidebar({
2985
2985
  ] }) : null,
2986
2986
  filterOrgs(org.organizations, orgFilter).map((o) => {
2987
2987
  const selected = o.id === org.id;
2988
+ const iconSrc = resolveOrgLogoUrl(o.iconUrl);
2989
+ const logoSrc = iconSrc ? void 0 : resolveOrgLogoUrl(o.logoUrl);
2988
2990
  return /* @__PURE__ */ jsxRuntime.jsxs(
2989
2991
  "button",
2990
2992
  {
@@ -3003,12 +3005,13 @@ function NavSidebar({
3003
3005
  /* @__PURE__ */ jsxRuntime.jsx(
3004
3006
  "span",
3005
3007
  {
3006
- style: { backgroundColor: o.brandColor || ORG_PILL_DEFAULT },
3007
- className: "flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden rounded-full text-[10px] font-bold text-[#FFFFFF]",
3008
- children: resolveOrgLogoUrl(o.logoUrl) ? /* @__PURE__ */ jsxRuntime.jsx(
3008
+ "data-org-option-mark": iconSrc ? "icon" : logoSrc ? "logo" : "initials",
3009
+ style: iconSrc ? void 0 : { backgroundColor: o.brandColor || ORG_PILL_DEFAULT },
3010
+ className: `flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden text-[10px] font-bold text-[#FFFFFF] ${iconSrc ? "rounded-[4px] bg-[#FFFFFF]" : "rounded-full"}`,
3011
+ children: iconSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: iconSrc, alt: "", className: "max-h-full max-w-full object-contain" }) : logoSrc ? /* @__PURE__ */ jsxRuntime.jsx(
3009
3012
  "img",
3010
3013
  {
3011
- src: resolveOrgLogoUrl(o.logoUrl),
3014
+ src: logoSrc,
3012
3015
  alt: "",
3013
3016
  className: "h-full w-full object-cover"
3014
3017
  }
@@ -3180,6 +3183,7 @@ function NavSidebar({
3180
3183
  "a",
3181
3184
  {
3182
3185
  href: safeHref(l.href),
3186
+ ...l.external ? { target: "_blank", rel: "noopener noreferrer" } : {},
3183
3187
  className: "text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] hover:text-[color:var(--sidebar-text,var(--foreground))] hover:underline",
3184
3188
  children: l.label
3185
3189
  }
@@ -5071,6 +5075,7 @@ function FrameBody({
5071
5075
  name: activeCoreOrg.name,
5072
5076
  id: activeCoreOrg.id,
5073
5077
  logoUrl: activeCoreOrg.logoUrl,
5078
+ iconUrl: activeCoreOrg.iconUrl ?? null,
5074
5079
  brandColor: activeCoreOrg.brandColor,
5075
5080
  organizations: coreOrgs,
5076
5081
  onSwitch: chrome?.setOrgId
@@ -5174,6 +5179,7 @@ function TokenChromeStateProvider({
5174
5179
  id: o.id,
5175
5180
  name: o.name,
5176
5181
  logoUrl: o.logoUrl,
5182
+ iconUrl: o.iconUrl ?? null,
5177
5183
  brandColor: o.brandColor,
5178
5184
  role: o.role,
5179
5185
  rawRole: o.rawRole ?? null
@@ -5434,6 +5440,7 @@ function ChromeStateProvider({
5434
5440
  id: o.id,
5435
5441
  name: o.name,
5436
5442
  logoUrl: o.logoUrl,
5443
+ iconUrl: o.iconUrl ?? null,
5437
5444
  brandColor: o.brandColor,
5438
5445
  role: o.role,
5439
5446
  rawRole: o.rawRole ?? null
@@ -5451,6 +5458,7 @@ function ChromeStateProvider({
5451
5458
  id: o.id,
5452
5459
  name: o.name,
5453
5460
  logoUrl: o.logoUrl,
5461
+ iconUrl: o.iconUrl ?? null,
5454
5462
  brandColor: o.brandColor,
5455
5463
  role: o.role,
5456
5464
  rawRole: o.rawRole ?? null
@@ -5668,14 +5676,11 @@ function useIsSuperAdmin() {
5668
5676
  return (state?.orgs ?? []).some((o) => /super/i.test(o.rawRole ?? ""));
5669
5677
  }
5670
5678
  function footerLinks() {
5671
- const auth = authBaseUrl();
5672
- return [
5673
- { label: "Privacy", href: `${auth}/privacy-policy`, external: true },
5674
- { label: "Terms", href: `${auth}/terms-and-conditions`, external: true },
5675
- ...FOOTER_LINKS_STATIC
5676
- ];
5679
+ return FOOTER_LINKS.map((l) => ({ ...l }));
5677
5680
  }
5678
- var FOOTER_LINKS_STATIC = [
5681
+ var FOOTER_LINKS = [
5682
+ { label: "Privacy", href: "https://politogyvrm.com/privacy", external: true },
5683
+ { label: "Terms", href: "https://politogyvrm.com/terms-of-service", external: true },
5679
5684
  {
5680
5685
  label: "Subscriptions",
5681
5686
  href: "https://politogyvrm.com/subscription-cancellation-policy",