@growth-operations/ui-shared 1.28.0 → 1.29.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growth-operations/ui-shared",
3
- "version": "1.28.0",
3
+ "version": "1.29.0",
4
4
  "description": "Shared HubSpot UI-extension modules (Home, Billing) for Growth Operations apps.",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -61,19 +61,25 @@ function RecommendedTile({ notInUse, isSuperAdmin, onNavigate }) {
61
61
  <Flex direction="column" gap="small">
62
62
  <Text format={{ fontWeight: "bold" }}>Recommended to explore</Text>
63
63
  {picks.map((f) => {
64
- // Setup CTAs are gated PER ITEM (1.28.0): adminOnly items point at
65
- // HubSpot permission-wall surfaces (the layout editor above all) —
66
- // super admins only, since a non-admin clicking into a permission
67
- // wall is worse than no link. Items marked adminOnly: false are
68
- // per-user surfaces (install the Chrome extension, open the in-app
69
- // extension page) and render for everyone. Old backends emit no
70
- // marker → adminOnly defaults true → the blanket gate is preserved.
64
+ // Setup CTAs render for EVERYONE (1.29.0, Jasper 2026-10-14: "why
65
+ // gate so much on super admin?"). The old blanket super-admin gate
66
+ // assumed the targets were admin-only surfaces — but HubSpot
67
+ // permissions are granular (CRM customization ≠ super admin), and
68
+ // hiding the CTA kept non-admins from even knowing what to ask
69
+ // their admin for. adminOnly items instead carry a "(Super Admin)"
70
+ // hint for non-admin viewers, so the permission wall is never a
71
+ // blind click. The adminOnly marker still distinguishes the two
72
+ // surface kinds; old backends emit no marker → every item gets the
73
+ // hint for non-admins (conservative, and matches the old gate's
74
+ // assumption that the targets are admin surfaces).
71
75
  //
72
76
  // "Learn more →" (docs_url) intentionally NOT rendered (Jasper
73
77
  // 2026-10-14): every feature's docs_url points at the same single
74
78
  // setup guide — noise until per-feature articles exist. docs_url
75
79
  // stays in the wire contract; re-enabling is a one-line revert.
76
- const ctas = f.ctas.filter((c) => !c.adminOnly || isSuperAdmin);
80
+ const ctas = f.ctas;
81
+ const hint = (c) =>
82
+ c.adminOnly && !isSuperAdmin ? " (Super Admin)" : "";
77
83
  return (
78
84
  <Flex key={f.key} direction="column" gap="extra-small">
79
85
  <Text format={{ fontWeight: "demibold" }}>{f.name}</Text>
@@ -81,7 +87,8 @@ function RecommendedTile({ notInUse, isSuperAdmin, onNavigate }) {
81
87
  {ctas.map((cta) =>
82
88
  cta.url ? (
83
89
  <Link key={cta.label} href={{ url: cta.url, external: true }}>
84
- {cta.label} →
90
+ {cta.label}
91
+ {hint(cta)} →
85
92
  </Link>
86
93
  ) : onNavigate ? (
87
94
  <Button
@@ -90,6 +97,7 @@ function RecommendedTile({ notInUse, isSuperAdmin, onNavigate }) {
90
97
  onClick={() => onNavigate(cta.route)}
91
98
  >
92
99
  {cta.label}
100
+ {hint(cta)}
93
101
  </Button>
94
102
  ) : null
95
103
  )}