mirror of https://github.com/coder/coder.git
chore: remove `Maybe` (#9880)
This commit is contained in:
parent
72e8f88af3
commit
066b25f710
|
@ -1,25 +0,0 @@
|
|||
import { StoryObj, Meta } from "@storybook/react";
|
||||
import { Maybe } from "./Maybe";
|
||||
|
||||
const meta: Meta<typeof Maybe> = {
|
||||
title: "components/Conditionals/Maybe",
|
||||
component: Maybe,
|
||||
args: {
|
||||
children: "Now you see me",
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof Maybe>;
|
||||
|
||||
export const ConditionIsTrue: Story = {
|
||||
args: {
|
||||
condition: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const ConditionIsFalse: Story = {
|
||||
args: {
|
||||
condition: false,
|
||||
},
|
||||
};
|
|
@ -1,17 +0,0 @@
|
|||
import { PropsWithChildren } from "react";
|
||||
|
||||
export interface MaybeProps {
|
||||
condition: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper component for conditionally rendering a child component without using "curly brace mode."
|
||||
* @param condition boolean expression that determines whether the child will be rendered
|
||||
* @returns the child or null
|
||||
*/
|
||||
export const Maybe = ({
|
||||
children,
|
||||
condition,
|
||||
}: PropsWithChildren<MaybeProps>): JSX.Element | null => {
|
||||
return condition ? <>{children}</> : null;
|
||||
};
|
|
@ -1,6 +1,5 @@
|
|||
import makeStyles from "@mui/styles/makeStyles";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { ChangeEvent, useState, PropsWithChildren, FC } from "react";
|
||||
import { ConfirmDialog } from "../ConfirmDialog/ConfirmDialog";
|
||||
|
||||
|
@ -34,9 +33,7 @@ export const DeleteDialog: FC<PropsWithChildren<DeleteDialogProps>> = ({
|
|||
const content = (
|
||||
<>
|
||||
<p>Deleting this {entity} is irreversible!</p>
|
||||
<Maybe condition={info !== undefined}>
|
||||
<p className={styles.warning}>{info}</p>
|
||||
</Maybe>
|
||||
{Boolean(info) && <p className={styles.warning}>{info}</p>}
|
||||
<p>Are you sure you want to proceed?</p>
|
||||
<p>Type {name} below to confirm.</p>
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { makeStyles } from "@mui/styles";
|
||||
import { PropsWithChildren, FC } from "react";
|
||||
import { combineClasses } from "../../utils/combineClasses";
|
||||
import { type FC, type PropsWithChildren, type ReactNode } from "react";
|
||||
import { combineClasses } from "utils/combineClasses";
|
||||
import { Stack } from "../Stack/Stack";
|
||||
|
||||
export interface PageHeaderProps {
|
||||
actions?: JSX.Element;
|
||||
actions?: ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft";
|
|||
import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight";
|
||||
import { useActor } from "@xstate/react";
|
||||
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { CSSProperties } from "react";
|
||||
import { PaginationMachineRef } from "xServices/pagination/paginationXService";
|
||||
import { PageButton } from "./PageButton";
|
||||
|
@ -40,57 +39,59 @@ export const PaginationWidget = ({
|
|||
// if beyond page 1, show pagination widget even if there's only one true page, so user can navigate back
|
||||
const showWidget = numPages > 1 || currentPage > 1;
|
||||
|
||||
if (!showWidget) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Maybe condition={showWidget}>
|
||||
<div style={containerStyle} className={styles.defaultContainerStyles}>
|
||||
<Button
|
||||
className={styles.prevLabelStyles}
|
||||
aria-label="Previous page"
|
||||
disabled={firstPageActive}
|
||||
onClick={() => send({ type: "PREVIOUS_PAGE" })}
|
||||
>
|
||||
<KeyboardArrowLeft />
|
||||
<div>{prevLabel}</div>
|
||||
</Button>
|
||||
<ChooseOne>
|
||||
<Cond condition={isMobile}>
|
||||
<PageButton
|
||||
activePage={currentPage}
|
||||
page={currentPage}
|
||||
numPages={numPages}
|
||||
/>
|
||||
</Cond>
|
||||
<Cond>
|
||||
{buildPagedList(numPages, currentPage).map((page) =>
|
||||
typeof page !== "number" ? (
|
||||
<PageButton
|
||||
key={`Page${page}`}
|
||||
activePage={currentPage}
|
||||
placeholder="..."
|
||||
disabled
|
||||
/>
|
||||
) : (
|
||||
<PageButton
|
||||
key={`Page${page}`}
|
||||
activePage={currentPage}
|
||||
page={page}
|
||||
numPages={numPages}
|
||||
onPageClick={() => send({ type: "GO_TO_PAGE", page })}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</Cond>
|
||||
</ChooseOne>
|
||||
<Button
|
||||
aria-label="Next page"
|
||||
disabled={lastPageActive}
|
||||
onClick={() => send({ type: "NEXT_PAGE" })}
|
||||
>
|
||||
<div>{nextLabel}</div>
|
||||
<KeyboardArrowRight />
|
||||
</Button>
|
||||
</div>
|
||||
</Maybe>
|
||||
<div style={containerStyle} className={styles.defaultContainerStyles}>
|
||||
<Button
|
||||
className={styles.prevLabelStyles}
|
||||
aria-label="Previous page"
|
||||
disabled={firstPageActive}
|
||||
onClick={() => send({ type: "PREVIOUS_PAGE" })}
|
||||
>
|
||||
<KeyboardArrowLeft />
|
||||
<div>{prevLabel}</div>
|
||||
</Button>
|
||||
<ChooseOne>
|
||||
<Cond condition={isMobile}>
|
||||
<PageButton
|
||||
activePage={currentPage}
|
||||
page={currentPage}
|
||||
numPages={numPages}
|
||||
/>
|
||||
</Cond>
|
||||
<Cond>
|
||||
{buildPagedList(numPages, currentPage).map((page) =>
|
||||
typeof page !== "number" ? (
|
||||
<PageButton
|
||||
key={`Page${page}`}
|
||||
activePage={currentPage}
|
||||
placeholder="..."
|
||||
disabled
|
||||
/>
|
||||
) : (
|
||||
<PageButton
|
||||
key={`Page${page}`}
|
||||
activePage={currentPage}
|
||||
page={page}
|
||||
numPages={numPages}
|
||||
onPageClick={() => send({ type: "GO_TO_PAGE", page })}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</Cond>
|
||||
</ChooseOne>
|
||||
<Button
|
||||
aria-label="Next page"
|
||||
disabled={lastPageActive}
|
||||
onClick={() => send({ type: "NEXT_PAGE" })}
|
||||
>
|
||||
<div>{nextLabel}</div>
|
||||
<KeyboardArrowRight />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { makeStyles } from "@mui/styles";
|
||||
import { AppPreviewLink } from "components/Resources/AppLink/AppPreviewLink";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { FC } from "react";
|
||||
import { combineClasses } from "utils/combineClasses";
|
||||
import { WorkspaceAgent } from "../../api/typesGenerated";
|
||||
import { WorkspaceAgent } from "api/typesGenerated";
|
||||
import { Stack } from "../Stack/Stack";
|
||||
|
||||
interface AgentRowPreviewStyles {
|
||||
|
@ -90,9 +89,9 @@ export const AgentRowPreview: FC<AgentRowPreviewProps> = ({
|
|||
{agent.apps.map((app) => (
|
||||
<AppPreviewLink key={app.slug} app={app} />
|
||||
))}
|
||||
<Maybe condition={agent.apps.length === 0}>
|
||||
{agent.apps.length === 0 && (
|
||||
<span className={styles.agentDataValue}>None</span>
|
||||
</Maybe>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { FC } from "react";
|
||||
import * as TypesGen from "api/typesGenerated";
|
||||
import { Alert } from "components/Alert/Alert";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
|
||||
export interface TemplateVersionWarningsProps {
|
||||
warnings?: TypesGen.TemplateVersionWarning[];
|
||||
|
@ -9,19 +8,19 @@ export interface TemplateVersionWarningsProps {
|
|||
|
||||
export const TemplateVersionWarnings: FC<
|
||||
React.PropsWithChildren<TemplateVersionWarningsProps>
|
||||
> = ({ warnings }) => {
|
||||
if (!warnings) {
|
||||
return <></>;
|
||||
> = (props) => {
|
||||
const { warnings = [] } = props;
|
||||
|
||||
if (!warnings.includes("UNSUPPORTED_WORKSPACES")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Maybe condition={Boolean(warnings.includes("UNSUPPORTED_WORKSPACES"))}>
|
||||
<div data-testid="error-unsupported-workspaces">
|
||||
<Alert severity="error">
|
||||
This template uses legacy parameters which are not supported anymore.
|
||||
Contact your administrator for assistance.
|
||||
</Alert>
|
||||
</div>
|
||||
</Maybe>
|
||||
<div data-testid="error-unsupported-workspaces">
|
||||
<Alert severity="error">
|
||||
This template uses legacy parameters which are not supported anymore.
|
||||
Contact your administrator for assistance.
|
||||
</Alert>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { StatsItem } from "components/Stats/Stats";
|
||||
import Link from "@mui/material/Link";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
|
@ -6,12 +5,15 @@ import styled from "@emotion/styled";
|
|||
import { Workspace } from "api/typesGenerated";
|
||||
import { displayDormantDeletion } from "./utils";
|
||||
import { useDashboard } from "components/Dashboard/DashboardProvider";
|
||||
import { type FC } from "react";
|
||||
|
||||
export const DormantDeletionStat = ({
|
||||
workspace,
|
||||
}: {
|
||||
interface DormantDeletionStatProps {
|
||||
workspace: Workspace;
|
||||
}): JSX.Element => {
|
||||
}
|
||||
|
||||
export const DormantDeletionStat: FC<DormantDeletionStatProps> = ({
|
||||
workspace,
|
||||
}) => {
|
||||
const { entitlements, experiments } = useDashboard();
|
||||
const allowAdvancedScheduling =
|
||||
entitlements.features["advanced_template_scheduling"].enabled;
|
||||
|
@ -19,29 +21,31 @@ export const DormantDeletionStat = ({
|
|||
// is merged up
|
||||
const allowWorkspaceActions = experiments.includes("workspace_actions");
|
||||
|
||||
if (
|
||||
!displayDormantDeletion(
|
||||
workspace,
|
||||
allowAdvancedScheduling,
|
||||
allowWorkspaceActions,
|
||||
)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Maybe
|
||||
condition={displayDormantDeletion(
|
||||
workspace,
|
||||
allowAdvancedScheduling,
|
||||
allowWorkspaceActions,
|
||||
)}
|
||||
>
|
||||
<StyledStatsItem
|
||||
label="Deletion on"
|
||||
className="containerClass"
|
||||
value={
|
||||
<Link
|
||||
component={RouterLink}
|
||||
to={`/templates/${workspace.template_name}/settings/schedule`}
|
||||
title="Schedule settings"
|
||||
>
|
||||
{/* We check for string existence in the conditional */}
|
||||
{new Date(workspace.deleting_at as string).toLocaleString()}
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
</Maybe>
|
||||
<StyledStatsItem
|
||||
label="Deletion on"
|
||||
className="containerClass"
|
||||
value={
|
||||
<Link
|
||||
component={RouterLink}
|
||||
to={`/templates/${workspace.template_name}/settings/schedule`}
|
||||
title="Schedule settings"
|
||||
>
|
||||
{/* We check for string existence in the conditional */}
|
||||
{new Date(workspace.deleting_at!).toLocaleString()}
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { useMachine } from "@xstate/react";
|
||||
import { isApiValidationError } from "api/errors";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { useDashboard } from "components/Dashboard/DashboardProvider";
|
||||
import { FullPageHorizontalForm } from "components/FullPageForm/FullPageHorizontalForm";
|
||||
import { Loader } from "components/Loader/Loader";
|
||||
|
@ -55,14 +54,12 @@ const CreateTemplatePage: FC = () => {
|
|||
</Helmet>
|
||||
|
||||
<FullPageHorizontalForm title="Create Template" onCancel={onCancel}>
|
||||
<Maybe condition={state.hasTag("loading")}>
|
||||
<Loader />
|
||||
</Maybe>
|
||||
{state.hasTag("loading") && <Loader />}
|
||||
|
||||
<Stack spacing={6}>
|
||||
<Maybe condition={Boolean(error && !isApiValidationError(error))}>
|
||||
{Boolean(error) && !isApiValidationError(error) && (
|
||||
<ErrorAlert error={error} />
|
||||
</Maybe>
|
||||
)}
|
||||
|
||||
{shouldDisplayForm && (
|
||||
<CreateTemplateForm
|
||||
|
|
|
@ -24,11 +24,10 @@ import {
|
|||
import { Stack } from "components/Stack/Stack";
|
||||
import { TableRowMenu } from "components/TableRowMenu/TableRowMenu";
|
||||
import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete";
|
||||
import { useState } from "react";
|
||||
import { type FC, useState } from "react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { Link as RouterLink, useNavigate, useParams } from "react-router-dom";
|
||||
import { pageTitle } from "utils/page";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import {
|
||||
PaginationStatus,
|
||||
|
@ -47,7 +46,7 @@ import {
|
|||
import { displayError, displaySuccess } from "components/GlobalSnackbar/utils";
|
||||
import { getErrorMessage } from "api/errors";
|
||||
|
||||
export const GroupPage: React.FC = () => {
|
||||
export const GroupPage: FC = () => {
|
||||
const { groupId } = useParams() as { groupId: string };
|
||||
const queryClient = useQueryClient();
|
||||
const navigate = useNavigate();
|
||||
|
@ -79,25 +78,27 @@ export const GroupPage: React.FC = () => {
|
|||
<Margins>
|
||||
<PageHeader
|
||||
actions={
|
||||
<Maybe condition={canUpdateGroup}>
|
||||
<Button
|
||||
startIcon={<SettingsOutlined />}
|
||||
to="settings"
|
||||
component={RouterLink}
|
||||
>
|
||||
Settings
|
||||
</Button>
|
||||
<Button
|
||||
disabled={groupData?.id === groupData?.organization_id}
|
||||
onClick={() => {
|
||||
setIsDeletingGroup(true);
|
||||
}}
|
||||
startIcon={<DeleteOutline />}
|
||||
className={styles.removeButton}
|
||||
>
|
||||
Delete…
|
||||
</Button>
|
||||
</Maybe>
|
||||
canUpdateGroup && (
|
||||
<>
|
||||
<Button
|
||||
startIcon={<SettingsOutlined />}
|
||||
to="settings"
|
||||
component={RouterLink}
|
||||
>
|
||||
Settings
|
||||
</Button>
|
||||
<Button
|
||||
disabled={groupData?.id === groupData?.organization_id}
|
||||
onClick={() => {
|
||||
setIsDeletingGroup(true);
|
||||
}}
|
||||
startIcon={<DeleteOutline />}
|
||||
className={styles.removeButton}
|
||||
>
|
||||
Delete…
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
>
|
||||
<PageHeaderTitle>
|
||||
|
@ -113,13 +114,7 @@ export const GroupPage: React.FC = () => {
|
|||
</PageHeader>
|
||||
|
||||
<Stack spacing={1}>
|
||||
<Maybe
|
||||
condition={
|
||||
canUpdateGroup &&
|
||||
groupData !== undefined &&
|
||||
!isEveryoneGroup(groupData)
|
||||
}
|
||||
>
|
||||
{canUpdateGroup && groupData && !isEveryoneGroup(groupData) && (
|
||||
<AddGroupMember
|
||||
isLoading={addMemberMutation.isLoading}
|
||||
onSubmit={async (user, reset) => {
|
||||
|
@ -136,7 +131,7 @@ export const GroupPage: React.FC = () => {
|
|||
}
|
||||
}}
|
||||
/>
|
||||
</Maybe>
|
||||
)}
|
||||
<TableToolbar>
|
||||
<PaginationStatus
|
||||
isLoading={Boolean(isLoading)}
|
||||
|
@ -279,7 +274,7 @@ const GroupMemberRow = (props: {
|
|||
/>
|
||||
</TableCell>
|
||||
<TableCell width="1%">
|
||||
<Maybe condition={canUpdate}>
|
||||
{canUpdate && (
|
||||
<TableRowMenu
|
||||
data={member}
|
||||
menuItems={[
|
||||
|
@ -302,7 +297,7 @@ const GroupMemberRow = (props: {
|
|||
},
|
||||
]}
|
||||
/>
|
||||
</Maybe>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
|
|
|
@ -2,7 +2,6 @@ import { makeStyles } from "@mui/styles";
|
|||
import { FormikTouched } from "formik";
|
||||
import { FC, useState } from "react";
|
||||
import { AuthMethods } from "api/typesGenerated";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { PasswordSignInForm } from "./PasswordSignInForm";
|
||||
import { OAuthSignInForm } from "./OAuthSignInForm";
|
||||
import { BuiltInAuthFormValues } from "./SignInForm.types";
|
||||
|
@ -97,58 +96,65 @@ export const SignInForm: FC<React.PropsWithChildren<SignInFormProps>> = ({
|
|||
<h1 className={styles.title}>
|
||||
Sign in to <strong>Coder</strong>
|
||||
</h1>
|
||||
<Maybe condition={error !== undefined}>
|
||||
|
||||
{Boolean(error) && (
|
||||
<div className={styles.alert}>
|
||||
<ErrorAlert error={error} />
|
||||
</div>
|
||||
</Maybe>
|
||||
<Maybe condition={Boolean(info) && info !== "" && error === undefined}>
|
||||
)}
|
||||
|
||||
{Boolean(info) && Boolean(error) && (
|
||||
<div className={styles.alert}>
|
||||
<Alert severity="info">{info}</Alert>
|
||||
</div>
|
||||
</Maybe>
|
||||
<Maybe condition={passwordEnabled && showPasswordAuth}>
|
||||
)}
|
||||
|
||||
{passwordEnabled && showPasswordAuth && (
|
||||
<PasswordSignInForm
|
||||
onSubmit={onSubmit}
|
||||
initialTouched={initialTouched}
|
||||
isSigningIn={isSigningIn}
|
||||
/>
|
||||
</Maybe>
|
||||
<Maybe condition={passwordEnabled && showPasswordAuth && oAuthEnabled}>
|
||||
)}
|
||||
|
||||
{passwordEnabled && showPasswordAuth && oAuthEnabled && (
|
||||
<div className={styles.divider}>
|
||||
<div className={styles.dividerLine} />
|
||||
<div className={styles.dividerLabel}>Or</div>
|
||||
<div className={styles.dividerLine} />
|
||||
</div>
|
||||
</Maybe>
|
||||
<Maybe condition={oAuthEnabled}>
|
||||
)}
|
||||
|
||||
{oAuthEnabled && (
|
||||
<OAuthSignInForm
|
||||
isSigningIn={isSigningIn}
|
||||
redirectTo={redirectTo}
|
||||
authMethods={authMethods}
|
||||
/>
|
||||
</Maybe>
|
||||
)}
|
||||
|
||||
<Maybe condition={!passwordEnabled && !oAuthEnabled}>
|
||||
{!passwordEnabled && !oAuthEnabled && (
|
||||
<Alert severity="error">No authentication methods configured!</Alert>
|
||||
</Maybe>
|
||||
)}
|
||||
|
||||
<Maybe condition={passwordEnabled && !showPasswordAuth}>
|
||||
<div className={styles.divider}>
|
||||
<div className={styles.dividerLine} />
|
||||
<div className={styles.dividerLabel}>Or</div>
|
||||
<div className={styles.dividerLine} />
|
||||
</div>
|
||||
{passwordEnabled && !showPasswordAuth && (
|
||||
<>
|
||||
<div className={styles.divider}>
|
||||
<div className={styles.dividerLine} />
|
||||
<div className={styles.dividerLabel}>Or</div>
|
||||
<div className={styles.dividerLine} />
|
||||
</div>
|
||||
|
||||
<Button
|
||||
fullWidth
|
||||
size="large"
|
||||
onClick={() => setShowPasswordAuth(true)}
|
||||
startIcon={<EmailIcon className={styles.icon} />}
|
||||
>
|
||||
Email and password
|
||||
</Button>
|
||||
</Maybe>
|
||||
<Button
|
||||
fullWidth
|
||||
size="large"
|
||||
onClick={() => setShowPasswordAuth(true)}
|
||||
startIcon={<EmailIcon className={styles.icon} />}
|
||||
>
|
||||
Email and password
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { makeStyles } from "@mui/styles";
|
||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { Loader } from "components/Loader/Loader";
|
||||
import { Margins } from "components/Margins/Margins";
|
||||
import {
|
||||
|
@ -59,13 +58,9 @@ export const StarterTemplatesPageView: FC<StarterTemplatesPageViewProps> = ({
|
|||
</PageHeaderSubtitle>
|
||||
</PageHeader>
|
||||
|
||||
<Maybe condition={Boolean(error)}>
|
||||
<ErrorAlert error={error} />
|
||||
</Maybe>
|
||||
{Boolean(error) && <ErrorAlert error={error} />}
|
||||
|
||||
<Maybe condition={Boolean(!starterTemplatesByTag)}>
|
||||
<Loader />
|
||||
</Maybe>
|
||||
{Boolean(!starterTemplatesByTag) && <Loader />}
|
||||
|
||||
<Stack direction="row" spacing={4}>
|
||||
{starterTemplatesByTag && tags && (
|
||||
|
|
|
@ -6,7 +6,6 @@ import {
|
|||
TemplateVersion,
|
||||
} from "api/typesGenerated";
|
||||
import { Avatar } from "components/Avatar/Avatar";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog";
|
||||
import {
|
||||
PageHeader,
|
||||
|
@ -132,13 +131,13 @@ export const TemplatePageHeader: FC<TemplatePageHeaderProps> = ({
|
|||
actions={
|
||||
<>
|
||||
<CreateWorkspaceButton templateName={template.name} />
|
||||
<Maybe condition={permissions.canUpdateTemplate}>
|
||||
{permissions.canUpdateTemplate && (
|
||||
<TemplateMenu
|
||||
templateVersion={activeVersion.name}
|
||||
templateName={template.name}
|
||||
onDelete={deleteTemplate.openDeleteConfirmation}
|
||||
/>
|
||||
</Maybe>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
>
|
||||
|
|
|
@ -27,7 +27,6 @@ import {
|
|||
UserOrGroupAutocompleteValue,
|
||||
} from "components/UserOrGroupAutocomplete/UserOrGroupAutocomplete";
|
||||
import { FC, useState } from "react";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { GroupAvatar } from "components/GroupAvatar/GroupAvatar";
|
||||
import { getGroupSubtitle } from "utils/groups";
|
||||
import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader";
|
||||
|
@ -213,7 +212,7 @@ export const TemplatePermissionsPageView: FC<
|
|||
</PageHeader>
|
||||
|
||||
<Stack spacing={2.5}>
|
||||
<Maybe condition={canUpdatePermissions}>
|
||||
{canUpdatePermissions && (
|
||||
<AddTemplateUserOrGroup
|
||||
templateACL={templateACL}
|
||||
templateID={templateID}
|
||||
|
@ -225,7 +224,7 @@ export const TemplatePermissionsPageView: FC<
|
|||
: onAddUser(value, role, resetAutocomplete)
|
||||
}
|
||||
/>
|
||||
</Maybe>
|
||||
)}
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<TableHead>
|
||||
|
@ -288,7 +287,7 @@ export const TemplatePermissionsPageView: FC<
|
|||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<Maybe condition={canUpdatePermissions}>
|
||||
{canUpdatePermissions && (
|
||||
<TableRowMenu
|
||||
data={group}
|
||||
menuItems={[
|
||||
|
@ -299,7 +298,7 @@ export const TemplatePermissionsPageView: FC<
|
|||
},
|
||||
]}
|
||||
/>
|
||||
</Maybe>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
|
@ -336,7 +335,7 @@ export const TemplatePermissionsPageView: FC<
|
|||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<Maybe condition={canUpdatePermissions}>
|
||||
{canUpdatePermissions && (
|
||||
<TableRowMenu
|
||||
data={user}
|
||||
menuItems={[
|
||||
|
@ -347,7 +346,7 @@ export const TemplatePermissionsPageView: FC<
|
|||
},
|
||||
]}
|
||||
/>
|
||||
</Maybe>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
|
|
|
@ -8,7 +8,6 @@ import TableHead from "@mui/material/TableHead";
|
|||
import TableRow from "@mui/material/TableRow";
|
||||
import AddIcon from "@mui/icons-material/AddOutlined";
|
||||
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { FC } from "react";
|
||||
import { useNavigate, Link as RouterLink } from "react-router-dom";
|
||||
import { createDayString } from "utils/createDayString";
|
||||
|
@ -158,19 +157,21 @@ export const TemplatesPageView: FC<TemplatesPageViewProps> = ({
|
|||
<Margins>
|
||||
<PageHeader
|
||||
actions={
|
||||
<Maybe condition={canCreateTemplates}>
|
||||
<Button component={RouterLink} to="/starter-templates">
|
||||
Starter Templates
|
||||
</Button>
|
||||
<Button
|
||||
startIcon={<AddIcon />}
|
||||
component={RouterLink}
|
||||
to="new"
|
||||
variant="contained"
|
||||
>
|
||||
Create Template
|
||||
</Button>
|
||||
</Maybe>
|
||||
canCreateTemplates && (
|
||||
<>
|
||||
<Button component={RouterLink} to="/starter-templates">
|
||||
Starter Templates
|
||||
</Button>
|
||||
<Button
|
||||
startIcon={<AddIcon />}
|
||||
component={RouterLink}
|
||||
to="new"
|
||||
variant="contained"
|
||||
>
|
||||
Create Template
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
>
|
||||
<PageHeaderTitle>
|
||||
|
@ -179,11 +180,11 @@ export const TemplatesPageView: FC<TemplatesPageViewProps> = ({
|
|||
<TemplateHelpTooltip />
|
||||
</Stack>
|
||||
</PageHeaderTitle>
|
||||
<Maybe condition={Boolean(templates && templates.length > 0)}>
|
||||
{templates && templates.length > 0 && (
|
||||
<PageHeaderSubtitle>
|
||||
Select a template to create a workspace.
|
||||
</PageHeaderSubtitle>
|
||||
</Maybe>
|
||||
)}
|
||||
</PageHeader>
|
||||
|
||||
<ChooseOne>
|
||||
|
@ -204,9 +205,7 @@ export const TemplatesPageView: FC<TemplatesPageViewProps> = ({
|
|||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<Maybe condition={isLoading}>
|
||||
<TableLoader />
|
||||
</Maybe>
|
||||
{isLoading && <TableLoader />}
|
||||
|
||||
<ChooseOne>
|
||||
<Cond condition={isEmpty}>
|
||||
|
|
|
@ -12,7 +12,6 @@ import {
|
|||
} from "components/DeploySettingsLayout/Badges";
|
||||
import { ProxyLatencyReport } from "contexts/useProxyLatency";
|
||||
import { getLatencyColor } from "utils/latency";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import Box from "@mui/material/Box";
|
||||
|
||||
export const ProxyRow: FC<{
|
||||
|
@ -72,7 +71,7 @@ export const ProxyRow: FC<{
|
|||
{latency ? `${latency.latencyMS.toFixed(0)} ms` : "Not available"}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<Maybe condition={shouldShowMessages}>
|
||||
{shouldShowMessages && (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={4}
|
||||
|
@ -81,7 +80,7 @@ export const ProxyRow: FC<{
|
|||
<ProxyMessagesRow proxy={proxy as WorkspaceProxy} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</Maybe>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -12,7 +12,6 @@ import {
|
|||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "components/HelpTooltip/HelpTooltip";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
|
||||
const roleDescriptions: Record<string, string> = {
|
||||
owner:
|
||||
|
@ -94,7 +93,7 @@ export const EditRolesButton: FC<EditRolesButtonProps> = ({
|
|||
|
||||
return (
|
||||
<>
|
||||
<Maybe condition={canSetRoles}>
|
||||
{canSetRoles ? (
|
||||
<IconButton
|
||||
ref={anchorRef}
|
||||
size="small"
|
||||
|
@ -104,15 +103,14 @@ export const EditRolesButton: FC<EditRolesButtonProps> = ({
|
|||
>
|
||||
<EditSquare />
|
||||
</IconButton>
|
||||
</Maybe>
|
||||
<Maybe condition={!canSetRoles}>
|
||||
) : (
|
||||
<HelpTooltip size="small">
|
||||
<HelpTooltipTitle>Externally controlled</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
Roles for this user are controlled by the OIDC identity provider.
|
||||
</HelpTooltipText>
|
||||
</HelpTooltip>
|
||||
</Maybe>
|
||||
)}
|
||||
|
||||
<Popover
|
||||
id={id}
|
||||
|
|
|
@ -29,7 +29,6 @@ import { DormantWorkspaceBanner } from "components/WorkspaceDeletion";
|
|||
import { useLocalStorage } from "hooks";
|
||||
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
|
||||
import AlertTitle from "@mui/material/AlertTitle";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export enum WorkspaceErrors {
|
||||
|
@ -278,7 +277,7 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
|
|||
|
||||
<TemplateVersionWarnings warnings={templateWarnings} />
|
||||
|
||||
<Maybe condition={showAlertPendingInQueue}>
|
||||
{showAlertPendingInQueue && (
|
||||
<Alert severity="info">
|
||||
<AlertTitle>Workspace build is pending</AlertTitle>
|
||||
<AlertDetail>
|
||||
|
@ -294,7 +293,7 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
|
|||
</div>
|
||||
</AlertDetail>
|
||||
</Alert>
|
||||
</Maybe>
|
||||
)}
|
||||
|
||||
{workspace.latest_build.job.error && (
|
||||
<Alert
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import Link from "@mui/material/Link";
|
||||
import { Workspace } from "api/typesGenerated";
|
||||
import { Maybe } from "components/Conditionals/Maybe";
|
||||
import { PaginationWidgetBase } from "components/PaginationWidget/PaginationWidgetBase";
|
||||
import { ComponentProps, FC } from "react";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
|
@ -97,9 +96,9 @@ export const WorkspacesPageView: FC<
|
|||
</PageHeader>
|
||||
|
||||
<Stack>
|
||||
<Maybe condition={hasError(error) && !isApiValidationError(error)}>
|
||||
{hasError(error) && !isApiValidationError(error) && (
|
||||
<ErrorAlert error={error} />
|
||||
</Maybe>
|
||||
)}
|
||||
{/* <DormantWorkspaceBanner/> determines its own visibility */}
|
||||
<DormantWorkspaceBanner
|
||||
workspaces={dormantWorkspaces}
|
||||
|
|
Loading…
Reference in New Issue