feat: show feature gated setting pages (#3167)

This commit is contained in:
David Nguyen
2026-08-12 17:33:08 +10:00
committed by GitHub
parent 1bd09480e6
commit 617f8cc204
17 changed files with 940 additions and 32 deletions
@@ -1,5 +1,5 @@
import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation';
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
import { IS_BILLING_ENABLED, IS_DOCUMENSO_CLOUD } from '@documenso/lib/constants/app';
import { canExecuteOrganisationAction } from '@documenso/lib/utils/organisations';
import type { SanitizeBrandingCssWarning } from '@documenso/lib/utils/sanitize-branding-css';
import { trpc } from '@documenso/trpc/react';
@@ -17,6 +17,7 @@ import {
type TBrandingPreferencesFormSchema,
} from '~/components/forms/branding-preferences-form';
import { SettingsHeader } from '~/components/general/settings-header';
import { BrandingUpsell } from '~/components/general/settings-upsell/branding-upsell';
import { useOptionalCurrentTeam } from '~/providers/team';
import { appMetaTags } from '~/utils/meta';
@@ -121,11 +122,18 @@ export default function OrganisationSettingsBrandingPage() {
? t`Here you can set branding preferences for your team.`
: t`Here you can set branding preferences for your organisation. Teams will inherit these settings by default.`;
const brandingPreferencesFormEnabled =
organisationWithSettings.organisationClaim.flags.allowCustomBranding || !IS_BILLING_ENABLED();
return (
<div>
<SettingsHeader title={settingsHeaderText} subtitle={settingsHeaderSubtitle} />
<SettingsHeader
title={settingsHeaderText}
subtitle={settingsHeaderSubtitle}
hideDivider={!brandingPreferencesFormEnabled}
/>
{organisationWithSettings.organisationClaim.flags.allowCustomBranding || !IS_BILLING_ENABLED() ? (
{brandingPreferencesFormEnabled ? (
<section>
<BrandingPreferencesForm
context="Organisation"
@@ -160,6 +168,8 @@ export default function OrganisationSettingsBrandingPage() {
</Alert>
)}
</section>
) : IS_DOCUMENSO_CLOUD() ? (
<BrandingUpsell />
) : (
<Alert className="mt-8 flex flex-col justify-between p-6 sm:flex-row sm:items-center" variant="neutral">
<div className="mb-4 sm:mb-0">
@@ -1,5 +1,5 @@
import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation';
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
import { IS_BILLING_ENABLED, IS_DOCUMENSO_CLOUD } from '@documenso/lib/constants/app';
import { generateEmailDomainRecords } from '@documenso/lib/utils/email-domains';
import { trpc } from '@documenso/trpc/react';
import type { TGetOrganisationEmailDomainResponse } from '@documenso/trpc/server/enterprise-router/get-organisation-email-domain.types';
@@ -27,8 +27,9 @@ import { OrganisationEmailDomainRecordsDialog } from '~/components/dialogs/organ
import { OrganisationEmailUpdateDialog } from '~/components/dialogs/organisation-email-update-dialog';
import { GenericErrorLayout } from '~/components/general/generic-error-layout';
import { SettingsHeader } from '~/components/general/settings-header';
import { EmailDomainsUpsell } from '~/components/general/settings-upsell/email-domains-upsell';
import type { Route } from './+types/o.$orgUrl.settings.groups.$id';
import type { Route } from './+types/o.$orgUrl.settings.email-domains.$id';
export default function OrganisationEmailDomainSettingsPage({ params }: Route.ComponentProps) {
const { t } = useLingui();
@@ -96,10 +97,23 @@ export default function OrganisationEmailDomainSettingsPage({ params }: Route.Co
] satisfies DataTableColumnDef<TGetOrganisationEmailDomainResponse['emails'][number]>[];
}, [organisation]);
const pageHeader = t`Email Domain Settings`;
const pageSubtitle = t`Manage your email domain settings.`;
if (!IS_BILLING_ENABLED()) {
return null;
}
if (!organisation.organisationClaim.flags.emailDomains && IS_DOCUMENSO_CLOUD()) {
return (
<div>
<SettingsHeader hideDivider title={pageHeader} subtitle={pageSubtitle} />
<EmailDomainsUpsell />
</div>
);
}
if (isLoadingEmailDomain) {
return <SpinnerBox className="py-32" />;
}
@@ -132,7 +146,7 @@ export default function OrganisationEmailDomainSettingsPage({ params }: Route.Co
return (
<div>
<SettingsHeader hideDivider title={t`Email Domain Settings`} subtitle={t`Manage your email domain settings.`}>
<SettingsHeader hideDivider title={pageHeader} subtitle={pageSubtitle}>
<OrganisationEmailCreateDialog emailDomain={emailDomain} />
</SettingsHeader>
@@ -1,5 +1,5 @@
import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation';
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
import { IS_BILLING_ENABLED, IS_DOCUMENSO_CLOUD } from '@documenso/lib/constants/app';
import { canExecuteOrganisationAction } from '@documenso/lib/utils/organisations';
import { Alert, AlertDescription, AlertTitle } from '@documenso/ui/primitives/alert';
import { Button } from '@documenso/ui/primitives/button';
@@ -9,6 +9,7 @@ import { Link } from 'react-router';
import { OrganisationEmailDomainCreateDialog } from '~/components/dialogs/organisation-email-domain-create-dialog';
import { SettingsHeader } from '~/components/general/settings-header';
import { EmailDomainsUpsell } from '~/components/general/settings-upsell/email-domains-upsell';
import { OrganisationEmailDomainsDataTable } from '~/components/tables/organisation-email-domains-table';
import { appMetaTags } from '~/utils/meta';
@@ -41,6 +42,8 @@ export default function OrganisationSettingsEmailDomains() {
<section>
<OrganisationEmailDomainsDataTable />
</section>
) : IS_DOCUMENSO_CLOUD() ? (
<EmailDomainsUpsell />
) : (
<Alert className="mt-8 flex flex-col justify-between p-6 sm:flex-row sm:items-center" variant="neutral">
<div className="mb-4 sm:mb-0">
@@ -1,4 +1,5 @@
import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation';
import { IS_DOCUMENSO_CLOUD } from '@documenso/lib/constants/app';
import { ORGANISATION_MEMBER_ROLE_HIERARCHY } from '@documenso/lib/constants/organisations';
import { ORGANISATION_MEMBER_ROLE_MAP } from '@documenso/lib/constants/organisations-translations';
import {
@@ -28,6 +29,7 @@ import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { SettingsHeader } from '~/components/general/settings-header';
import { SsoPortalUpsell } from '~/components/general/settings-upsell/sso-portal-upsell';
import { appMetaTags } from '~/utils/meta';
const ZProviderFormSchema = ZUpdateOrganisationAuthenticationPortalRequestSchema.shape.data
@@ -63,10 +65,33 @@ export default function OrganisationSettingSSOLoginPage() {
const { t } = useLingui();
const organisation = useCurrentOrganisation();
const isAuthenticationPortalEnabled = organisation.organisationClaim.flags.authenticationPortal === true;
const { data: authenticationPortal, isLoading: isLoadingAuthenticationPortal } =
trpc.enterprise.organisation.authenticationPortal.get.useQuery({
organisationId: organisation.id,
});
trpc.enterprise.organisation.authenticationPortal.get.useQuery(
{
organisationId: organisation.id,
},
{
// The endpoint rejects orgs without the claim flag, so don't fire
// requests that are guaranteed to error.
enabled: isAuthenticationPortalEnabled,
},
);
if (!isAuthenticationPortalEnabled && IS_DOCUMENSO_CLOUD()) {
return (
<div>
<SettingsHeader
hideDivider
title={t`Organisation SSO Portal`}
subtitle={t`Manage a custom SSO login portal for your organisation.`}
/>
<SsoPortalUpsell />
</div>
);
}
if (isLoadingAuthenticationPortal || !authenticationPortal) {
return <SpinnerBox className="py-32" />;
@@ -1,5 +1,5 @@
import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation';
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
import { IS_BILLING_ENABLED, IS_DOCUMENSO_CLOUD } from '@documenso/lib/constants/app';
import { canExecuteOrganisationAction } from '@documenso/lib/utils/organisations';
import type { SanitizeBrandingCssWarning } from '@documenso/lib/utils/sanitize-branding-css';
import { trpc } from '@documenso/trpc/react';
@@ -17,6 +17,7 @@ import {
type TBrandingPreferencesFormSchema,
} from '~/components/forms/branding-preferences-form';
import { SettingsHeader } from '~/components/general/settings-header';
import { BrandingUpsell } from '~/components/general/settings-upsell/branding-upsell';
import { useCurrentTeam } from '~/providers/team';
export default function TeamsSettingsPage() {
@@ -155,6 +156,8 @@ export default function TeamsSettingsPage() {
</Alert>
)}
</section>
) : IS_DOCUMENSO_CLOUD() ? (
<BrandingUpsell />
) : (
<Alert className="mt-8 flex flex-col justify-between p-6 sm:flex-row sm:items-center" variant="neutral">
<div className="mb-4 sm:mb-0">