Skip to content

Commit fbefd1f

Browse files
committed
feat: implement cloud plan management and update related components
- Introduced a new useCloudPlan hook and context for managing cloud plan state across the application. - Replaced useCloudMode with useCloudPlan in various components, including HeaderAction, CloudVersionSelect, and DocTemplate, to streamline cloud plan handling. - Added scripts in gatsby-ssr.js to manage cloud plan state based on URL parameters and update UI elements accordingly. - Removed the deprecated useCloudMode hook and updated related imports to enhance code clarity and maintainability.
1 parent 6436bce commit fbefd1f

File tree

7 files changed

+159
-70
lines changed

7 files changed

+159
-70
lines changed

gatsby-ssr.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export { default as wrapRootElement } from "./src/state/wrap-with-provider";
2+
import { CLOUD_PLAN_LABEL_ELEMENT_ID } from "components/Layout/VersionSelect/CloudVersionSelect";
23
import docsJson from "./docs/docs.json";
4+
import { GLOBAL_STATE_CLOUD_PLAN_KEY } from "./src/shared/useCloudPlan";
35

46
// https://github.com/gatsbyjs/gatsby/issues/1526
57
export const onPreRenderHTML = ({ getHeadComponents }) => {
@@ -79,6 +81,25 @@ const redirectScript = `
7981
})();
8082
`;
8183

84+
const cloudPlanScript = `
85+
(function() {
86+
const searchParams = new URLSearchParams(location.search);
87+
const cloudMode = searchParams.get("plan");
88+
if (cloudMode) {
89+
window["${GLOBAL_STATE_CLOUD_PLAN_KEY}"] = cloudMode;
90+
}
91+
})();
92+
`;
93+
94+
const fulfillCloudPlanScript = `
95+
(function() {
96+
const cloudPlanLabel = document.getElementById("${CLOUD_PLAN_LABEL_ELEMENT_ID}");
97+
if (cloudPlanLabel) {
98+
cloudPlanLabel.textContent = cloudMode;
99+
}
100+
})();
101+
`;
102+
82103
export const onRenderBody = ({ setPostBodyComponents, setHeadComponents }) => {
83104
setHeadComponents([
84105
<link
@@ -113,6 +134,10 @@ export const onRenderBody = ({ setPostBodyComponents, setHeadComponents }) => {
113134
type="font/woff2"
114135
crossOrigin="anonymous"
115136
/>,
137+
<script
138+
key="cloud-plan"
139+
dangerouslySetInnerHTML={{ __html: cloudPlanScript }}
140+
/>,
116141
]);
117142
setPostBodyComponents([
118143
<script key="deprecated" dangerouslySetInnerHTML={{ __html: script }} />,
@@ -128,5 +153,9 @@ export const onRenderBody = ({ setPostBodyComponents, setHeadComponents }) => {
128153
data-chat-engine="pingcap-doc"
129154
data-measurement-id="G-GRPCMS37RV"
130155
/>,
156+
<script
157+
key="fulfill-cloud-plan"
158+
dangerouslySetInnerHTML={{ __html: fulfillCloudPlanScript }}
159+
/>,
131160
]);
132161
};

src/components/Layout/Header.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ export default function Header(props: HeaderProps) {
8585
docInfo={props.docInfo}
8686
buildType={props.buildType}
8787
pageUrl={props.pageUrl}
88-
pathConfig={props.pathConfig}
8988
/>
9089
</Toolbar>
9190
</AppBar>

src/components/Layout/HeaderAction.tsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { Locale, BuildType, PathConfig, Repo } from "shared/interface";
2121
import { ActionButton } from "components/Card/FeedbackSection/components";
2222
import { Link } from "gatsby";
2323
import { useIsAutoTranslation } from "shared/useIsAutoTranslation";
24-
import { useCloudMode } from "shared/useCloudMode";
24+
import { useCloudPlan } from "shared/useCloudPlan";
2525

2626
const useTiDBAIStatus = () => {
2727
const [showTiDBAIButton, setShowTiDBAIButton] = React.useState(true);
@@ -63,9 +63,8 @@ export default function HeaderAction(props: {
6363
docInfo?: { type: string; version: string };
6464
buildType?: BuildType;
6565
pageUrl?: string;
66-
pathConfig?: PathConfig;
6766
}) {
68-
const { supportedLocales, docInfo, buildType, pageUrl, pathConfig } = props;
67+
const { supportedLocales, docInfo, buildType, pageUrl } = props;
6968
const { language, t } = useI18next();
7069
const { showTiDBAIButton, initializingTiDBAI } = useTiDBAIStatus();
7170
const isAutoTranslation = useIsAutoTranslation(pageUrl || "");
@@ -80,10 +79,7 @@ export default function HeaderAction(props: {
8079
sx={{ marginLeft: "auto", alignItems: "center" }}
8180
>
8281
{supportedLocales.length > 0 && (
83-
<LangSwitch
84-
supportedLocales={supportedLocales}
85-
pathConfig={pathConfig}
86-
/>
82+
<LangSwitch supportedLocales={supportedLocales} />
8783
)}
8884
{docInfo && !isAutoTranslation && buildType !== "archive" && (
8985
<>
@@ -126,15 +122,14 @@ const LangSwitch = (props: {
126122
language?: string;
127123
changeLanguage?: () => void;
128124
supportedLocales: Locale[];
129-
pathConfig?: PathConfig;
130125
}) => {
131-
const { supportedLocales, pathConfig } = props;
126+
const { supportedLocales } = props;
132127

133128
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
134129

135130
const theme = useTheme();
136131
const { language, changeLanguage } = useI18next();
137-
const { isClassic } = useCloudMode(pathConfig?.repo || Repo.tidb);
132+
const { isClassic } = useCloudPlan();
138133

139134
const open = Boolean(anchorEl);
140135
const handleClick = (event: React.MouseEvent<HTMLElement>) => {

src/components/Layout/VersionSelect/CloudVersionSelect.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ import { AllVersion } from "shared/utils";
88
import LinkComponent from "components/Link";
99
import { Box, Typography } from "@mui/material";
1010
import { Chip } from "@mui/material";
11-
import { CLOUD_MODE_KEY, useCloudMode } from "shared/useCloudMode";
11+
import { CLOUD_MODE_KEY, useCloudPlan } from "shared/useCloudPlan";
1212
import { VersionSelectButton, VersionSelectMenu } from "./SharedSelect";
13-
import { useRef } from "react";
13+
import { useEffect, useRef } from "react";
14+
15+
export const CLOUD_PLAN_LABEL_ELEMENT_ID = "cloud-plan-label";
1416

1517
const CLOUD_VERSIONS = [
1618
{
@@ -54,9 +56,9 @@ const VersionItems = (props: {
5456
availablePlans: string[];
5557
}) => {
5658
const { pathConfig } = props;
57-
const { cloudMode } = useCloudMode(pathConfig.repo);
59+
const { cloudPlan, setCloudPlan } = useCloudPlan();
5860
const currentCloudVersion =
59-
CLOUD_VERSIONS.find((version) => version.value === cloudMode) ||
61+
CLOUD_VERSIONS.find((version) => version.value === cloudPlan) ||
6062
CLOUD_VERSIONS[0];
6163

6264
const getToUrl = (version: string) => {
@@ -67,7 +69,7 @@ const VersionItems = (props: {
6769
: `/${pathConfig.repo}/${version}/?${searchParams.toString()}`;
6870
};
6971
const onClick = (version: string) => {
70-
sessionStorage.setItem(CLOUD_MODE_KEY, version);
72+
setCloudPlan(version);
7173
props.onClick();
7274
};
7375

@@ -121,14 +123,21 @@ interface VersionSelectProps {
121123

122124
export default function CloudVersionSelect(props: VersionSelectProps) {
123125
const { name, pathConfig, availIn, availablePlans } = props;
124-
const { cloudMode } = useCloudMode(pathConfig.repo);
126+
const { cloudPlan } = useCloudPlan();
125127
const currentCloudVersion =
126-
CLOUD_VERSIONS.find((version) => version.value === cloudMode) ||
128+
CLOUD_VERSIONS.find((version) => version.value === cloudPlan) ||
127129
CLOUD_VERSIONS[0];
128130
const anchorEl = useRef<HTMLButtonElement>(null);
129131
const [open, setOpen] = React.useState<boolean>(false);
130132
const handleClick = () => setOpen(true);
131133
const handleClose = () => setOpen(false);
134+
const labelRef = useRef<HTMLSpanElement>(null);
135+
136+
useEffect(() => {
137+
if (labelRef.current && currentCloudVersion.label) {
138+
labelRef.current.textContent = currentCloudVersion.label as string;
139+
}
140+
}, [currentCloudVersion]);
132141

133142
return (
134143
<>
@@ -142,7 +151,7 @@ export default function CloudVersionSelect(props: VersionSelectProps) {
142151
lineHeight: "1.25rem",
143152
}}
144153
>
145-
{currentCloudVersion?.label}
154+
<span id={CLOUD_PLAN_LABEL_ELEMENT_ID} ref={labelRef}></span>
146155
</Typography>
147156
{currentCloudVersion?.icon}
148157
</Box>

src/shared/useCloudMode.ts

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/shared/useCloudPlan.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { navigate } from "gatsby";
2+
import {
3+
createContext,
4+
Dispatch,
5+
SetStateAction,
6+
useContext,
7+
useEffect,
8+
useState,
9+
} from "react";
10+
import { Repo } from "./interface";
11+
12+
export const CLOUD_MODE_KEY = "plan";
13+
export const CLOUD_MODE_VALUE_STARTER = "starter";
14+
export const CLOUD_MODE_VALUE_ESSENTIAL = "essential";
15+
export const GLOBAL_STATE_CLOUD_PLAN_KEY =
16+
"__TIDB_DOCS_GLOBAL_STATE_CLOUD_PLAN__";
17+
18+
const CloudPlanContext = createContext<{
19+
repo: Repo;
20+
cloudPlan: string | null;
21+
setCloudPlan: Dispatch<SetStateAction<string | null>>;
22+
}>({
23+
repo: Repo.tidb,
24+
cloudPlan: null,
25+
setCloudPlan: () => {},
26+
});
27+
export const CloudPlanProvider = CloudPlanContext.Provider;
28+
29+
export const useCloudPlan = () => {
30+
const {
31+
cloudPlan,
32+
setCloudPlan: _setCloudPlan,
33+
repo,
34+
} = useContext(CloudPlanContext);
35+
const isTidbcloud = repo === Repo.tidbcloud;
36+
const [isStarter, setIsStarter] = useState<boolean>(false);
37+
const [isEssential, setIsEssential] = useState<boolean>(false);
38+
const [isClassic, setIsClassic] = useState<boolean>(true);
39+
40+
const setCloudPlan = (cloudPlan: string) => {
41+
_setCloudPlan(cloudPlan);
42+
sessionStorage.setItem(CLOUD_MODE_KEY, cloudPlan);
43+
};
44+
45+
useEffect(() => {
46+
const searchParams = new URLSearchParams(location.search);
47+
const cloudPlanFromSession = sessionStorage.getItem(CLOUD_MODE_KEY);
48+
const cloudPlan = searchParams.get(CLOUD_MODE_KEY) || cloudPlanFromSession;
49+
const isStarter = isTidbcloud && cloudPlan === CLOUD_MODE_VALUE_STARTER;
50+
const isEssential = isTidbcloud && cloudPlan === CLOUD_MODE_VALUE_ESSENTIAL;
51+
const isClassic =
52+
!isTidbcloud || !cloudPlan || (!isStarter && !isEssential);
53+
54+
_setCloudPlan(cloudPlan);
55+
setIsStarter(isStarter);
56+
setIsEssential(isEssential);
57+
setIsClassic(isClassic);
58+
}, []);
59+
60+
return {
61+
cloudPlan,
62+
setCloudPlan,
63+
isStarter,
64+
isEssential,
65+
isClassic,
66+
};
67+
};
68+
69+
export const useCloudPlanNavigate = () => {
70+
useEffect(() => {
71+
const searchParams = new URLSearchParams(location.search);
72+
const cloudModeFromSession = sessionStorage.getItem(CLOUD_MODE_KEY);
73+
const cloudMode = searchParams.get(CLOUD_MODE_KEY) || cloudModeFromSession;
74+
75+
if (!!cloudMode && cloudMode !== "dedicated") {
76+
navigate(
77+
`${location.pathname}?${CLOUD_MODE_KEY}=${cloudMode}${
78+
location.hash ? location.hash : ""
79+
}`
80+
);
81+
}
82+
}, []);
83+
};

src/templates/DocTemplate.tsx

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ import { FeedbackSection } from "components/Card/FeedbackSection";
3131
import { FeedbackSurveyCampaign } from "components/Campaign/FeedbackSurvey";
3232
import { DOC_HOME_URL } from "shared/resources";
3333
import { useReportReadingRate } from "shared/useReportReadingRate";
34-
import { useCloudMode } from "shared/useCloudMode";
34+
import {
35+
CloudPlanProvider,
36+
useCloudPlan,
37+
useCloudPlanNavigate,
38+
} from "shared/useCloudPlan";
3539

3640
interface DocTemplateProps {
3741
pageContext: PageContext & {
@@ -67,7 +71,24 @@ interface DocTemplateProps {
6771
};
6872
}
6973

70-
export default function DocTemplate({
74+
const DocTemplateWithProvider = (props: DocTemplateProps) => {
75+
const [cloudPlan, setCloudPlan] = React.useState<string | null>(null);
76+
return (
77+
<CloudPlanProvider
78+
value={{
79+
cloudPlan,
80+
setCloudPlan,
81+
repo: props.pageContext.pathConfig.repo,
82+
}}
83+
>
84+
<DocTemplate {...props} />
85+
</CloudPlanProvider>
86+
);
87+
};
88+
89+
export default DocTemplateWithProvider;
90+
91+
function DocTemplate({
7192
pageContext: {
7293
name,
7394
availIn,
@@ -86,8 +107,8 @@ export default function DocTemplate({
86107
essentialNavigation: essentialNav,
87108
} = data;
88109

89-
const { isStarter, isEssential } = useCloudMode(pathConfig.repo);
90-
110+
const { isStarter, isEssential } = useCloudPlan();
111+
useCloudPlanNavigate();
91112
useReportReadingRate(timeToRead);
92113

93114
const classicNavigation = originNav ? originNav.navigation : [];

0 commit comments

Comments
 (0)