@the-portland-company/shell 0.84.0 → 0.86.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 +19 -0
- package/dist/app-chrome.cjs +28 -6
- package/dist/app-chrome.cjs.map +1 -1
- package/dist/app-chrome.d.cts +1 -1
- package/dist/app-chrome.d.ts +1 -1
- package/dist/app-chrome.js +23 -7
- package/dist/app-chrome.js.map +1 -1
- package/dist/{chunk-QS3Z4N73.js → chunk-3JOLELB4.js} +9 -3
- package/dist/chunk-3JOLELB4.js.map +1 -0
- package/dist/{index-C4ob05Pc.d.ts → index-C31E7M9l.d.ts} +6 -0
- package/dist/{index--q40spnY.d.cts → index-bfbWLC7_.d.cts} +6 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/native.cjs +7 -1
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +1 -1
- package/dist/native.d.ts +1 -1
- package/dist/native.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-QS3Z4N73.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
## 0.86.0
|
|
2
|
+
|
|
3
|
+
Campaign Mode gets a Tribes row. Spec cited: Specs/Tribes §2.3–§2.4 and Specs/Left-Navigation §9.2 (decided 2026-10-16 by Ben: Campaign and Relationship Tribes are separate; Campaign Tribes live in Campaign Mode).
|
|
4
|
+
|
|
5
|
+
- **Campaign tree.** Race data now lists Battleground · District data · **Tribes** (`users-round`), linking to `https://battleground.politogyvrm.com/tribes` (org carried as before). It is a page of the Battleground app at `/tribes`, so it is the only active row there.
|
|
6
|
+
- **Relationship tree unchanged.** Relationship Tribes stay inside Contacts → Tribes; there is still no Relationship Tribes row.
|
|
7
|
+
- **Release order.** Publish after the Battleground app serves `/tribes`, so the row never links to a missing page.
|
|
8
|
+
- Tests: `__tests__/standardNav.test.ts`.
|
|
9
|
+
|
|
10
|
+
## 0.85.0
|
|
11
|
+
|
|
12
|
+
The mode switcher, the rail and the rows always show one mode. Spec cited: Specs/Left-Navigation §9.1, §9.2, §9.4 and §11.1 ("the rail never shows a mix of two modes").
|
|
13
|
+
|
|
14
|
+
- **Why.** Reported by Ben and measured on production 2026-10-16 on "We need Steve": after picking Campaign, Contacts (and Forms, Surveys, CTAs) drew the red "Campaign mode" rail and the Campaign search placeholder around Relationship rows, even after a reload. These apps had no registry mode, so the switcher took the user's last choice (`vrm.activeMode`) while the rows stayed Relationship.
|
|
15
|
+
- **Registry.** `contacts`, `forms`, `surveys` and `ctas` are pinned to `mode: 'relationship'`: they are Relationship rows only (§9.1) and Campaign has none of them (§9.2). Same fix as the Dashboard's earlier pin. Clicking another mode still goes to that mode's landing.
|
|
16
|
+
- **Unpinned apps** (Settings: the Account section is in every mode, §9.4) draw the tree of the mode their switcher shows, so rows, rail colour and label agree. Core (`vrm`) is unchanged.
|
|
17
|
+
- **Loading Screen.** For an unpinned app it stays up until the organization's Modes are read, so the rail never changes mode under the user. `NavMode` gains optional `resolved` (false while the id is a stand-in).
|
|
18
|
+
- Tests: `__tests__/modeNavAgree.test.tsx`; `frame-grants.test.tsx` updated for the new pins.
|
|
19
|
+
|
|
1
20
|
## 0.84.0
|
|
2
21
|
|
|
3
22
|
An organization switch lands on the new organization's Relationship Dashboard. Spec cited: Specs/Left-Navigation §6 and §11.2 (v21, decided 2026-10-15 by Ben; supersedes the 2026-10-06 rule that kept mode, page and tab).
|
package/dist/app-chrome.cjs
CHANGED
|
@@ -2443,13 +2443,19 @@ function standardPolitogyNav(opts) {
|
|
|
2443
2443
|
const rows = [
|
|
2444
2444
|
// Left-Navigation §9.2: Race data -> Research -> GOTV -> Account.
|
|
2445
2445
|
// Battleground is the Campaign landing page; there is no Campaign
|
|
2446
|
-
// Dashboard row, and Voter Contact
|
|
2446
|
+
// Dashboard row, and Voter Contact has no row. Campaign Tribes has its
|
|
2447
|
+
// own row after District data (decided 2026-10-16).
|
|
2447
2448
|
{ kind: "section", label: "Race data" },
|
|
2448
2449
|
// Battleground is the Campaign Mode landing page, its own app on its own
|
|
2449
2450
|
// host (registry key `battleground`; Specs/Left-Navigation §9.2, §13, §14).
|
|
2450
2451
|
{ label: "Battleground", icon: icon("crosshair"), href: withOrg(`${BATTLEGROUND_ORIGIN}battleground`) },
|
|
2451
2452
|
// District Data is its own Campaign Mode app on its own host (registry key `districts`).
|
|
2452
2453
|
{ label: "District data", icon: icon("landmark"), href: withOrg(`${DISTRICTS_ORIGIN}districts`) },
|
|
2454
|
+
// Campaign Tribes (Specs/Tribes §2.3–§2.4, Left-Navigation §9.2; decided
|
|
2455
|
+
// 2026-10-16, Ben): a page of the Battleground app at /tribes, so it is
|
|
2456
|
+
// the only active row there (Battleground's /battleground prefix does
|
|
2457
|
+
// not match it). Relationship Tribes stay inside Contacts.
|
|
2458
|
+
{ label: "Tribes", icon: icon("usersRound"), href: withOrg(`${BATTLEGROUND_ORIGIN}tribes`) },
|
|
2453
2459
|
{ kind: "section", label: "Research" },
|
|
2454
2460
|
{
|
|
2455
2461
|
label: "Polling",
|
|
@@ -4593,10 +4599,19 @@ var CORE_APP = "vrm";
|
|
|
4593
4599
|
var DEFAULT_SIGN_OUT_URL = "/auth/signout";
|
|
4594
4600
|
var POLITOGY_APPS = {
|
|
4595
4601
|
vrm: { title: "Politogy VRM", origin: "https://app.politogyvrm.com", storagePrefix: "vrm" },
|
|
4602
|
+
// Contacts, Forms, Surveys and CTAs are Relationship rows only (Specs/
|
|
4603
|
+
// Left-Navigation §9.1; Campaign has none of them, §9.2), so they are
|
|
4604
|
+
// PINNED to Relationship like the Dashboard below. Left unscoped, the mode
|
|
4605
|
+
// switcher and rail colour took the user's last mode choice while the rows
|
|
4606
|
+
// stayed Relationship: after picking Campaign, Contacts drew the red
|
|
4607
|
+
// "Campaign mode" rail around Relationship rows, even after a reload
|
|
4608
|
+
// (measured 2026-10-16 on We need Steve; §11.1 "the rail never shows a mix
|
|
4609
|
+
// of two modes").
|
|
4596
4610
|
contacts: {
|
|
4597
4611
|
title: "Contacts",
|
|
4598
4612
|
origin: "https://contacts.politogyvrm.com",
|
|
4599
4613
|
storagePrefix: "contacts",
|
|
4614
|
+
mode: "relationship",
|
|
4600
4615
|
pageTitle: false
|
|
4601
4616
|
},
|
|
4602
4617
|
// 'title' for forms/surveys/polls/ctas for the same reason as petitions
|
|
@@ -4605,11 +4620,11 @@ var POLITOGY_APPS = {
|
|
|
4605
4620
|
// page header falls back to the static registry title forever, so the
|
|
4606
4621
|
// designed "<mode> mode" eyebrow + H2 + subtitle block never gets the real
|
|
4607
4622
|
// per-page title an app passes it (UI-Platform → Page header).
|
|
4608
|
-
forms: { title: "Forms", origin: "https://forms.politogyvrm.com", storagePrefix: "forms", grants: ["title"] },
|
|
4609
|
-
surveys: { title: "Surveys", origin: "https://surveys.politogyvrm.com", storagePrefix: "surveys", grants: ["title"] },
|
|
4623
|
+
forms: { title: "Forms", origin: "https://forms.politogyvrm.com", storagePrefix: "forms", mode: "relationship", grants: ["title"] },
|
|
4624
|
+
surveys: { title: "Surveys", origin: "https://surveys.politogyvrm.com", storagePrefix: "surveys", mode: "relationship", grants: ["title"] },
|
|
4610
4625
|
// Specs/Left-Navigation §9.2: Polling is a Campaign row (Research).
|
|
4611
4626
|
polls: { title: "Polls", origin: "https://polls.politogyvrm.com", storagePrefix: "polls", mode: "campaign", grants: ["title"] },
|
|
4612
|
-
ctas: { title: "CTAs", origin: "https://ctas.politogyvrm.com", storagePrefix: "ctas", grants: ["title"] },
|
|
4627
|
+
ctas: { title: "CTAs", origin: "https://ctas.politogyvrm.com", storagePrefix: "ctas", mode: "relationship", grants: ["title"] },
|
|
4613
4628
|
// V2 apps that replace retired app.politogyvrm.com pages (Reference/
|
|
4614
4629
|
// UI-Platform v42 "Retirement of app.politogyvrm.com"). Dashboard is the
|
|
4615
4630
|
// Relationship Dashboard, the Relationship Mode landing page, and nothing
|
|
@@ -4833,7 +4848,7 @@ function FrameBody({
|
|
|
4833
4848
|
const coreOrgs = chrome?.orgs ?? [];
|
|
4834
4849
|
const activeCoreOrg = coreOrgs.find((o) => o.id === chrome?.orgId) ?? null;
|
|
4835
4850
|
const navDisplay = chrome?.navDisplay ?? "both";
|
|
4836
|
-
const navMode = appMode ?? "relationship";
|
|
4851
|
+
const navMode = appMode ?? (app !== CORE_APP && isStandardNavMode(mode.id) ? mode.id : "relationship");
|
|
4837
4852
|
const activeOrgId = chrome?.orgId ?? null;
|
|
4838
4853
|
const derivedNavItems = react.useMemo(
|
|
4839
4854
|
() => standardPolitogyNav({
|
|
@@ -4876,7 +4891,7 @@ function FrameBody({
|
|
|
4876
4891
|
{
|
|
4877
4892
|
visible: bootVisible,
|
|
4878
4893
|
bootProgress,
|
|
4879
|
-
syntheticReady: (appReady ?? chromeResolved) && !chrome?.orgPending,
|
|
4894
|
+
syntheticReady: (appReady ?? chromeResolved) && !chrome?.orgPending && (appMode !== void 0 || mode.resolved !== false),
|
|
4880
4895
|
onExitComplete: () => setBootVisible(false)
|
|
4881
4896
|
},
|
|
4882
4897
|
bootGeneration
|
|
@@ -5596,6 +5611,7 @@ function useChromeMode(arg = {}) {
|
|
|
5596
5611
|
const orgId = ctx?.orgId ?? null;
|
|
5597
5612
|
const orgPending = ctx?.orgPending ?? false;
|
|
5598
5613
|
const [entitled, setEntitled] = react.useState(null);
|
|
5614
|
+
const [settledOrgId, setSettledOrgId] = react.useState(null);
|
|
5599
5615
|
const [selectedModeId, setSelectedModeId] = react.useState(null);
|
|
5600
5616
|
react.useEffect(() => {
|
|
5601
5617
|
try {
|
|
@@ -5610,6 +5626,7 @@ function useChromeMode(arg = {}) {
|
|
|
5610
5626
|
const bootMe = me;
|
|
5611
5627
|
if (bootMe && bootMe.account === orgId && bootMe.modes !== void 0) {
|
|
5612
5628
|
setEntitled(bootMe.modes ?? null);
|
|
5629
|
+
setSettledOrgId(orgId);
|
|
5613
5630
|
return;
|
|
5614
5631
|
}
|
|
5615
5632
|
let cancelled = false;
|
|
@@ -5617,7 +5634,9 @@ function useChromeMode(arg = {}) {
|
|
|
5617
5634
|
if (cancelled) return;
|
|
5618
5635
|
const modes = data?.modes ?? null;
|
|
5619
5636
|
setEntitled(modes);
|
|
5637
|
+
setSettledOrgId(orgId);
|
|
5620
5638
|
}).catch(() => {
|
|
5639
|
+
if (!cancelled) setSettledOrgId(orgId);
|
|
5621
5640
|
});
|
|
5622
5641
|
return () => {
|
|
5623
5642
|
cancelled = true;
|
|
@@ -5631,6 +5650,9 @@ function useChromeMode(arg = {}) {
|
|
|
5631
5650
|
id: current.id,
|
|
5632
5651
|
label: current.label,
|
|
5633
5652
|
icon: current.icon,
|
|
5653
|
+
// A registry pin is final at once; otherwise the mode is final when the
|
|
5654
|
+
// active org's Modes are in (or nothing can be read: no chrome or no org).
|
|
5655
|
+
resolved: Boolean(pinned) || !dedupedFetch || !orgId || settledOrgId === orgId && !orgPending,
|
|
5634
5656
|
// Left-Navigation §7 / Reference/UI-Platform: always the row of three icon
|
|
5635
5657
|
// buttons. A mode the organization does not hold is shown dimmed and not
|
|
5636
5658
|
// selectable, never hidden. Before entitlements land only the current mode
|