@growth-operations/ui-shared 1.27.0 → 1.28.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
|
@@ -61,16 +61,19 @@ 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
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
// wall is worse than no link
|
|
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.
|
|
68
71
|
//
|
|
69
72
|
// "Learn more →" (docs_url) intentionally NOT rendered (Jasper
|
|
70
73
|
// 2026-10-14): every feature's docs_url points at the same single
|
|
71
74
|
// setup guide — noise until per-feature articles exist. docs_url
|
|
72
75
|
// stays in the wire contract; re-enabling is a one-line revert.
|
|
73
|
-
const ctas =
|
|
76
|
+
const ctas = f.ctas.filter((c) => !c.adminOnly || isSuperAdmin);
|
|
74
77
|
return (
|
|
75
78
|
<Flex key={f.key} direction="column" gap="extra-small">
|
|
76
79
|
<Text format={{ fontWeight: "demibold" }}>{f.name}</Text>
|
package/src/lib/featureUsage.js
CHANGED
|
@@ -18,13 +18,17 @@ const normalizeUnit = (u) =>
|
|
|
18
18
|
// One well-formed setup CTA is {label: non-empty string, url XOR route:
|
|
19
19
|
// non-empty string}. Anything else (missing label, both targets, neither
|
|
20
20
|
// target, wrong types) is dropped — a malformed item never renders.
|
|
21
|
+
// admin_only (1.28.0): an explicit false marks a per-user surface (installing
|
|
22
|
+
// the Chrome extension) that renders for EVERYONE; a missing marker means
|
|
23
|
+
// admin-only, so old backends keep the blanket super-admin gate.
|
|
21
24
|
const normalizeCta = (c) => {
|
|
22
25
|
if (!c || typeof c !== "object") return null;
|
|
23
26
|
const label = typeof c.label === "string" && c.label ? c.label : null;
|
|
24
27
|
const url = typeof c.url === "string" && c.url ? c.url : null;
|
|
25
28
|
const route = typeof c.route === "string" && c.route ? c.route : null;
|
|
26
29
|
if (!label || !(url || route) || (url && route)) return null;
|
|
27
|
-
|
|
30
|
+
const adminOnly = c.admin_only !== false;
|
|
31
|
+
return { label, ...(url ? { url } : { route }), adminOnly };
|
|
28
32
|
};
|
|
29
33
|
|
|
30
34
|
// Resolve the feature_usage block into render-ready shape:
|