diff --git a/site/src/components/SettingsHeader/SettingsHeader.tsx b/site/src/components/SettingsHeader/SettingsHeader.tsx index fcac611aa85..cd5015a9bc7 100644 --- a/site/src/components/SettingsHeader/SettingsHeader.tsx +++ b/site/src/components/SettingsHeader/SettingsHeader.tsx @@ -1,7 +1,6 @@ import { cva, type VariantProps } from "class-variance-authority"; -import { SquareArrowOutUpRightIcon } from "lucide-react"; import type { FC, PropsWithChildren, ReactNode } from "react"; -import { Button } from "#/components/Button/Button"; +import { Link } from "#/components/Link/Link"; import { cn } from "#/utils/cn"; type SettingsHeaderProps = Readonly< @@ -26,20 +25,22 @@ export const SettingsHeader: FC = ({ }; type SettingsHeaderDocsLinkProps = Readonly< - PropsWithChildren<{ href: string }> + PropsWithChildren<{ + href: string; + context?: string; + }> >; export const SettingsHeaderDocsLink: FC = ({ href, - children = "Read the docs", + context, + children = "View docs", }) => { return ( - + + {children} + {context && {context}} + (opens in new tab) + ); }; diff --git a/site/src/pages/AISettingsPage/GatewayKeysPage/GatewayKeysPageView.stories.tsx b/site/src/pages/AISettingsPage/GatewayKeysPage/GatewayKeysPageView.stories.tsx index cf2d6169770..6b94315e252 100644 --- a/site/src/pages/AISettingsPage/GatewayKeysPage/GatewayKeysPageView.stories.tsx +++ b/site/src/pages/AISettingsPage/GatewayKeysPage/GatewayKeysPageView.stories.tsx @@ -83,7 +83,7 @@ export const Paywall: Story = { const cta = canvas.getByRole("link", { name: "Start trial for free" }); await expect(cta).toHaveAttribute("href", "/deployment/premium"); await expect( - canvas.getByRole("link", { name: /Read the docs/ }), + canvas.getByRole("link", { name: /View docs/ }), ).toHaveAttribute( "href", docs("/ai-coder/ai-gateway/standalone#create-a-gateway-key"), diff --git a/site/src/pages/AISettingsPage/GatewayKeysPage/GatewayKeysPageView.tsx b/site/src/pages/AISettingsPage/GatewayKeysPage/GatewayKeysPageView.tsx index 2b12c6d2c27..9d5f269d329 100644 --- a/site/src/pages/AISettingsPage/GatewayKeysPage/GatewayKeysPageView.tsx +++ b/site/src/pages/AISettingsPage/GatewayKeysPage/GatewayKeysPageView.tsx @@ -47,25 +47,21 @@ export const GatewayKeysPageView: FC = ({
- - {!showPaywall && ( - - )} -
+ !showPaywall && ( + + ) } > AI Gateway Keys Keys authenticate standalone AI Gateway replicas to this deployment. - The key value is shown only once when created. + The key value is shown only once when created.{" "} + diff --git a/site/src/pages/AuditPage/AuditPageView.stories.tsx b/site/src/pages/AuditPage/AuditPageView.stories.tsx index cba54475f79..929161e0ea0 100644 --- a/site/src/pages/AuditPage/AuditPageView.stories.tsx +++ b/site/src/pages/AuditPage/AuditPageView.stories.tsx @@ -103,7 +103,7 @@ export const NotVisible: Story = { const cta = canvas.getByRole("link", { name: "Start trial for free" }); await expect(cta).toHaveAttribute("href", "/deployment/premium"); await expect( - canvas.getByRole("link", { name: /Read the docs/ }), + canvas.getByRole("link", { name: /View docs/ }), ).toHaveAttribute("href", docs("/admin/security/audit-logs")); }, }; diff --git a/site/src/pages/AuditPage/AuditPageView.tsx b/site/src/pages/AuditPage/AuditPageView.tsx index 0ed109f0ec0..21502b02aba 100644 --- a/site/src/pages/AuditPage/AuditPageView.tsx +++ b/site/src/pages/AuditPage/AuditPageView.tsx @@ -51,18 +51,17 @@ export const AuditPageView: FC = ({ return ( - - } - > +
Audit
- View events in your audit log. + + View events in your audit log.{" "} + +
{isAuditLogVisible ? ( diff --git a/site/src/pages/ConnectionLogPage/ConnectionLogPageView.stories.tsx b/site/src/pages/ConnectionLogPage/ConnectionLogPageView.stories.tsx index ff238731a5c..f3c50280170 100644 --- a/site/src/pages/ConnectionLogPage/ConnectionLogPageView.stories.tsx +++ b/site/src/pages/ConnectionLogPage/ConnectionLogPageView.stories.tsx @@ -102,7 +102,7 @@ export const NotVisible: Story = { const cta = canvas.getByRole("link", { name: "Start trial for free" }); await expect(cta).toHaveAttribute("href", "/deployment/premium"); await expect( - canvas.getByRole("link", { name: /Read the docs/ }), + canvas.getByRole("link", { name: /View docs/ }), ).toHaveAttribute("href", docs("/admin/monitoring/connection-logs")); }, }; diff --git a/site/src/pages/ConnectionLogPage/ConnectionLogPageView.tsx b/site/src/pages/ConnectionLogPage/ConnectionLogPageView.tsx index 520aaddbdba..5f4282470d0 100644 --- a/site/src/pages/ConnectionLogPage/ConnectionLogPageView.tsx +++ b/site/src/pages/ConnectionLogPage/ConnectionLogPageView.tsx @@ -50,13 +50,7 @@ export const ConnectionLogPageView: FC = ({ return ( - - } - > +
Connection Log @@ -64,7 +58,10 @@ export const ConnectionLogPageView: FC = ({
- View workspace connection events. + View workspace connection events.{" "} +
diff --git a/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.tsx index f83663e684e..b7d69818b67 100644 --- a/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.tsx @@ -29,16 +29,13 @@ export const AIGovernanceSettingsPageView: FC<
- - } - > + AI Gateway - Monitor and manage AI requests across your deployment. + Monitor and manage AI requests across your deployment.{" "} + diff --git a/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.stories.tsx b/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.stories.tsx index bc81d061c79..dbdb2aba3ae 100644 --- a/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.stories.tsx +++ b/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.stories.tsx @@ -58,7 +58,7 @@ export const NotEntitled: Story = { const cta = canvas.getByRole("link", { name: "Start trial for free" }); await expect(cta).toHaveAttribute("href", "/deployment/premium"); await expect( - canvas.getByRole("link", { name: /Read the docs/ }), + canvas.getByRole("link", { name: /View docs/ }), ).toHaveAttribute("href", docs("/admin/setup/appearance")); await expect( canvas.queryByRole("form", { name: "Appearance settings" }), diff --git a/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.tsx index 7c5484aa318..f17a113a983 100644 --- a/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.tsx @@ -49,14 +49,11 @@ export const AppearanceSettingsPageView: FC< return (
- - } - > + Appearance - Customize the look and feel of your Coder deployment. + Customize the look and feel of your Coder deployment.{" "} + diff --git a/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.stories.tsx b/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.stories.tsx index 0b5ac04cd8c..8880f583ea3 100644 --- a/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.stories.tsx +++ b/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.stories.tsx @@ -1,5 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, within } from "storybook/test"; +import { docs } from "#/utils/docs"; import { ExternalAuthSettingsPageView } from "./ExternalAuthSettingsPageView"; const meta: Meta = { @@ -49,6 +50,9 @@ export const Page: Story = { await expect( canvas.getByRole("link", { name: "Start trial for free" }), ).toHaveAttribute("href", "/deployment/premium"); + await expect( + canvas.getByRole("link", { name: /View docs/ }), + ).toHaveAttribute("href", docs("/admin/external-auth")); }, }; diff --git a/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.tsx index c27648515e2..8c5cb354762 100644 --- a/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.tsx @@ -33,13 +33,12 @@ export const ExternalAuthSettingsPageView: FC< > = ({ config, isEntitled, canViewPremium }) => { return ( <> - } - > + External Authentication Coder integrates with GitHub, GitLab, BitBucket, Azure Repos, and - OpenID Connect to authenticate developers with external services. + OpenID Connect to authenticate developers with external services.{" "} + diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx index 56f5ef031ce..48163500d23 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx @@ -70,19 +70,15 @@ const IdpOrgSyncPage: FC = () => {
- - -
- } + actions={} > Organization IdP Sync Automatically assign users to an organization based on their IdP - claims. + claims.{" "} +
{!isIdpSyncEnabled ? ( diff --git a/site/src/pages/DeploymentSettingsPage/NetworkSettingsPage/NetworkSettingsPageView.stories.tsx b/site/src/pages/DeploymentSettingsPage/NetworkSettingsPage/NetworkSettingsPageView.stories.tsx index 6aa7dc2c5c9..9c8f1c9465d 100644 --- a/site/src/pages/DeploymentSettingsPage/NetworkSettingsPage/NetworkSettingsPageView.stories.tsx +++ b/site/src/pages/DeploymentSettingsPage/NetworkSettingsPage/NetworkSettingsPageView.stories.tsx @@ -1,5 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, within } from "storybook/test"; import type { SerpentGroup } from "#/api/typesGenerated"; +import { docs } from "#/utils/docs"; import { NetworkSettingsPageView } from "./NetworkSettingsPageView"; const group: SerpentGroup = { @@ -67,4 +69,18 @@ const meta: Meta = { export default meta; type Story = StoryObj; -export const Page: Story = {}; +export const Page: Story = { + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const docsLinks = canvas.getAllByRole("link", { name: /View docs/ }); + await expect(docsLinks).toHaveLength(2); + await expect(docsLinks[0]).toHaveAttribute( + "href", + docs("/admin/networking"), + ); + await expect(docsLinks[1]).toHaveAttribute( + "href", + docs("/admin/networking/port-forwarding"), + ); + }, +}; diff --git a/site/src/pages/DeploymentSettingsPage/NetworkSettingsPage/NetworkSettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/NetworkSettingsPage/NetworkSettingsPageView.tsx index aa218f6f88d..b545af5497a 100644 --- a/site/src/pages/DeploymentSettingsPage/NetworkSettingsPage/NetworkSettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/NetworkSettingsPage/NetworkSettingsPageView.tsx @@ -27,12 +27,14 @@ export const NetworkSettingsPageView: FC = ({ }) => (
- } - > + Network - Configure your deployment connectivity. + Configure your deployment connectivity.{" "} + @@ -44,19 +46,17 @@ export const NetworkSettingsPageView: FC = ({
- - } - > + Port Forwarding Port forwarding lets developers securely access processes on their - Coder workspace from a local machine. + Coder workspace from a local machine.{" "} + diff --git a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.stories.tsx b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.stories.tsx index 131e29f1223..58bf9fdf4e2 100644 --- a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.stories.tsx +++ b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.stories.tsx @@ -1,9 +1,10 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; -import { spyOn, userEvent, within } from "storybook/test"; +import { expect, spyOn, userEvent, within } from "storybook/test"; import { API } from "#/api/api"; import { selectTemplatesByGroup } from "#/api/queries/notifications"; import type { DeploymentValues } from "#/api/typesGenerated"; import { MockSystemNotificationTemplates } from "#/testHelpers/entities"; +import { docs } from "#/utils/docs"; import { NotificationEvents } from "./NotificationEvents"; import { baseMeta } from "./storybookUtils"; @@ -36,6 +37,15 @@ export const SMTPNotConfigured: Story = { }, } as DeploymentValues, }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await expect( + canvas.getByRole("link", { name: /View docs/ }), + ).toHaveAttribute( + "href", + docs("/admin/monitoring/notifications#smtp-email"), + ); + }, }; export const WebhookNotConfigured: Story = { @@ -53,6 +63,12 @@ export const WebhookNotConfigured: Story = { }, } as DeploymentValues, }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await expect( + canvas.getByRole("link", { name: /View docs/ }), + ).toHaveAttribute("href", docs("/admin/monitoring/notifications#webhook")); + }, }; export const ChangeMethod: Story = { diff --git a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.tsx b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.tsx index a0000ea5722..e12199edae6 100644 --- a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.tsx +++ b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.tsx @@ -8,7 +8,7 @@ import { } from "#/api/queries/notifications"; import type { DeploymentValues } from "#/api/typesGenerated"; import { Alert } from "#/components/Alert/Alert"; -import { Button } from "#/components/Button/Button"; +import { Link } from "#/components/Link/Link"; import { Select, SelectContent, @@ -66,15 +66,14 @@ export const NotificationEvents: FC = ({ severity="warning" prominent actions={ - + + View docs + (opens in new tab) + } > Webhook notifications are enabled, but not properly configured. @@ -86,15 +85,14 @@ export const NotificationEvents: FC = ({ severity="warning" prominent actions={ - + + View docs + (opens in new tab) + } > SMTP notifications are enabled but not properly configured. diff --git a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.stories.tsx b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.stories.tsx index 4cc9b242df2..504edd2375c 100644 --- a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.stories.tsx +++ b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.stories.tsx @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; -import { userEvent, within } from "storybook/test"; +import { expect, userEvent, within } from "storybook/test"; import { customNotificationTemplatesKey, notificationDispatchMethodsKey, @@ -10,6 +10,7 @@ import { MockNotificationMethodsResponse, MockSystemNotificationTemplates, } from "#/testHelpers/entities"; +import { docs } from "#/utils/docs"; import NotificationsPage from "./NotificationsPage"; import { baseMeta } from "./storybookUtils"; @@ -64,6 +65,20 @@ export const LoadingDispatchMethods: Story = { export const Events: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); + const docsLinks = canvas.getAllByRole("link", { name: /View docs/ }); + await expect(docsLinks).toHaveLength(3); + await expect(docsLinks[0]).toHaveAttribute( + "href", + docs("/admin/monitoring/notifications"), + ); + await expect(docsLinks[1]).toHaveAttribute( + "href", + docs("/admin/monitoring/notifications#webhook"), + ); + await expect(docsLinks[2]).toHaveAttribute( + "href", + docs("/admin/monitoring/notifications#smtp-email"), + ); // System notification templates await canvas.findByText("Template Events"); diff --git a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.tsx b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.tsx index 2214d8ac106..55c492e557c 100644 --- a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.tsx +++ b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.tsx @@ -78,16 +78,14 @@ const NotificationsPage: FC = () => { <> Codestin Search App - + Notifications + + Control delivery methods for notifications on this deployment.{" "} - } - > - Notifications - - Control delivery methods for notifications on this deployment. diff --git a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.stories.tsx b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.stories.tsx index 031b3fcc070..0c7a2c6666a 100644 --- a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.stories.tsx +++ b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.stories.tsx @@ -167,7 +167,7 @@ export const AddApplicationIsScopedToApplicationsTab: Story = { // The docs link is tab-agnostic and stays put, which is what makes the // other one's disappearance a scoping decision rather than a quirk. - const docsLink = canvas.getByRole("link", { name: /read the docs/i }); + const docsLink = canvas.getByRole("link", { name: /view docs/i }); await expect(docsLink).toBeVisible(); await userEvent.click(canvas.getByRole("tab", { name: "Settings" })); @@ -175,7 +175,7 @@ export const AddApplicationIsScopedToApplicationsTab: Story = { canvas.queryByRole("link", { name: "Add application" }), ).not.toBeInTheDocument(); await expect( - canvas.getByRole("link", { name: /read the docs/i }), + canvas.getByRole("link", { name: /view docs/i }), ).toBeVisible(); await userEvent.click(canvas.getByRole("tab", { name: "Applications" })); diff --git a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx index 13556be8130..91d948f1ea1 100644 --- a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx @@ -141,23 +141,10 @@ const OAuth2AppsSettingsPageView: FC = ({ return (
- {/* - * The header sits outside the tabs, so a tab-specific action here would - * promise to act on content it navigates away from. The docs link is - * tab-agnostic, so it stays on both. - */} - {canCreateApp && activeTab === "applications" && ( - - )} - - + canCreateApp && + activeTab === "applications" && } > OAuth2 applications @@ -168,7 +155,12 @@ const OAuth2AppsSettingsPageView: FC = ({ */} Register applications to use Coder as an OAuth2 provider - {settings && ", and configure how this deployment behaves as one"}. + {settings && ", and configure how this deployment behaves as one"}.{" "} + diff --git a/site/src/pages/DeploymentSettingsPage/ObservabilitySettingsPage/ObservabilitySettingsPageView.stories.tsx b/site/src/pages/DeploymentSettingsPage/ObservabilitySettingsPage/ObservabilitySettingsPageView.stories.tsx index 87ef677ef32..bc152e37bc6 100644 --- a/site/src/pages/DeploymentSettingsPage/ObservabilitySettingsPage/ObservabilitySettingsPageView.stories.tsx +++ b/site/src/pages/DeploymentSettingsPage/ObservabilitySettingsPage/ObservabilitySettingsPageView.stories.tsx @@ -82,9 +82,16 @@ export const OSS: Story = { await expect( canvas.getByRole("link", { name: "Start trial for free" }), ).toHaveAttribute("href", "/deployment/premium"); - await expect( - canvas.getByRole("link", { name: /Read the docs/ }), - ).toHaveAttribute("href", docs("/admin/security/audit-logs")); + const docsLinks = canvas.getAllByRole("link", { name: /View docs/ }); + await expect(docsLinks).toHaveLength(2); + await expect(docsLinks[0]).toHaveAttribute( + "href", + docs("/admin/security/audit-logs"), + ); + await expect(docsLinks[1]).toHaveAttribute( + "href", + docs("/admin/monitoring"), + ); await expect( canvas.queryByText("Audit Logs Retention"), ).not.toBeInTheDocument(); diff --git a/site/src/pages/DeploymentSettingsPage/ObservabilitySettingsPage/ObservabilitySettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/ObservabilitySettingsPage/ObservabilitySettingsPageView.tsx index 62b53185445..6c7f8a9ba09 100644 --- a/site/src/pages/DeploymentSettingsPage/ObservabilitySettingsPage/ObservabilitySettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/ObservabilitySettingsPage/ObservabilitySettingsPageView.tsx @@ -23,11 +23,7 @@ export const ObservabilitySettingsPageView: FC< return (
- - } - > + Observability @@ -36,7 +32,11 @@ export const ObservabilitySettingsPageView: FC< Audit Logging - Allow auditors to monitor user operations in your deployment. + Allow auditors to monitor user operations in your deployment.{" "} + @@ -66,7 +66,11 @@ export const ObservabilitySettingsPageView: FC< Monitoring - Monitoring your Coder application with logs and metrics. + Monitoring your Coder application with logs and metrics.{" "} + diff --git a/site/src/pages/DeploymentSettingsPage/OverviewPage/OverviewPageView.stories.tsx b/site/src/pages/DeploymentSettingsPage/OverviewPage/OverviewPageView.stories.tsx index f6f84b222c1..d07aa4255ea 100644 --- a/site/src/pages/DeploymentSettingsPage/OverviewPage/OverviewPageView.stories.tsx +++ b/site/src/pages/DeploymentSettingsPage/OverviewPage/OverviewPageView.stories.tsx @@ -1,5 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, within } from "storybook/test"; import { MockDeploymentDAUResponse } from "#/testHelpers/entities"; +import { docs } from "#/utils/docs"; import { OverviewPageView } from "./OverviewPageView"; const meta: Meta = { @@ -44,7 +46,14 @@ const meta: Meta = { export default meta; type Story = StoryObj; -export const Page: Story = {}; +export const Page: Story = { + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await expect( + canvas.getByRole("link", { name: /View docs/ }), + ).toHaveAttribute("href", docs("/admin/setup")); + }, +}; export const allExperimentsEnabled: Story = { args: { diff --git a/site/src/pages/DeploymentSettingsPage/OverviewPage/OverviewPageView.tsx b/site/src/pages/DeploymentSettingsPage/OverviewPage/OverviewPageView.tsx index 4a2c75fa4b4..87dfc033e5c 100644 --- a/site/src/pages/DeploymentSettingsPage/OverviewPage/OverviewPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/OverviewPage/OverviewPageView.tsx @@ -32,12 +32,11 @@ export const OverviewPageView: FC = ({ }) => { return ( <> - } - > + General - Information about your Coder deployment. + Information about your Coder deployment.{" "} + diff --git a/site/src/pages/DeploymentSettingsPage/PremiumPage/PremiumPage.tsx b/site/src/pages/DeploymentSettingsPage/PremiumPage/PremiumPage.tsx index cfef257a06e..98a239b7df3 100644 --- a/site/src/pages/DeploymentSettingsPage/PremiumPage/PremiumPage.tsx +++ b/site/src/pages/DeploymentSettingsPage/PremiumPage/PremiumPage.tsx @@ -49,17 +49,14 @@ const PremiumPage: FC = () => { <> Codestin Search App - - Review Coder system requirements - - } - > + Start a Coder trial For enterprises ready to achieve world-class security, scalability, - and developer experience. + and developer experience.{" "} + + Review Coder system requirements + = ({ Security - Ensure your Coder deployment is secure. + Ensure your Coder deployment is secure.{" "} + @@ -57,14 +61,12 @@ export const SecuritySettingsPageView: FC = ({
- - } - > - + + Browser-Only Connections{" "} {featureBrowserOnlyEnabled ? : } @@ -72,13 +74,14 @@ export const SecuritySettingsPageView: FC = ({ Block all workspace access via SSH, port forward, and other - non-browser connections. + non-browser connections.{" "} + - - {featureBrowserOnlyEnabled ? : } - {!isBrowserOnlyEntitled ? ( = { export default meta; type Story = StoryObj; -export const Page: Story = {}; +export const Page: Story = { + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const docsLinks = canvas.getAllByRole("link", { name: /View docs/ }); + await expect(docsLinks).toHaveLength(2); + await expect(docsLinks[0]).toHaveAttribute( + "href", + docs("/admin/users/oidc-auth"), + ); + await expect(docsLinks[1]).toHaveAttribute( + "href", + docs("/admin/users/github-auth"), + ); + }, +}; diff --git a/site/src/pages/DeploymentSettingsPage/UserAuthSettingsPage/UserAuthSettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/UserAuthSettingsPage/UserAuthSettingsPageView.tsx index 1a5087d95cb..c460292d9c6 100644 --- a/site/src/pages/DeploymentSettingsPage/UserAuthSettingsPage/UserAuthSettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/UserAuthSettingsPage/UserAuthSettingsPageView.tsx @@ -39,16 +39,16 @@ export const UserAuthSettingsPageView = ({ User Authentication - - } - > + Login with OpenID Connect - Set up authentication to login with OpenID Connect. + Set up authentication to login with OpenID Connect.{" "} + @@ -64,16 +64,16 @@ export const UserAuthSettingsPageView = ({
- - } - > + Login with GitHub - Set up authentication to login with GitHub. + Set up authentication to login with GitHub.{" "} + diff --git a/site/src/pages/GroupsPage/GroupsPage.tsx b/site/src/pages/GroupsPage/GroupsPage.tsx index fcf2eff29e4..cf0ff7fbef9 100644 --- a/site/src/pages/GroupsPage/GroupsPage.tsx +++ b/site/src/pages/GroupsPage/GroupsPage.tsx @@ -113,15 +113,12 @@ const GroupsPage: FC = () => {
{title} - - } - > + Groups Manage groups for this{" "} - {showOrganizations ? "organization" : "deployment"}. + {showOrganizations ? "organization" : "deployment"}.{" "} + diff --git a/site/src/pages/OrganizationSettingsPage/CreateOrganizationPageView.stories.tsx b/site/src/pages/OrganizationSettingsPage/CreateOrganizationPageView.stories.tsx index 453db8c8aca..206e31f1b3f 100644 --- a/site/src/pages/OrganizationSettingsPage/CreateOrganizationPageView.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/CreateOrganizationPageView.stories.tsx @@ -36,7 +36,7 @@ export const NotEntitled: Story = { const canvas = within(canvasElement); await expect( - canvas.getByRole("link", { name: /Read the docs/ }), + canvas.getByRole("link", { name: /View docs/ }), ).toHaveAttribute("href", docs("/admin/users/organizations")); const cta = canvas.getByRole("link", { name: "Start trial for free" }); await expect(cta).toHaveAttribute("href", "/deployment/premium"); diff --git a/site/src/pages/OrganizationSettingsPage/CreateOrganizationPageView.tsx b/site/src/pages/OrganizationSettingsPage/CreateOrganizationPageView.tsx index 5e17adcce6d..76667e5cdec 100644 --- a/site/src/pages/OrganizationSettingsPage/CreateOrganizationPageView.tsx +++ b/site/src/pages/OrganizationSettingsPage/CreateOrganizationPageView.tsx @@ -76,9 +76,6 @@ export const CreateOrganizationPageView: FC< Go Back
-
- -
{Boolean(error) && !isApiValidationError(error) && ( @@ -97,7 +94,10 @@ export const CreateOrganizationPageView: FC<

New Organization

Organize your deployment into multiple platform teams with unique - provisioners, templates, groups, and members. + provisioners, templates, groups, and members.{" "} +

diff --git a/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CustomRolesPage.tsx b/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CustomRolesPage.tsx index 611117319c4..059fe7cd8a4 100644 --- a/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CustomRolesPage.tsx +++ b/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CustomRolesPage.tsx @@ -82,14 +82,11 @@ const CustomRolesPage: FC = () => { - - } - > + Roles - Manage roles for this organization. + Manage roles for this organization.{" "} + diff --git a/site/src/pages/OrganizationSettingsPage/IdpSyncPage/IdpSyncPage.tsx b/site/src/pages/OrganizationSettingsPage/IdpSyncPage/IdpSyncPage.tsx index 3fb537523c1..46511527dda 100644 --- a/site/src/pages/OrganizationSettingsPage/IdpSyncPage/IdpSyncPage.tsx +++ b/site/src/pages/OrganizationSettingsPage/IdpSyncPage/IdpSyncPage.tsx @@ -123,15 +123,12 @@ const IdpSyncPage: FC = () => {
{title} - - } - > + IdP Sync Automatically assign groups or roles to a user based on their IdP - claims. + claims.{" "} + {!isIdpSyncEnabled ? ( diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.stories.tsx index a7854060d3d..2c573f2f45c 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.stories.tsx @@ -3,6 +3,7 @@ import { useState } from "react"; import { expect, fn, userEvent, waitFor, within } from "storybook/test"; import type { ProvisionerJob } from "#/api/typesGenerated"; import { MockOrganization, MockProvisionerJob } from "#/testHelpers/entities"; +import { docs } from "#/utils/docs"; import { daysAgo } from "#/utils/time"; import OrganizationProvisionerJobsPageView from "./OrganizationProvisionerJobsPageView"; @@ -29,7 +30,17 @@ const meta: Meta = { export default meta; type Story = StoryObj; -export const Default: Story = {}; +export const Default: Story = { + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await expect( + canvas.getByRole("link", { name: /View docs/ }), + ).toHaveAttribute( + "href", + docs("/admin/provisioners/manage-provisioner-jobs"), + ); + }, +}; export const OrganizationNotFound: Story = { args: { diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx index 8d09ad1b6e3..42bd3437ea4 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx @@ -110,7 +110,9 @@ const OrganizationProvisionerJobsPageView: FC< Provisioner Jobs are the individual tasks assigned to Provisioners when the workspaces are being built.{" "} - View docs + + View docs + diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerKeysPage/OrganizationProvisionerKeysPageView.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerKeysPage/OrganizationProvisionerKeysPageView.stories.tsx index ce34141fe94..1b905046cf8 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerKeysPage/OrganizationProvisionerKeysPageView.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerKeysPage/OrganizationProvisionerKeysPageView.stories.tsx @@ -101,7 +101,7 @@ export const Paywalled: Story = { const cta = canvas.getByRole("link", { name: "Start trial for free" }); await expect(cta).toHaveAttribute("href", "/deployment/premium"); await expect( - canvas.getByRole("link", { name: /Read the docs/ }), + canvas.getByRole("link", { name: /View docs/ }), ).toHaveAttribute("href", docs("/admin/provisioners")); }, }; diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerKeysPage/OrganizationProvisionerKeysPageView.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerKeysPage/OrganizationProvisionerKeysPageView.tsx index da9be24980a..4800dc1a101 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerKeysPage/OrganizationProvisionerKeysPageView.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerKeysPage/OrganizationProvisionerKeysPageView.tsx @@ -51,12 +51,11 @@ export const OrganizationProvisionerKeysPageView: FC< return (
- } - > + Provisioner Keys - Manage provisioner keys used to authenticate provisioner instances. + Manage provisioner keys used to authenticate provisioner instances.{" "} + diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage/OrganizationProvisionersPageView.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage/OrganizationProvisionersPageView.stories.tsx index 340a75608bd..36f38e98d2a 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage/OrganizationProvisionersPageView.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage/OrganizationProvisionersPageView.stories.tsx @@ -77,7 +77,7 @@ export const Paywall: Story = { const cta = canvas.getByRole("link", { name: "Start trial for free" }); await expect(cta).toHaveAttribute("href", "/deployment/premium"); await expect( - canvas.getByRole("link", { name: /Read the docs/ }), + canvas.getByRole("link", { name: /View docs/ }), ).toHaveAttribute("href", docs("/admin/provisioners")); }, }; diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage/OrganizationProvisionersPageView.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage/OrganizationProvisionersPageView.tsx index 916765ef8a8..8389ca33a7c 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage/OrganizationProvisionersPageView.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage/OrganizationProvisionersPageView.tsx @@ -61,13 +61,12 @@ export const OrganizationProvisionersPageView: FC< }) => { return (
- } - > + Provisioners Coder server runs provisioner daemons which execute terraform during - workspace and template builds. + workspace and template builds.{" "} + diff --git a/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPage.tsx b/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPage.tsx index aaef36b2896..99ad3485e07 100644 --- a/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPage.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPage.tsx @@ -41,16 +41,13 @@ const TemplatePermissionsPage: FC = () => { Codestin Search App
- + Permissions + + Manage which members and groups can use this template.{" "} - } - > - Permissions - - Manage which members and groups can use this template. diff --git a/site/src/pages/UserSettingsPage/SecretsPage/SecretsPageView.stories.tsx b/site/src/pages/UserSettingsPage/SecretsPage/SecretsPageView.stories.tsx index 6c440a44365..d6c5c5688e0 100644 --- a/site/src/pages/UserSettingsPage/SecretsPage/SecretsPageView.stories.tsx +++ b/site/src/pages/UserSettingsPage/SecretsPage/SecretsPageView.stories.tsx @@ -109,7 +109,7 @@ export const Loaded: Story = { await expect(canvas.getByText("env var + file")).toBeInTheDocument(); await expect(canvas.getByText("not injected")).toBeInTheDocument(); - const docsLink = canvas.getByRole("link", { name: "Read the docs" }); + const docsLink = canvas.getByRole("link", { name: /View docs/ }); await expect(docsLink).toHaveAttribute( "href", expect.stringContaining("/user-guides/user-secrets"), diff --git a/site/src/pages/UserSettingsPage/SecretsPage/SecretsPageView.tsx b/site/src/pages/UserSettingsPage/SecretsPage/SecretsPageView.tsx index cfac6530ab9..5d356592e8e 100644 --- a/site/src/pages/UserSettingsPage/SecretsPage/SecretsPageView.tsx +++ b/site/src/pages/UserSettingsPage/SecretsPage/SecretsPageView.tsx @@ -1,4 +1,4 @@ -import { PlusIcon, SquareArrowOutUpRightIcon } from "lucide-react"; +import { PlusIcon } from "lucide-react"; import { type FC, useRef, useState } from "react"; import type { CreateUserSecretRequest, @@ -11,6 +11,7 @@ import { Button } from "#/components/Button/Button"; import { SettingsHeader, SettingsHeaderDescription, + SettingsHeaderDocsLink, SettingsHeaderTitle, } from "#/components/SettingsHeader/SettingsHeader"; import { docs } from "#/utils/docs"; @@ -86,29 +87,18 @@ export const SecretsPageView: FC = ({
- - -
+ } > Secrets Secrets with an environment variable or file path are injected into workspaces you own when they start. Each environment variable and file - path must be unique. + path must be unique.{" "} + diff --git a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.stories.tsx b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.stories.tsx index fd782de8a03..f95f3269bb3 100644 --- a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.stories.tsx +++ b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.stories.tsx @@ -8,6 +8,7 @@ import { MockWorkspaceProxies, mockApiError, } from "#/testHelpers/entities"; +import { docs } from "#/utils/docs"; import { WorkspaceProxyView } from "./WorkspaceProxyView"; const meta: Meta = { @@ -30,6 +31,12 @@ export const PrimarySelected: Story = { proxyLatencies: MockProxyLatencies, preferredProxy: MockPrimaryWorkspaceProxy, }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await expect( + canvas.getByRole("link", { name: /View docs/ }), + ).toHaveAttribute("href", docs("/admin/networking/workspace-proxies")); + }, }; export const Example: Story = { diff --git a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx index db6402b6717..e3636135008 100644 --- a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx +++ b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx @@ -46,17 +46,14 @@ export const WorkspaceProxyView: FC = ({ }) => { return (
- - } - > + Workspace Proxies Workspace proxies improve terminal and web app connections to - workspaces. + workspaces.{" "} + diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceSharingPage/WorkspaceSharingPageView.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceSharingPage/WorkspaceSharingPageView.tsx index 6329d2f73cb..b719afb1272 100644 --- a/site/src/pages/WorkspaceSettingsPage/WorkspaceSharingPage/WorkspaceSharingPageView.tsx +++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceSharingPage/WorkspaceSharingPageView.tsx @@ -59,16 +59,13 @@ export const WorkspaceSharingPageView: FC = ({ }) => { return (
- + Sharing + + Share this workspace with other users and groups.{" "} - } - > - Sharing - - Share this workspace with other users and groups.