From 7382787f192d5149267bd7fa88ac8aa2bbbe7dd0 Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Wed, 25 Sep 2024 17:46:30 +0000 Subject: [PATCH 1/5] chore: add paywall to provisioners page --- .../OrganizationProvisionersPage.tsx | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx index e2e3fc75c3c2d..80bcaa39dabcd 100644 --- a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx +++ b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx @@ -3,23 +3,26 @@ import { organizationsPermissions, provisionerDaemonGroups, } from "api/queries/organizations"; -import type { Organization, ProvisionerDaemon } from "api/typesGenerated"; +import type { Organization } from "api/typesGenerated"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { EmptyState } from "components/EmptyState/EmptyState"; import { Loader } from "components/Loader/Loader"; import { useEmbeddedMetadata } from "hooks/useEmbeddedMetadata"; -import NotFoundPage from "pages/404Page/404Page"; import type { FC } from "react"; import { useQuery } from "react-query"; import { useParams } from "react-router-dom"; import { useOrganizationSettings } from "./ManagementSettingsLayout"; import { OrganizationProvisionersPageView } from "./OrganizationProvisionersPageView"; +import { useDashboard } from "modules/dashboard/useDashboard"; +import { Paywall } from "components/Paywall/Paywall"; +import { docs } from "utils/docs"; const OrganizationProvisionersPage: FC = () => { const { organization: organizationName } = useParams() as { organization: string; }; const { organizations } = useOrganizationSettings(); + const { entitlements } = useDashboard(); const { metadata } = useEmbeddedMetadata(); const buildInfoQuery = useQuery(buildInfo(metadata["build-info"])); @@ -32,6 +35,16 @@ const OrganizationProvisionersPage: FC = () => { ); const provisionersQuery = useQuery(provisionerDaemonGroups(organizationName)); + if (!entitlements.features.multiple_organizations.enabled) { + return ( + + ); + } + if (!organization) { return ; } @@ -47,18 +60,6 @@ const OrganizationProvisionersPage: FC = () => { return ; } - // The user may not be able to edit this org but they can still see it because - // they can edit members, etc. In this case they will be shown a read-only - // summary page instead of the settings form. - // Similarly, if the feature is not entitled then the user will not be able to - // edit the organization. - if (!permissions[organization.id]?.viewProvisioners) { - // This probably doesn't work with the layout................fix this pls - // Kayla, hey, yes you, you gotta fix this. - // Don't scroll past this. It's important. Fix it!!! - return ; - } - return ( Date: Wed, 25 Sep 2024 18:13:58 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=E3=81=8D=E3=82=8C=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ManagementSettingsPage/OrganizationProvisionersPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx index 80bcaa39dabcd..7b03454834273 100644 --- a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx +++ b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx @@ -7,15 +7,15 @@ import type { Organization } from "api/typesGenerated"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { EmptyState } from "components/EmptyState/EmptyState"; import { Loader } from "components/Loader/Loader"; +import { Paywall } from "components/Paywall/Paywall"; import { useEmbeddedMetadata } from "hooks/useEmbeddedMetadata"; +import { useDashboard } from "modules/dashboard/useDashboard"; import type { FC } from "react"; import { useQuery } from "react-query"; import { useParams } from "react-router-dom"; +import { docs } from "utils/docs"; import { useOrganizationSettings } from "./ManagementSettingsLayout"; import { OrganizationProvisionersPageView } from "./OrganizationProvisionersPageView"; -import { useDashboard } from "modules/dashboard/useDashboard"; -import { Paywall } from "components/Paywall/Paywall"; -import { docs } from "utils/docs"; const OrganizationProvisionersPage: FC = () => { const { organization: organizationName } = useParams() as { From 9b478c01abfe07056853baa4138446023bfbcc08 Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Wed, 25 Sep 2024 21:50:54 +0000 Subject: [PATCH 3/5] move some things into the page view --- .../modules/provisioners/ProvisionerGroup.tsx | 16 ++--- .../OrganizationProvisionersPage.tsx | 28 +------- ...ganizationProvisionersPageView.stories.tsx | 16 +++++ .../OrganizationProvisionersPageView.tsx | 71 ++++++++++++++----- 4 files changed, 79 insertions(+), 52 deletions(-) diff --git a/site/src/modules/provisioners/ProvisionerGroup.tsx b/site/src/modules/provisioners/ProvisionerGroup.tsx index b6077da9614bc..4d9b0841bfe98 100644 --- a/site/src/modules/provisioners/ProvisionerGroup.tsx +++ b/site/src/modules/provisioners/ProvisionerGroup.tsx @@ -31,7 +31,7 @@ import { ProvisionerTag } from "./ProvisionerTag"; type ProvisionerGroupType = "builtin" | "psk" | "key"; interface ProvisionerGroupProps { - readonly buildInfo?: BuildInfoResponse; + readonly buildInfo: BuildInfoResponse; readonly keyName: string; readonly keyTags: Record; readonly type: ProvisionerGroupType; @@ -72,7 +72,7 @@ export const ProvisionerGroup: FC = ({ let warnings = 0; let provisionersWithWarnings = 0; const provisionersWithWarningInfo = provisioners.map((it) => { - const outOfDate = Boolean(buildInfo) && it.version !== buildInfo?.version; + const outOfDate = it.version !== buildInfo.version; const warningCount = outOfDate ? 1 : 0; warnings += warningCount; if (warnings > 0) { @@ -285,7 +285,7 @@ export const ProvisionerGroup: FC = ({ }; interface ProvisionerVersionPopoverProps { - buildInfo?: BuildInfoResponse; + buildInfo: BuildInfoResponse; provisioner: ProvisionerDaemon; } @@ -297,11 +297,9 @@ const ProvisionerVersionPopover: FC = ({ - {buildInfo - ? provisioner.version === buildInfo.version - ? "Up to date" - : "Out of date" - : provisioner.version} + {provisioner.version === buildInfo.version + ? "Up to date" + : "Out of date"} = ({

{provisioner.version}

Protocol version

{provisioner.api_version}

- {provisioner.api_version !== buildInfo?.provisioner_api_version && ( + {provisioner.api_version !== buildInfo.provisioner_api_version && (

This provisioner is out of date. You may experience issues when using a provisioner version that doesn’t match your Coder diff --git a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx index 7b03454834273..55dff198822a0 100644 --- a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx +++ b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPage.tsx @@ -30,40 +30,18 @@ const OrganizationProvisionersPage: FC = () => { const organization = organizations ? getOrganizationByName(organizations, organizationName) : undefined; - const permissionsQuery = useQuery( - organizationsPermissions(organizations?.map((o) => o.id)), - ); const provisionersQuery = useQuery(provisionerDaemonGroups(organizationName)); - if (!entitlements.features.multiple_organizations.enabled) { - return ( - - ); - } - if (!organization) { return ; } - if (permissionsQuery.isLoading || provisionersQuery.isLoading) { - return ; - } - - const permissions = permissionsQuery.data; - const provisioners = provisionersQuery.data; - const error = permissionsQuery.error || provisionersQuery.error; - if (error || !permissions || !provisioners) { - return ; - } - return ( ); }; diff --git a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx index 439fba6c2f432..00d77e55ab379 100644 --- a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx +++ b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx @@ -1,6 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { screen, userEvent } from "@storybook/test"; import { + mockApiError, MockBuildInfo, MockProvisioner, MockProvisioner2, @@ -109,3 +110,18 @@ export const Empty: Story = { provisioners: [], }, }; + +export const WithError: Story = { + args: { + error: mockApiError({ + message: "Serie doesn't like you", + detail: "She thinks your favorite spell is lame", + }), + }, +}; + +export const Paywall: Story = { + args: { + showPaywall: true, + }, +}; diff --git a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.tsx b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.tsx index e2bafae1a76db..c535095ae4c0c 100644 --- a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.tsx +++ b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.tsx @@ -5,8 +5,11 @@ import type { ProvisionerKey, ProvisionerKeyDaemons, } from "api/typesGenerated"; +import { ErrorAlert } from "components/Alert/ErrorAlert"; import { EmptyState } from "components/EmptyState/EmptyState"; import { FeatureStageBadge } from "components/FeatureStageBadge/FeatureStageBadge"; +import { Loader } from "components/Loader/Loader"; +import { Paywall } from "components/Paywall/Paywall"; import { SettingsHeader } from "components/SettingsHeader/SettingsHeader"; import { Stack } from "components/Stack/Stack"; import { ProvisionerGroup } from "modules/provisioners/ProvisionerGroup"; @@ -14,24 +17,22 @@ import type { FC } from "react"; import { docs } from "utils/docs"; interface OrganizationProvisionersPageViewProps { + /** Determines if the paywall will be shown or not */ + showPaywall?: boolean; + + /** An error to display instead of the page content */ + error?: unknown; + /** Info about the version of coderd */ buildInfo?: BuildInfoResponse; /** Groups of provisioners, along with their key information */ - provisioners: readonly ProvisionerKeyDaemons[]; + provisioners?: readonly ProvisionerKeyDaemons[]; } export const OrganizationProvisionersPageView: FC< OrganizationProvisionersPageViewProps -> = ({ buildInfo, provisioners }) => { - const isEmpty = provisioners.every((group) => group.daemons.length === 0); - - const provisionerGroupsCount = provisioners.length; - const provisionersCount = provisioners.reduce( - (a, group) => a + group.daemons.length, - 0, - ); - +> = ({ showPaywall, error, buildInfo, provisioners }) => { return (

} /> - + {!showPaywall && ( + + )} + {showPaywall ? ( + + ) : error ? ( + + ) : !buildInfo || !provisioners ? ( + + ) : ( + + )} +
+ ); +}; + +type ViewContentProps = Required< + Pick +>; + +const ViewContent: FC = ({ buildInfo, provisioners }) => { + const isEmpty = provisioners.every((group) => group.daemons.length === 0); + + const provisionerGroupsCount = provisioners.length; + const provisionersCount = provisioners.reduce( + (a, group) => a + group.daemons.length, + 0, + ); + + return ( + <> {isEmpty ? ( - + ); }; From beca55536274465b389ccb9c88851132b02dfdf7 Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Wed, 25 Sep 2024 21:59:22 +0000 Subject: [PATCH 4/5] I guess I'm not allowed to use proper nouns --- .../OrganizationProvisionersPageView.stories.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx index 3cc2751ec7261..d778820ef58c2 100644 --- a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx +++ b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx @@ -117,8 +117,8 @@ export const Empty: Story = { export const WithError: Story = { args: { error: mockApiError({ - message: "Serie doesn't like you", - detail: "She thinks your favorite spell is lame", + message: "Fern is mad", + detail: "Frieren slept in and didn't get groceries", }), }, }; From 5ac39bd22b4657efe05ae152d9ae16d175c8e458 Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Wed, 25 Sep 2024 22:44:37 +0000 Subject: [PATCH 5/5] :| --- .../OrganizationProvisionersPageView.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx index d778820ef58c2..dec8e40e28d59 100644 --- a/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx +++ b/site/src/pages/ManagementSettingsPage/OrganizationProvisionersPageView.stories.tsx @@ -1,7 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react"; import { screen, userEvent } from "@storybook/test"; import { - mockApiError, MockBuildInfo, MockProvisioner, MockProvisioner2, @@ -10,6 +9,7 @@ import { MockProvisionerPskKey, MockProvisionerWithTags, MockUserProvisioner, + mockApiError, } from "testHelpers/entities"; import { OrganizationProvisionersPageView } from "./OrganizationProvisionersPageView";