From da84dd6e47438c2b4c7640d397afb336ac81310e Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Wed, 25 Jun 2025 17:54:29 +0000 Subject: [PATCH 1/6] refactor: move required external auth buttons to the submit side --- site/src/pages/TasksPage/TasksPage.tsx | 130 ++++++++++++++----------- 1 file changed, 74 insertions(+), 56 deletions(-) diff --git a/site/src/pages/TasksPage/TasksPage.tsx b/site/src/pages/TasksPage/TasksPage.tsx index f86979f8eae00..1abb4501c53fa 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 { @@ -39,7 +38,7 @@ import { import { useAuthenticated } from "hooks"; import { useExternalAuth } from "hooks/useExternalAuth"; -import { RotateCcwIcon, SendIcon } from "lucide-react"; +import { AlertTriangleIcon, 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"; @@ -52,10 +51,12 @@ import { pageTitle } from "utils/page"; import { relativeTime } from "utils/time"; import { ExternalAuthButton } from "../CreateWorkspacePage/ExternalAuthButton"; import { type UserOption, UsersCombobox } from "./UsersCombobox"; +import { ExternalImage } from "components/ExternalImage/ExternalImage"; type TasksFilter = { user: UserOption | undefined; }; + const TasksPage: FC = () => { const { user, permissions } = useAuthenticated(); const [filter, setFilter] = useState({ @@ -201,21 +202,20 @@ type TaskFormProps = { const TaskForm: FC = ({ templates }) => { const { user } = useAuthenticated(); const queryClient = useQueryClient(); - - const [templateId, setTemplateId] = useState(templates[0].id); - const { - externalAuth, - externalAuthPollingState, - startPollingExternalAuth, - isLoadingExternalAuth, - externalAuthError, - } = useExternalAuth( - templates.find((t) => t.id === templateId)?.active_version_id, + const [selectedTemplateId, setSelectedTemplateId] = useState( + templates[0].id, ); - - const hasAllRequiredExternalAuth = externalAuth?.every( - (auth) => auth.optional || auth.authenticated, + const selectedTemplate = templates.find( + (t) => t.id === selectedTemplateId, + ) as Template; + const { externalAuth, isLoadingExternalAuth, externalAuthError } = + 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 +235,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 +249,12 @@ const TaskForm: FC = ({ templates }) => { }; return ( -
- {Boolean(externalAuthError) && } + + {externalAuthError && }
= ({ templates }) => {
- +
+ {missedExternalAuth && isMissingExternalAuth && ( + + )} + + +
+ + ); +}; - {!hasAllRequiredExternalAuth && - externalAuth && - externalAuth.length > 0 && ( - - - {externalAuth.map((auth) => ( - - ))} - - - )} - +type ExternalAuthButtonProps = { + template: Template; + missedExternalAuth: TemplateVersionExternalAuth[]; +}; + +const ExternalAuthButtons: FC = ({ + template, + missedExternalAuth, +}) => { + const { startPollingExternalAuth, isLoadingExternalAuth } = useExternalAuth( + template.active_version_id, ); + + return missedExternalAuth.map((auth) => { + return ( + + ); + }); }; type TasksFilterProps = { From db8a91b57f1ebe0104a941dc352e0bfc894ad688 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Wed, 25 Jun 2025 18:10:08 +0000 Subject: [PATCH 2/6] fmt --- site/src/pages/TasksPage/TasksPage.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/site/src/pages/TasksPage/TasksPage.tsx b/site/src/pages/TasksPage/TasksPage.tsx index 1abb4501c53fa..b9652b09a8819 100644 --- a/site/src/pages/TasksPage/TasksPage.tsx +++ b/site/src/pages/TasksPage/TasksPage.tsx @@ -36,9 +36,10 @@ import { TableRowSkeleton, } from "components/TableLoader/TableLoader"; +import { ExternalImage } from "components/ExternalImage/ExternalImage"; import { useAuthenticated } from "hooks"; import { useExternalAuth } from "hooks/useExternalAuth"; -import { AlertTriangleIcon, RotateCcwIcon, SendIcon } from "lucide-react"; +import { 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"; @@ -49,9 +50,7 @@ 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"; -import { ExternalImage } from "components/ExternalImage/ExternalImage"; type TasksFilter = { user: UserOption | undefined; From 8a12f602fc8f87b18093d1560b0aed1af96ed77a Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 26 Jun 2025 19:52:38 +0000 Subject: [PATCH 3/6] Apply asher's review comments --- site/src/hooks/useExternalAuth.ts | 1 + site/src/pages/TasksPage/TasksPage.tsx | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) 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.tsx b/site/src/pages/TasksPage/TasksPage.tsx index b9652b09a8819..a1cdf39f78f0a 100644 --- a/site/src/pages/TasksPage/TasksPage.tsx +++ b/site/src/pages/TasksPage/TasksPage.tsx @@ -207,7 +207,7 @@ const TaskForm: FC = ({ templates }) => { const selectedTemplate = templates.find( (t) => t.id === selectedTemplateId, ) as Template; - const { externalAuth, isLoadingExternalAuth, externalAuthError } = + const { externalAuth, externalAuthError, isPollingExternalAuth } = useExternalAuth(selectedTemplate.active_version_id); const missedExternalAuth = externalAuth?.filter( (auth) => !auth.optional && !auth.authenticated, @@ -294,7 +294,7 @@ const TaskForm: FC = ({ templates }) => {
- {missedExternalAuth && isMissingExternalAuth && ( + {missedExternalAuth && ( = ({ templates }) => { ); }); From a6ff6850b5dbaf99218ae42419954ec893e97ff0 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 26 Jun 2025 20:16:20 +0000 Subject: [PATCH 4/6] Add retry --- site/src/pages/TasksPage/TasksPage.tsx | 72 +++++++++++++++++++------- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/site/src/pages/TasksPage/TasksPage.tsx b/site/src/pages/TasksPage/TasksPage.tsx index a1cdf39f78f0a..c47708d43225e 100644 --- a/site/src/pages/TasksPage/TasksPage.tsx +++ b/site/src/pages/TasksPage/TasksPage.tsx @@ -39,7 +39,7 @@ import { import { ExternalImage } from "components/ExternalImage/ExternalImage"; 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"; @@ -51,6 +51,12 @@ import TextareaAutosize from "react-textarea-autosize"; import { pageTitle } from "utils/page"; import { relativeTime } from "utils/time"; import { type UserOption, UsersCombobox } from "./UsersCombobox"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "components/Tooltip/Tooltip"; type TasksFilter = { user: UserOption | undefined; @@ -325,27 +331,55 @@ const ExternalAuthButtons: FC = ({ template, missedExternalAuth, }) => { - const { startPollingExternalAuth, isPollingExternalAuth } = useExternalAuth( - template.active_version_id, - ); + const { + startPollingExternalAuth, + isPollingExternalAuth, + externalAuthPollingState, + } = useExternalAuth(template.active_version_id); + const shouldRetry = externalAuthPollingState === "abandoned"; return missedExternalAuth.map((auth) => { return ( - +
+ + + {shouldRetry && !auth.authenticated && ( + + + + + + + Retry connect to {auth.display_name} + + + + )} +
); }); }; From 2c2be532cc47cf23c71dec3015b6122c0520959b Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 26 Jun 2025 20:33:18 +0000 Subject: [PATCH 5/6] fmt --- site/src/pages/TasksPage/TasksPage.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/site/src/pages/TasksPage/TasksPage.tsx b/site/src/pages/TasksPage/TasksPage.tsx index c47708d43225e..212d9bce493dc 100644 --- a/site/src/pages/TasksPage/TasksPage.tsx +++ b/site/src/pages/TasksPage/TasksPage.tsx @@ -37,6 +37,12 @@ import { } 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 { RedoIcon, RotateCcwIcon, SendIcon } from "lucide-react"; @@ -51,12 +57,6 @@ import TextareaAutosize from "react-textarea-autosize"; import { pageTitle } from "utils/page"; import { relativeTime } from "utils/time"; import { type UserOption, UsersCombobox } from "./UsersCombobox"; -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from "components/Tooltip/Tooltip"; type TasksFilter = { user: UserOption | undefined; From d294d9bf85270025dff6ec8f1b4feb9399e69905 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 27 Jun 2025 13:37:34 +0000 Subject: [PATCH 6/6] Apply Asher's comments --- site/src/pages/TasksPage/TasksPage.stories.tsx | 2 +- site/src/pages/TasksPage/TasksPage.tsx | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) 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 212d9bce493dc..10781434e5358 100644 --- a/site/src/pages/TasksPage/TasksPage.tsx +++ b/site/src/pages/TasksPage/TasksPage.tsx @@ -213,8 +213,12 @@ const TaskForm: FC = ({ templates }) => { const selectedTemplate = templates.find( (t) => t.id === selectedTemplateId, ) as Template; - const { externalAuth, externalAuthError, isPollingExternalAuth } = - useExternalAuth(selectedTemplate.active_version_id); + const { + externalAuth, + externalAuthError, + isPollingExternalAuth, + isLoadingExternalAuth, + } = useExternalAuth(selectedTemplate.active_version_id); const missedExternalAuth = externalAuth?.filter( (auth) => !auth.optional && !auth.authenticated, ); @@ -309,7 +313,11 @@ const TaskForm: FC = ({ templates }) => { - Retry connect to {auth.display_name} + Retry connecting to {auth.display_name} 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