@growth-operations/ui-shared 1.0.8 → 1.0.10
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 +1 -1
- package/src/home/AppHome.jsx +22 -2
- package/src/home/HelpfulLinks.jsx +75 -0
- package/src/index.js +1 -0
package/package.json
CHANGED
package/src/home/AppHome.jsx
CHANGED
|
@@ -6,6 +6,7 @@ import { OnboardingChecklist } from "./OnboardingChecklist";
|
|
|
6
6
|
import { SyncPulse } from "./SyncPulse";
|
|
7
7
|
import { CreditMeter } from "./CreditMeter";
|
|
8
8
|
import { FeatureNudges } from "./FeatureNudges";
|
|
9
|
+
import { HelpfulLinks } from "./HelpfulLinks";
|
|
9
10
|
|
|
10
11
|
// Minimal inline ATS tile (the `pipeline` block). Kept tiny here rather than a
|
|
11
12
|
// separate file — it's the simplest of the three archetype tiles. Renders
|
|
@@ -76,7 +77,13 @@ function ArchetypeTile({ state }) {
|
|
|
76
77
|
// PageLink navigation (the host owns the router).
|
|
77
78
|
// appName — display name override; defaults to state.app.name.
|
|
78
79
|
// onRetry — optional, passed to InstallProgress for the failed state.
|
|
79
|
-
|
|
80
|
+
// helpfulLinks — optional props for the standard HelpfulLinks section
|
|
81
|
+
// (e.g. { portalId, appId, appName, docsUrl, supportUrl,
|
|
82
|
+
// links }). Omit to hide the section. The host passes this
|
|
83
|
+
// (it owns context.portal.id + the app's docs/support); it can
|
|
84
|
+
// also come from a state.helpful_links block if the backend
|
|
85
|
+
// builds one.
|
|
86
|
+
export function AppHome({ state, onNavigate, appName, onRetry, helpfulLinks }) {
|
|
80
87
|
if (!state) {
|
|
81
88
|
return <LoadingSpinner showLabel label="Loading…" />;
|
|
82
89
|
}
|
|
@@ -85,10 +92,21 @@ export function AppHome({ state, onNavigate, appName, onRetry }) {
|
|
|
85
92
|
const activationComplete =
|
|
86
93
|
!activation || activation.complete === true || activation.status === "completed";
|
|
87
94
|
|
|
95
|
+
// HelpfulLinks props: explicit prop wins, else a state.helpful_links block if
|
|
96
|
+
// the backend builds one. Shown in both the install and cockpit views so help
|
|
97
|
+
// is reachable even mid-setup.
|
|
98
|
+
const links = helpfulLinks ?? state.helpful_links ?? null;
|
|
99
|
+
const helpfulLinksEl = links ? <HelpfulLinks {...links} /> : null;
|
|
100
|
+
|
|
88
101
|
// Install isn't finished (running / failed / completed-with-warnings) — show
|
|
89
102
|
// the install experience instead of the cockpit.
|
|
90
103
|
if (!activationComplete) {
|
|
91
|
-
return
|
|
104
|
+
return (
|
|
105
|
+
<Flex direction="column" gap="medium">
|
|
106
|
+
<InstallProgress state={state} onRetry={onRetry} />
|
|
107
|
+
{helpfulLinksEl}
|
|
108
|
+
</Flex>
|
|
109
|
+
);
|
|
92
110
|
}
|
|
93
111
|
|
|
94
112
|
const onboardingComplete = state.onboarding?.complete === true;
|
|
@@ -108,6 +126,8 @@ export function AppHome({ state, onNavigate, appName, onRetry }) {
|
|
|
108
126
|
<ArchetypeTile state={state} />
|
|
109
127
|
|
|
110
128
|
<FeatureNudges nudges={state.nudges} onNavigate={onNavigate} />
|
|
129
|
+
|
|
130
|
+
{helpfulLinksEl}
|
|
111
131
|
</Flex>
|
|
112
132
|
);
|
|
113
133
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Flex, Text, Link, Divider } from "@hubspot/ui-extensions";
|
|
3
|
+
|
|
4
|
+
// Build the in-app app-pages deep link (the app's Home/tabs live under /app).
|
|
5
|
+
function appPagesUrl(portalId, appId, pagePath = "") {
|
|
6
|
+
const suffix = pagePath ? `/${pagePath.replace(/^\//, "")}` : "";
|
|
7
|
+
return `https://app.hubspot.com/app/${portalId}/${appId}${suffix}`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// HelpfulLinks — a standard "Helpful Links" section for every Growth Operations
|
|
11
|
+
// app. Renders a labeled list of links: optionally an "Open <app>" deep link
|
|
12
|
+
// back to the app pages (so the settings extension isn't a dead end), docs +
|
|
13
|
+
// support from the app config, and any app-specific extras.
|
|
14
|
+
//
|
|
15
|
+
// Props:
|
|
16
|
+
// portalId — context.portal.id (number/string).
|
|
17
|
+
// appId — this app's HubSpot app id (per-env). Needed for the app-pages
|
|
18
|
+
// deep link; omit to hide that link.
|
|
19
|
+
// appName — display name, e.g. "Sparkfly" (used in the deep-link label).
|
|
20
|
+
// appPages — when true (default) and appId is set, show "Open <appName> →"
|
|
21
|
+
// linking to the app pages. Set the page path via appPagesPath.
|
|
22
|
+
// appPagesPath — optional pages route to deep-link into (default: Home).
|
|
23
|
+
// docsUrl, supportUrl — external help links (omit to hide).
|
|
24
|
+
// links — app-specific extras: [{ label, url }]. Rendered after the
|
|
25
|
+
// standard links.
|
|
26
|
+
// title — section heading (default "Helpful Links").
|
|
27
|
+
export function HelpfulLinks({
|
|
28
|
+
portalId,
|
|
29
|
+
appId,
|
|
30
|
+
appName = "the app",
|
|
31
|
+
appPages = true,
|
|
32
|
+
appPagesPath = "",
|
|
33
|
+
docsUrl,
|
|
34
|
+
supportUrl,
|
|
35
|
+
links = [],
|
|
36
|
+
title = "Helpful Links",
|
|
37
|
+
}) {
|
|
38
|
+
// external=false keeps navigation in the SAME tab. The app-pages deep link is
|
|
39
|
+
// an in-app HubSpot URL, so it must stay same-tab (external:true would force a
|
|
40
|
+
// new tab). Docs/support and app-specific extras are off-platform → external.
|
|
41
|
+
const items = [];
|
|
42
|
+
|
|
43
|
+
if (appPages && appId && portalId != null) {
|
|
44
|
+
items.push({
|
|
45
|
+
label: `Open ${appName} →`,
|
|
46
|
+
url: appPagesUrl(portalId, appId, appPagesPath),
|
|
47
|
+
external: false,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (docsUrl) items.push({ label: "Documentation", url: docsUrl, external: true });
|
|
51
|
+
if (supportUrl) items.push({ label: "Support", url: supportUrl, external: true });
|
|
52
|
+
for (const l of links) {
|
|
53
|
+
if (l && l.url && l.label) {
|
|
54
|
+
// Default app-specific extras to external (they're usually HubSpot record
|
|
55
|
+
// URLs or off-platform), but let a link opt into same-tab via external:false.
|
|
56
|
+
items.push({ label: l.label, url: l.url, external: l.external !== false });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (items.length === 0) return null;
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<Flex direction="column" gap="small">
|
|
64
|
+
<Text format={{ fontWeight: "bold" }}>{title}</Text>
|
|
65
|
+
<Divider />
|
|
66
|
+
{items.map((item) => (
|
|
67
|
+
<Link key={item.url} href={{ url: item.url, external: item.external }}>
|
|
68
|
+
{item.label}
|
|
69
|
+
</Link>
|
|
70
|
+
))}
|
|
71
|
+
</Flex>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export default HelpfulLinks;
|
package/src/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export { OnboardingChecklist } from "./home/OnboardingChecklist";
|
|
|
12
12
|
export { SyncPulse } from "./home/SyncPulse";
|
|
13
13
|
export { FeatureNudges } from "./home/FeatureNudges";
|
|
14
14
|
export { CreditMeter } from "./home/CreditMeter";
|
|
15
|
+
export { HelpfulLinks } from "./home/HelpfulLinks";
|
|
15
16
|
|
|
16
17
|
// Billing.
|
|
17
18
|
export { BillingTab } from "./billing/BillingTab";
|