@the-portland-company/shell 0.25.0 → 0.26.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 CHANGED
@@ -1,3 +1,19 @@
1
+ ## 0.26.0 — 2026-07-23
2
+
3
+ ### Added — `PolitogyAppFrame` data plumbing (so Contacts can adopt it)
4
+
5
+ `PolitogyFrameData` (the optional `data` prop) carries the things that differ by
6
+ **where an app's data comes from**, never by how its chrome looks:
7
+
8
+ - `fetchJson` / `devNotes` — for apps that authenticate client-side instead of
9
+ through a same-origin `/api/chrome/*` proxy (Contacts).
10
+ - `org` — controlled active-org state for apps that own switching.
11
+ - `contactsItem` — app-owned children for a standard nav entry the app owns.
12
+ - `fallbackAvatarUrl` — avatar fallback (stored memoji / default) when the
13
+ profile has no uploaded photo.
14
+
15
+ Adding a *visual* option here would re-open the drift this component closes.
16
+
1
17
  ## 0.25.0 — 2026-07-23
2
18
 
3
19
  ### Added — `PolitogyAppFrame`: one component owns the whole app frame
@@ -1963,6 +1963,7 @@ function PolitogyAppFrame({
1963
1963
  session,
1964
1964
  onSignOut,
1965
1965
  buildMeta,
1966
+ data,
1966
1967
  children
1967
1968
  }) {
1968
1969
  const meta = POLITOGY_APPS[app];
@@ -1970,6 +1971,9 @@ function PolitogyAppFrame({
1970
1971
  PolitogyAppChrome,
1971
1972
  {
1972
1973
  storagePrefix: meta.storagePrefix,
1974
+ fetchJson: data?.fetchJson,
1975
+ devNotes: data?.devNotes,
1976
+ org: data?.org,
1973
1977
  identity: {
1974
1978
  userId: session.userId,
1975
1979
  userName: session.userName ?? null,
@@ -1986,6 +1990,7 @@ function PolitogyAppFrame({
1986
1990
  session,
1987
1991
  onSignOut,
1988
1992
  buildMeta,
1993
+ data,
1989
1994
  children
1990
1995
  }
1991
1996
  )
@@ -2000,6 +2005,7 @@ function FrameBody({
2000
2005
  session,
2001
2006
  onSignOut,
2002
2007
  buildMeta,
2008
+ data,
2003
2009
  children
2004
2010
  }) {
2005
2011
  const meta = POLITOGY_APPS[app];
@@ -2016,8 +2022,14 @@ function FrameBody({
2016
2022
  const activeCoreOrg = coreOrgs.find((o) => o.id === chrome?.orgId) ?? null;
2017
2023
  const navDisplay = chrome?.navDisplay ?? "both";
2018
2024
  const navItems = react.useMemo(
2019
- () => standardPolitogyNav({ coreBaseUrl: POLITOGY_APPS.vrm.origin, icons: standardNavIcons }),
2020
- []
2025
+ () => standardPolitogyNav({
2026
+ coreBaseUrl: POLITOGY_APPS.vrm.origin,
2027
+ icons: standardNavIcons,
2028
+ // An app that OWNS a standard nav entry (Contacts) nests its own routes
2029
+ // under it. This is routing data, not chrome configuration.
2030
+ contactsItem: data?.contactsItem
2031
+ }),
2032
+ [data?.contactsItem]
2021
2033
  );
2022
2034
  const breadcrumbs = react.useMemo(
2023
2035
  () => deriveBreadcrumbs(navItems, pathname, { search, origin: meta.origin }),
@@ -2056,7 +2068,9 @@ function FrameBody({
2056
2068
  user: {
2057
2069
  name: identity.userName,
2058
2070
  email: identity.email,
2059
- avatarUrl: identity.avatarUrl,
2071
+ // The chrome API's avatar wins; the app may supply a fallback chain
2072
+ // (e.g. a stored memoji) for users with no uploaded photo.
2073
+ avatarUrl: identity.avatarUrl ?? data?.fallbackAvatarUrl ?? null,
2060
2074
  role: session.role
2061
2075
  },
2062
2076
  userMenu,