diff --git a/site/src/hooks/useExternalAuth.ts b/site/src/hooks/useExternalAuth.ts index 942ce25fa892e..04197235289d9 100644 --- a/site/src/hooks/useExternalAuth.ts +++ b/site/src/hooks/useExternalAuth.ts @@ -50,5 +50,6 @@ export const useExternalAuth = (versionId: string | undefined) => { externalAuthPollingState, isLoadingExternalAuth, externalAuthError: error, + isPollingExternalAuth: externalAuthPollingState === "polling", }; }; diff --git a/site/src/pages/TasksPage/TasksPage.stories.tsx b/site/src/pages/TasksPage/TasksPage.stories.tsx index 287018cf5a2d7..9707532d82ded 100644 --- a/site/src/pages/TasksPage/TasksPage.stories.tsx +++ b/site/src/pages/TasksPage/TasksPage.stories.tsx @@ -245,7 +245,7 @@ export const MissingExternalAuth: Story = { }); await step("Renders external authentication", async () => { - await canvas.findByRole("button", { name: /login with github/i }); + await canvas.findByRole("button", { name: /connect to github/i }); }); }, }; diff --git a/site/src/pages/TasksPage/TasksPage.tsx b/site/src/pages/TasksPage/TasksPage.tsx index f86979f8eae00..10781434e5358 100644 --- a/site/src/pages/TasksPage/TasksPage.tsx +++ b/site/src/pages/TasksPage/TasksPage.tsx @@ -2,13 +2,12 @@ import Skeleton from "@mui/material/Skeleton"; import { API } from "api/api"; import { getErrorDetail, getErrorMessage } from "api/errors"; import { disabledRefetchOptions } from "api/queries/util"; -import type { Template } from "api/typesGenerated"; +import type { Template, TemplateVersionExternalAuth } from "api/typesGenerated"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { Avatar } from "components/Avatar/Avatar"; import { AvatarData } from "components/Avatar/AvatarData"; import { AvatarDataSkeleton } from "components/Avatar/AvatarDataSkeleton"; import { Button } from "components/Button/Button"; -import { Form, FormFields, FormSection } from "components/Form/Form"; import { displayError } from "components/GlobalSnackbar/utils"; import { Margins } from "components/Margins/Margins"; import { @@ -37,9 +36,16 @@ import { TableRowSkeleton, } from "components/TableLoader/TableLoader"; +import { ExternalImage } from "components/ExternalImage/ExternalImage"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "components/Tooltip/Tooltip"; import { useAuthenticated } from "hooks"; import { useExternalAuth } from "hooks/useExternalAuth"; -import { RotateCcwIcon, SendIcon } from "lucide-react"; +import { RedoIcon, RotateCcwIcon, SendIcon } from "lucide-react"; import { AI_PROMPT_PARAMETER_NAME, type Task } from "modules/tasks/tasks"; import { WorkspaceAppStatus } from "modules/workspaces/WorkspaceAppStatus/WorkspaceAppStatus"; import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName"; @@ -50,12 +56,12 @@ import { Link as RouterLink } from "react-router-dom"; import TextareaAutosize from "react-textarea-autosize"; import { pageTitle } from "utils/page"; import { relativeTime } from "utils/time"; -import { ExternalAuthButton } from "../CreateWorkspacePage/ExternalAuthButton"; import { type UserOption, UsersCombobox } from "./UsersCombobox"; type TasksFilter = { user: UserOption | undefined; }; + const TasksPage: FC = () => { const { user, permissions } = useAuthenticated(); const [filter, setFilter] = useState({ @@ -201,21 +207,24 @@ type TaskFormProps = { const TaskForm: FC = ({ templates }) => { const { user } = useAuthenticated(); const queryClient = useQueryClient(); - - const [templateId, setTemplateId] = useState(templates[0].id); + const [selectedTemplateId, setSelectedTemplateId] = useState( + templates[0].id, + ); + const selectedTemplate = templates.find( + (t) => t.id === selectedTemplateId, + ) as Template; const { externalAuth, - externalAuthPollingState, - startPollingExternalAuth, - isLoadingExternalAuth, externalAuthError, - } = useExternalAuth( - templates.find((t) => t.id === templateId)?.active_version_id, - ); - - const hasAllRequiredExternalAuth = externalAuth?.every( - (auth) => auth.optional || auth.authenticated, + isPollingExternalAuth, + isLoadingExternalAuth, + } = useExternalAuth(selectedTemplate.active_version_id); + const missedExternalAuth = externalAuth?.filter( + (auth) => !auth.optional && !auth.authenticated, ); + const isMissingExternalAuth = missedExternalAuth + ? missedExternalAuth.length > 0 + : true; const createTaskMutation = useMutation({ mutationFn: async ({ prompt, templateId }: CreateTaskMutationFnProps) => @@ -235,10 +244,6 @@ const TaskForm: FC = ({ templates }) => { const prompt = formData.get("prompt") as string; const templateID = formData.get("templateID") as string; - if (!prompt || !templateID) { - return; - } - try { await createTaskMutation.mutateAsync({ prompt, @@ -253,8 +258,12 @@ const TaskForm: FC = ({ templates }) => { }; return ( -
- {Boolean(externalAuthError) && } + + {externalAuthError && }
= ({ templates }) => {
- +
+ {missedExternalAuth && ( + + )} + + +
+ + ); +}; - {!hasAllRequiredExternalAuth && - externalAuth && - externalAuth.length > 0 && ( - - - {externalAuth.map((auth) => ( - - ))} - - +type ExternalAuthButtonProps = { + template: Template; + missedExternalAuth: TemplateVersionExternalAuth[]; +}; + +const ExternalAuthButtons: FC = ({ + template, + missedExternalAuth, +}) => { + const { + startPollingExternalAuth, + isPollingExternalAuth, + externalAuthPollingState, + } = useExternalAuth(template.active_version_id); + const shouldRetry = externalAuthPollingState === "abandoned"; + + return missedExternalAuth.map((auth) => { + return ( +
+ + + {shouldRetry && !auth.authenticated && ( + + + + + + + Retry connecting to {auth.display_name} + + + )} - - ); +
+ ); + }); }; type TasksFilterProps = { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy