diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml index 13d1d2e5e..bad3e474c 100644 --- a/.github/workflows/production.yml +++ b/.github/workflows/production.yml @@ -36,10 +36,16 @@ jobs: runs-on: ubuntu-latest name: Build website steps: - - name: Check disk usage - run: df -h - - name: Remove unused Docker images - run: docker system prune -af + - name: Maximize build space + run: | + df -h + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/local/lib/android + sudo rm -rf /opt/ghc + sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo docker image prune --all --force + sudo docker builder prune -a + df -h - uses: actions/checkout@v3 with: @@ -63,7 +69,9 @@ jobs: echo "build_date=$(date)" >> $GITHUB_OUTPUT - name: Install deps - run: yarn + run: | + yarn + df -h - name: Calc gatsby cache key id: calc-cache-key @@ -195,7 +203,8 @@ jobs: architecture: "x64" - name: Install Tencent Cloud CLI - run: pipx install tccli + run: | + pipx install tccli - name: Purge production CDN cache run: tccli cdn PurgePathCache --Paths '["https://docs-preview.pingcap.com/"]' --FlushType flush diff --git a/docs b/docs index 994429ca2..0d2c6cf36 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 994429ca2b304a2373cac38f6dc739b0c321b9c0 +Subproject commit 0d2c6cf365673ac810cda415604458bf713b9faa diff --git a/gatsby-browser.js b/gatsby-browser.js index 72e840878..2be1b7e5c 100644 --- a/gatsby-browser.js +++ b/gatsby-browser.js @@ -1,7 +1,5 @@ import "./src/styles/global.css"; -import { pageView } from "./scripts/track"; - export { default as wrapRootElement } from "./src/state/wrap-with-provider"; export const onClientEntry = () => { @@ -19,9 +17,3 @@ export const onClientEntry = () => { ===================================== `); }; - -export const onRouteUpdate = ({ location, prevLocation }) => { - if (process.env.NODE_ENV === "production") { - pageView(); - } -}; diff --git a/gatsby/cloud-plan.ts b/gatsby/cloud-plan.ts index 37032a261..fd2e9c49e 100644 --- a/gatsby/cloud-plan.ts +++ b/gatsby/cloud-plan.ts @@ -1,7 +1,7 @@ import { mdxAstToToc, TocQueryData } from "./toc"; import { generateConfig } from "./path"; import { extractFilesFromToc } from "./toc-filter"; -import { CloudPlan } from "shared/useCloudPlan"; +import { CloudPlan } from "shared/interface"; type TocMap = Map< string, diff --git a/gatsby/create-pages/create-404.ts b/gatsby/create-pages/create-404.ts new file mode 100644 index 000000000..14087517b --- /dev/null +++ b/gatsby/create-pages/create-404.ts @@ -0,0 +1,22 @@ +import { resolve } from "path"; +import type { CreatePagesArgs } from "gatsby"; +import { DEFAULT_BUILD_TYPE } from "./interface"; +import { BuildType } from "../../src/shared/interface"; + +export const create404 = async ({ + actions: { createPage }, +}: CreatePagesArgs) => { + const template = resolve(__dirname, "../../src/templates/404Template.tsx"); + + createPage({ + path: "/404/", + component: template, + context: { + buildType: (process.env.WEBSITE_BUILD_TYPE ?? + DEFAULT_BUILD_TYPE) as BuildType, + feature: { + banner: false, + }, + }, + }); +}; diff --git a/gatsby/create-pages/create-cloud-api.ts b/gatsby/create-pages/create-cloud-api.ts new file mode 100644 index 000000000..41d5f73f1 --- /dev/null +++ b/gatsby/create-pages/create-cloud-api.ts @@ -0,0 +1,41 @@ +import { resolve } from "path"; + +import type { CreatePagesArgs } from "gatsby"; + +import { Locale, BuildType } from "../../src/shared/interface"; +import { docs as DOCS_CONFIG } from "../../docs/docs.json"; +import { DEFAULT_BUILD_TYPE } from "./interface"; + +export const createCloudAPIReference = async ({ + actions: { createPage }, +}: CreatePagesArgs) => { + const template = resolve( + __dirname, + "../../src/templates/CloudAPIReferenceTemplate.tsx" + ); + const pageCfg = DOCS_CONFIG.tidbcloud.openAPI; + const pageList = pageCfg.data; + const locale = [Locale.en]; + + pageList.forEach((page) => { + const path = `/tidbcloud/${pageCfg.path}/${page.pathname}`; + const isProduction = process.env.CI === "true"; + createPage({ + path, + component: template, + context: { + ...page, + isProduction, + availIn: { + locale, + version: [], + }, + buildType: (process.env.WEBSITE_BUILD_TYPE ?? + DEFAULT_BUILD_TYPE) as BuildType, + feature: { + banner: false, + }, + }, + }); + }); +}; diff --git a/gatsby/create-pages/create-doc-home.ts b/gatsby/create-pages/create-doc-home.ts new file mode 100644 index 000000000..0f2e1d018 --- /dev/null +++ b/gatsby/create-pages/create-doc-home.ts @@ -0,0 +1,118 @@ +import { resolve } from "path"; + +import type { CreatePagesArgs } from "gatsby"; +import sig from "signale"; + +import { Locale, BuildType } from "../../src/shared/interface"; +import { + generateConfig, + generateNav, + generateDocHomeUrl, +} from "../../gatsby/path"; +import { DEFAULT_BUILD_TYPE, PageQueryData } from "./interface"; + +export const createDocHome = async ({ + actions: { createPage }, + graphql, +}: CreatePagesArgs) => { + // const template = resolve(__dirname, "../src/doc/index.tsx"); + const template = resolve(__dirname, "../../src/templates/DocTemplate.tsx"); + + const prodQueryStr = ` + { + allMdx( + filter: { + fileAbsolutePath: { regex: "/tidbcloud/master/_docHome.md$/" } + frontmatter: { draft: { ne: true } } + } + ) { + nodes { + id + frontmatter { + aliases + } + slug + parent { + ... on File { + relativePath + } + } + } + } + } +`; + + const archiveQueryStr = ` + { + allMdx( + filter: { + fileAbsolutePath: { regex: "/tidb/_docHome.md$/" } + frontmatter: { draft: { ne: true } } + } + ) { + nodes { + id + frontmatter { + aliases + } + slug + parent { + ... on File { + relativePath + } + } + } + } + } +`; + + const docs = await graphql( + process.env.WEBSITE_BUILD_TYPE === "archive" + ? archiveQueryStr + : prodQueryStr + ); + + if (docs.errors) { + sig.error(docs.errors); + } + + const nodes = docs.data!.allMdx.nodes.map((node) => { + const { config, name, filePath } = generateConfig(node.slug); + return { ...node, pathConfig: config, name, filePath }; + }); + + nodes.forEach((node) => { + const { id, name, pathConfig, filePath, slug } = node; + const path = generateDocHomeUrl(name, pathConfig); + const navUrl = generateNav(pathConfig); + const locale = + process.env.WEBSITE_BUILD_TYPE === "archive" + ? [Locale.en, Locale.zh] + : [Locale.en, Locale.zh, Locale.ja]; + + createPage({ + path, + component: template, + context: { + id, + name, + pathConfig, + // use for edit in github + filePath, + navUrl, + pageUrl: path, + availIn: { + locale, + version: [], + }, + buildType: (process.env.WEBSITE_BUILD_TYPE ?? + DEFAULT_BUILD_TYPE) as BuildType, + feature: { + banner: true, + feedback: true, + globalHome: true, + }, + }, + }); + }); +}; diff --git a/gatsby/create-pages.ts b/gatsby/create-pages/create-docs.ts similarity index 50% rename from gatsby/create-pages.ts rename to gatsby/create-pages/create-docs.ts index bc7288264..81cb06b33 100644 --- a/gatsby/create-pages.ts +++ b/gatsby/create-pages/create-docs.ts @@ -3,20 +3,11 @@ import { resolve } from "path"; import type { CreatePagesArgs } from "gatsby"; import sig from "signale"; -import { Locale, Repo, BuildType } from "../src/shared/interface"; -import { - generateConfig, - generateUrl, - generateNav, - generateDocHomeUrl, -} from "./path"; -import { docs as DOCS_CONFIG } from "../docs/docs.json"; -import { cpMarkdown } from "./cp-markdown"; -import { - getTidbCloudFilesFromTocs, - determineInDefaultPlan, -} from "./cloud-plan"; -import { getFilesFromTocs, filterNodesByToc } from "./toc-filter"; +import { Locale, Repo, BuildType } from "../../src/shared/interface"; +import { generateConfig, generateUrl, generateNav } from "../path"; +import { cpMarkdown } from "../cp-markdown"; +import { getTidbCloudFilesFromTocs } from "../cloud-plan"; +import { getFilesFromTocs, filterNodesByToc } from "../toc-filter"; interface PageQueryData { allMdx: { @@ -179,178 +170,3 @@ export const createDocs = async (createPagesArgs: CreatePagesArgs) => { } }); }; - -export const createCloudAPIReference = async ({ - actions: { createPage, createRedirect }, - graphql, -}: CreatePagesArgs) => { - const template = resolve( - __dirname, - "../src/templates/CloudAPIReferenceTemplate.tsx" - ); - const pageCfg = DOCS_CONFIG.tidbcloud.openAPI; - const pageList = pageCfg.data; - const locale = [Locale.en]; - - pageList.forEach((page) => { - const path = `/tidbcloud/${pageCfg.path}/${page.pathname}`; - const isProduction = process.env.CI === "true"; - createPage({ - path, - component: template, - context: { - ...page, - isProduction, - availIn: { - locale, - version: [], - }, - buildType: (process.env.WEBSITE_BUILD_TYPE ?? - DEFAULT_BUILD_TYPE) as BuildType, - feature: { - banner: false, - }, - }, - }); - }); -}; - -export const createDocHome = async ({ - actions: { createPage, createRedirect }, - graphql, -}: CreatePagesArgs) => { - // const template = resolve(__dirname, "../src/doc/index.tsx"); - const template = resolve(__dirname, "../src/templates/DocTemplate.tsx"); - - const prodQueryStr = ` - { - allMdx( - filter: { - fileAbsolutePath: { regex: "/tidbcloud/master/_docHome.md$/" } - frontmatter: { draft: { ne: true } } - } - ) { - nodes { - id - frontmatter { - aliases - } - slug - parent { - ... on File { - relativePath - } - } - } - } - } -`; - - const archiveQueryStr = ` - { - allMdx( - filter: { - fileAbsolutePath: { regex: "/tidb/_docHome.md$/" } - frontmatter: { draft: { ne: true } } - } - ) { - nodes { - id - frontmatter { - aliases - } - slug - parent { - ... on File { - relativePath - } - } - } - } - } -`; - - const docs = await graphql( - process.env.WEBSITE_BUILD_TYPE === "archive" - ? archiveQueryStr - : prodQueryStr - ); - - if (docs.errors) { - sig.error(docs.errors); - } - - const nodes = docs.data!.allMdx.nodes.map((node) => { - const { config, name, filePath } = generateConfig(node.slug); - return { ...node, pathConfig: config, name, filePath }; - }); - - nodes.forEach((node) => { - const { id, name, pathConfig, filePath, slug } = node; - const path = generateDocHomeUrl(name, pathConfig); - const navUrl = generateNav(pathConfig); - const locale = - process.env.WEBSITE_BUILD_TYPE === "archive" - ? [Locale.en, Locale.zh] - : [Locale.en, Locale.zh, Locale.ja]; - - createPage({ - path, - component: template, - context: { - id, - name, - pathConfig, - // use for edit in github - filePath, - navUrl, - pageUrl: path, - availIn: { - locale, - version: [], - }, - buildType: (process.env.WEBSITE_BUILD_TYPE ?? - DEFAULT_BUILD_TYPE) as BuildType, - feature: { - banner: true, - feedback: true, - globalHome: true, - }, - }, - }); - }); -}; - -export const createDocSearch = async ({ - actions: { createPage }, -}: CreatePagesArgs) => { - const template = resolve(__dirname, "../src/templates/DocSearchTemplate.tsx"); - - createPage({ - path: "/search/", - component: template, - context: { - feature: { - banner: false, - }, - }, - }); -}; - -export const create404 = async ({ - actions: { createPage }, -}: CreatePagesArgs) => { - const template = resolve(__dirname, "../src/templates/404Template.tsx"); - - createPage({ - path: "/404/", - component: template, - context: { - buildType: (process.env.WEBSITE_BUILD_TYPE ?? - DEFAULT_BUILD_TYPE) as BuildType, - feature: { - banner: false, - }, - }, - }); -}; diff --git a/gatsby/create-pages/create-search.ts b/gatsby/create-pages/create-search.ts new file mode 100644 index 000000000..3fd6c571e --- /dev/null +++ b/gatsby/create-pages/create-search.ts @@ -0,0 +1,21 @@ +import { resolve } from "path"; +import type { CreatePagesArgs } from "gatsby"; + +export const createDocSearch = async ({ + actions: { createPage }, +}: CreatePagesArgs) => { + const template = resolve( + __dirname, + "../../src/templates/DocSearchTemplate.tsx" + ); + + createPage({ + path: "/search/", + component: template, + context: { + feature: { + banner: false, + }, + }, + }); +}; diff --git a/gatsby/create-pages/index.ts b/gatsby/create-pages/index.ts new file mode 100644 index 000000000..2efeba8e7 --- /dev/null +++ b/gatsby/create-pages/index.ts @@ -0,0 +1,5 @@ +export { createDocHome } from "./create-doc-home"; +export { createDocs } from "./create-docs"; +export { createCloudAPIReference } from "./create-cloud-api"; +export { createDocSearch } from "./create-search"; +export { create404 } from "./create-404"; diff --git a/gatsby/create-pages/interface.ts b/gatsby/create-pages/interface.ts new file mode 100644 index 000000000..a87d27237 --- /dev/null +++ b/gatsby/create-pages/interface.ts @@ -0,0 +1,13 @@ +import { BuildType } from "../../src/shared/interface"; + +export const DEFAULT_BUILD_TYPE: BuildType = "prod"; + +export interface PageQueryData { + allMdx: { + nodes: { + id: string; + frontmatter: { aliases: string[] }; + slug: string; + }[]; + }; +} diff --git a/gatsby/path.ts b/gatsby/path.ts index 3438c5e56..b57733ddf 100644 --- a/gatsby/path.ts +++ b/gatsby/path.ts @@ -1,4 +1,4 @@ -import { Locale, Repo, PathConfig } from "../src/shared/interface"; +import { Locale, Repo, PathConfig, CloudPlan } from "../src/shared/interface"; import CONFIG from "../docs/docs.json"; export function generateUrl(filename: string, config: PathConfig) { @@ -50,17 +50,17 @@ export function generateConfig(slug: string): { let name = rest[rest.length - 1]; name = name === "_index" ? "" : name; - let prefix = undefined; + let prefix: CloudPlan | undefined = undefined; if (repo === Repo.tidbcloud) { - if (slug.includes("starter/")) { - prefix = "starter"; - } else if (slug.includes("essential/")) { - prefix = "essential"; - } else if (slug.includes("dedicated/")) { - if (!!name) { - prefix = "dedicated"; - } + const simplePrefixes = ["starter", "essential", "premium"]; + prefix = simplePrefixes.find((p) => slug.includes(`${p}/`)) as + | CloudPlan + | undefined; + + // dedicated prefix is only used when the name is not empty + if (!prefix && slug.includes("dedicated/") && name) { + prefix = "dedicated"; } } diff --git a/gatsby/toc.ts b/gatsby/toc.ts index f037db07e..bce566caa 100644 --- a/gatsby/toc.ts +++ b/gatsby/toc.ts @@ -9,10 +9,20 @@ import { Heading, } from "mdast"; -import { RepoNav, RepoNavLink, PathConfig } from "../src/shared/interface"; +import { + RepoNav, + RepoNavLink, + PathConfig, + CloudPlan, +} from "../src/shared/interface"; import { generateUrl } from "./path"; -export const EXTENDS_FOLDERS = ["starter", "essential", "dedicated"]; +export const EXTENDS_FOLDERS: CloudPlan[] = [ + "starter", + "essential", + "dedicated", + "premium", +]; const SKIP_MODE_HEADING = "_BUILD_ALLOWLIST"; diff --git a/scripts/track.js b/scripts/track.js deleted file mode 100644 index f4a8d314b..000000000 --- a/scripts/track.js +++ /dev/null @@ -1,49 +0,0 @@ -exports.pageView = function () { - _reportLog('pageview', { - dl: document.location.href, - dr: document.referrer, - ts: _getCurrentTS(), - ul: navigator.language || navigator.userLanguage, - dt: document.title, - }) -} - -function _getCurrentTS() { - return new Date().getTime() -} - -function _getCookie(cname) { - var name = cname + '=' - var ca = document.cookie.split(';') - for (var i = 0; i < ca.length; i++) { - var c = ca[i].trim() - if (c.indexOf(name) === 0) return c.substring(name.length, c.length) - } - return '' -} - -function _reportLog(logType, params) { - var eventUrl = 'https://accounts.pingcap.com/_analytics/event?' - var uid = _getCookie('uid') - - if (uid) { - params.uid = uid - } - - params.e = logType - // version - params.v = 1 - - var paramsArr = [] - Object.keys(params).forEach(item => { - if (typeof params[item] !== 'undefined') { - paramsArr.push(item + '=' + encodeURIComponent(params[item])) - } - }) - eventUrl += paramsArr.join('&') - - var oReq = new XMLHttpRequest() - oReq.open('GET', eventUrl) - oReq.withCredentials = true - oReq.send() -} diff --git a/sentry.config.js b/sentry.config.js index f37c53e0e..993b487b8 100644 --- a/sentry.config.js +++ b/sentry.config.js @@ -5,5 +5,5 @@ Sentry.init({ dsn: process.env.GATSBY_SENTRY_DSN, integrations: [Sentry.browserTracingIntegration()], - tracesSampleRate: 0.1, + tracesSampleRate: 0.01, }); diff --git a/src/components/Contributors/index.tsx b/src/components/Contributors/index.tsx index 8d275ccb6..1a9a360fe 100644 --- a/src/components/Contributors/index.tsx +++ b/src/components/Contributors/index.tsx @@ -237,7 +237,13 @@ export const useTotalContributors = ( return; } ReactDOM.unmountComponentAtNode(appendedNode); - appendedNode?.parentNode?.removeChild(appendedNode); + // Check if the node is still a child of its parent before removing + if ( + appendedNode.parentNode && + appendedNode.parentNode.contains(appendedNode) + ) { + appendedNode.parentNode.removeChild(appendedNode); + } }; }, [totalContributors]); diff --git a/src/components/Layout/HeaderNav.tsx b/src/components/Layout/HeaderNav.tsx index 7d9d6e07a..0e34a3e7b 100644 --- a/src/components/Layout/HeaderNav.tsx +++ b/src/components/Layout/HeaderNav.tsx @@ -15,7 +15,6 @@ import { generateDownloadURL, generateContactURL, generateLearningCenterURL, - generateDocsHomeUrl, getPageType, PageType, } from "shared/utils"; @@ -161,7 +160,6 @@ export function HeaderNavStackMobile(props: { buildType?: BuildType }) { const theme = useTheme(); const { language, t } = useI18next(); const selectedItem = useSelectedNavItem(language); - const open = Boolean(anchorEl); const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); @@ -240,7 +238,7 @@ export function HeaderNavStackMobile(props: { buildType?: BuildType }) { > gtmTrack(GTMEvent.ClickHeadNav, { diff --git a/src/components/Layout/Navigation/LeftNavTree.tsx b/src/components/Layout/Navigation/LeftNavTree.tsx index c31c02d67..4f033ae86 100644 --- a/src/components/Layout/Navigation/LeftNavTree.tsx +++ b/src/components/Layout/Navigation/LeftNavTree.tsx @@ -72,11 +72,18 @@ function StyledTreeItem(props: StyledTreeItemProps) { ); } -const calcExpandedIds = (data: RepoNavLink[], targetLink: string) => { +const calcExpandedIds = ( + data: RepoNavLink[], + targetLink: string, + targetId?: string +) => { const ids: string[] = []; const treeForeach = (data: RepoNavLink[], parents: string[] = []): void => { data.forEach((item) => { - if (item.link === targetLink) { + const isMatch = targetId + ? item.link === targetLink && item.id === targetId + : item.link === targetLink; + if (isMatch) { ids.push(...parents); ids.push(item.id); return; @@ -90,6 +97,29 @@ const calcExpandedIds = (data: RepoNavLink[], targetLink: string) => { return ids; }; +// Session storage key prefix for nav item id +const NAV_ITEM_ID_STORAGE_KEY = "nav_item_id_"; + +// Get nav item id from session storage for a given path +const getNavItemIdFromStorage = (path: string): string | null => { + if (typeof window === "undefined") return null; + try { + return sessionStorage.getItem(`${NAV_ITEM_ID_STORAGE_KEY}${path}`); + } catch { + return null; + } +}; + +// Save nav item id to session storage for a given path +const saveNavItemIdToStorage = (path: string, id: string): void => { + if (typeof window === "undefined") return; + try { + sessionStorage.setItem(`${NAV_ITEM_ID_STORAGE_KEY}${path}`, id); + } catch { + // Ignore storage errors + } +}; + export default function ControlledTreeView(props: { data: RepoNav; current: string; @@ -110,7 +140,12 @@ export default function ControlledTreeView(props: { const theme = useTheme(); React.useEffect(() => { - const expandedIds = calcExpandedIds(data, currentUrl); + const storedId = getNavItemIdFromStorage(currentUrl); + const expandedIds = calcExpandedIds( + data, + currentUrl, + storedId || undefined + ); setExpanded(expandedIds); expandedIds.length && setSelected([expandedIds[expandedIds.length - 1]]); }, [data, currentUrl]); @@ -191,7 +226,13 @@ export default function ControlledTreeView(props: { key={item.id} to={item.link} style={{ width: "100%", color: "inherit" }} - onClick={(e) => e.stopPropagation()} + onClick={(e) => { + e.stopPropagation(); + // Save nav item id to session storage when clicked + if (item.link) { + saveNavItemIdToStorage(item.link, item.id); + } + }} > { setRenderedTabs((prev) => { if (prev.includes(id)) { @@ -135,19 +136,25 @@ export const TabContentDetector = ({ children, id, activeTab, + renderedTabs, onRendered, }: { children: ReactElement; id: string; activeTab: string; + renderedTabs: string[]; onRendered: (id: string) => void; }) => { const ref = useRef(null); useEffect(() => { - if (ref.current && ref.current.children.length > 0) { + if ( + ref.current && + ref.current.children.length > 0 && + !renderedTabs.includes(id) + ) { onRendered(id); } - }, []); + }); return (
{children} diff --git a/src/components/MDXContent.tsx b/src/components/MDXContent.tsx index 8b629b7e1..615c03ba2 100644 --- a/src/components/MDXContent.tsx +++ b/src/components/MDXContent.tsx @@ -8,13 +8,17 @@ import Box from "@mui/material/Box"; import * as MDXComponents from "components/MDXComponents"; import { CustomNotice } from "components/Card/CustomNotice"; -import { PathConfig, FrontMatter, BuildType } from "shared/interface"; +import { + PathConfig, + FrontMatter, + BuildType, + CloudPlan, +} from "shared/interface"; import { useTotalContributors } from "components/Contributors"; import replaceInternalHref from "shared/utils/anchor"; import { Pre } from "components/MDXComponents/Pre"; import { useCustomContent } from "components/MDXComponents/CustomContent"; import { getPageType } from "shared/utils"; -import { CloudPlan } from "shared/useCloudPlan"; export default function MDXContent(props: { data: any; diff --git a/src/shared/filterRightToc.ts b/src/shared/filterRightToc.ts index 59048afb6..0b1e57549 100644 --- a/src/shared/filterRightToc.ts +++ b/src/shared/filterRightToc.ts @@ -1,6 +1,5 @@ -import { TableOfContent } from "./interface"; +import { TableOfContent, CloudPlan } from "./interface"; import { PageType } from "./utils"; -import { CloudPlan } from "./useCloudPlan"; /** * Filter right TOC based on CustomContent conditions diff --git a/src/shared/interface.ts b/src/shared/interface.ts index e7a8a314e..97cd2b16d 100644 --- a/src/shared/interface.ts +++ b/src/shared/interface.ts @@ -67,3 +67,5 @@ export interface RepoNavLink { export type RepoNav = RepoNavLink[]; export type BuildType = "prod" | "archive"; + +export type CloudPlan = "dedicated" | "starter" | "essential" | "premium"; diff --git a/src/shared/resources.ts b/src/shared/resources.ts index 54e630b90..04229be9f 100644 --- a/src/shared/resources.ts +++ b/src/shared/resources.ts @@ -17,27 +17,27 @@ export const DOC_HOME_URL = "https://docs.pingcap.com"; export const DEFAULT_PINGCAP_URL = `https://www.pingcap.com`; export const EN_PINGCAP_URL = `https://www.pingcap.com/`; -export const ZH_PINGCAP_URL = `https://cn.pingcap.com/`; +export const ZH_PINGCAP_URL = `https://pingkai.cn/`; export const JA_PINGCAP_URL = `https://pingcap.co.jp/`; export const EN_PINGCAP_DOWNLOAD_URL = "https://www.pingcap.com/download/"; export const ZH_PINGCAP_DOWNLOAD_URL = - "https://cn.pingcap.com/product/#SelectProduct"; + "https://pingkai.cn/opensource/tidb"; export const JA_PINGCAP_DOWNLOAD_URL = "https://pingcap.co.jp/event/"; export const EN_CONTACT_URL = "https://www.pingcap.com/contact-us/"; -export const ZH_CONTACT_URL = "https://cn.pingcap.com/contact/"; +export const ZH_CONTACT_URL = "https://pingkai.cn/contact"; export const JA_CONTACT_URL = "https://pingcap.co.jp/contact-us/"; export const EN_PRIVACY_POLICY_URL = "https://www.pingcap.com/privacy-policy"; -export const ZH_PRIVACY_POLICY_URL = "https://cn.pingcap.com/privacy-policy"; +export const ZH_PRIVACY_POLICY_URL = "https://pingkai.cn/legal/privacy-policy"; export const JA_PRIVACY_POLICY_URL = "https://pingcap.co.jp/privacy-policy"; export const EN_LEARNING_CENTER_URL = "https://www.pingcap.com/education/"; -export const ZH_LEARNING_CENTER_URL = "https://cn.pingcap.com/education/"; +export const ZH_LEARNING_CENTER_URL = "https://learn.pingcap.cn/learner/course"; export const EN_LEGAL_URL = "https://www.pingcap.com/legal/"; -export const ZH_LEGAL_URL = "https://cn.pingcap.com/law/"; +export const ZH_LEGAL_URL = "https://pingkai.cn/legal/compliance"; export const JA_LEGAL_URL = "https://pingcap.co.jp/legal/"; export const ICON_GROUP_CHUNK_SIZE = 3; @@ -305,7 +305,7 @@ export const ZH_FOOTER_ITEMS = [ }, { name: "TiDB", - url: "https://cn.pingcap.com/product/#SelectProduct", + url: "https://pingkai.cn/opensource/tidb", }, { name: "TiDB Cloud", @@ -347,11 +347,11 @@ export const ZH_FOOTER_ITEMS = [ }, { name: "博客", - url: "https://cn.pingcap.com/blog/", + url: "https://tidb.net/blog", }, { name: "Education", - url: "https://cn.pingcap.com/education/", + url: "https://learn.pingcap.cn/learner/course", }, ], }, @@ -364,7 +364,7 @@ export const ZH_FOOTER_ITEMS = [ }, { name: "联系我们", - url: "https://cn.pingcap.com/contact/", + url: "https://pingkai.cn/contact", }, ], }, @@ -373,7 +373,7 @@ export const ZH_FOOTER_ITEMS = [ items: [ { name: "关于我们", - url: "https://cn.pingcap.com/about-us?tab=companyOverview", + url: "https://pingkai.cn/about", }, { name: "招贤纳士", @@ -381,7 +381,7 @@ export const ZH_FOOTER_ITEMS = [ }, { name: "新闻报道", - url: "https://cn.pingcap.com/company-activity/", + url: "https://pingkai.cn/news", }, ], }, diff --git a/src/shared/useCloudPlan.ts b/src/shared/useCloudPlan.ts index beac65471..34b0cdc48 100644 --- a/src/shared/useCloudPlan.ts +++ b/src/shared/useCloudPlan.ts @@ -7,15 +7,13 @@ import { useEffect, useState, } from "react"; -import { Repo } from "./interface"; +import { CloudPlan, Repo } from "./interface"; export const CLOUD_MODE_KEY = "plan"; export const CLOUD_MODE_VALUE_STARTER = "starter"; export const CLOUD_MODE_VALUE_ESSENTIAL = "essential"; export const CLOUD_MODE_VALUE_PREMIUM = "premium"; -export type CloudPlan = "dedicated" | "starter" | "essential" | "premium"; - const CloudPlanContext = createContext<{ repo: Repo; cloudPlan: CloudPlan | null; diff --git a/src/shared/utils/index.ts b/src/shared/utils/index.ts index 72beeee6c..4b61f0ba6 100644 --- a/src/shared/utils/index.ts +++ b/src/shared/utils/index.ts @@ -289,15 +289,7 @@ export function isInViewport(element: HTMLElement) { export function scrollToElementIfInView( element: HTMLElement & { scrollIntoViewIfNeeded: () => void } ) { - const isVisiable = isInViewport(element); - if (isVisiable) { - return; - } - if (element.scrollIntoViewIfNeeded) { - element.scrollIntoViewIfNeeded(); - } else { - element.scrollIntoView({ block: "end" }); - } + element.scrollIntoView({ block: "center" }); } export type PageType = "home" | "tidb" | "tidbcloud" | undefined; diff --git a/src/templates/DocTemplate.tsx b/src/templates/DocTemplate.tsx index 5b473537d..0bc31d4fb 100644 --- a/src/templates/DocTemplate.tsx +++ b/src/templates/DocTemplate.tsx @@ -23,6 +23,7 @@ import { RepoNav, BuildType, Locale, + CloudPlan, } from "shared/interface"; import Seo from "components/Seo"; import { getStable, generateUrl, getPageType } from "shared/utils"; @@ -32,7 +33,6 @@ import { FeedbackSurveyCampaign } from "components/Campaign/FeedbackSurvey"; import { DOC_HOME_URL } from "shared/resources"; import { useReportReadingRate } from "shared/useReportReadingRate"; import { - CloudPlan, CloudPlanProvider, useCloudPlan, useCloudPlanNavigate, diff --git a/static/zh/llms.txt b/static/zh/llms.txt index 22ea26286..44f69c25b 100644 --- a/static/zh/llms.txt +++ b/static/zh/llms.txt @@ -5,7 +5,7 @@ ## TiDB Self-Managed 文档(使用 TiUP 部署) - [TiDB Self-Managed 文档](https://docs.pingcap.com/zh/tidb/stable.md): TiDB 是 PingCAP 公司自主设计、研发的开源分布式关系型数据库。产品文档包括了 TiDB 简介、功能概览、TiFlash、快速上手 TiDB、HTAP、开发者手册概览、软硬件环境需求、使用 TiUP 部署 TiDB、数据迁移概览、运维、监控、调优、工具、TiDB 路线图、配置文件参数、命令行参数、TiDB Control、系统变量、发布历史、常见问题。 -- [TiDB 版本周期支持策略](https://cn.pingcap.com/tidb-release-support-policy/): 阐述了 PingCAP 就 TiDB 版本提供支持服务的标准和规则。 +- [TiDB 版本周期支持策略](https://pingkai.cn/tidb-release-support-policy): 阐述了 PingCAP 就 TiDB 版本提供支持服务的标准和规则。 - [50 TiB 数据导入最佳实践](https://docs.pingcap.com/zh/tidb/stable/data-import-best-practices.md): 了解将大规模数据导入 TiDB 的最佳实践。 - [ADD COLUMN](https://docs.pingcap.com/zh/tidb/stable/sql-statement-add-column.md): TiDB 数据库中 ADD COLUMN 的使用概况。 - [ADD INDEX](https://docs.pingcap.com/zh/tidb/stable/sql-statement-add-index.md): TiDB 数据库中 ADD INDEX 的使用概况。