mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore(site): replace custom LoadingButton from the one in MUI (#10351)
This commit is contained in:
@@ -1,12 +1,9 @@
|
||||
import MuiDialog, { DialogProps as MuiDialogProps } from "@mui/material/Dialog";
|
||||
import { type ReactNode } from "react";
|
||||
import { colors } from "theme/colors";
|
||||
import {
|
||||
LoadingButton,
|
||||
LoadingButtonProps,
|
||||
} from "../LoadingButton/LoadingButton";
|
||||
import { ConfirmDialogType } from "./types";
|
||||
import { type Interpolation, type Theme } from "@emotion/react";
|
||||
import LoadingButton, { LoadingButtonProps } from "@mui/lab/LoadingButton";
|
||||
|
||||
export interface DialogActionButtonsProps {
|
||||
/** Text to display in the cancel button */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Button from "@mui/material/Button";
|
||||
import { type FC } from "react";
|
||||
import { LoadingButton } from "../LoadingButton/LoadingButton";
|
||||
import { Interpolation, Theme } from "@emotion/react";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
|
||||
export const Language = {
|
||||
cancelLabel: "Cancel",
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import { LoadingButton } from "./LoadingButton";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
|
||||
const meta: Meta<typeof LoadingButton> = {
|
||||
title: "components/LoadingButton",
|
||||
component: LoadingButton,
|
||||
args: {
|
||||
children: "Create workspace",
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof LoadingButton>;
|
||||
|
||||
export const Loading: Story = {
|
||||
args: {
|
||||
loading: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const NotLoading: Story = {
|
||||
args: {
|
||||
loading: false,
|
||||
},
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
import { forwardRef } from "react";
|
||||
import MuiLoadingButton, {
|
||||
LoadingButtonProps as MuiLoadingButtonProps,
|
||||
} from "@mui/lab/LoadingButton";
|
||||
|
||||
export type LoadingButtonProps = MuiLoadingButtonProps;
|
||||
|
||||
export const LoadingButton = forwardRef<
|
||||
HTMLButtonElement,
|
||||
MuiLoadingButtonProps
|
||||
>(({ children, loadingIndicator, ...buttonProps }, ref) => {
|
||||
return (
|
||||
<MuiLoadingButton
|
||||
variant="outlined"
|
||||
color="neutral"
|
||||
ref={ref}
|
||||
{...buttonProps}
|
||||
>
|
||||
{/* known issue: https://github.com/mui/material-ui/issues/27853 */}
|
||||
<span>
|
||||
{buttonProps.loading && loadingIndicator ? loadingIndicator : children}
|
||||
</span>
|
||||
</MuiLoadingButton>
|
||||
);
|
||||
});
|
||||
@@ -3,9 +3,9 @@ import Button from "@mui/material/Button";
|
||||
import FormHelperText from "@mui/material/FormHelperText";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import { type FC } from "react";
|
||||
import { LoadingButton } from "components/LoadingButton/LoadingButton";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import { type ExternalAuthPollingState } from "./CreateWorkspacePage";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
|
||||
export interface ExternalAuthProps {
|
||||
displayName: string;
|
||||
@@ -34,6 +34,7 @@ export const ExternalAuth: FC<ExternalAuthProps> = (props) => {
|
||||
>
|
||||
<Stack alignItems="center" spacing={1}>
|
||||
<LoadingButton
|
||||
loadingPosition="start"
|
||||
loading={externalAuthPollingState === "polling"}
|
||||
href={authenticateURL}
|
||||
variant="contained"
|
||||
@@ -42,8 +43,8 @@ export const ExternalAuth: FC<ExternalAuthProps> = (props) => {
|
||||
<img
|
||||
src={displayIcon}
|
||||
alt={`${displayName} Icon`}
|
||||
width={24}
|
||||
height={24}
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
}
|
||||
disabled={authenticated}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { Link } from "react-router-dom";
|
||||
import useWindowSize from "react-use/lib/useWindowSize";
|
||||
import MuiLink from "@mui/material/Link";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import { LoadingButton } from "components/LoadingButton/LoadingButton";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
|
||||
type Props = {
|
||||
showConfetti: boolean;
|
||||
@@ -72,6 +72,7 @@ const LicensesSettingsPageView: FC<Props> = ({
|
||||
</Button>
|
||||
<Tooltip title="Refresh license entitlements. This is done automatically every 10 minutes.">
|
||||
<LoadingButton
|
||||
loadingPosition="start"
|
||||
loading={isRefreshing}
|
||||
onClick={refreshEntitlements}
|
||||
startIcon={<RefreshIcon />}
|
||||
|
||||
@@ -13,7 +13,6 @@ import { AvatarData } from "components/AvatarData/AvatarData";
|
||||
import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog";
|
||||
import { EmptyState } from "components/EmptyState/EmptyState";
|
||||
import { Loader } from "components/Loader/Loader";
|
||||
import { LoadingButton } from "components/LoadingButton/LoadingButton";
|
||||
import { Margins } from "components/Margins/Margins";
|
||||
import {
|
||||
PageHeader,
|
||||
@@ -44,6 +43,7 @@ import {
|
||||
} from "api/queries/groups";
|
||||
import { displayError, displaySuccess } from "components/GlobalSnackbar/utils";
|
||||
import { getErrorMessage } from "api/errors";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
|
||||
export const GroupPage: FC = () => {
|
||||
const { groupId } = useParams() as { groupId: string };
|
||||
@@ -235,6 +235,7 @@ const AddGroupMember: React.FC<{
|
||||
/>
|
||||
|
||||
<LoadingButton
|
||||
loadingPosition="start"
|
||||
disabled={!selectedUser}
|
||||
type="submit"
|
||||
startIcon={<PersonAdd />}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import { getFormHelpers, onChangeTrimmed } from "utils/formUtils";
|
||||
import { LoadingButton } from "components/LoadingButton/LoadingButton";
|
||||
import { Language } from "./SignInForm";
|
||||
import { FormikContextType, FormikTouched, useFormik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import { FC } from "react";
|
||||
import { BuiltInAuthFormValues } from "./SignInForm.types";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
|
||||
type PasswordSignInFormProps = {
|
||||
onSubmit: (credentials: { email: string; password: string }) => void;
|
||||
@@ -66,7 +66,7 @@ export const PasswordSignInForm: FC<PasswordSignInFormProps> = ({
|
||||
fullWidth
|
||||
type="submit"
|
||||
>
|
||||
{isSigningIn ? "" : Language.passwordSignIn}
|
||||
{Language.passwordSignIn}
|
||||
</LoadingButton>
|
||||
</div>
|
||||
</Stack>
|
||||
|
||||
@@ -2,7 +2,6 @@ import Box from "@mui/material/Box";
|
||||
import Checkbox from "@mui/material/Checkbox";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { LoadingButton } from "components/LoadingButton/LoadingButton";
|
||||
import { SignInLayout } from "components/SignInLayout/SignInLayout";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import { Welcome } from "components/Welcome/Welcome";
|
||||
@@ -14,6 +13,7 @@ import {
|
||||
} from "utils/formUtils";
|
||||
import * as Yup from "yup";
|
||||
import type * as TypesGen from "api/typesGenerated";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
|
||||
export const Language = {
|
||||
emailLabel: "Email",
|
||||
|
||||
+2
-1
@@ -18,7 +18,6 @@ import type {
|
||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
|
||||
import { EmptyState } from "components/EmptyState/EmptyState";
|
||||
import { LoadingButton } from "components/LoadingButton/LoadingButton";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import { TableLoader } from "components/TableLoader/TableLoader";
|
||||
import { TableRowMenu } from "components/TableRowMenu/TableRowMenu";
|
||||
@@ -30,6 +29,7 @@ import { type FC, useState } from "react";
|
||||
import { GroupAvatar } from "components/GroupAvatar/GroupAvatar";
|
||||
import { getGroupSubtitle } from "utils/groups";
|
||||
import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
|
||||
type AddTemplateUserOrGroupProps = {
|
||||
organizationId: string;
|
||||
@@ -106,6 +106,7 @@ const AddTemplateUserOrGroup: React.FC<AddTemplateUserOrGroupProps> = ({
|
||||
</Select>
|
||||
|
||||
<LoadingButton
|
||||
loadingPosition="start"
|
||||
disabled={!selectedRole || !selectedOption}
|
||||
type="submit"
|
||||
startIcon={<PersonAdd />}
|
||||
|
||||
@@ -7,10 +7,10 @@ import {
|
||||
nameValidator,
|
||||
onChangeTrimmed,
|
||||
} from "utils/formUtils";
|
||||
import { LoadingButton } from "components/LoadingButton/LoadingButton";
|
||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
import { Form, FormFields } from "components/Form/Form";
|
||||
import { UpdateUserProfileRequest } from "api/typesGenerated";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
|
||||
export const Language = {
|
||||
usernameLabel: "Username",
|
||||
@@ -76,12 +76,11 @@ export const AccountForm: FC<AccountFormProps> = ({
|
||||
<div>
|
||||
<LoadingButton
|
||||
loading={isLoading}
|
||||
aria-disabled={!editable}
|
||||
disabled={!editable}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
>
|
||||
{isLoading ? "" : Language.updateSettings}
|
||||
{Language.updateSettings}
|
||||
</LoadingButton>
|
||||
</div>
|
||||
</FormFields>
|
||||
|
||||
@@ -3,7 +3,6 @@ import { FormikContextType, useFormik } from "formik";
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import * as Yup from "yup";
|
||||
import { getFormHelpers } from "utils/formUtils";
|
||||
import { LoadingButton } from "components/LoadingButton/LoadingButton";
|
||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
import { Form, FormFields } from "components/Form/Form";
|
||||
import {
|
||||
@@ -15,6 +14,7 @@ import { Stack } from "components/Stack/Stack";
|
||||
import { timeZones, getPreferredTimezone } from "utils/timeZones";
|
||||
import { Alert } from "components/Alert/Alert";
|
||||
import { timeToCron, quietHoursDisplay, validTime } from "utils/schedule";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
|
||||
export interface ScheduleFormValues {
|
||||
time: string;
|
||||
@@ -130,7 +130,7 @@ export const ScheduleForm: FC<React.PropsWithChildren<ScheduleFormProps>> = ({
|
||||
type="submit"
|
||||
variant="contained"
|
||||
>
|
||||
{!isLoading && "Update schedule"}
|
||||
Update schedule
|
||||
</LoadingButton>
|
||||
</div>
|
||||
</FormFields>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
import { Form, FormFields } from "components/Form/Form";
|
||||
import { Alert } from "components/Alert/Alert";
|
||||
import { getFormHelpers } from "utils/formUtils";
|
||||
import { LoadingButton } from "components/LoadingButton/LoadingButton";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
|
||||
interface SecurityFormValues {
|
||||
old_password: string;
|
||||
@@ -107,7 +107,7 @@ export const SecurityForm: FC<SecurityFormProps> = ({
|
||||
type="submit"
|
||||
variant="contained"
|
||||
>
|
||||
{isLoading ? "" : Language.updatePassword}
|
||||
{Language.updatePassword}
|
||||
</LoadingButton>
|
||||
</div>
|
||||
</FormFields>
|
||||
|
||||
@@ -4,13 +4,13 @@ import CloudQueueIcon from "@mui/icons-material/CloudQueue";
|
||||
import CropSquareIcon from "@mui/icons-material/CropSquare";
|
||||
import PlayCircleOutlineIcon from "@mui/icons-material/PlayCircleOutline";
|
||||
import ReplayIcon from "@mui/icons-material/Replay";
|
||||
import { LoadingButton } from "components/LoadingButton/LoadingButton";
|
||||
import { FC } from "react";
|
||||
import BlockOutlined from "@mui/icons-material/BlockOutlined";
|
||||
import ButtonGroup from "@mui/material/ButtonGroup";
|
||||
import { Workspace, WorkspaceBuildParameter } from "api/typesGenerated";
|
||||
import { BuildParametersPopover } from "./BuildParametersPopover";
|
||||
import PowerSettingsNewIcon from "@mui/icons-material/PowerSettingsNew";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
|
||||
interface WorkspaceAction {
|
||||
loading?: boolean;
|
||||
@@ -24,13 +24,12 @@ export const UpdateButton: FC<WorkspaceAction> = ({
|
||||
return (
|
||||
<LoadingButton
|
||||
loading={loading}
|
||||
loadingIndicator={<>Updating…</>}
|
||||
loadingPosition="start"
|
||||
data-testid="workspace-update-button"
|
||||
startIcon={<CloudQueueIcon />}
|
||||
onClick={handleAction}
|
||||
>
|
||||
Update…
|
||||
{loading ? <>Updating…</> : <>Update…</>}
|
||||
</LoadingButton>
|
||||
);
|
||||
};
|
||||
@@ -42,12 +41,11 @@ export const ActivateButton: FC<WorkspaceAction> = ({
|
||||
return (
|
||||
<LoadingButton
|
||||
loading={loading}
|
||||
loadingIndicator={<>Activating…</>}
|
||||
loadingPosition="start"
|
||||
startIcon={<PowerSettingsNewIcon />}
|
||||
onClick={handleAction}
|
||||
>
|
||||
Activate
|
||||
{loading ? <>Activating…</> : "Activate"}
|
||||
</LoadingButton>
|
||||
);
|
||||
};
|
||||
@@ -70,12 +68,11 @@ export const StartButton: FC<
|
||||
>
|
||||
<LoadingButton
|
||||
loading={loading}
|
||||
loadingIndicator={<>Starting…</>}
|
||||
loadingPosition="start"
|
||||
startIcon={<PlayCircleOutlineIcon />}
|
||||
onClick={() => handleAction()}
|
||||
>
|
||||
Start
|
||||
{loading ? <>Starting…</> : "Start"}
|
||||
</LoadingButton>
|
||||
<BuildParametersPopover
|
||||
workspace={workspace}
|
||||
@@ -90,13 +87,12 @@ export const StopButton: FC<WorkspaceAction> = ({ handleAction, loading }) => {
|
||||
return (
|
||||
<LoadingButton
|
||||
loading={loading}
|
||||
loadingIndicator={<>Stopping…</>}
|
||||
loadingPosition="start"
|
||||
startIcon={<CropSquareIcon />}
|
||||
onClick={handleAction}
|
||||
data-testid="workspace-stop-button"
|
||||
>
|
||||
Stop
|
||||
{loading ? <>Stopping…</> : "Stop"}
|
||||
</LoadingButton>
|
||||
);
|
||||
};
|
||||
@@ -119,13 +115,12 @@ export const RestartButton: FC<
|
||||
>
|
||||
<LoadingButton
|
||||
loading={loading}
|
||||
loadingIndicator={<>Restarting…</>}
|
||||
loadingPosition="start"
|
||||
startIcon={<ReplayIcon />}
|
||||
onClick={() => handleAction()}
|
||||
data-testid="workspace-restart-button"
|
||||
>
|
||||
Restart…
|
||||
{loading ? <>Restarting…</> : <>Restart…</>}
|
||||
</LoadingButton>
|
||||
<BuildParametersPopover
|
||||
workspace={workspace}
|
||||
@@ -162,12 +157,8 @@ interface LoadingProps {
|
||||
|
||||
export const ActionLoadingButton: FC<LoadingProps> = ({ label }) => {
|
||||
return (
|
||||
<LoadingButton
|
||||
loading
|
||||
loadingPosition="start"
|
||||
loadingIndicator={label}
|
||||
// This icon can be anything
|
||||
startIcon={<ReplayIcon />}
|
||||
/>
|
||||
<LoadingButton loading loadingPosition="start" startIcon={<ReplayIcon />}>
|
||||
{label}
|
||||
</LoadingButton>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -218,6 +218,12 @@ dark = createTheme(dark, {
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiLoadingButton: {
|
||||
defaultProps: {
|
||||
variant: "outlined",
|
||||
color: "neutral",
|
||||
},
|
||||
},
|
||||
MuiTableContainer: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
|
||||
Reference in New Issue
Block a user