UNPKG

@airplane/views

Version:

A React library for building Airplane views. Views components are optimized in style and functionality to produce internal apps that are easy to build and maintain.

197 lines (196 loc) 7.05 kB
import { useMutation } from "@tanstack/react-query"; import { useState, useContext, useEffect } from "react"; import { PERMISSIONS_GET } from "../../client/endpoints.js"; import { executeRunbook, isExecuteRunbookError } from "../../client/executeRunbook.js"; import { executeTaskBackground, executeTask, isExecuteTaskError } from "../../client/executeTask.js"; import { Fetcher } from "../../client/fetcher.js"; import { getSlug } from "../../components/query.js"; import { RequestDialogContext } from "../../components/requestDialog/RequestDialogProvider.js"; import { MISSING_EXECUTE_PERMISSIONS_ERROR_PREFIX } from "../../errors/formatErrors.js"; import { useRefetchTasks } from "./useRefetchTask.js"; import { RunnerScaleSignalContext } from "../context/RunnerScaleSignalProvider.js"; const useTaskOrRunbookMutation = (mutation) => { const [executedRunID, setExecutedRunID] = useState(); const slug = getTaskOrRunbookSlug(mutation); const { params, refetchTasks: refetchQuery } = mutation.mutation; const refetchTasks = useRefetchTasks(); const requestDialogContext = useContext(RequestDialogContext); const { createScaleSignal } = useContext(RunnerScaleSignalContext); useEffect(() => { async function warmupTask() { if (mutation.type !== "TASK") { return; } await createScaleSignal({ signalKey: "views_warmup", expirationDurationSeconds: 300, taskSlug: slug }); } warmupTask(); }, [slug, mutation.type, createScaleSignal]); const { data, error, isLoading, mutate } = useMutation(async (opts) => { switch (mutation.type) { case "TASK": { setExecutedRunID(void 0); const runID = await executeTaskBackground(slug, "mutation", (opts == null ? void 0 : opts.params) ?? params); if (typeof runID === "object") { throw runID; } setExecutedRunID(runID); const r = await executeTask(slug, "mutation", (opts == null ? void 0 : opts.params) ?? params, runID); if (isExecuteTaskError(r)) { throw r; } return r; } case "RUNBOOK": { const r = await executeRunbook(slug, "mutation", (opts == null ? void 0 : opts.params) ?? params); if (isExecuteRunbookError(r)) { throw r; } return r; } default: throw new Error("invalid mutation type"); } }, { onSuccess: (result, opts) => { var _a, _b; switch (mutation.type) { case "TASK": { result = result; const taskOnSuccess = (opts == null ? void 0 : opts.onSuccess) ?? ((_a = mutation.mutation) == null ? void 0 : _a.onSuccess); taskOnSuccess == null ? void 0 : taskOnSuccess(result.output, result.runID); break; } case "RUNBOOK": { result = result; const runbookOnSuccess = (opts == null ? void 0 : opts.onSuccess) ?? ((_b = mutation.mutation) == null ? void 0 : _b.onSuccess); runbookOnSuccess == null ? void 0 : runbookOnSuccess(result.sessionID); break; } default: throw new Error("invalid mutation type"); } const refetch = (opts == null ? void 0 : opts.refetchTasks) ?? refetchQuery; if (refetch) { refetchTasks(refetch); } }, onError: async (e, opts) => { var _a, _b; if (e.error.type === "AIRPLANE_INTERNAL" && e.error.message.startsWith(MISSING_EXECUTE_PERMISSIONS_ERROR_PREFIX)) { try { const showRequestDialog = await shouldShowRequestDialog(slug, mutation.type); if (showRequestDialog) { requestDialogContext.setState({ params: (opts == null ? void 0 : opts.params) ?? params ?? {}, taskSlug: mutation.type === "TASK" ? slug : void 0, runbookSlug: mutation.type === "RUNBOOK" ? slug : void 0, opened: true }); return; } } catch (shouldShowReqErr) { if (shouldShowReqErr instanceof Error) { e.error.message = `${e.error.message} (error checking request permissions: ${shouldShowReqErr.message})`; } else { e.error.message = `${e.error.message} (error checking request permissions: ${shouldShowReqErr})`; } } } switch (mutation.type) { case "TASK": { const taskOnError = (opts == null ? void 0 : opts.onError) ?? ((_a = mutation.mutation) == null ? void 0 : _a.onError); const err = e; taskOnError == null ? void 0 : taskOnError(err.output, err.error, err.runID); return e; } case "RUNBOOK": { const runbookOnError = (opts == null ? void 0 : opts.onError) ?? ((_b = mutation.mutation) == null ? void 0 : _b.onError); const err = e; runbookOnError == null ? void 0 : runbookOnError(err.error, err.sessionID); return e; } default: throw new Error("invalid mutation type"); } } }); switch (mutation.type) { case "TASK": { const taskData = data; const taskError = error; return { type: mutation.type, result: { output: (taskData == null ? void 0 : taskData.output) ?? (taskError == null ? void 0 : taskError.output), runID: executedRunID ?? (taskData == null ? void 0 : taskData.runID) ?? (taskError == null ? void 0 : taskError.runID), loading: isLoading, mutate, error: taskError == null ? void 0 : taskError.error } }; } case "RUNBOOK": { const sessionData = data; const sessionError = error; return { type: mutation.type, result: { sessionID: (sessionData == null ? void 0 : sessionData.sessionID) ?? (sessionError == null ? void 0 : sessionError.sessionID), loading: isLoading, mutate, error: sessionError == null ? void 0 : sessionError.error } }; } } }; const shouldShowRequestDialog = async (slug, mutationType) => { if (mutationType === "TASK") { const fetcher = new Fetcher(); const result = await fetcher.get(PERMISSIONS_GET, { task_slug: slug, actions: ["tasks.request_run"] }); if (result.resource["tasks.request_run"]) { return true; } } else if (mutationType === "RUNBOOK") { const fetcher = new Fetcher(); const result = await fetcher.get(PERMISSIONS_GET, { runbook_slug: slug, actions: ["trigger_requests.create"] }); if (result.resource["trigger_requests.create"]) { return true; } } return false; }; const getTaskOrRunbookSlug = (mutation) => { switch (mutation.type) { case "TASK": return getSlug(mutation.mutation); case "RUNBOOK": return mutation.mutation.slug; default: throw new Error("invalid mutation type"); } }; export { useTaskOrRunbookMutation }; //# sourceMappingURL=useTaskOrRunbookMutation.js.map