import { faArrowLeft, faPlay } from "@fortawesome/free-solid-svg-icons"; import { useEventBus } from "@vueuse/core"; import { GalaxyApi } from "@/api"; import type { WorkflowInvocation } from "@/api/invocations"; import type { StoredWorkflowDetailed } from "@/api/workflows"; import { useUserStore } from "@/stores/userStore"; import { useWorkflowStore } from "@/stores/workflowStore"; import _l from "@/utils/localization"; import { rethrowSimple } from "@/utils/simple-error"; import type { ActionArray, FieldArray, GridConfig } from "./types"; const { emit } = useEventBus("grid-router-push"); /** * Local types */ type SortKeyLiteral = "create_time" | "update_time" | "None" | null | undefined; /** * Request and return invocations for the given history (and current user) from server */ async function getData( offset: number, limit: number, search: string, sort_by: string, sort_desc: boolean, extraProps?: Record, ) { const userStore = useUserStore(); if (userStore.currentUser?.isAnonymous || !userStore.currentUser || !extraProps || !extraProps["history_id"]) { // TODO: maybe raise an error here? return [[], 0]; } const historyId = extraProps["history_id"] as string; const { response, data, error } = await GalaxyApi().GET("/api/invocations", { params: { query: { limit, offset, sort_by: sort_by as SortKeyLiteral, sort_desc, user_id: userStore.currentUser.id, include_nested_invocations: false, history_id: historyId, }, }, }); if (error) { rethrowSimple(error); } fetchHistories(data); const totalMatches = parseInt(response.headers.get("total_matches") ?? "0"); return [data, totalMatches]; } /** * Fetch workflows for the given history's invocations, if not already loaded, * so that they are cached and names are available for display in the grid */ function fetchHistories(invocations: Array) { const workflowStore = useWorkflowStore(); const workflowIds: Set = new Set(); invocations.forEach((invocation) => { workflowIds.add(invocation.workflow_id); }); workflowIds.forEach((workflow_id) => workflowStore.fetchWorkflowForInstanceIdCached(workflow_id)); } /** * Actions are grid-wide operations */ const actions: ActionArray = [ { title: "Invocations List", icon: faArrowLeft, handler: () => { emit("/workflows/invocations"); }, }, ]; /** * Declare columns to be displayed */ const fields: FieldArray = [ { key: "expand", title: null, type: "expand", }, { key: "workflow_id", title: "Workflow", type: "link", handler: (data) => { const invocation = data as WorkflowInvocation; emit(`/workflows/invocations/${invocation.id}`); }, converter: (data) => { const workflowStore = useWorkflowStore(); const invocation = data as WorkflowInvocation; return workflowStore.getStoredWorkflowNameByInstanceId(invocation.workflow_id); }, }, { key: "create_time", title: "Invoked", type: "date", }, { key: "state", title: "State", type: "helptext", converter: (data) => { const invocation = data as WorkflowInvocation; return `galaxy.invocations.states.${invocation.state}`; }, }, { key: "execute", title: "Run", type: "button", icon: faPlay, condition: (data) => { const invocation = data as WorkflowInvocation; const workflowStore = useWorkflowStore(); const workflow = workflowStore.getStoredWorkflowByInstanceId( invocation.workflow_id, ) as unknown as StoredWorkflowDetailed; return !workflow?.deleted; }, handler: (data) => { const invocation = data as WorkflowInvocation; const workflowStore = useWorkflowStore(); emit(`/workflows/run?id=${workflowStore.getStoredWorkflowIdByInstanceId(invocation.workflow_id)}`); }, converter: () => "", }, ]; /** * Grid configuration */ const gridConfig: GridConfig = { id: "invocations-history-grid", actions: actions, fields: fields, getData: getData, plural: "Workflow Invocations", sortBy: "create_time", sortDesc: true, sortKeys: ["create_time"], title: "Workflow Invocations For History", }; export default gridConfig;