@the-portland-company/shell 0.69.0 → 0.70.0
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 +16 -0
- package/dist/app-chrome.cjs +242 -158
- package/dist/app-chrome.cjs.map +1 -1
- package/dist/app-chrome.js +43 -36
- package/dist/app-chrome.js.map +1 -1
- package/dist/{chunk-6UHJV2FH.js → chunk-7YVJ7HQG.js} +41 -3
- package/dist/chunk-7YVJ7HQG.js.map +1 -0
- package/dist/{chunk-WFUWFMCA.js → chunk-CZI66JVG.js} +104 -65
- package/dist/chunk-CZI66JVG.js.map +1 -0
- package/dist/native.cjs +151 -63
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +13 -2
- package/dist/native.d.ts +13 -2
- package/dist/native.js +2 -1
- package/dist/nav-preference.cjs +44 -0
- package/dist/nav-preference.cjs.map +1 -1
- package/dist/nav-preference.d.cts +8 -1
- package/dist/nav-preference.d.ts +8 -1
- package/dist/nav-preference.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-6UHJV2FH.js.map +0 -1
- package/dist/chunk-WFUWFMCA.js.map +0 -1
|
@@ -57,7 +57,45 @@ var cookie=fromCookie();
|
|
|
57
57
|
if(cookie&&VALID.indexOf(cookie)!==-1){var ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}
|
|
58
58
|
if(cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}}
|
|
59
59
|
}catch(e){}})();`;
|
|
60
|
+
var RAIL_STORAGE_KEY = "politogy_rail";
|
|
61
|
+
var RAIL_COOKIE = "politogy_rail";
|
|
62
|
+
var RAIL_DEFAULT = "collapsed";
|
|
63
|
+
function isRailPreference(v) {
|
|
64
|
+
return v === "expanded" || v === "collapsed";
|
|
65
|
+
}
|
|
66
|
+
function readRailPreference() {
|
|
67
|
+
if (typeof document !== "undefined") {
|
|
68
|
+
try {
|
|
69
|
+
const m = document.cookie.match(new RegExp(`(?:^|;\\s*)${RAIL_COOKIE}=([^;]+)`));
|
|
70
|
+
const v = m ? decodeURIComponent(m[1]) : null;
|
|
71
|
+
if (isRailPreference(v)) return v;
|
|
72
|
+
} catch {
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (typeof localStorage !== "undefined") {
|
|
76
|
+
try {
|
|
77
|
+
const v = localStorage.getItem(RAIL_STORAGE_KEY);
|
|
78
|
+
if (isRailPreference(v)) return v;
|
|
79
|
+
} catch {
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return RAIL_DEFAULT;
|
|
83
|
+
}
|
|
84
|
+
function writeRailPreference(pref) {
|
|
85
|
+
if (typeof document === "undefined" || typeof window === "undefined") return;
|
|
86
|
+
const host = window.location.hostname;
|
|
87
|
+
const domainAttr = /(^|\.)politogyvrm\.com$/i.test(host) ? "; Domain=.politogyvrm.com" : "";
|
|
88
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
89
|
+
try {
|
|
90
|
+
document.cookie = `${RAIL_COOKIE}=${pref}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`;
|
|
91
|
+
} catch {
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
localStorage.setItem(RAIL_STORAGE_KEY, pref);
|
|
95
|
+
} catch {
|
|
96
|
+
}
|
|
97
|
+
}
|
|
60
98
|
|
|
61
|
-
export { LEGACY_NAV_DISPLAY_KEY, NAV_DISPLAY_COOKIE, NAV_DISPLAY_DEFAULT, NAV_DISPLAY_PREPAINT_SCRIPT, NAV_DISPLAY_STORAGE_KEY, isNavDisplayPreference, readNavDisplayCookie, readNavDisplayLocal, resolveNavDisplay, writeNavDisplayCookie, writeNavDisplayLocal };
|
|
62
|
-
//# sourceMappingURL=chunk-
|
|
63
|
-
//# sourceMappingURL=chunk-
|
|
99
|
+
export { LEGACY_NAV_DISPLAY_KEY, NAV_DISPLAY_COOKIE, NAV_DISPLAY_DEFAULT, NAV_DISPLAY_PREPAINT_SCRIPT, NAV_DISPLAY_STORAGE_KEY, RAIL_COOKIE, RAIL_DEFAULT, RAIL_STORAGE_KEY, isNavDisplayPreference, isRailPreference, readNavDisplayCookie, readNavDisplayLocal, readRailPreference, resolveNavDisplay, writeNavDisplayCookie, writeNavDisplayLocal, writeRailPreference };
|
|
100
|
+
//# sourceMappingURL=chunk-7YVJ7HQG.js.map
|
|
101
|
+
//# sourceMappingURL=chunk-7YVJ7HQG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/nav-preference.ts"],"names":[],"mappings":"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","file":"chunk-7YVJ7HQG.js","sourcesContent":["// Universal navigation-display preference — the same cross-app contract as the\n// theme (see ./theme-preference, which this deliberately mirrors).\n//\n// The user's choice of how navigation renders (Menu / Tabs / Both) follows the\n// authenticated user across every Politogy app + subdomain. Three layers:\n// 1. VRM Core `profiles.nav_display_preference` — source of truth, persisted\n// via the chrome API (`PATCH me/preferences { navDisplay }`) and read back\n// from `GET me` (`navDisplay`).\n// 2. `.politogyvrm.com` cookie `politogy_nav_display` — the cross-subdomain\n// vehicle (app session cookies are host-only, and so is localStorage).\n// 3. localStorage — same-app fast reads and cross-tab `storage` events.\n//\n// Before this existed the preference lived ONLY in localStorage under\n// `vrm.navDisplay`, which is per-ORIGIN: every app subdomain kept its own copy\n// and a freshly opened app booted the default, so the setting appeared not to\n// hold when moving between apps. The legacy key is still read as a fallback so\n// an existing local choice survives the upgrade.\n//\n// Server-safe (no 'use client'): layouts may import NAV_DISPLAY_PREPAINT_SCRIPT.\n\nexport type NavDisplayPreference = 'menu' | 'tabs' | 'both'\n\n// One key for BOTH the localStorage store and the cross-subdomain cookie, so a\n// choice in one app is the same key in the next.\nexport const NAV_DISPLAY_STORAGE_KEY = 'politogy_nav_display'\nexport const NAV_DISPLAY_COOKIE = 'politogy_nav_display'\n\n/** Pre-0.37 host-only key. Read for migration; never written. */\nexport const LEGACY_NAV_DISPLAY_KEY = 'vrm.navDisplay'\n\nexport const NAV_DISPLAY_DEFAULT: NavDisplayPreference = 'both'\n\nconst VALID: readonly NavDisplayPreference[] = ['menu', 'tabs', 'both']\n\nexport function isNavDisplayPreference(v: unknown): v is NavDisplayPreference {\n return typeof v === 'string' && (VALID as readonly string[]).includes(v)\n}\n\n/** Read the shared cookie (browser only; null on the server or when unset). */\nexport function readNavDisplayCookie(): NavDisplayPreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isNavDisplayPreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Same host-aware scoping as the theme cookie: parent domain on\n// *.politogyvrm.com so every app subdomain reads it, host-only elsewhere\n// (localhost, *.pages.dev preview) because browsers silently drop a mismatched\n// Domain attribute. 1-year, SameSite=Lax, Secure on https.\nexport function writeNavDisplayCookie(pref: NavDisplayPreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${NAV_DISPLAY_COOKIE}=${encodeURIComponent(\n pref,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/** Read the local store, falling back to the legacy host-only key. */\nexport function readNavDisplayLocal(): NavDisplayPreference | null {\n if (typeof localStorage === 'undefined') return null\n try {\n const current = localStorage.getItem(NAV_DISPLAY_STORAGE_KEY)\n if (isNavDisplayPreference(current)) return current\n const legacy = localStorage.getItem(LEGACY_NAV_DISPLAY_KEY)\n return isNavDisplayPreference(legacy) ? legacy : null\n } catch {\n return null\n }\n}\n\nexport function writeNavDisplayLocal(pref: NavDisplayPreference): void {\n if (typeof localStorage === 'undefined') return\n try {\n localStorage.setItem(NAV_DISPLAY_STORAGE_KEY, pref)\n } catch {\n /* storage unavailable */\n }\n}\n\n/** Boot precedence: cookie → localStorage (incl. legacy) → default. */\nexport function resolveNavDisplay(): NavDisplayPreference {\n return readNavDisplayCookie() ?? readNavDisplayLocal() ?? NAV_DISPLAY_DEFAULT\n}\n\n// Inline pre-paint script — optional, and the mirror of THEME_PREPAINT_SCRIPT.\n// Nav display has no paint-blocking visual (the frame is client-rendered), but\n// seeding localStorage from the cookie before hydration keeps the first render\n// on the synced value instead of the default. Self-contained and silent.\nexport const NAV_DISPLAY_PREPAINT_SCRIPT = `(function(){try{\nvar KEY=${JSON.stringify(NAV_DISPLAY_STORAGE_KEY)};\nvar VALID=[\"menu\",\"tabs\",\"both\"];\nfunction fromCookie(){try{var m=document.cookie.match(/(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}\nvar cookie=fromCookie();\nif(cookie&&VALID.indexOf(cookie)!==-1){var ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}\nif(cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}}\n}catch(e){}})();`\n\n// ---------------------------------------------------------------------------\n// Rail expand preference — Left-Navigation §11.6: below `md` the rail\n// collapses to the 64px icon rail; \"the user can also collapse and expand it;\n// the choice is remembered per user\". Same cookie + localStorage layers as the\n// nav-display preference above (no server column yet), so the choice follows\n// the user across every app subdomain and survives reloads. Only an explicit\n// Expand / Collapse writes it; a route change that closes the overlay does not.\n// ---------------------------------------------------------------------------\n\nexport type RailPreference = 'expanded' | 'collapsed'\n\nexport const RAIL_STORAGE_KEY = 'politogy_rail'\nexport const RAIL_COOKIE = 'politogy_rail'\nexport const RAIL_DEFAULT: RailPreference = 'collapsed'\n\nexport function isRailPreference(v: unknown): v is RailPreference {\n return v === 'expanded' || v === 'collapsed'\n}\n\nexport function readRailPreference(): RailPreference {\n if (typeof document !== 'undefined') {\n try {\n const m = document.cookie.match(new RegExp(`(?:^|;\\\\s*)${RAIL_COOKIE}=([^;]+)`))\n const v = m ? decodeURIComponent(m[1]) : null\n if (isRailPreference(v)) return v\n } catch {\n /* ignore */\n }\n }\n if (typeof localStorage !== 'undefined') {\n try {\n const v = localStorage.getItem(RAIL_STORAGE_KEY)\n if (isRailPreference(v)) return v\n } catch {\n /* ignore */\n }\n }\n return RAIL_DEFAULT\n}\n\nexport function writeRailPreference(pref: RailPreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n try {\n document.cookie = `${RAIL_COOKIE}=${pref}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n } catch {\n /* ignore */\n }\n try {\n localStorage.setItem(RAIL_STORAGE_KEY, pref)\n } catch {\n /* storage unavailable */\n }\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { warnDeprecated } from './chunk-LPSBSAF3.js';
|
|
2
2
|
import { readThemeCookie, THEME_STORAGE_KEY, isThemePreference, applyThemePreference, readPendingThemeChoice, writeThemeCookie, clearPendingThemeChoice, markThemeChoicePending } from './chunk-NHBNM5P3.js';
|
|
3
|
+
import { readRailPreference, writeRailPreference } from './chunk-7YVJ7HQG.js';
|
|
3
4
|
import { createContext, useRef, useState, useEffect, useContext, useCallback, useMemo, useSyncExternalStore } from 'react';
|
|
4
5
|
import clsx from 'clsx';
|
|
5
6
|
import { FiUser, FiSettings, FiMessageSquare, FiMail, FiInfo, FiSun, FiMoon, FiHelpCircle, FiLifeBuoy, FiAlertCircle, FiAlertTriangle, FiBell, FiGrid, FiZap, FiBatteryCharging, FiBattery } from 'react-icons/fi';
|
|
@@ -1763,7 +1764,6 @@ var PHONEBANK_ORIGIN = "https://phonebank.politogyvrm.com/";
|
|
|
1763
1764
|
var CANVASS_ORIGIN = "https://canvass.politogyvrm.com/";
|
|
1764
1765
|
var SIGNS_ORIGIN = "https://signs.politogyvrm.com/";
|
|
1765
1766
|
var POLLS_ORIGIN = "https://polls.politogyvrm.com/";
|
|
1766
|
-
var CONTACTS_TRIBES = "https://contacts.politogyvrm.com/tribes";
|
|
1767
1767
|
var PETITION_MODE_ORIGIN = "https://petition-mode.politogyvrm.com/";
|
|
1768
1768
|
function applyHiddenItems(items, hidden) {
|
|
1769
1769
|
if (!hidden || hidden.length === 0) return items;
|
|
@@ -1833,10 +1833,6 @@ var APP_POLLS_CHILDREN = [
|
|
|
1833
1833
|
{ label: "Command Center", icon: "grid", href: "https://polls.politogyvrm.com/" },
|
|
1834
1834
|
{ label: "New Poll", icon: "edit", href: "https://polls.politogyvrm.com/polls/new" }
|
|
1835
1835
|
];
|
|
1836
|
-
var APP_CTAS_CHILDREN = [
|
|
1837
|
-
{ label: "CTAs", icon: "list", href: "https://ctas.politogyvrm.com/" },
|
|
1838
|
-
{ label: "Canvas", icon: "edit", href: "https://ctas.politogyvrm.com/?tab=canvas" }
|
|
1839
|
-
];
|
|
1840
1836
|
var APP_A2P_CHILDREN = [
|
|
1841
1837
|
{ label: "Dashboard", icon: "grid", path: "dashboard" },
|
|
1842
1838
|
{ label: "Compose", icon: "edit", path: "compose" },
|
|
@@ -1884,16 +1880,27 @@ function standardPolitogyNav(opts) {
|
|
|
1884
1880
|
return { label: c.label, icon: icon(c.icon), href: withOrg(withMode) };
|
|
1885
1881
|
});
|
|
1886
1882
|
};
|
|
1883
|
+
const accountRows = () => [
|
|
1884
|
+
{ kind: "section", label: "Account" },
|
|
1885
|
+
// My Profile is global — NOT org-suffixed (main-app ShellChromeBridge).
|
|
1886
|
+
{ label: "My profile", icon: icon("circleUser"), href: withOrg(abs("/my-profile")) },
|
|
1887
|
+
{
|
|
1888
|
+
label: "Organization settings",
|
|
1889
|
+
icon: icon("settings"),
|
|
1890
|
+
href: withOrg(abs("/organization-settings")),
|
|
1891
|
+
children: branches(ORG_SETTINGS_CHILDREN)
|
|
1892
|
+
}
|
|
1893
|
+
];
|
|
1887
1894
|
const buildRelationship = () => {
|
|
1888
1895
|
const contacts = opts.contactsItem ? {
|
|
1889
1896
|
label: "Contacts",
|
|
1890
|
-
icon: icon("
|
|
1897
|
+
icon: icon("usersRound"),
|
|
1891
1898
|
href: opts.contactsItem.href,
|
|
1892
1899
|
children: opts.contactsItem.children,
|
|
1893
1900
|
badge: opts.contactsItem.count ?? void 0
|
|
1894
1901
|
} : {
|
|
1895
1902
|
label: "Contacts",
|
|
1896
|
-
icon: icon("
|
|
1903
|
+
icon: icon("usersRound"),
|
|
1897
1904
|
href: withOrg(`${CONTACTS_APP}/`),
|
|
1898
1905
|
children: APP_CONTACTS_CHILDREN.map((c) => ({
|
|
1899
1906
|
label: c.label,
|
|
@@ -1903,7 +1910,7 @@ function standardPolitogyNav(opts) {
|
|
|
1903
1910
|
};
|
|
1904
1911
|
return [
|
|
1905
1912
|
{ kind: "section", label: "Relationship" },
|
|
1906
|
-
{ label: "Dashboard", icon: icon("
|
|
1913
|
+
{ label: "Dashboard", icon: icon("layoutDashboard"), href: withOrg(abs("/relationship/dashboard")) },
|
|
1907
1914
|
contacts,
|
|
1908
1915
|
{
|
|
1909
1916
|
label: "Email broadcast",
|
|
@@ -1926,40 +1933,20 @@ function standardPolitogyNav(opts) {
|
|
|
1926
1933
|
},
|
|
1927
1934
|
{ kind: "section", label: "Collect" },
|
|
1928
1935
|
// Carries no top-level href in VRM core (parent row only toggles).
|
|
1929
|
-
{ label: "Calls to action", icon: icon("
|
|
1936
|
+
{ label: "Calls to action", icon: icon("mousePointerClick"), children: leaves(CTA_CHILDREN) },
|
|
1930
1937
|
{
|
|
1931
1938
|
label: "Forms",
|
|
1932
|
-
icon: icon("
|
|
1939
|
+
icon: icon("fileText"),
|
|
1933
1940
|
href: withOrg("https://forms.politogyvrm.com/"),
|
|
1934
1941
|
children: APP_FORMS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) }))
|
|
1935
1942
|
},
|
|
1936
1943
|
{
|
|
1937
1944
|
label: "Surveys",
|
|
1938
|
-
icon: icon("
|
|
1945
|
+
icon: icon("clipboardList"),
|
|
1939
1946
|
href: withOrg("https://surveys.politogyvrm.com/surveys"),
|
|
1940
1947
|
children: APP_SURVEYS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) }))
|
|
1941
1948
|
},
|
|
1942
|
-
|
|
1943
|
-
label: "Polls",
|
|
1944
|
-
icon: icon("barChart"),
|
|
1945
|
-
href: withOrg("https://polls.politogyvrm.com/"),
|
|
1946
|
-
children: APP_POLLS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) }))
|
|
1947
|
-
},
|
|
1948
|
-
{
|
|
1949
|
-
label: "CTAs",
|
|
1950
|
-
icon: icon("layout"),
|
|
1951
|
-
href: withOrg("https://ctas.politogyvrm.com/"),
|
|
1952
|
-
children: APP_CTAS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) }))
|
|
1953
|
-
},
|
|
1954
|
-
{ kind: "section", label: "Account" },
|
|
1955
|
-
// My Profile is global — NOT org-suffixed (main-app ShellChromeBridge).
|
|
1956
|
-
{ label: "My profile", icon: icon("user"), href: withOrg(abs("/my-profile")) },
|
|
1957
|
-
{
|
|
1958
|
-
label: "Organization settings",
|
|
1959
|
-
icon: icon("settings"),
|
|
1960
|
-
href: withOrg(abs("/organization-settings")),
|
|
1961
|
-
children: branches(ORG_SETTINGS_CHILDREN)
|
|
1962
|
-
}
|
|
1949
|
+
...accountRows()
|
|
1963
1950
|
];
|
|
1964
1951
|
};
|
|
1965
1952
|
const buildCampaign = () => {
|
|
@@ -1968,40 +1955,57 @@ function standardPolitogyNav(opts) {
|
|
|
1968
1955
|
...opts.campaignAvailability
|
|
1969
1956
|
};
|
|
1970
1957
|
const rows = [
|
|
1971
|
-
|
|
1972
|
-
|
|
1958
|
+
// Left-Navigation §9.2: Race data -> Research -> GOTV -> Account.
|
|
1959
|
+
// Battleground is the Campaign landing page; there is no Campaign
|
|
1960
|
+
// Dashboard row, and Voter Contact and Tribes have no row.
|
|
1961
|
+
{ kind: "section", label: "Race data" },
|
|
1962
|
+
{ label: "Battleground", icon: icon("crosshair"), href: withOrg(abs("/campaign/battleground")) },
|
|
1963
|
+
{ label: "District data", icon: icon("landmark"), href: withOrg(abs("/campaign/districts")) },
|
|
1964
|
+
{ kind: "section", label: "Research" },
|
|
1973
1965
|
{
|
|
1974
|
-
label: "
|
|
1975
|
-
icon: icon("
|
|
1976
|
-
href: withOrg(
|
|
1977
|
-
children:
|
|
1978
|
-
flag: "
|
|
1966
|
+
label: "Polling",
|
|
1967
|
+
icon: icon("chartNoAxes"),
|
|
1968
|
+
href: withOrg(POLLS_ORIGIN),
|
|
1969
|
+
children: APP_POLLS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),
|
|
1970
|
+
flag: "polling"
|
|
1979
1971
|
},
|
|
1972
|
+
{ kind: "section", label: "GOTV" },
|
|
1980
1973
|
{
|
|
1981
|
-
label: "
|
|
1974
|
+
label: "Field canvassing",
|
|
1975
|
+
icon: icon("doorOpen"),
|
|
1976
|
+
href: withOrg(CANVASS_ORIGIN),
|
|
1977
|
+
children: appLeaves(CANVASS_ORIGIN, APP_CANVASS_CHILDREN),
|
|
1978
|
+
flag: "canvass"
|
|
1979
|
+
},
|
|
1980
|
+
{
|
|
1981
|
+
label: "Phone banking",
|
|
1982
1982
|
icon: icon("phone"),
|
|
1983
1983
|
href: withOrg(PHONEBANK_ORIGIN),
|
|
1984
1984
|
children: appLeaves(PHONEBANK_ORIGIN, APP_PHONEBANK_CHILDREN),
|
|
1985
1985
|
flag: "phonebank"
|
|
1986
1986
|
},
|
|
1987
1987
|
{
|
|
1988
|
-
label: "
|
|
1989
|
-
icon: icon("
|
|
1990
|
-
href: withOrg(
|
|
1991
|
-
children: appLeaves(
|
|
1992
|
-
flag: "
|
|
1988
|
+
label: "A2P texting",
|
|
1989
|
+
icon: icon("messageSquare"),
|
|
1990
|
+
href: withOrg(A2P_ORIGIN),
|
|
1991
|
+
children: appLeaves(A2P_ORIGIN, APP_A2P_CHILDREN),
|
|
1992
|
+
flag: "a2p"
|
|
1993
1993
|
},
|
|
1994
1994
|
{
|
|
1995
|
-
label: "Sign
|
|
1996
|
-
icon: icon("
|
|
1995
|
+
label: "Sign mapping",
|
|
1996
|
+
icon: icon("signpost"),
|
|
1997
1997
|
href: withOrg(SIGNS_ORIGIN),
|
|
1998
1998
|
children: appLeaves(SIGNS_ORIGIN, APP_SIGNS_CHILDREN),
|
|
1999
1999
|
flag: "signs"
|
|
2000
2000
|
},
|
|
2001
|
-
|
|
2002
|
-
{ label: "Polling Engine", icon: icon("barChart"), href: withOrg(POLLS_ORIGIN), flag: "polling" }
|
|
2001
|
+
...accountRows()
|
|
2003
2002
|
];
|
|
2004
|
-
|
|
2003
|
+
const kept = rows.filter((r) => !r.flag || avail[r.flag]).map(({ flag: _flag, ...item }) => item);
|
|
2004
|
+
return kept.filter((item, idx) => {
|
|
2005
|
+
if (item.kind !== "section") return true;
|
|
2006
|
+
const next = kept[idx + 1];
|
|
2007
|
+
return !!next && next.kind !== "section";
|
|
2008
|
+
});
|
|
2005
2009
|
};
|
|
2006
2010
|
const buildPetition = () => [
|
|
2007
2011
|
opts.petitionsItem ? {
|
|
@@ -2108,7 +2112,9 @@ function NavSidebar({
|
|
|
2108
2112
|
footer,
|
|
2109
2113
|
linkComponent,
|
|
2110
2114
|
open,
|
|
2111
|
-
onClose
|
|
2115
|
+
onClose,
|
|
2116
|
+
onOpen,
|
|
2117
|
+
onNavigate
|
|
2112
2118
|
}) {
|
|
2113
2119
|
const Link = linkComponent ?? DefaultLink;
|
|
2114
2120
|
const collapsible = !open;
|
|
@@ -2205,7 +2211,7 @@ function NavSidebar({
|
|
|
2205
2211
|
style: { fontFamily: 'var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif)' },
|
|
2206
2212
|
onKeyDown: trapTab,
|
|
2207
2213
|
onClick: (e) => {
|
|
2208
|
-
if (open && e.target.closest("a[href]")) onClose?.();
|
|
2214
|
+
if (open && e.target.closest("a[href]")) (onNavigate ?? onClose)?.();
|
|
2209
2215
|
},
|
|
2210
2216
|
children: [
|
|
2211
2217
|
open ? /* @__PURE__ */ jsx(
|
|
@@ -2214,18 +2220,30 @@ function NavSidebar({
|
|
|
2214
2220
|
type: "button",
|
|
2215
2221
|
ref: closeButtonRef,
|
|
2216
2222
|
onClick: onClose,
|
|
2217
|
-
"aria-label": "
|
|
2223
|
+
"aria-label": "Collapse navigation",
|
|
2218
2224
|
className: "absolute right-3 top-3 flex h-8 w-8 items-center justify-center rounded-full text-[color:var(--muted)] transition hover:bg-[color:var(--panel-elevated)] hover:text-[color:var(--foreground)] md:hidden",
|
|
2219
2225
|
children: /* @__PURE__ */ jsx(CloseIcon, {})
|
|
2220
2226
|
}
|
|
2221
2227
|
) : null,
|
|
2222
2228
|
/* @__PURE__ */ jsxs("div", { className: `flex flex-shrink-0 flex-col gap-[14px] border-b border-[color:var(--sidebar-line,var(--line))] px-[18px] py-4 ${rc("max-md:items-center max-md:px-[10px]")}`, children: [
|
|
2229
|
+
onOpen ? /* @__PURE__ */ jsx(
|
|
2230
|
+
"button",
|
|
2231
|
+
{
|
|
2232
|
+
type: "button",
|
|
2233
|
+
onClick: onOpen,
|
|
2234
|
+
"aria-label": "Expand navigation",
|
|
2235
|
+
"aria-expanded": open ?? false,
|
|
2236
|
+
"data-rail-toggle": "expand",
|
|
2237
|
+
className: `hidden h-8 w-8 items-center justify-center rounded-lg ${rc("max-md:flex")}`,
|
|
2238
|
+
children: brand.logoSquareSrc ? /* @__PURE__ */ jsx("img", { src: brand.logoSquareSrc, alt: "", draggable: false, className: "h-8 w-8 object-contain" }) : brand.logoPending ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "block h-8 w-8" }) : /* @__PURE__ */ jsx("span", { className: "flex h-8 w-8 items-center justify-center rounded-xl bg-[color:var(--color-accent)] text-sm font-black text-[#FFFFFF]", children: brand.badgeLabel })
|
|
2239
|
+
}
|
|
2240
|
+
) : null,
|
|
2223
2241
|
/* @__PURE__ */ jsxs(
|
|
2224
2242
|
Link,
|
|
2225
2243
|
{
|
|
2226
2244
|
href: brand.homeHref ?? "/",
|
|
2227
2245
|
"aria-label": brand.logoAlt ?? brand.title,
|
|
2228
|
-
className: `flex items-center gap-2.5 ${rc("max-md:justify-center")}`,
|
|
2246
|
+
className: `flex items-center gap-2.5 ${rc("max-md:justify-center")} ${onOpen ? rc("max-md:hidden") : ""}`,
|
|
2229
2247
|
children: [
|
|
2230
2248
|
brand.logoSquareSrc ? /* @__PURE__ */ jsx(
|
|
2231
2249
|
"img",
|
|
@@ -2999,7 +3017,7 @@ function NavTopBar({
|
|
|
2999
3017
|
const initials = (hasRealName ? rawName : user?.email ?? "P").slice(0, 2).toUpperCase();
|
|
3000
3018
|
const secondary = hasRealName ? user?.email || [user?.tier, user?.role].filter(Boolean).join(" \xB7 ") || "member" : [user?.tier, user?.role].filter(Boolean).join(" \xB7 ") || "member";
|
|
3001
3019
|
return /* @__PURE__ */ jsxs("div", { className: "sticky top-0 z-20", children: [
|
|
3002
|
-
/* @__PURE__ */ jsxs("header", { className: "flex h-[var(--topbar-height,60px)] items-center justify-between gap-[14px] border-b border-[color:var(--line)] bg-[color:var(--panel)] px-[var(--topbar-padding-x,20px)]", children: [
|
|
3020
|
+
/* @__PURE__ */ jsxs("header", { className: "flex min-w-0 h-[var(--topbar-height,60px)] items-center justify-between gap-[8px] md:gap-[14px] border-b border-[color:var(--line)] bg-[color:var(--panel)] px-[var(--topbar-padding-x,20px)]", children: [
|
|
3003
3021
|
onOpenNav ? /* @__PURE__ */ jsx(
|
|
3004
3022
|
"button",
|
|
3005
3023
|
{
|
|
@@ -3012,7 +3030,7 @@ function NavTopBar({
|
|
|
3012
3030
|
children: /* @__PURE__ */ jsx(HamburgerIcon, {})
|
|
3013
3031
|
}
|
|
3014
3032
|
) : null,
|
|
3015
|
-
/* @__PURE__ */ jsxs("label", { className: "relative flex h-9 w-[320px] max-w-full shrink
|
|
3033
|
+
/* @__PURE__ */ jsxs("label", { className: "relative flex h-9 w-[320px] min-w-0 max-w-full shrink items-center md:shrink-0", children: [
|
|
3016
3034
|
/* @__PURE__ */ jsx(SearchIcon, { className: "pointer-events-none absolute left-[10px] h-[15px] w-[15px] text-[color:var(--muted)]" }),
|
|
3017
3035
|
/* @__PURE__ */ jsx(
|
|
3018
3036
|
"input",
|
|
@@ -3032,13 +3050,13 @@ function NavTopBar({
|
|
|
3032
3050
|
"kbd",
|
|
3033
3051
|
{
|
|
3034
3052
|
"aria-hidden": true,
|
|
3035
|
-
className: "pointer-events-none absolute right-[10px] rounded-[3px] border border-[color:var(--line)] px-[5px] py-px font-[family-name:var(--font-plex-mono,ui-monospace,monospace)] text-[12px] leading-[1.2] text-[color:var(--muted)]",
|
|
3053
|
+
className: "pointer-events-none absolute right-[10px] hidden md:block rounded-[3px] border border-[color:var(--line)] px-[5px] py-px font-[family-name:var(--font-plex-mono,ui-monospace,monospace)] text-[12px] leading-[1.2] text-[color:var(--muted)]",
|
|
3036
3054
|
children: "/"
|
|
3037
3055
|
}
|
|
3038
3056
|
)
|
|
3039
3057
|
] }),
|
|
3040
3058
|
/* @__PURE__ */ jsxs("div", { className: "relative ml-auto flex shrink-0 items-center gap-[var(--topbar-icon-gap,8px)]", children: [
|
|
3041
|
-
/* @__PURE__ */ jsxs(
|
|
3059
|
+
buildNotes ? /* @__PURE__ */ jsxs(
|
|
3042
3060
|
"button",
|
|
3043
3061
|
{
|
|
3044
3062
|
type: "button",
|
|
@@ -3049,7 +3067,7 @@ function NavTopBar({
|
|
|
3049
3067
|
buildNotes?.label ?? "Build notes"
|
|
3050
3068
|
]
|
|
3051
3069
|
}
|
|
3052
|
-
),
|
|
3070
|
+
) : null,
|
|
3053
3071
|
actionsList && actionsList.length > 0 ? actionsList.map((action) => /* @__PURE__ */ jsx(NavTopBarActionButton, { action }, action.key)) : null,
|
|
3054
3072
|
actions,
|
|
3055
3073
|
themeToggle,
|
|
@@ -3624,9 +3642,22 @@ function NavAppShell({
|
|
|
3624
3642
|
);
|
|
3625
3643
|
}
|
|
3626
3644
|
const [navOpen, setNavOpen] = useState(false);
|
|
3645
|
+
const expandRail = () => {
|
|
3646
|
+
writeRailPreference("expanded");
|
|
3647
|
+
setNavOpen(true);
|
|
3648
|
+
};
|
|
3649
|
+
const collapseRail = () => {
|
|
3650
|
+
writeRailPreference("collapsed");
|
|
3651
|
+
setNavOpen(false);
|
|
3652
|
+
};
|
|
3627
3653
|
useEffect(() => {
|
|
3628
3654
|
setNavOpen(false);
|
|
3629
3655
|
}, [sidebar.pathname]);
|
|
3656
|
+
useEffect(() => {
|
|
3657
|
+
if (readRailPreference() !== "expanded") return;
|
|
3658
|
+
const narrow = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(max-width: 767.98px)").matches : false;
|
|
3659
|
+
if (narrow) setNavOpen(true);
|
|
3660
|
+
}, []);
|
|
3630
3661
|
useEffect(() => {
|
|
3631
3662
|
if (!navOpen) return;
|
|
3632
3663
|
const previous = document.body.style.overflow;
|
|
@@ -3647,15 +3678,23 @@ function NavAppShell({
|
|
|
3647
3678
|
"data-politogy-mode": modeId,
|
|
3648
3679
|
className: "min-h-screen bg-[color:var(--background)] text-[color:var(--foreground)]",
|
|
3649
3680
|
children: [
|
|
3650
|
-
/* @__PURE__ */ jsx(
|
|
3681
|
+
/* @__PURE__ */ jsx(
|
|
3682
|
+
NavSidebar,
|
|
3683
|
+
{
|
|
3684
|
+
...sidebar,
|
|
3685
|
+
footer: sidebarFooter,
|
|
3686
|
+
open: navOpen,
|
|
3687
|
+
onClose: collapseRail,
|
|
3688
|
+
onOpen: expandRail,
|
|
3689
|
+
onNavigate: () => setNavOpen(false)
|
|
3690
|
+
}
|
|
3691
|
+
),
|
|
3651
3692
|
/* @__PURE__ */ jsxs("div", { className: "pl-[var(--sidebar-collapsed-width,64px)] md:pl-[var(--sidebar-width,236px)]", children: [
|
|
3652
3693
|
/* @__PURE__ */ jsx(
|
|
3653
3694
|
NavTopBar,
|
|
3654
3695
|
{
|
|
3655
3696
|
...topBar,
|
|
3656
|
-
accountMenu: topBar.accountMenu ?? (accountMenuPlacement === "sidebar" ? "sidebar" : "topbar")
|
|
3657
|
-
onOpenNav: () => setNavOpen(true),
|
|
3658
|
-
navOpen
|
|
3697
|
+
accountMenu: topBar.accountMenu ?? (accountMenuPlacement === "sidebar" ? "sidebar" : "topbar")
|
|
3659
3698
|
}
|
|
3660
3699
|
),
|
|
3661
3700
|
betaBanner ? /* @__PURE__ */ jsx(NavBetaBanner, { ...betaBanner }) : null,
|
|
@@ -3684,5 +3723,5 @@ function NavAppShell({
|
|
|
3684
3723
|
}
|
|
3685
3724
|
|
|
3686
3725
|
export { BETA_BANNER_DISMISS_KEY, CAMPAIGN_FEATURE_AVAILABILITY, CORE_APP_ORIGIN, CORE_BILLING_PATH, FuelAction, NavAppShell, NavBetaBanner, NavChromeProvider, NavDisplayAction, NavSidebar, NavTabStrip, NavThemeControl, NavTopBar, NotificationsAction, SPECS_ORIGIN, SpecOverlayAction, SupportAction, TopBarCountBadge, TopBarPanelArrow, TopBarPopover, TopBarTooltip, TopBarWidgetSlot, clearBetaBannerDismissal, envChipClasses, isNavItemActive, resolveOrgLogoUrl, standardPolitogyNav, topBarIconButtonClass, useChromeMe, useChromeOrgs, useNavChromeFetcher, useThemePreference };
|
|
3687
|
-
//# sourceMappingURL=chunk-
|
|
3688
|
-
//# sourceMappingURL=chunk-
|
|
3726
|
+
//# sourceMappingURL=chunk-CZI66JVG.js.map
|
|
3727
|
+
//# sourceMappingURL=chunk-CZI66JVG.js.map
|