diff --git a/site/src/pages/TemplateBuilder/TemplateBuilderPage.tsx b/site/src/pages/TemplateBuilder/TemplateBuilderPage.tsx index 5561bbe9c5..ffda44a0bf 100644 --- a/site/src/pages/TemplateBuilder/TemplateBuilderPage.tsx +++ b/site/src/pages/TemplateBuilder/TemplateBuilderPage.tsx @@ -7,6 +7,7 @@ import { templateBuilderBases, } from "#/api/queries/templateBuilder"; import { Loader } from "#/components/Loader/Loader"; +import { useAuthenticated } from "#/hooks/useAuthenticated"; import { linkToTemplate, useLinks } from "#/modules/navigation"; import { pageTitle } from "#/utils/page"; import { TemplateBuilderPageView } from "./TemplateBuilderPageView"; @@ -16,17 +17,25 @@ import { toCreateTemplateRequest } from "./wizardState"; const TemplateBuilderPage: FC = () => { const navigate = useNavigate(); const getLink = useLinks(); + const { permissions } = useAuthenticated(); const { data, error, isLoading } = useQuery(deploymentConfig()); - const basesQuery = useQuery(templateBuilderBases()); const createMutation = useMutation(createTemplateFromBuilder()); + const builderDisabled = data?.config?.template_builder?.disabled ?? false; + + const basesQuery = useQuery({ + ...templateBuilderBases(), + enabled: !builderDisabled && !isLoading && permissions.createTemplates, + }); + if (isLoading) { return ; } - // If the template builder is disabled in the deployment config, - // redirect to the new template page. - const builderDisabled = data?.config?.template_builder?.disabled ?? false; + if (!permissions.createTemplates) { + return ; + } + if (builderDisabled) { return ; } diff --git a/site/src/pages/TemplatesPage/EmptyTemplates.tsx b/site/src/pages/TemplatesPage/EmptyTemplates.tsx index ab58d48ab7..a3d1848e20 100644 --- a/site/src/pages/TemplatesPage/EmptyTemplates.tsx +++ b/site/src/pages/TemplatesPage/EmptyTemplates.tsx @@ -35,12 +35,14 @@ const findFeaturedExamples = (examples: TemplateExample[]) => { interface EmptyTemplatesProps { canCreateTemplates: boolean; + templateBuilderEnabled: boolean; examples: TemplateExample[]; isUsingFilter: boolean; } export const EmptyTemplates: FC = ({ canCreateTemplates, + templateBuilderEnabled, examples, isUsingFilter, }) => { @@ -76,7 +78,13 @@ export const EmptyTemplates: FC = ({ ))} diff --git a/site/src/pages/TemplatesPage/TemplatesPage.tsx b/site/src/pages/TemplatesPage/TemplatesPage.tsx index d35c6e767b..20def48a3a 100644 --- a/site/src/pages/TemplatesPage/TemplatesPage.tsx +++ b/site/src/pages/TemplatesPage/TemplatesPage.tsx @@ -1,6 +1,7 @@ import type { FC } from "react"; import { useQuery } from "react-query"; import { useSearchParams } from "react-router"; +import { deploymentConfig } from "#/api/queries/deployment"; import { workspacePermissionsByOrganization } from "#/api/queries/organizations"; import { templateExamples, templates } from "#/api/queries/templates"; import { type UseFilterResult, useFilter } from "#/components/Filter/Filter"; @@ -33,6 +34,15 @@ const TemplatesPage: FC = () => { ), ); + const deploymentConfigQuery = useQuery({ + ...deploymentConfig(), + enabled: permissions.createTemplates, + }); + const templateBuilderEnabled = + deploymentConfigQuery.isSuccess && + !deploymentConfigQuery.data?.config?.template_builder?.disabled && + permissions.createTemplates; + const error = templatesQuery.error || examplesQuery.error || @@ -46,6 +56,7 @@ const TemplatesPage: FC = () => { filterState={filterState} showOrganizations={showOrganizations} canCreateTemplates={permissions.createTemplates} + templateBuilderEnabled={templateBuilderEnabled} examples={examplesQuery.data} templates={templatesQuery.data} workspacePermissions={workspacePermissionsQuery.data} diff --git a/site/src/pages/TemplatesPage/TemplatesPageView.stories.tsx b/site/src/pages/TemplatesPage/TemplatesPageView.stories.tsx index a2c1ee8201..79f4ae39bc 100644 --- a/site/src/pages/TemplatesPage/TemplatesPageView.stories.tsx +++ b/site/src/pages/TemplatesPage/TemplatesPageView.stories.tsx @@ -31,6 +31,7 @@ const meta: Meta = { component: TemplatesPageView, args: { filterState: defaultFilterProps, + templateBuilderEnabled: false, }, }; @@ -99,6 +100,13 @@ export const WithTemplates: Story = { }, }; +export const WithTemplatesBuilderEnabled: Story = { + args: { + ...WithTemplates.args, + templateBuilderEnabled: true, + }, +}; + export const MultipleOrganizations: Story = { args: { ...WithTemplates.args, @@ -159,6 +167,16 @@ export const EmptyCanCreate: Story = { }, }; +export const EmptyCanCreateWithBuilder: Story = { + args: { + canCreateTemplates: true, + templateBuilderEnabled: true, + error: undefined, + templates: [], + examples: [MockTemplateExample, MockTemplateExample2], + }, +}; + export const EmptyCannotCreate: Story = { args: { error: undefined, diff --git a/site/src/pages/TemplatesPage/TemplatesPageView.tsx b/site/src/pages/TemplatesPage/TemplatesPageView.tsx index ea3272eca3..8ba88d2706 100644 --- a/site/src/pages/TemplatesPage/TemplatesPageView.tsx +++ b/site/src/pages/TemplatesPage/TemplatesPageView.tsx @@ -196,6 +196,7 @@ interface TemplatesPageViewProps { filterState: TemplateFilterState; showOrganizations: boolean; canCreateTemplates: boolean; + templateBuilderEnabled: boolean; examples: TemplateExample[] | undefined; templates: Template[] | undefined; workspacePermissions: Record | undefined; @@ -206,6 +207,7 @@ export const TemplatesPageView: FC = ({ filterState, showOrganizations, canCreateTemplates, + templateBuilderEnabled, examples, templates, workspacePermissions, @@ -219,7 +221,13 @@ export const TemplatesPageView: FC = ({ actions={ canCreateTemplates && (