FE Auth vendor changes (#270)
This commit is contained in:
@@ -18,7 +18,9 @@ export function setAuthorizationHeader(token: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function removeAuthorizationHeader() {
|
export function removeAuthorizationHeader() {
|
||||||
delete client.defaults.headers.common["Authorization"];
|
if (client.defaults.headers.common["Authorization"]) {
|
||||||
|
delete client.defaults.headers.common["Authorization"];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setApiKeyHeader(apiKey: string) {
|
export function setApiKeyHeader(apiKey: string) {
|
||||||
@@ -26,7 +28,24 @@ export function setApiKeyHeader(apiKey: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function removeApiKeyHeader() {
|
export function removeApiKeyHeader() {
|
||||||
delete client.defaults.headers.common["X-API-Key"];
|
if (client.defaults.headers.common["X-API-Key"]) {
|
||||||
|
delete client.defaults.headers.common["X-API-Key"];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { client, artifactApiClient };
|
async function getClient(credentialGetter: CredentialGetter | null) {
|
||||||
|
if (credentialGetter) {
|
||||||
|
removeApiKeyHeader();
|
||||||
|
const credential = await credentialGetter();
|
||||||
|
if (!credential) {
|
||||||
|
console.warn("No credential found");
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
setAuthorizationHeader(credential);
|
||||||
|
}
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CredentialGetter = () => Promise<string | null>;
|
||||||
|
|
||||||
|
export { getClient, artifactApiClient };
|
||||||
|
|||||||
15
skyvern-frontend/src/components/useThemeAsDarkOrLight.ts
Normal file
15
skyvern-frontend/src/components/useThemeAsDarkOrLight.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { useTheme } from "./useTheme";
|
||||||
|
|
||||||
|
function useThemeAsDarkOrLight(): "light" | "dark" {
|
||||||
|
const { theme: baseTheme } = useTheme();
|
||||||
|
|
||||||
|
if (baseTheme === "dark" || baseTheme === "light") {
|
||||||
|
return baseTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||||
|
? "dark"
|
||||||
|
: "light";
|
||||||
|
}
|
||||||
|
|
||||||
|
export { useThemeAsDarkOrLight };
|
||||||
9
skyvern-frontend/src/hooks/useCredentialGetter.ts
Normal file
9
skyvern-frontend/src/hooks/useCredentialGetter.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { CredentialGetterContext } from "@/store/CredentialGetterContext";
|
||||||
|
import { useContext } from "react";
|
||||||
|
|
||||||
|
function useCredentialGetter() {
|
||||||
|
const credentialGetter = useContext(CredentialGetterContext);
|
||||||
|
return credentialGetter;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { useCredentialGetter };
|
||||||
@@ -3,10 +3,9 @@ import { ExitIcon, PersonIcon } from "@radix-ui/react-icons";
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
name: string;
|
name: string;
|
||||||
onLogout?: () => void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function Profile({ name, onLogout }: Props) {
|
function Profile({ name }: Props) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center border-2 p-2 rounded-lg">
|
<div className="flex items-center border-2 p-2 rounded-lg">
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
@@ -14,13 +13,7 @@ function Profile({ name, onLogout }: Props) {
|
|||||||
<p className="w-40 overflow-hidden text-ellipsis">{name}</p>
|
<p className="w-40 overflow-hidden text-ellipsis">{name}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button variant="outline" size="icon">
|
||||||
variant="outline"
|
|
||||||
size="icon"
|
|
||||||
onClick={() => {
|
|
||||||
onLogout?.();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ExitIcon className="h-4 w-4" />
|
<ExitIcon className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,11 +7,7 @@ import { Profile } from "./Profile";
|
|||||||
import { useContext } from "react";
|
import { useContext } from "react";
|
||||||
import { UserContext } from "@/store/UserContext";
|
import { UserContext } from "@/store/UserContext";
|
||||||
|
|
||||||
type Props = {
|
function RootLayout() {
|
||||||
onLogout?: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
function RootLayout({ onLogout }: Props) {
|
|
||||||
const user = useContext(UserContext);
|
const user = useContext(UserContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -30,7 +26,7 @@ function RootLayout({ onLogout }: Props) {
|
|||||||
<SideNav />
|
<SideNav />
|
||||||
{user ? (
|
{user ? (
|
||||||
<div className="absolute bottom-2 left-0 w-72 px-6 shrink-0">
|
<div className="absolute bottom-2 left-0 w-72 px-6 shrink-0">
|
||||||
<Profile name={user.name} onLogout={onLogout} />
|
<Profile name={user.name} />
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</aside>
|
</aside>
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import { NavLink } from "react-router-dom";
|
|||||||
|
|
||||||
function SideNav() {
|
function SideNav() {
|
||||||
return (
|
return (
|
||||||
<nav className="flex flex-col gap-4">
|
<nav>
|
||||||
<NavLink
|
<NavLink
|
||||||
to="create"
|
to="create"
|
||||||
className={({ isActive }) => {
|
className={({ isActive }) => {
|
||||||
return cn(
|
return cn(
|
||||||
"flex items-center px-6 py-2 hover:bg-primary-foreground rounded-2xl",
|
"flex items-center px-6 py-4 hover:bg-primary-foreground rounded-2xl",
|
||||||
{
|
{
|
||||||
"bg-primary-foreground": isActive,
|
"bg-primary-foreground": isActive,
|
||||||
},
|
},
|
||||||
@@ -27,7 +27,7 @@ function SideNav() {
|
|||||||
to="tasks"
|
to="tasks"
|
||||||
className={({ isActive }) => {
|
className={({ isActive }) => {
|
||||||
return cn(
|
return cn(
|
||||||
"flex items-center px-6 py-2 hover:bg-primary-foreground rounded-2xl",
|
"flex items-center px-6 py-4 hover:bg-primary-foreground rounded-2xl",
|
||||||
{
|
{
|
||||||
"bg-primary-foreground": isActive,
|
"bg-primary-foreground": isActive,
|
||||||
},
|
},
|
||||||
@@ -41,7 +41,7 @@ function SideNav() {
|
|||||||
to="settings"
|
to="settings"
|
||||||
className={({ isActive }) => {
|
className={({ isActive }) => {
|
||||||
return cn(
|
return cn(
|
||||||
"flex items-center px-6 py-2 hover:bg-primary-foreground rounded-2xl",
|
"flex items-center px-6 py-4 hover:bg-primary-foreground rounded-2xl",
|
||||||
{
|
{
|
||||||
"bg-primary-foreground": isActive,
|
"bg-primary-foreground": isActive,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
} from "../data/descriptionHelperContent";
|
} from "../data/descriptionHelperContent";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
import { client } from "@/api/AxiosClient";
|
import { getClient } from "@/api/AxiosClient";
|
||||||
import { useToast } from "@/components/ui/use-toast";
|
import { useToast } from "@/components/ui/use-toast";
|
||||||
import { InfoCircledIcon } from "@radix-ui/react-icons";
|
import { InfoCircledIcon } from "@radix-ui/react-icons";
|
||||||
import {
|
import {
|
||||||
@@ -34,6 +34,7 @@ import { ToastAction } from "@radix-ui/react-toast";
|
|||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import fetchToCurl from "fetch-to-curl";
|
import fetchToCurl from "fetch-to-curl";
|
||||||
import { apiBaseUrl, envCredential } from "@/util/env";
|
import { apiBaseUrl, envCredential } from "@/util/env";
|
||||||
|
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||||
|
|
||||||
const createNewTaskFormSchema = z.object({
|
const createNewTaskFormSchema = z.object({
|
||||||
url: z.string().url({
|
url: z.string().url({
|
||||||
@@ -68,6 +69,7 @@ function createTaskRequestObject(formValues: CreateNewTaskFormValues) {
|
|||||||
function CreateNewTaskForm({ initialValues }: Props) {
|
function CreateNewTaskForm({ initialValues }: Props) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
const credentialGetter = useCredentialGetter();
|
||||||
|
|
||||||
const form = useForm<CreateNewTaskFormValues>({
|
const form = useForm<CreateNewTaskFormValues>({
|
||||||
resolver: zodResolver(createNewTaskFormSchema),
|
resolver: zodResolver(createNewTaskFormSchema),
|
||||||
@@ -75,8 +77,9 @@ function CreateNewTaskForm({ initialValues }: Props) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationFn: (formValues: CreateNewTaskFormValues) => {
|
mutationFn: async (formValues: CreateNewTaskFormValues) => {
|
||||||
const taskRequest = createTaskRequestObject(formValues);
|
const taskRequest = createTaskRequestObject(formValues);
|
||||||
|
const client = await getClient(credentialGetter);
|
||||||
return client.post<
|
return client.post<
|
||||||
ReturnType<typeof createTaskRequestObject>,
|
ReturnType<typeof createTaskRequestObject>,
|
||||||
{ data: { task_id: string } }
|
{ data: { task_id: string } }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { client } from "@/api/AxiosClient";
|
import { getClient } from "@/api/AxiosClient";
|
||||||
import {
|
import {
|
||||||
ArtifactApiResponse,
|
ArtifactApiResponse,
|
||||||
ArtifactType,
|
ArtifactType,
|
||||||
@@ -16,6 +16,7 @@ import { TextArtifact } from "./TextArtifact";
|
|||||||
import { getImageURL } from "./artifactUtils";
|
import { getImageURL } from "./artifactUtils";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { basicTimeFormat } from "@/util/timeFormat";
|
import { basicTimeFormat } from "@/util/timeFormat";
|
||||||
|
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -24,6 +25,7 @@ type Props = {
|
|||||||
|
|
||||||
function StepArtifacts({ id, stepProps }: Props) {
|
function StepArtifacts({ id, stepProps }: Props) {
|
||||||
const { taskId } = useParams();
|
const { taskId } = useParams();
|
||||||
|
const credentialGetter = useCredentialGetter();
|
||||||
const {
|
const {
|
||||||
data: artifacts,
|
data: artifacts,
|
||||||
isFetching,
|
isFetching,
|
||||||
@@ -32,6 +34,7 @@ function StepArtifacts({ id, stepProps }: Props) {
|
|||||||
} = useQuery<Array<ArtifactApiResponse>>({
|
} = useQuery<Array<ArtifactApiResponse>>({
|
||||||
queryKey: ["task", taskId, "steps", id, "artifacts"],
|
queryKey: ["task", taskId, "steps", id, "artifacts"],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
const client = await getClient(credentialGetter);
|
||||||
return client
|
return client
|
||||||
.get(`/tasks/${taskId}/steps/${id}/artifacts`)
|
.get(`/tasks/${taskId}/steps/${id}/artifacts`)
|
||||||
.then((response) => response.data);
|
.then((response) => response.data);
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ import { StepArtifacts } from "./StepArtifacts";
|
|||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { StepApiResponse } from "@/api/types";
|
import { StepApiResponse } from "@/api/types";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { client } from "@/api/AxiosClient";
|
import { getClient } from "@/api/AxiosClient";
|
||||||
|
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||||
|
|
||||||
function StepArtifactsLayout() {
|
function StepArtifactsLayout() {
|
||||||
const [activeIndex, setActiveIndex] = useState(0);
|
const [activeIndex, setActiveIndex] = useState(0);
|
||||||
|
const credentialGetter = useCredentialGetter();
|
||||||
const { taskId } = useParams();
|
const { taskId } = useParams();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -17,6 +19,7 @@ function StepArtifactsLayout() {
|
|||||||
} = useQuery<Array<StepApiResponse>>({
|
} = useQuery<Array<StepApiResponse>>({
|
||||||
queryKey: ["task", taskId, "steps"],
|
queryKey: ["task", taskId, "steps"],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
const client = await getClient(credentialGetter);
|
||||||
return client
|
return client
|
||||||
.get(`/tasks/${taskId}/steps`)
|
.get(`/tasks/${taskId}/steps`)
|
||||||
.then((response) => response.data);
|
.then((response) => response.data);
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { client } from "@/api/AxiosClient";
|
import { getClient } from "@/api/AxiosClient";
|
||||||
import { StepApiResponse } from "@/api/types";
|
import { StepApiResponse } from "@/api/types";
|
||||||
import { cn } from "@/util/utils";
|
import { cn } from "@/util/utils";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { useParams, useSearchParams } from "react-router-dom";
|
import { useParams, useSearchParams } from "react-router-dom";
|
||||||
import { PAGE_SIZE } from "../constants";
|
import { PAGE_SIZE } from "../constants";
|
||||||
import { CheckboxIcon, CrossCircledIcon } from "@radix-ui/react-icons";
|
import { CheckboxIcon, CrossCircledIcon } from "@radix-ui/react-icons";
|
||||||
|
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
activeIndex: number;
|
activeIndex: number;
|
||||||
@@ -15,6 +16,7 @@ function StepNavigation({ activeIndex, onActiveIndexChange }: Props) {
|
|||||||
const { taskId } = useParams();
|
const { taskId } = useParams();
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const page = searchParams.get("page") ? Number(searchParams.get("page")) : 1;
|
const page = searchParams.get("page") ? Number(searchParams.get("page")) : 1;
|
||||||
|
const credentialGetter = useCredentialGetter();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: steps,
|
data: steps,
|
||||||
@@ -23,6 +25,7 @@ function StepNavigation({ activeIndex, onActiveIndexChange }: Props) {
|
|||||||
} = useQuery<Array<StepApiResponse>>({
|
} = useQuery<Array<StepApiResponse>>({
|
||||||
queryKey: ["task", taskId, "steps", page],
|
queryKey: ["task", taskId, "steps", page],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
const client = await getClient(credentialGetter);
|
||||||
return client
|
return client
|
||||||
.get(`/tasks/${taskId}/steps`, {
|
.get(`/tasks/${taskId}/steps`, {
|
||||||
params: {
|
params: {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { client } from "@/api/AxiosClient";
|
import { getClient } from "@/api/AxiosClient";
|
||||||
import { Status, TaskApiResponse } from "@/api/types";
|
import { Status, TaskApiResponse } from "@/api/types";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
@@ -20,9 +20,11 @@ import {
|
|||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
|
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||||
|
|
||||||
function TaskDetails() {
|
function TaskDetails() {
|
||||||
const { taskId } = useParams();
|
const { taskId } = useParams();
|
||||||
|
const credentialGetter = useCredentialGetter();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: task,
|
data: task,
|
||||||
@@ -32,6 +34,7 @@ function TaskDetails() {
|
|||||||
} = useQuery<TaskApiResponse>({
|
} = useQuery<TaskApiResponse>({
|
||||||
queryKey: ["task", taskId, "details"],
|
queryKey: ["task", taskId, "details"],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
const client = await getClient(credentialGetter);
|
||||||
return client.get(`/tasks/${taskId}`).then((response) => response.data);
|
return client.get(`/tasks/${taskId}`).then((response) => response.data);
|
||||||
},
|
},
|
||||||
refetchInterval: (query) => {
|
refetchInterval: (query) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { client } from "@/api/AxiosClient";
|
import { getClient } from "@/api/AxiosClient";
|
||||||
import { TaskApiResponse } from "@/api/types";
|
import { TaskApiResponse } from "@/api/types";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import {
|
import {
|
||||||
@@ -32,11 +32,13 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
|
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||||
|
|
||||||
function TaskList() {
|
function TaskList() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const page = searchParams.get("page") ? Number(searchParams.get("page")) : 1;
|
const page = searchParams.get("page") ? Number(searchParams.get("page")) : 1;
|
||||||
|
const credentialGetter = useCredentialGetter();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: tasks,
|
data: tasks,
|
||||||
@@ -46,6 +48,7 @@ function TaskList() {
|
|||||||
} = useQuery<Array<TaskApiResponse>>({
|
} = useQuery<Array<TaskApiResponse>>({
|
||||||
queryKey: ["tasks", "all", page],
|
queryKey: ["tasks", "all", page],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
const client = await getClient(credentialGetter);
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.append("page", String(page));
|
params.append("page", String(page));
|
||||||
params.append("page_size", String(PAGE_SIZE));
|
params.append("page_size", String(PAGE_SIZE));
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { client } from "@/api/AxiosClient";
|
import { getClient } from "@/api/AxiosClient";
|
||||||
import {
|
import {
|
||||||
ArtifactApiResponse,
|
ArtifactApiResponse,
|
||||||
ArtifactType,
|
ArtifactType,
|
||||||
@@ -7,12 +7,15 @@ import {
|
|||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import { keepPreviousData, useQuery } from "@tanstack/react-query";
|
import { keepPreviousData, useQuery } from "@tanstack/react-query";
|
||||||
import { getImageURL } from "../detail/artifactUtils";
|
import { getImageURL } from "../detail/artifactUtils";
|
||||||
|
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function LatestScreenshot({ id }: Props) {
|
function LatestScreenshot({ id }: Props) {
|
||||||
|
const credentialGetter = useCredentialGetter();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: artifact,
|
data: artifact,
|
||||||
isFetching,
|
isFetching,
|
||||||
@@ -20,6 +23,7 @@ function LatestScreenshot({ id }: Props) {
|
|||||||
} = useQuery<ArtifactApiResponse | undefined>({
|
} = useQuery<ArtifactApiResponse | undefined>({
|
||||||
queryKey: ["task", id, "latestScreenshot"],
|
queryKey: ["task", id, "latestScreenshot"],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
const client = await getClient(credentialGetter);
|
||||||
const steps: StepApiResponse[] = await client
|
const steps: StepApiResponse[] = await client
|
||||||
.get(`/tasks/${id}/steps`)
|
.get(`/tasks/${id}/steps`)
|
||||||
.then((response) => response.data);
|
.then((response) => response.data);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { client } from "@/api/AxiosClient";
|
import { getClient } from "@/api/AxiosClient";
|
||||||
import { Status, TaskApiResponse } from "@/api/types";
|
import { Status, TaskApiResponse } from "@/api/types";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { basicTimeFormat } from "@/util/timeFormat";
|
import { basicTimeFormat } from "@/util/timeFormat";
|
||||||
@@ -12,12 +12,16 @@ import {
|
|||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { StatusBadge } from "@/components/StatusBadge";
|
import { StatusBadge } from "@/components/StatusBadge";
|
||||||
|
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||||
|
|
||||||
function QueuedTasks() {
|
function QueuedTasks() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const credentialGetter = useCredentialGetter();
|
||||||
|
|
||||||
const { data: tasks } = useQuery<Array<TaskApiResponse>>({
|
const { data: tasks } = useQuery<Array<TaskApiResponse>>({
|
||||||
queryKey: ["tasks", "queued"],
|
queryKey: ["tasks", "queued"],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
const client = await getClient(credentialGetter);
|
||||||
return client
|
return client
|
||||||
.get("/tasks", {
|
.get("/tasks", {
|
||||||
params: {
|
params: {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { client } from "@/api/AxiosClient";
|
import { getClient } from "@/api/AxiosClient";
|
||||||
import { TaskApiResponse } from "@/api/types";
|
import { TaskApiResponse } from "@/api/types";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
@@ -12,13 +12,16 @@ import {
|
|||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { basicTimeFormat } from "@/util/timeFormat";
|
import { basicTimeFormat } from "@/util/timeFormat";
|
||||||
import { LatestScreenshot } from "./LatestScreenshot";
|
import { LatestScreenshot } from "./LatestScreenshot";
|
||||||
|
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||||
|
|
||||||
function RunningTasks() {
|
function RunningTasks() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const credentialGetter = useCredentialGetter();
|
||||||
|
|
||||||
const { data: runningTasks } = useQuery<Array<TaskApiResponse>>({
|
const { data: runningTasks } = useQuery<Array<TaskApiResponse>>({
|
||||||
queryKey: ["tasks", "running"],
|
queryKey: ["tasks", "running"],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
const client = await getClient(credentialGetter);
|
||||||
return client
|
return client
|
||||||
.get("/tasks", {
|
.get("/tasks", {
|
||||||
params: {
|
params: {
|
||||||
|
|||||||
6
skyvern-frontend/src/store/CredentialGetterContext.ts
Normal file
6
skyvern-frontend/src/store/CredentialGetterContext.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { CredentialGetter } from "@/api/AxiosClient";
|
||||||
|
import { createContext } from "react";
|
||||||
|
|
||||||
|
const CredentialGetterContext = createContext<CredentialGetter | null>(null);
|
||||||
|
|
||||||
|
export { CredentialGetterContext };
|
||||||
Reference in New Issue
Block a user