mirror of
https://github.com/coder/coder.git
synced 2026-09-22 05:05:20 +08:00
feat: add a page to showcase the local installation script (#16122)
This commit is contained in:
@@ -65,7 +65,7 @@ export const CodeExample: FC<CodeExampleProps> = ({
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<>{code}</>
|
||||
code
|
||||
)}
|
||||
</code>
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import AccountIcon from "@mui/icons-material/AccountCircleOutlined";
|
||||
import BugIcon from "@mui/icons-material/BugReportOutlined";
|
||||
import ChatIcon from "@mui/icons-material/ChatOutlined";
|
||||
import LogoutIcon from "@mui/icons-material/ExitToAppOutlined";
|
||||
import InstallDesktopIcon from "@mui/icons-material/InstallDesktop";
|
||||
import LaunchIcon from "@mui/icons-material/LaunchOutlined";
|
||||
import DocsIcon from "@mui/icons-material/MenuBook";
|
||||
import Divider from "@mui/material/Divider";
|
||||
@@ -21,7 +22,6 @@ import { Stack } from "components/Stack/Stack";
|
||||
import { usePopover } from "components/deprecated/Popover/Popover";
|
||||
import type { FC } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export const Language = {
|
||||
accountLabel: "Account",
|
||||
signOutLabel: "Sign Out",
|
||||
@@ -76,6 +76,13 @@ export const UserDropdownContent: FC<UserDropdownContentProps> = ({
|
||||
|
||||
<Divider css={{ marginBottom: 8 }} />
|
||||
|
||||
<Link to="/install" css={styles.link}>
|
||||
<MenuItem css={styles.menuItem} onClick={onPopoverClose}>
|
||||
<InstallDesktopIcon css={styles.menuItemIcon} />
|
||||
<span css={styles.menuItemText}>Install CLI</span>
|
||||
</MenuItem>
|
||||
</Link>
|
||||
|
||||
<Link to="/settings/account" css={styles.link}>
|
||||
<MenuItem css={styles.menuItem} onClick={onPopoverClose}>
|
||||
<AccountIcon css={styles.menuItemIcon} />
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { FC } from "react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { pageTitle } from "utils/page";
|
||||
import { CliInstallPageView } from "./CliInstallPageView";
|
||||
|
||||
export const CliInstallPage: FC = () => {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>{pageTitle("Install the Coder CLI")}</title>
|
||||
</Helmet>
|
||||
<CliInstallPageView />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CliInstallPage;
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { CliInstallPageView } from "./CliInstallPageView";
|
||||
|
||||
const meta: Meta<typeof CliInstallPageView> = {
|
||||
title: "pages/CliInstallPage",
|
||||
component: CliInstallPageView,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof CliInstallPageView>;
|
||||
|
||||
const Example: Story = {};
|
||||
|
||||
export { Example as CliInstallPage };
|
||||
@@ -0,0 +1,78 @@
|
||||
import type { Interpolation, Theme } from "@emotion/react";
|
||||
import { CodeExample } from "components/CodeExample/CodeExample";
|
||||
import { Welcome } from "components/Welcome/Welcome";
|
||||
import type { FC } from "react";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
|
||||
export const CliInstallPageView: FC = () => {
|
||||
const origin = location.origin;
|
||||
|
||||
return (
|
||||
<div css={styles.container}>
|
||||
<Welcome>Install the Coder CLI</Welcome>
|
||||
|
||||
<p css={styles.instructions}>
|
||||
Copy the command below and{" "}
|
||||
<strong css={{ display: "block" }}>paste it in your terminal.</strong>
|
||||
</p>
|
||||
|
||||
<CodeExample
|
||||
css={{ maxWidth: "100%" }}
|
||||
data-chromatic="ignore"
|
||||
code={`curl -fsSL ${origin}/install.sh | sh`}
|
||||
secret={false}
|
||||
/>
|
||||
|
||||
<div css={{ paddingTop: 16 }}>
|
||||
<RouterLink to="/workspaces" css={styles.backLink}>
|
||||
Go to workspaces
|
||||
</RouterLink>
|
||||
</div>
|
||||
<div css={styles.copyright}>
|
||||
{"\u00a9"} {new Date().getFullYear()} Coder Technologies, Inc.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
flex: 1,
|
||||
height: "-webkit-fill-available",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
width: 480,
|
||||
margin: "auto",
|
||||
},
|
||||
|
||||
instructions: (theme) => ({
|
||||
fontSize: 16,
|
||||
color: theme.palette.text.secondary,
|
||||
paddingBottom: 8,
|
||||
textAlign: "center",
|
||||
lineHeight: 1.4,
|
||||
}),
|
||||
|
||||
backLink: (theme) => ({
|
||||
display: "block",
|
||||
textAlign: "center",
|
||||
color: theme.palette.text.primary,
|
||||
textDecoration: "underline",
|
||||
textUnderlineOffset: 3,
|
||||
textDecorationColor: "hsla(0deg, 0%, 100%, 0.7)",
|
||||
paddingTop: 16,
|
||||
paddingBottom: 16,
|
||||
|
||||
"&:hover": {
|
||||
textDecoration: "none",
|
||||
},
|
||||
}),
|
||||
|
||||
copyright: (theme) => ({
|
||||
fontSize: 12,
|
||||
color: theme.palette.text.secondary,
|
||||
marginTop: 24,
|
||||
}),
|
||||
} satisfies Record<string, Interpolation<Theme>>;
|
||||
+10
-6
@@ -34,14 +34,15 @@ const DeploymentSettingsLayout = lazy(
|
||||
const DeploymentSettingsProvider = lazy(
|
||||
() => import("./modules/management/DeploymentSettingsProvider"),
|
||||
);
|
||||
const OrganizationSettingsLayout = lazy(
|
||||
() => import("./modules/management/OrganizationSettingsLayout"),
|
||||
);
|
||||
const OrganizationSidebarLayout = lazy(
|
||||
() => import("./modules/management/OrganizationSidebarLayout"),
|
||||
);
|
||||
const CliAuthenticationPage = lazy(
|
||||
() => import("./pages/CliAuthPage/CliAuthPage"),
|
||||
const OrganizationSettingsLayout = lazy(
|
||||
() => import("./modules/management/OrganizationSettingsLayout"),
|
||||
);
|
||||
const CliAuthPage = lazy(() => import("./pages/CliAuthPage/CliAuthPage"));
|
||||
const CliInstallPage = lazy(
|
||||
() => import("./pages/CliInstallPage/CliInstallPage"),
|
||||
);
|
||||
const AccountPage = lazy(
|
||||
() => import("./pages/UserSettingsPage/AccountPage/AccountPage"),
|
||||
@@ -542,6 +543,9 @@ export const router = createBrowserRouter(
|
||||
element={<ProvisionerDaemonsHealthPage />}
|
||||
/>
|
||||
</Route>
|
||||
|
||||
<Route path="/install" element={<CliInstallPage />} />
|
||||
|
||||
{/* Using path="*"" means "match anything", so this route
|
||||
acts like a catch-all for URLs that we don't have explicit
|
||||
routes for. */}
|
||||
@@ -562,7 +566,7 @@ export const router = createBrowserRouter(
|
||||
path="/:username/:workspace/terminal"
|
||||
element={<TerminalPage />}
|
||||
/>
|
||||
<Route path="/cli-auth" element={<CliAuthenticationPage />} />
|
||||
<Route path="/cli-auth" element={<CliAuthPage />} />
|
||||
<Route path="/icons" element={<IconsPage />} />
|
||||
</Route>
|
||||
</Route>,
|
||||
|
||||
Reference in New Issue
Block a user