diff --git a/site/e2e/helpers.ts b/site/e2e/helpers.ts index 3a3355d18e222..3ab726f245c54 100644 --- a/site/e2e/helpers.ts +++ b/site/e2e/helpers.ts @@ -267,8 +267,13 @@ export const createTemplate = async ( ); } - await orgPicker.click(); - await page.getByText(orgName, { exact: true }).click(); + // picker is disabled if only one org is available + const pickerIsDisabled = await orgPicker.isDisabled(); + + if (!pickerIsDisabled) { + await orgPicker.click(); + await page.getByText(orgName, { exact: true }).click(); + } } const name = randomName(); diff --git a/site/src/components/OrganizationAutocomplete/OrganizationAutocomplete.stories.tsx b/site/src/components/OrganizationAutocomplete/OrganizationAutocomplete.stories.tsx new file mode 100644 index 0000000000000..87a7c544366a8 --- /dev/null +++ b/site/src/components/OrganizationAutocomplete/OrganizationAutocomplete.stories.tsx @@ -0,0 +1,55 @@ +import { action } from "@storybook/addon-actions"; +import type { Meta, StoryObj } from "@storybook/react"; +import { userEvent, within } from "@storybook/test"; +import { + MockOrganization, + MockOrganization2, + MockUser, +} from "testHelpers/entities"; +import { OrganizationAutocomplete } from "./OrganizationAutocomplete"; + +const meta: Meta = { + title: "components/OrganizationAutocomplete", + component: OrganizationAutocomplete, + args: { + onChange: action("Selected organization"), + }, +}; + +export default meta; +type Story = StoryObj; + +export const ManyOrgs: Story = { + parameters: { + showOrganizations: true, + user: MockUser, + features: ["multiple_organizations"], + permissions: { viewDeploymentConfig: true }, + queries: [ + { + key: ["organizations"], + data: [MockOrganization, MockOrganization2], + }, + ], + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const button = canvas.getByRole("button"); + await userEvent.click(button); + }, +}; + +export const OneOrg: Story = { + parameters: { + showOrganizations: true, + user: MockUser, + features: ["multiple_organizations"], + permissions: { viewDeploymentConfig: true }, + queries: [ + { + key: ["organizations"], + data: [MockOrganization], + }, + ], + }, +}; diff --git a/site/src/components/OrganizationAutocomplete/OrganizationAutocomplete.tsx b/site/src/components/OrganizationAutocomplete/OrganizationAutocomplete.tsx index 9449252bda3f2..d5135980d2dc0 100644 --- a/site/src/components/OrganizationAutocomplete/OrganizationAutocomplete.tsx +++ b/site/src/components/OrganizationAutocomplete/OrganizationAutocomplete.tsx @@ -7,7 +7,7 @@ import { organizations } from "api/queries/organizations"; import type { AuthorizationCheck, Organization } from "api/typesGenerated"; import { Avatar } from "components/Avatar/Avatar"; import { AvatarData } from "components/Avatar/AvatarData"; -import { type ComponentProps, type FC, useState } from "react"; +import { type ComponentProps, type FC, useEffect, useState } from "react"; import { useQuery } from "react-query"; export type OrganizationAutocompleteProps = { @@ -57,11 +57,26 @@ export const OrganizationAutocomplete: FC = ({ : []; } + // Unfortunate: this useEffect sets a default org value + // if only one is available and is necessary as the autocomplete loads + // its own data. Until we refactor, proceed cautiously! + useEffect(() => { + const org = options[0]; + if (options.length !== 1 || org === selected) { + return; + } + + setSelected(org); + onChange(org); + }, [options, selected, onChange]); + return (