mirror of
https://github.com/coder/coder.git
synced 2026-09-22 05:05:20 +08:00
feat: add premium license behavior for create organization page (#14650)
* fix: type * chore: paywall improvements * feat: update create org for premium license * fix: remove [] * feat: update licensing pills to reflect new premium tier (#14670) * feat: update licensing pills to reflect new premium tier * fix: format
This commit is contained in:
@@ -106,15 +106,32 @@ export const DisabledBadge: FC = forwardRef<
|
||||
);
|
||||
});
|
||||
|
||||
export const EnterpriseBadge: FC = () => {
|
||||
return (
|
||||
<span
|
||||
css={[
|
||||
styles.badge,
|
||||
(theme) => ({
|
||||
backgroundColor: theme.branding.enterprise.background,
|
||||
border: `1px solid ${theme.branding.enterprise.border}`,
|
||||
color: theme.branding.enterprise.text,
|
||||
}),
|
||||
]}
|
||||
>
|
||||
Enterprise
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export const PremiumBadge: FC = () => {
|
||||
return (
|
||||
<span
|
||||
css={[
|
||||
styles.badge,
|
||||
(theme) => ({
|
||||
backgroundColor: theme.branding.background,
|
||||
border: `1px solid ${theme.branding.border}`,
|
||||
color: theme.roles.notice.text,
|
||||
backgroundColor: theme.branding.premium.background,
|
||||
border: `1px solid ${theme.branding.premium.border}`,
|
||||
color: theme.branding.premium.text,
|
||||
}),
|
||||
]}
|
||||
>
|
||||
|
||||
@@ -19,15 +19,7 @@ export const Paywall: FC<PaywallProps> = ({
|
||||
documentationLink,
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
css={[
|
||||
styles.root,
|
||||
(theme) => ({
|
||||
backgroundImage: `linear-gradient(160deg, transparent, ${theme.branding.background})`,
|
||||
border: `1px solid ${theme.branding.border}`,
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<div css={styles.root}>
|
||||
<div>
|
||||
<Stack direction="row" alignItems="center" css={{ marginBottom: 24 }}>
|
||||
<h5 css={styles.title}>{message}</h5>
|
||||
@@ -45,7 +37,7 @@ export const Paywall: FC<PaywallProps> = ({
|
||||
</Link>
|
||||
</div>
|
||||
<div css={styles.separator} />
|
||||
<Stack direction="column" alignItems="center" spacing={3}>
|
||||
<Stack direction="column" alignItems="left" spacing={3}>
|
||||
<ul css={styles.featureList}>
|
||||
<li css={styles.feature}>
|
||||
<FeatureIcon />
|
||||
@@ -64,16 +56,18 @@ export const Paywall: FC<PaywallProps> = ({
|
||||
Unlimited Git & external auth integrations
|
||||
</li>
|
||||
</ul>
|
||||
<Button
|
||||
href={docs("/enterprise")}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
startIcon={<span css={{ fontSize: 22 }}>→</span>}
|
||||
variant="outlined"
|
||||
color="neutral"
|
||||
>
|
||||
Learn about Premium
|
||||
</Button>
|
||||
<div css={styles.learnButton}>
|
||||
<Button
|
||||
href={docs("/enterprise")}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
startIcon={<span css={{ fontSize: 22 }}>→</span>}
|
||||
variant="outlined"
|
||||
color="neutral"
|
||||
>
|
||||
Learn about Premium
|
||||
</Button>
|
||||
</div>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
@@ -84,7 +78,7 @@ const FeatureIcon: FC = () => {
|
||||
<TaskAltIcon
|
||||
css={[
|
||||
(theme) => ({
|
||||
color: theme.branding.border,
|
||||
color: theme.branding.premium.border,
|
||||
}),
|
||||
]}
|
||||
/>
|
||||
@@ -92,7 +86,7 @@ const FeatureIcon: FC = () => {
|
||||
};
|
||||
|
||||
const styles = {
|
||||
root: () => ({
|
||||
root: (theme) => ({
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
@@ -101,6 +95,8 @@ const styles = {
|
||||
padding: 24,
|
||||
borderRadius: 8,
|
||||
gap: 32,
|
||||
backgroundImage: `linear-gradient(160deg, transparent, ${theme.branding.premium.background})`,
|
||||
border: `1px solid ${theme.branding.premium.border}`,
|
||||
}),
|
||||
title: {
|
||||
fontWeight: 600,
|
||||
@@ -116,9 +112,12 @@ const styles = {
|
||||
separator: (theme) => ({
|
||||
width: 1,
|
||||
height: 220,
|
||||
backgroundColor: theme.branding.divider,
|
||||
backgroundColor: theme.branding.premium.divider,
|
||||
marginLeft: 8,
|
||||
}),
|
||||
learnButton: {
|
||||
padding: "0 28px",
|
||||
},
|
||||
featureList: {
|
||||
listStyle: "none",
|
||||
margin: 0,
|
||||
|
||||
@@ -23,8 +23,8 @@ export const PopoverPaywall: FC<PopoverPaywallProps> = ({
|
||||
css={[
|
||||
styles.root,
|
||||
(theme) => ({
|
||||
backgroundImage: `linear-gradient(160deg, transparent, ${theme.branding.background})`,
|
||||
border: `1px solid ${theme.branding.border}`,
|
||||
backgroundImage: `linear-gradient(160deg, transparent, ${theme.branding.premium.background})`,
|
||||
border: `1px solid ${theme.branding.premium.border}`,
|
||||
}),
|
||||
]}
|
||||
>
|
||||
@@ -45,7 +45,7 @@ export const PopoverPaywall: FC<PopoverPaywallProps> = ({
|
||||
</Link>
|
||||
</div>
|
||||
<div css={styles.separator} />
|
||||
<Stack direction="column" alignItems="center" spacing={2}>
|
||||
<Stack direction="column" alignItems="left" spacing={2}>
|
||||
<ul css={styles.featureList}>
|
||||
<li css={styles.feature}>
|
||||
<FeatureIcon /> High availability & workspace proxies
|
||||
@@ -60,16 +60,18 @@ export const PopoverPaywall: FC<PopoverPaywallProps> = ({
|
||||
<FeatureIcon /> Unlimited Git & external auth integrations
|
||||
</li>
|
||||
</ul>
|
||||
<Button
|
||||
href={docs("/enterprise")}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
startIcon={<span css={{ fontSize: 22 }}>→</span>}
|
||||
variant="outlined"
|
||||
color="neutral"
|
||||
>
|
||||
Learn about Premium
|
||||
</Button>
|
||||
<div css={styles.learnButton}>
|
||||
<Button
|
||||
href={docs("/enterprise")}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
startIcon={<span css={{ fontSize: 22 }}>→</span>}
|
||||
variant="outlined"
|
||||
color="neutral"
|
||||
>
|
||||
Learn about Premium
|
||||
</Button>
|
||||
</div>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
@@ -80,7 +82,7 @@ const FeatureIcon: FC = () => {
|
||||
<TaskAltIcon
|
||||
css={[
|
||||
(theme) => ({
|
||||
color: theme.branding.border,
|
||||
color: theme.branding.premium.border,
|
||||
}),
|
||||
]}
|
||||
/>
|
||||
@@ -92,7 +94,7 @@ const styles = {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
maxWidth: 600,
|
||||
maxWidth: 770,
|
||||
padding: "24px 36px",
|
||||
borderRadius: 8,
|
||||
gap: 18,
|
||||
@@ -106,7 +108,7 @@ const styles = {
|
||||
description: (theme) => ({
|
||||
marginTop: 8,
|
||||
fontFamily: "inherit",
|
||||
maxWidth: 420,
|
||||
maxWidth: 360,
|
||||
lineHeight: "160%",
|
||||
color: theme.palette.text.secondary,
|
||||
fontSize: 14,
|
||||
@@ -121,10 +123,13 @@ const styles = {
|
||||
listStyle: "none",
|
||||
margin: 0,
|
||||
marginRight: 8,
|
||||
padding: "0 12px",
|
||||
padding: "0 0 0 24px",
|
||||
fontSize: 13,
|
||||
fontWeight: 500,
|
||||
},
|
||||
learnButton: {
|
||||
padding: "0 28px",
|
||||
},
|
||||
feature: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
|
||||
@@ -3,6 +3,7 @@ import { appearanceConfigKey, updateAppearance } from "api/queries/appearance";
|
||||
import type { UpdateAppearanceConfig } from "api/typesGenerated";
|
||||
import { displayError, displaySuccess } from "components/GlobalSnackbar/utils";
|
||||
import { useDashboard } from "modules/dashboard/useDashboard";
|
||||
import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility";
|
||||
import type { FC } from "react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { useMutation, useQueryClient } from "react-query";
|
||||
@@ -15,6 +16,7 @@ import { AppearanceSettingsPageView } from "./AppearanceSettingsPageView";
|
||||
// the command line would be a significantly worse user experience.
|
||||
const AppearanceSettingsPage: FC = () => {
|
||||
const { appearance, entitlements } = useDashboard();
|
||||
const { multiple_organizations: hasPremiumLicense } = useFeatureVisibility();
|
||||
const queryClient = useQueryClient();
|
||||
const updateAppearanceMutation = useMutation(updateAppearance(queryClient));
|
||||
|
||||
@@ -46,6 +48,7 @@ const AppearanceSettingsPage: FC = () => {
|
||||
isEntitled={
|
||||
entitlements.features.appearance.entitlement !== "not_entitled"
|
||||
}
|
||||
isPremium={hasPremiumLicense}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
+13
-9
@@ -4,8 +4,7 @@ import TextField from "@mui/material/TextField";
|
||||
import type { UpdateAppearanceConfig } from "api/typesGenerated";
|
||||
import {
|
||||
Badges,
|
||||
DisabledBadge,
|
||||
EntitledBadge,
|
||||
EnterpriseBadge,
|
||||
PremiumBadge,
|
||||
} from "components/Badges/Badges";
|
||||
import { PopoverPaywall } from "components/Paywall/PopoverPaywall";
|
||||
@@ -24,6 +23,7 @@ import { AnnouncementBannerSettings } from "./AnnouncementBannerSettings";
|
||||
export type AppearanceSettingsPageViewProps = {
|
||||
appearance: UpdateAppearanceConfig;
|
||||
isEntitled: boolean;
|
||||
isPremium: boolean;
|
||||
onSaveAppearance: (
|
||||
newConfig: Partial<UpdateAppearanceConfig>,
|
||||
) => Promise<void>;
|
||||
@@ -31,7 +31,7 @@ export type AppearanceSettingsPageViewProps = {
|
||||
|
||||
export const AppearanceSettingsPageView: FC<
|
||||
AppearanceSettingsPageViewProps
|
||||
> = ({ appearance, isEntitled, onSaveAppearance }) => {
|
||||
> = ({ appearance, isEntitled, isPremium, onSaveAppearance }) => {
|
||||
const applicationNameForm = useFormik<{
|
||||
application_name: string;
|
||||
}>({
|
||||
@@ -60,13 +60,17 @@ export const AppearanceSettingsPageView: FC<
|
||||
/>
|
||||
|
||||
<Badges>
|
||||
{isEntitled ? <EntitledBadge /> : <DisabledBadge />}
|
||||
<Popover mode="hover">
|
||||
<PopoverTrigger>
|
||||
<span>
|
||||
<PremiumBadge />
|
||||
</span>
|
||||
</PopoverTrigger>
|
||||
{isEntitled && !isPremium ? (
|
||||
<EnterpriseBadge />
|
||||
) : (
|
||||
<PopoverTrigger>
|
||||
<span>
|
||||
<PremiumBadge />
|
||||
</span>
|
||||
</PopoverTrigger>
|
||||
)}
|
||||
|
||||
<PopoverContent css={{ transform: "translateY(-28px)" }}>
|
||||
<PopoverPaywall
|
||||
message="Appearance"
|
||||
|
||||
+3
@@ -1,5 +1,6 @@
|
||||
import { Loader } from "components/Loader/Loader";
|
||||
import { useDashboard } from "modules/dashboard/useDashboard";
|
||||
import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility";
|
||||
import type { FC } from "react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { pageTitle } from "utils/page";
|
||||
@@ -9,6 +10,7 @@ import { ObservabilitySettingsPageView } from "./ObservabilitySettingsPageView";
|
||||
const ObservabilitySettingsPage: FC = () => {
|
||||
const { deploymentValues } = useDeploySettings();
|
||||
const { entitlements } = useDashboard();
|
||||
const { multiple_organizations: hasPremiumLicense } = useFeatureVisibility();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -20,6 +22,7 @@ const ObservabilitySettingsPage: FC = () => {
|
||||
<ObservabilitySettingsPageView
|
||||
options={deploymentValues.options}
|
||||
featureAuditLogEnabled={entitlements.features.audit_log.enabled}
|
||||
isPremium={hasPremiumLicense}
|
||||
/>
|
||||
) : (
|
||||
<Loader />
|
||||
|
||||
+28
-5
@@ -1,10 +1,15 @@
|
||||
import type { SerpentOption } from "api/typesGenerated";
|
||||
import {
|
||||
Badges,
|
||||
DisabledBadge,
|
||||
EnabledBadge,
|
||||
EnterpriseBadge,
|
||||
PremiumBadge,
|
||||
} from "components/Badges/Badges";
|
||||
import { PopoverPaywall } from "components/Paywall/PopoverPaywall";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "components/Popover/Popover";
|
||||
import { SettingsHeader } from "components/SettingsHeader/SettingsHeader";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import type { FC } from "react";
|
||||
@@ -15,11 +20,12 @@ import OptionsTable from "../OptionsTable";
|
||||
export type ObservabilitySettingsPageViewProps = {
|
||||
options: SerpentOption[];
|
||||
featureAuditLogEnabled: boolean;
|
||||
isPremium: boolean;
|
||||
};
|
||||
|
||||
export const ObservabilitySettingsPageView: FC<
|
||||
ObservabilitySettingsPageViewProps
|
||||
> = ({ options, featureAuditLogEnabled }) => {
|
||||
> = ({ options, featureAuditLogEnabled, isPremium }) => {
|
||||
return (
|
||||
<>
|
||||
<Stack direction="column" spacing={6}>
|
||||
@@ -33,8 +39,25 @@ export const ObservabilitySettingsPageView: FC<
|
||||
/>
|
||||
|
||||
<Badges>
|
||||
{featureAuditLogEnabled ? <EnabledBadge /> : <DisabledBadge />}
|
||||
<PremiumBadge />
|
||||
<Popover mode="hover">
|
||||
{featureAuditLogEnabled && !isPremium ? (
|
||||
<EnterpriseBadge />
|
||||
) : (
|
||||
<PopoverTrigger>
|
||||
<span>
|
||||
<PremiumBadge />
|
||||
</span>
|
||||
</PopoverTrigger>
|
||||
)}
|
||||
|
||||
<PopoverContent css={{ transform: "translateY(-28px)" }}>
|
||||
<PopoverPaywall
|
||||
message="Observability"
|
||||
description="With a Premium license, you can monitor your application with logs and metrics."
|
||||
documentationLink="https://coder.com/docs/admin/appearance"
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</Badges>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,12 +2,8 @@ import TextField from "@mui/material/TextField";
|
||||
import { isApiValidationError } from "api/errors";
|
||||
import type { CreateOrganizationRequest } from "api/typesGenerated";
|
||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
import {
|
||||
Badges,
|
||||
DisabledBadge,
|
||||
EntitledBadge,
|
||||
PremiumBadge,
|
||||
} from "components/Badges/Badges";
|
||||
import { Badges, PremiumBadge } from "components/Badges/Badges";
|
||||
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
|
||||
import {
|
||||
FormFields,
|
||||
FormFooter,
|
||||
@@ -15,6 +11,7 @@ import {
|
||||
HorizontalForm,
|
||||
} from "components/Form/Form";
|
||||
import { IconField } from "components/IconField/IconField";
|
||||
import { Paywall } from "components/Paywall/Paywall";
|
||||
import { PopoverPaywall } from "components/Paywall/PopoverPaywall";
|
||||
import {
|
||||
Popover,
|
||||
@@ -22,6 +19,7 @@ import {
|
||||
PopoverTrigger,
|
||||
} from "components/Popover/Popover";
|
||||
import { SettingsHeader } from "components/SettingsHeader/SettingsHeader";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import { useFormik } from "formik";
|
||||
import type { FC } from "react";
|
||||
import { docs } from "utils/docs";
|
||||
@@ -67,79 +65,99 @@ export const CreateOrganizationPageView: FC<
|
||||
const getFieldHelpers = getFormHelpers(form, error);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SettingsHeader
|
||||
title="New Organization"
|
||||
description="Organize your deployment into multiple platform teams."
|
||||
/>
|
||||
<Stack>
|
||||
<div>
|
||||
<SettingsHeader
|
||||
title="New Organization"
|
||||
description="Organize your deployment into multiple platform teams."
|
||||
/>
|
||||
|
||||
<Badges>
|
||||
{isEntitled ? <EntitledBadge /> : <DisabledBadge />}
|
||||
<Popover mode="hover">
|
||||
<PopoverTrigger>
|
||||
<span>
|
||||
<PremiumBadge />
|
||||
</span>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent css={{ transform: "translateY(-28px)" }}>
|
||||
<PopoverPaywall
|
||||
message="Organizations"
|
||||
description="Organizations allow you to run a Coder deployment with multiple platform teams, all with unique use cases, templates, and even underlying infrastructure."
|
||||
documentationLink={docs("/guides/using-organizations")}
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</Badges>
|
||||
{Boolean(error) && !isApiValidationError(error) && (
|
||||
<div css={{ marginBottom: 32 }}>
|
||||
<ErrorAlert error={error} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{Boolean(error) && !isApiValidationError(error) && (
|
||||
<div css={{ marginBottom: 32 }}>
|
||||
<ErrorAlert error={error} />
|
||||
</div>
|
||||
)}
|
||||
<Badges>
|
||||
<Popover mode="hover">
|
||||
{isEntitled && (
|
||||
<PopoverTrigger>
|
||||
<span>
|
||||
<PremiumBadge />
|
||||
</span>
|
||||
</PopoverTrigger>
|
||||
)}
|
||||
|
||||
<HorizontalForm
|
||||
onSubmit={form.handleSubmit}
|
||||
aria-label="Organization settings form"
|
||||
>
|
||||
<FormSection
|
||||
title="General info"
|
||||
description="The name and description of the organization."
|
||||
>
|
||||
<fieldset
|
||||
disabled={form.isSubmitting}
|
||||
css={{ border: "unset", padding: 0, margin: 0, width: "100%" }}
|
||||
<PopoverContent css={{ transform: "translateY(-28px)" }}>
|
||||
<PopoverPaywall
|
||||
message="Organizations"
|
||||
description="Create multiple organizations within a single Coder deployment, allowing several platform teams to operate with isolated users, templates, and distinct underlying infrastructure."
|
||||
documentationLink={docs("/guides/using-organizations")}
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</Badges>
|
||||
</div>
|
||||
|
||||
<ChooseOne>
|
||||
<Cond condition={!isEntitled}>
|
||||
<Paywall
|
||||
message="Organizations"
|
||||
description="Create multiple organizations within a single Coder deployment, allowing several platform teams to operate with isolated users, templates, and distinct underlying infrastructure."
|
||||
documentationLink={docs("/guides/using-organizations")}
|
||||
/>
|
||||
</Cond>
|
||||
<Cond>
|
||||
<HorizontalForm
|
||||
onSubmit={form.handleSubmit}
|
||||
aria-label="Organization settings form"
|
||||
>
|
||||
<FormFields>
|
||||
<TextField
|
||||
{...getFieldHelpers("name")}
|
||||
onChange={onChangeTrimmed(form)}
|
||||
autoFocus
|
||||
fullWidth
|
||||
label="Name"
|
||||
/>
|
||||
<TextField
|
||||
{...getFieldHelpers("display_name")}
|
||||
fullWidth
|
||||
label="Display name"
|
||||
/>
|
||||
<TextField
|
||||
{...getFieldHelpers("description")}
|
||||
multiline
|
||||
fullWidth
|
||||
label="Description"
|
||||
rows={2}
|
||||
/>
|
||||
<IconField
|
||||
{...getFieldHelpers("icon")}
|
||||
onChange={onChangeTrimmed(form)}
|
||||
fullWidth
|
||||
onPickEmoji={(value) => form.setFieldValue("icon", value)}
|
||||
/>
|
||||
</FormFields>
|
||||
</fieldset>
|
||||
</FormSection>
|
||||
<FormFooter isLoading={form.isSubmitting} />
|
||||
</HorizontalForm>
|
||||
</div>
|
||||
<FormSection
|
||||
title="General info"
|
||||
description="The name and description of the organization."
|
||||
>
|
||||
<fieldset
|
||||
disabled={form.isSubmitting}
|
||||
css={{
|
||||
border: "unset",
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<FormFields>
|
||||
<TextField
|
||||
{...getFieldHelpers("name")}
|
||||
onChange={onChangeTrimmed(form)}
|
||||
autoFocus
|
||||
fullWidth
|
||||
label="Name"
|
||||
/>
|
||||
<TextField
|
||||
{...getFieldHelpers("display_name")}
|
||||
fullWidth
|
||||
label="Display name"
|
||||
/>
|
||||
<TextField
|
||||
{...getFieldHelpers("description")}
|
||||
multiline
|
||||
fullWidth
|
||||
label="Description"
|
||||
rows={2}
|
||||
/>
|
||||
<IconField
|
||||
{...getFieldHelpers("icon")}
|
||||
onChange={onChangeTrimmed(form)}
|
||||
fullWidth
|
||||
onPickEmoji={(value) => form.setFieldValue("icon", value)}
|
||||
/>
|
||||
</FormFields>
|
||||
</fieldset>
|
||||
</FormSection>
|
||||
<FormFooter isLoading={form.isSubmitting} />
|
||||
</HorizontalForm>
|
||||
</Cond>
|
||||
</ChooseOne>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ export const CustomRolesPageView: FC<CustomRolesPageViewProps> = ({
|
||||
{!isCustomRolesEnabled && (
|
||||
<Paywall
|
||||
message="Custom Roles"
|
||||
description="Custom Roles are available in the Premium plan and require an upgraded license. Please contact your Customer Success team for more information."
|
||||
description="Create custom roles to grant users a tailored set of granular permissions."
|
||||
documentationLink={docs("/admin/groups")}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -165,7 +165,7 @@ export const GroupPage: FC = () => {
|
||||
<TableRow>
|
||||
<TableCell width="59%">User</TableCell>
|
||||
<TableCell width="40">Status</TableCell>
|
||||
<TableCell width="1%"></TableCell>
|
||||
<TableCell width="1%" />
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ export const OrganizationMembersPageView: FC<
|
||||
<TableColumnHelpTooltip variant="groups" />
|
||||
</Stack>
|
||||
</TableCell>
|
||||
<TableCell width="1%"></TableCell>
|
||||
<TableCell width="1%" />
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
|
||||
+1
-1
@@ -213,7 +213,7 @@ export const TemplateSettingsForm: FC<TemplateSettingsForm> = ({
|
||||
css={{ marginTop: 16 }}
|
||||
>
|
||||
<PremiumBadge />
|
||||
<span>Premium license required to enabled.</span>
|
||||
<span>Premium license required to be enabled.</span>
|
||||
</Stack>
|
||||
)}
|
||||
</StackLabelHelperText>
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
export interface Branding {
|
||||
background: string;
|
||||
divider: string;
|
||||
border: string;
|
||||
text: string;
|
||||
enterprise: {
|
||||
background: string;
|
||||
divider: string;
|
||||
border: string;
|
||||
text: string;
|
||||
};
|
||||
premium: {
|
||||
background: string;
|
||||
divider: string;
|
||||
border: string;
|
||||
text: string;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,8 +2,16 @@ import type { Branding } from "../branding";
|
||||
import colors from "../tailwindColors";
|
||||
|
||||
export default {
|
||||
background: colors.violet[950],
|
||||
divider: colors.violet[900],
|
||||
border: colors.violet[400],
|
||||
text: colors.violet[50],
|
||||
enterprise: {
|
||||
background: colors.blue[950],
|
||||
divider: colors.blue[900],
|
||||
border: colors.blue[400],
|
||||
text: colors.blue[50],
|
||||
},
|
||||
premium: {
|
||||
background: colors.violet[950],
|
||||
divider: colors.violet[900],
|
||||
border: colors.violet[400],
|
||||
text: colors.violet[50],
|
||||
},
|
||||
} satisfies Branding;
|
||||
|
||||
@@ -2,8 +2,16 @@ import type { Branding } from "../branding";
|
||||
import colors from "../tailwindColors";
|
||||
|
||||
export default {
|
||||
background: colors.violet[950],
|
||||
divider: colors.violet[900],
|
||||
border: colors.violet[400],
|
||||
text: colors.violet[50],
|
||||
enterprise: {
|
||||
background: colors.blue[950],
|
||||
divider: colors.blue[900],
|
||||
border: colors.blue[400],
|
||||
text: colors.blue[50],
|
||||
},
|
||||
premium: {
|
||||
background: colors.violet[950],
|
||||
divider: colors.violet[900],
|
||||
border: colors.violet[400],
|
||||
text: colors.violet[50],
|
||||
},
|
||||
} satisfies Branding;
|
||||
|
||||
@@ -2,8 +2,16 @@ import type { Branding } from "../branding";
|
||||
import colors from "../tailwindColors";
|
||||
|
||||
export default {
|
||||
background: colors.violet[100],
|
||||
divider: colors.violet[300],
|
||||
border: colors.violet[600],
|
||||
text: colors.violet[950],
|
||||
enterprise: {
|
||||
background: colors.blue[100],
|
||||
divider: colors.blue[300],
|
||||
border: colors.blue[600],
|
||||
text: colors.blue[950],
|
||||
},
|
||||
premium: {
|
||||
background: colors.violet[100],
|
||||
divider: colors.violet[300],
|
||||
border: colors.violet[600],
|
||||
text: colors.violet[950],
|
||||
},
|
||||
} satisfies Branding;
|
||||
|
||||
Reference in New Issue
Block a user