mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore: replace MUI Button - 1 (#17865)
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
import { useTheme } from "@emotion/react";
|
||||
import Button from "@mui/material/Button";
|
||||
import { Button } from "components/Button/Button";
|
||||
import type { FC, ReactNode } from "react";
|
||||
|
||||
type NumberedPageButtonProps = {
|
||||
pageNumber: number;
|
||||
totalPages: number;
|
||||
|
||||
onClick?: () => void;
|
||||
highlighted?: boolean;
|
||||
disabled?: boolean;
|
||||
@@ -68,23 +66,10 @@ const BasePageButton: FC<BasePageButtonProps> = ({
|
||||
highlighted = false,
|
||||
disabled = false,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Button
|
||||
css={
|
||||
highlighted && {
|
||||
borderColor: theme.roles.active.outline,
|
||||
backgroundColor: theme.roles.active.background,
|
||||
|
||||
// Override the hover state with active colors, but not hover
|
||||
// colors because clicking won't do anything.
|
||||
"&:hover": {
|
||||
borderColor: theme.roles.active.outline,
|
||||
backgroundColor: theme.roles.active.background,
|
||||
},
|
||||
}
|
||||
}
|
||||
variant={highlighted ? "default" : "outline"}
|
||||
size="icon"
|
||||
aria-label={ariaLabel}
|
||||
name={name}
|
||||
disabled={disabled}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useTheme } from "@emotion/react";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import { Button } from "components/Button/Button";
|
||||
import {
|
||||
type ButtonHTMLAttributes,
|
||||
type ReactNode,
|
||||
@@ -32,7 +31,6 @@ function PaginationNavButtonCore({
|
||||
disabledMessageTimeout = 3000,
|
||||
...delegatedProps
|
||||
}: PaginationNavButtonProps) {
|
||||
const theme = useTheme();
|
||||
const [showDisabledMessage, setShowDisabledMessage] = useState(false);
|
||||
|
||||
// Inline state sync - this is safe/recommended by the React team in this case
|
||||
@@ -63,25 +61,10 @@ function PaginationNavButtonCore({
|
||||
* (mostly for giving direct UI feedback to those actions)
|
||||
*/}
|
||||
<Button
|
||||
aria-disabled={disabled}
|
||||
css={
|
||||
disabled && {
|
||||
borderColor: theme.palette.divider,
|
||||
color: theme.palette.text.disabled,
|
||||
cursor: "default",
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
borderColor: theme.palette.divider,
|
||||
},
|
||||
}
|
||||
}
|
||||
onClick={() => {
|
||||
if (disabled) {
|
||||
setShowDisabledMessage(true);
|
||||
} else {
|
||||
onClick();
|
||||
}
|
||||
}}
|
||||
variant="outline"
|
||||
size="icon"
|
||||
disabled={disabled}
|
||||
onClick={onClick}
|
||||
{...delegatedProps}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
type SampleProps = Omit<PaginationWidgetBaseProps, "onPageChange">;
|
||||
|
||||
describe(PaginationWidgetBase.name, () => {
|
||||
it("Should have its previous button be aria-disabled while on page 1", async () => {
|
||||
it("Should have its previous button be disabled while on page 1", async () => {
|
||||
const sampleProps: SampleProps[] = [
|
||||
{ currentPage: 1, pageSize: 5, totalRecords: 6 },
|
||||
{ currentPage: 1, pageSize: 50, totalRecords: 200 },
|
||||
@@ -23,8 +23,7 @@ describe(PaginationWidgetBase.name, () => {
|
||||
);
|
||||
|
||||
const prevButton = await screen.findByLabelText("Previous page");
|
||||
expect(prevButton).not.toBeDisabled();
|
||||
expect(prevButton).toHaveAttribute("aria-disabled", "true");
|
||||
expect(prevButton).toBeDisabled();
|
||||
|
||||
await userEvent.click(prevButton);
|
||||
expect(onPageChange).not.toHaveBeenCalled();
|
||||
@@ -32,7 +31,7 @@ describe(PaginationWidgetBase.name, () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("Should have its next button be aria-disabled while on last page", async () => {
|
||||
it("Should have its next button be disabled while on last page", async () => {
|
||||
const sampleProps: SampleProps[] = [
|
||||
{ currentPage: 2, pageSize: 5, totalRecords: 6 },
|
||||
{ currentPage: 4, pageSize: 50, totalRecords: 200 },
|
||||
@@ -46,8 +45,7 @@ describe(PaginationWidgetBase.name, () => {
|
||||
);
|
||||
|
||||
const button = await screen.findByLabelText("Next page");
|
||||
expect(button).not.toBeDisabled();
|
||||
expect(button).toHaveAttribute("aria-disabled", "true");
|
||||
expect(button).toBeDisabled();
|
||||
|
||||
await userEvent.click(button);
|
||||
expect(onPageChange).not.toHaveBeenCalled();
|
||||
@@ -72,13 +70,11 @@ describe(PaginationWidgetBase.name, () => {
|
||||
const nextButton = await screen.findByLabelText("Next page");
|
||||
|
||||
expect(prevButton).not.toBeDisabled();
|
||||
expect(prevButton).toHaveAttribute("aria-disabled", "false");
|
||||
|
||||
await userEvent.click(prevButton);
|
||||
expect(onPageChange).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(nextButton).not.toBeDisabled();
|
||||
expect(nextButton).toHaveAttribute("aria-disabled", "false");
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
expect(onPageChange).toHaveBeenCalledTimes(2);
|
||||
|
||||
@@ -59,7 +59,7 @@ export const PaginationWidgetBase: FC<PaginationWidgetBaseProps> = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ChevronLeftIcon className="size-icon-sm" />
|
||||
<ChevronLeftIcon />
|
||||
</PaginationNavButton>
|
||||
|
||||
{isMobile ? (
|
||||
@@ -86,7 +86,7 @@ export const PaginationWidgetBase: FC<PaginationWidgetBaseProps> = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ChevronRightIcon className="size-icon-sm" />
|
||||
<ChevronRightIcon />
|
||||
</PaginationNavButton>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import DownloadOutlined from "@mui/icons-material/DownloadOutlined";
|
||||
import Button from "@mui/material/Button";
|
||||
import { agentLogs } from "api/queries/workspaces";
|
||||
import type { WorkspaceAgent, WorkspaceAgentLog } from "api/typesGenerated";
|
||||
import { Button } from "components/Button/Button";
|
||||
import { displayError } from "components/GlobalSnackbar/utils";
|
||||
import { saveAs } from "file-saver";
|
||||
import { type FC, useState } from "react";
|
||||
@@ -35,10 +35,9 @@ export const DownloadAgentLogsButton: FC<DownloadAgentLogsButtonProps> = ({
|
||||
|
||||
return (
|
||||
<Button
|
||||
startIcon={<DownloadOutlined />}
|
||||
disabled={!isConnected || isDownloading}
|
||||
variant="text"
|
||||
size="small"
|
||||
variant="subtle"
|
||||
size="sm"
|
||||
onClick={async () => {
|
||||
try {
|
||||
setIsDownloading(true);
|
||||
@@ -57,6 +56,7 @@ export const DownloadAgentLogsButton: FC<DownloadAgentLogsButtonProps> = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DownloadOutlined />
|
||||
{isDownloading ? "Downloading..." : "Download logs"}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -2,15 +2,13 @@ import { type Interpolation, type Theme, useTheme } from "@emotion/react";
|
||||
import LockIcon from "@mui/icons-material/Lock";
|
||||
import LockOpenIcon from "@mui/icons-material/LockOpen";
|
||||
import SensorsIcon from "@mui/icons-material/Sensors";
|
||||
import MUIButton from "@mui/material/Button";
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
import FormControl from "@mui/material/FormControl";
|
||||
import Link from "@mui/material/Link";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Select from "@mui/material/Select";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import MUITooltip from "@mui/material/Tooltip";
|
||||
import { API } from "api/api";
|
||||
import {
|
||||
deleteWorkspacePortShare,
|
||||
@@ -33,6 +31,12 @@ import {
|
||||
HelpTooltipTitle,
|
||||
} from "components/HelpTooltip/HelpTooltip";
|
||||
import { Spinner } from "components/Spinner/Spinner";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "components/Tooltip/Tooltip";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
@@ -40,7 +44,12 @@ import {
|
||||
} from "components/deprecated/Popover/Popover";
|
||||
import { type FormikContextType, useFormik } from "formik";
|
||||
import { type ClassName, useClassName } from "hooks/useClassName";
|
||||
import { ChevronDownIcon, ExternalLinkIcon, X as XIcon } from "lucide-react";
|
||||
import {
|
||||
ChevronDownIcon,
|
||||
ExternalLinkIcon,
|
||||
ShareIcon,
|
||||
X as XIcon,
|
||||
} from "lucide-react";
|
||||
import { useDashboard } from "modules/dashboard/useDashboard";
|
||||
import { type FC, useState } from "react";
|
||||
import { useMutation, useQuery } from "react-query";
|
||||
@@ -77,26 +86,13 @@ export const PortForwardButton: FC<PortForwardButtonProps> = (props) => {
|
||||
return (
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<MUIButton
|
||||
disabled={!portsQuery.data}
|
||||
size="small"
|
||||
variant="text"
|
||||
endIcon={<ChevronDownIcon className="size-4" />}
|
||||
css={{ fontSize: 13, padding: "8px 12px" }}
|
||||
startIcon={
|
||||
portsQuery.data ? (
|
||||
<div>
|
||||
<span css={styles.portCount}>
|
||||
{portsQuery.data.ports.length}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<CircularProgress size={10} />
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button disabled={!portsQuery.data} size="sm" variant="subtle">
|
||||
<Spinner loading={!portsQuery.data}>
|
||||
<span css={styles.portCount}>{portsQuery.data?.ports.length}</span>
|
||||
</Spinner>
|
||||
Open ports
|
||||
</MUIButton>
|
||||
<ChevronDownIcon className="size-4" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent horizontal="right" classes={{ paper }}>
|
||||
<PortForwardPopoverView
|
||||
@@ -203,14 +199,14 @@ export const PortForwardPopoverView: FC<PortForwardPopoverViewProps> = ({
|
||||
canSharePorts && template.max_port_share_level === "public";
|
||||
|
||||
const disabledPublicMenuItem = (
|
||||
<Tooltip title="This workspace template does not allow sharing ports with unauthenticated users.">
|
||||
<MUITooltip title="This workspace template does not allow sharing ports with unauthenticated users.">
|
||||
{/* Tooltips don't work directly on disabled MenuItem components so you must wrap in div. */}
|
||||
<div>
|
||||
<MenuItem value="public" disabled>
|
||||
Public
|
||||
</MenuItem>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</MUITooltip>
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -297,24 +293,17 @@ export const PortForwardPopoverView: FC<PortForwardPopoverViewProps> = ({
|
||||
required
|
||||
css={styles.newPortInput}
|
||||
/>
|
||||
<MUIButton
|
||||
type="submit"
|
||||
size="small"
|
||||
variant="text"
|
||||
css={{
|
||||
paddingLeft: 12,
|
||||
paddingRight: 12,
|
||||
minWidth: 0,
|
||||
}}
|
||||
>
|
||||
<ExternalLinkIcon
|
||||
className="size-icon-xs"
|
||||
css={{
|
||||
flexShrink: 0,
|
||||
color: theme.palette.text.primary,
|
||||
}}
|
||||
/>
|
||||
</MUIButton>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button type="submit" size="icon" variant="subtle">
|
||||
<ExternalLinkIcon />
|
||||
<span className="sr-only">Connect to port</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Connect to port</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</form>
|
||||
</Stack>
|
||||
</Stack>
|
||||
@@ -369,21 +358,29 @@ export const PortForwardPopoverView: FC<PortForwardPopoverViewProps> = ({
|
||||
alignItems="center"
|
||||
>
|
||||
{canSharePorts && (
|
||||
<MUIButton
|
||||
size="small"
|
||||
variant="text"
|
||||
onClick={async () => {
|
||||
await upsertSharedPortMutation.mutateAsync({
|
||||
agent_name: agent.name,
|
||||
port: port.port,
|
||||
protocol: listeningPortProtocol,
|
||||
share_level: "authenticated",
|
||||
});
|
||||
await sharedPortsQuery.refetch();
|
||||
}}
|
||||
>
|
||||
Share
|
||||
</MUIButton>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="subtle"
|
||||
onClick={async () => {
|
||||
await upsertSharedPortMutation.mutateAsync({
|
||||
agent_name: agent.name,
|
||||
port: port.port,
|
||||
protocol: listeningPortProtocol,
|
||||
share_level: "authenticated",
|
||||
});
|
||||
await sharedPortsQuery.refetch();
|
||||
}}
|
||||
>
|
||||
<ShareIcon />
|
||||
<span className="sr-only">Share</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Share this port</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
@@ -483,10 +480,9 @@ export const PortForwardPopoverView: FC<PortForwardPopoverViewProps> = ({
|
||||
)}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<MUIButton
|
||||
size="small"
|
||||
variant="text"
|
||||
css={styles.deleteButton}
|
||||
<Button
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
onClick={async () => {
|
||||
await deleteSharedPortMutation.mutateAsync({
|
||||
agent_name: agent.name,
|
||||
@@ -502,7 +498,7 @@ export const PortForwardPopoverView: FC<PortForwardPopoverViewProps> = ({
|
||||
color: theme.palette.text.primary,
|
||||
}}
|
||||
/>
|
||||
</MUIButton>
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
@@ -617,11 +613,6 @@ const styles = {
|
||||
},
|
||||
}),
|
||||
|
||||
deleteButton: () => ({
|
||||
minWidth: 30,
|
||||
padding: 0,
|
||||
}),
|
||||
|
||||
newPortForm: (theme) => ({
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: "4px",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Interpolation, Theme } from "@emotion/react";
|
||||
import Button from "@mui/material/Button";
|
||||
import { Button } from "components/Button/Button";
|
||||
import { CodeExample } from "components/CodeExample/CodeExample";
|
||||
import {
|
||||
HelpTooltipLink,
|
||||
@@ -34,12 +34,12 @@ export const AgentSSHButton: FC<AgentSSHButtonProps> = ({
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<Button
|
||||
size="small"
|
||||
variant="text"
|
||||
endIcon={<ChevronDownIcon className="size-4" />}
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
css={{ fontSize: 13, padding: "8px 12px" }}
|
||||
>
|
||||
Connect via SSH
|
||||
<ChevronDownIcon className="size-4 ml-2" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
|
||||
@@ -96,12 +96,12 @@ export const AgentDevcontainerSSHButton: FC<
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<Button
|
||||
size="small"
|
||||
variant="text"
|
||||
endIcon={<ChevronDownIcon className="size-4" />}
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
css={{ fontSize: 13, padding: "8px 12px" }}
|
||||
>
|
||||
Connect via SSH
|
||||
<ChevronDownIcon className="size-4 ml-2" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Interpolation, Theme } from "@emotion/react";
|
||||
import Button from "@mui/material/Button";
|
||||
import Link from "@mui/material/Link";
|
||||
import type { TemplateExample } from "api/typesGenerated";
|
||||
import { Button } from "components/Button/Button";
|
||||
import { ExternalImage } from "components/ExternalImage/ExternalImage";
|
||||
import { Pill } from "components/Pill/Pill";
|
||||
import type { FC, HTMLAttributes } from "react";
|
||||
@@ -55,12 +55,10 @@ export const TemplateExampleCard: FC<TemplateExampleCardProps> = ({
|
||||
</div>
|
||||
|
||||
<div css={styles.useButtonContainer}>
|
||||
<Button
|
||||
component={RouterLink}
|
||||
fullWidth
|
||||
to={`/templates/new?exampleId=${example.id}`}
|
||||
>
|
||||
Use template
|
||||
<Button asChild className="w-full">
|
||||
<RouterLink to={`/templates/new?exampleId=${example.id}`}>
|
||||
Use template
|
||||
</RouterLink>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useTheme } from "@emotion/react";
|
||||
import Button from "@mui/material/Button";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import { createChat } from "api/queries/chats";
|
||||
import type { Chat } from "api/typesGenerated";
|
||||
import { Button } from "components/Button/Button";
|
||||
import { Margins } from "components/Margins/Margins";
|
||||
import { useAuthenticated } from "hooks";
|
||||
import { SendIcon } from "lucide-react";
|
||||
@@ -89,19 +89,19 @@ const ChatLanding: FC = () => {
|
||||
sx={{ mb: 2 }}
|
||||
>
|
||||
<Button
|
||||
variant="outlined"
|
||||
variant="outline"
|
||||
onClick={() => setInput("Help me work on issue #...")}
|
||||
>
|
||||
Work on Issue
|
||||
</Button>
|
||||
<Button
|
||||
variant="outlined"
|
||||
variant="outline"
|
||||
onClick={() => setInput("Help me build a template for...")}
|
||||
>
|
||||
Build a Template
|
||||
</Button>
|
||||
<Button
|
||||
variant="outlined"
|
||||
variant="outline"
|
||||
onClick={() => setInput("Help me start a new project using...")}
|
||||
>
|
||||
Start a Project
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
|
||||
import MuiButton from "@mui/material/Button";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import { requestOneTimePassword } from "api/queries/users";
|
||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
@@ -98,15 +97,9 @@ const RequestOTP: FC<RequestOTPProps> = ({
|
||||
<Spinner loading={isRequesting} />
|
||||
Reset password
|
||||
</Button>
|
||||
<MuiButton
|
||||
component={RouterLink}
|
||||
size="large"
|
||||
fullWidth
|
||||
variant="text"
|
||||
to="/login"
|
||||
>
|
||||
Cancel
|
||||
</MuiButton>
|
||||
<Button asChild size="lg" variant="outline" className="w-full">
|
||||
<RouterLink to="/login">Cancel</RouterLink>
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</fieldset>
|
||||
@@ -151,9 +144,9 @@ const RequestOTPSuccess: FC<{ email: string }> = ({ email }) => {
|
||||
Contact your deployment administrator if you encounter issues.
|
||||
</p>
|
||||
|
||||
<MuiButton component={RouterLink} to="/login">
|
||||
Back to login
|
||||
</MuiButton>
|
||||
<Button asChild variant="default">
|
||||
<RouterLink to="/login">Back to login</RouterLink>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import ExpandMoreOutlined from "@mui/icons-material/ExpandMoreOutlined";
|
||||
import Button from "@mui/material/Button";
|
||||
import Menu from "@mui/material/Menu";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import { Button } from "components/Button/Button";
|
||||
import { CheckIcon } from "lucide-react";
|
||||
import { type FC, useRef, useState } from "react";
|
||||
|
||||
@@ -38,9 +38,10 @@ export const IntervalMenu: FC<IntervalMenuProps> = ({ value, onChange }) => {
|
||||
aria-haspopup="true"
|
||||
aria-expanded={open ? "true" : undefined}
|
||||
onClick={() => setOpen(true)}
|
||||
endIcon={<ExpandMoreOutlined />}
|
||||
variant="outline"
|
||||
>
|
||||
{insightsIntervals[value].label}
|
||||
<ExpandMoreOutlined className="size-icon-xs ml-1" />
|
||||
</Button>
|
||||
<Menu
|
||||
id="interval-menu"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Interpolation, Theme } from "@emotion/react";
|
||||
import Button from "@mui/material/Button";
|
||||
import Link from "@mui/material/Link";
|
||||
import type { TemplateExample } from "api/typesGenerated";
|
||||
import { Button } from "components/Button/Button";
|
||||
import { CodeExample } from "components/CodeExample/CodeExample";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import { TableEmpty } from "components/TableEmpty/TableEmpty";
|
||||
@@ -78,13 +78,10 @@ export const EmptyTemplates: FC<EmptyTemplatesProps> = ({
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
size="small"
|
||||
component={RouterLink}
|
||||
to="/starter-templates"
|
||||
css={{ borderRadius: 9999 }}
|
||||
>
|
||||
View all starter templates
|
||||
<Button size="sm" asChild css={{ borderRadius: 9999 }}>
|
||||
<RouterLink to="/starter-templates">
|
||||
View all starter templates
|
||||
</RouterLink>
|
||||
</Button>
|
||||
</Stack>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { Interpolation, Theme } from "@emotion/react";
|
||||
import ArrowForwardOutlined from "@mui/icons-material/ArrowForwardOutlined";
|
||||
import MuiButton from "@mui/material/Button";
|
||||
import Skeleton from "@mui/material/Skeleton";
|
||||
import { hasError, isApiValidationError } from "api/errors";
|
||||
import type { Template, TemplateExample } from "api/typesGenerated";
|
||||
@@ -44,7 +43,7 @@ import { PlusIcon } from "lucide-react";
|
||||
import { linkToTemplate, useLinks } from "modules/navigation";
|
||||
import type { WorkspacePermissions } from "modules/permissions/workspaces";
|
||||
import type { FC } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { Link as RouterLink, useNavigate } from "react-router-dom";
|
||||
import { createDayString } from "utils/createDayString";
|
||||
import { docs } from "utils/docs";
|
||||
import {
|
||||
@@ -163,19 +162,20 @@ const TemplateRow: FC<TemplateRowProps> = ({
|
||||
<DeprecatedBadge />
|
||||
) : workspacePermissions?.[template.organization_id]
|
||||
?.createWorkspaceForUserID ? (
|
||||
<MuiButton
|
||||
size="small"
|
||||
css={styles.actionButton}
|
||||
className="actionButton"
|
||||
startIcon={<ArrowForwardOutlined />}
|
||||
<Button
|
||||
asChild
|
||||
variant="outline"
|
||||
size="sm"
|
||||
title={`Create a workspace using the ${template.display_name} template`}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
navigate(`${templatePageLink}/workspace`);
|
||||
}}
|
||||
>
|
||||
Create Workspace
|
||||
</MuiButton>
|
||||
<RouterLink to={`${templatePageLink}/workspace`}>
|
||||
<ArrowForwardOutlined />
|
||||
Create Workspace
|
||||
</RouterLink>
|
||||
</Button>
|
||||
) : null}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
@@ -204,18 +204,20 @@ export const TemplatesPageView: FC<TemplatesPageViewProps> = ({
|
||||
const isLoading = !templates;
|
||||
const isEmpty = templates && templates.length === 0;
|
||||
|
||||
const createTemplateAction = (
|
||||
<Button asChild size="lg">
|
||||
<Link to="/starter-templates">
|
||||
<PlusIcon />
|
||||
New template
|
||||
</Link>
|
||||
</Button>
|
||||
);
|
||||
|
||||
return (
|
||||
<Margins>
|
||||
<PageHeader actions={canCreateTemplates && createTemplateAction}>
|
||||
<PageHeader
|
||||
actions={
|
||||
canCreateTemplates && (
|
||||
<Button asChild size="lg">
|
||||
<RouterLink to="/starter-templates">
|
||||
<PlusIcon />
|
||||
New template
|
||||
</RouterLink>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
>
|
||||
<PageHeaderTitle>
|
||||
<Stack spacing={1} direction="row" alignItems="center">
|
||||
Templates
|
||||
|
||||
Reference in New Issue
Block a user