mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-28 02:58:18 +08:00
Create ToolSuccess route and refactor component
This commit is contained in:
@@ -10,12 +10,6 @@
|
||||
<div v-if="showEntryPoints">
|
||||
<ToolEntryPoints v-for="job in entryPoints" :key="job.id" :job-id="job.id" />
|
||||
</div>
|
||||
<ToolSuccess
|
||||
v-if="showSuccess"
|
||||
:job-def="jobDef"
|
||||
:job-response="jobResponse"
|
||||
:tool-name="toolName" />
|
||||
<Webhook v-if="showSuccess" type="tool" :tool-id="jobDef.tool_id" />
|
||||
<b-modal v-model="showError" size="sm" :title="errorTitle | l" scrollable ok-only>
|
||||
<b-alert v-if="errorMessage" show variant="danger">
|
||||
{{ errorMessage }}
|
||||
@@ -108,7 +102,8 @@
|
||||
<script>
|
||||
import { getGalaxyInstance } from "app";
|
||||
import { useHistoryItemsStore } from "stores/history/historyItemsStore";
|
||||
import { mapState } from "pinia";
|
||||
import { useJobStore } from "stores/jobStore";
|
||||
import { mapState, mapActions } from "pinia";
|
||||
import { getToolFormData, updateToolFormData, submitJob } from "./services";
|
||||
import { allowCachedJobs } from "./utilities";
|
||||
import { refreshContentsWrapper } from "utils/data";
|
||||
@@ -120,10 +115,8 @@ import LoadingSpan from "components/LoadingSpan";
|
||||
import FormDisplay from "components/Form/FormDisplay";
|
||||
import FormElement from "components/Form/FormElement";
|
||||
import ToolEntryPoints from "components/ToolEntryPoints/ToolEntryPoints";
|
||||
import ToolSuccess from "./ToolSuccess";
|
||||
import ToolRecommendation from "../ToolRecommendation";
|
||||
import UserHistories from "components/providers/UserHistories";
|
||||
import Webhook from "components/Common/Webhook";
|
||||
import Heading from "components/Common/Heading";
|
||||
|
||||
export default {
|
||||
@@ -136,10 +129,8 @@ export default {
|
||||
ToolCard,
|
||||
FormElement,
|
||||
ToolEntryPoints,
|
||||
ToolSuccess,
|
||||
ToolRecommendation,
|
||||
UserHistories,
|
||||
Webhook,
|
||||
Heading,
|
||||
},
|
||||
props: {
|
||||
@@ -168,7 +159,6 @@ export default {
|
||||
showForm: false,
|
||||
showEntryPoints: false,
|
||||
showRecommendation: false,
|
||||
showSuccess: false,
|
||||
showError: false,
|
||||
showExecuting: false,
|
||||
formConfig: {},
|
||||
@@ -239,6 +229,7 @@ export default {
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useJobStore, ["saveResponseForJobId"]),
|
||||
emailAllowed(config, user) {
|
||||
return config.server_mail_configured && !user.isAnonymous;
|
||||
},
|
||||
@@ -332,9 +323,16 @@ export default {
|
||||
const nJobs = jobResponse && jobResponse.jobs ? jobResponse.jobs.length : 0;
|
||||
if (nJobs > 0) {
|
||||
this.showForm = false;
|
||||
this.showSuccess = true;
|
||||
this.jobDef = jobDef;
|
||||
this.jobResponse = jobResponse;
|
||||
const refJobId = this.jobResponse.jobs[0].id;
|
||||
const response = {
|
||||
jobDef: this.jobDef,
|
||||
jobResponse: this.jobResponse,
|
||||
toolName: this.toolName,
|
||||
};
|
||||
this.saveResponseForJobId(refJobId, response);
|
||||
this.$router.push(`/jobs/${refJobId}/success`);
|
||||
} else {
|
||||
this.showError = true;
|
||||
this.showForm = true;
|
||||
|
||||
@@ -1,79 +1,70 @@
|
||||
<template>
|
||||
<div class="donemessagelarge">
|
||||
<p>
|
||||
Started tool <b>{{ toolName }}</b> and successfully added {{ nJobsText }} to the queue.
|
||||
</p>
|
||||
<p>The tool uses {{ nInputsText }}:</p>
|
||||
<ul>
|
||||
<li v-for="item of inputs" :key="item.hid">
|
||||
<b>{{ item.hid }}: {{ item.name }}</b>
|
||||
</li>
|
||||
</ul>
|
||||
<p>It produces {{ nOutputsText }}:</p>
|
||||
<ul>
|
||||
<li v-for="item of jobResponse.outputs" :key="item.hid">
|
||||
<b>{{ item.hid }}: {{ item.name }}</b>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
You can check the status of queued jobs and view the resulting data by refreshing the History panel. When
|
||||
the job has been run the status will change from 'running' to 'finished' if completed successfully or
|
||||
'error' if problems were encountered.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
// import FormBoolean from "./Elements/FormBoolean.vue";
|
||||
import { computed, onMounted } from "vue";
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
jobDef: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
jobResponse: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
toolName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
import type { ComputedRef } from "vue";
|
||||
import { useJobStore } from "@/stores/jobStore";
|
||||
import { useRouter } from "vue-router/composables";
|
||||
import { getGalaxyInstance } from "@/app";
|
||||
import ToolEntryPoints from "@/components/ToolEntryPoints/ToolEntryPoints.vue";
|
||||
import ToolSuccessMessage from "./ToolSuccessMessage.vue";
|
||||
import ToolRecommendation from "../ToolRecommendation.vue";
|
||||
import Webhook from "@/components/Common/Webhook.vue";
|
||||
|
||||
const jobStore = useJobStore();
|
||||
const router = useRouter();
|
||||
|
||||
/* interfaces */
|
||||
interface Job {
|
||||
id: string;
|
||||
}
|
||||
interface JobDef {
|
||||
tool_id: string;
|
||||
}
|
||||
interface JobResponse {
|
||||
produces_entry_points: boolean;
|
||||
jobs: Array<Job>;
|
||||
}
|
||||
interface ResponseVal {
|
||||
jobDef: JobDef;
|
||||
jobResponse: JobResponse;
|
||||
toolName: string;
|
||||
}
|
||||
|
||||
/* props */
|
||||
const props = defineProps({
|
||||
jobId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
computed: {
|
||||
inputs() {
|
||||
const inputs = [];
|
||||
const index = {};
|
||||
for (const i in this.jobDef.inputs) {
|
||||
const input = this.jobDef.inputs[i];
|
||||
if (input && Array.isArray(input.values)) {
|
||||
for (const j of input.values) {
|
||||
if (j.src && !index[j.id]) {
|
||||
inputs.push(j);
|
||||
index[j.id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return inputs;
|
||||
},
|
||||
nInputs() {
|
||||
return this.inputs.length;
|
||||
},
|
||||
nOutputs() {
|
||||
return this.jobResponse && this.jobResponse.outputs ? this.jobResponse.outputs.length : 0;
|
||||
},
|
||||
nJobs() {
|
||||
return this.jobResponse && this.jobResponse.jobs ? this.jobResponse.jobs.length : 0;
|
||||
},
|
||||
nJobsText() {
|
||||
return this.nJobs > 1 ? `${this.nJobs} jobs` : `1 job`;
|
||||
},
|
||||
nInputsText() {
|
||||
return this.nInputs > 1 ? `${this.nInputs} inputs` : `this input`;
|
||||
},
|
||||
nOutputsText() {
|
||||
return this.nOutputs > 1 ? `${this.nOutputs} outputs` : `this output`;
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const responseVal: ComputedRef<ResponseVal> = computed(() => jobStore.getResponseForJobId(props.jobId));
|
||||
|
||||
/* lifecyle */
|
||||
onMounted(() => {
|
||||
// no response means no tool produced this job in this session (nothing in store)
|
||||
if (!responseVal.value) {
|
||||
router.push(`/jobs/${props.jobId}/view`);
|
||||
}
|
||||
});
|
||||
|
||||
const jobDef: ComputedRef<JobDef> = computed(() => responseVal.value.jobDef);
|
||||
const jobResponse: ComputedRef<JobResponse> = computed(() => responseVal.value.jobResponse);
|
||||
const toolName: ComputedRef<string> = computed(() => responseVal.value.toolName);
|
||||
|
||||
// getGalaxyInstance is not reactive
|
||||
const configEnableRecommendations = getGalaxyInstance().config.enable_tool_recommendations;
|
||||
const showRecommendation: boolean = [true, "true"].includes(configEnableRecommendations);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section v-if="responseVal">
|
||||
<div v-if="jobResponse.produces_entry_points">
|
||||
<ToolEntryPoints v-for="job in jobResponse.jobs" :key="job.id" :job-id="job.id" />
|
||||
</div>
|
||||
<ToolSuccessMessage :job-def="jobDef" :job-response="jobResponse" :tool-name="toolName" />
|
||||
<Webhook type="tool" :tool-id="jobDef.tool_id" />
|
||||
<ToolRecommendation v-if="showRecommendation" :tool-id="jobDef.tool_id" />
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div class="donemessagelarge">
|
||||
<p>
|
||||
Started tool <b>{{ toolName }}</b> and successfully added {{ nJobsText }} to the queue.
|
||||
</p>
|
||||
<p>The tool uses {{ nInputsText }}:</p>
|
||||
<ul>
|
||||
<li v-for="item of inputs" :key="item.hid">
|
||||
<b>{{ item.hid }}: {{ item.name }}</b>
|
||||
</li>
|
||||
</ul>
|
||||
<p>It produces {{ nOutputsText }}:</p>
|
||||
<ul>
|
||||
<li v-for="item of jobResponse.outputs" :key="item.hid">
|
||||
<b>{{ item.hid }}: {{ item.name }}</b>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
You can check the status of queued jobs and view the resulting data by refreshing the History panel. When
|
||||
the job has been run the status will change from 'running' to 'finished' if completed successfully or
|
||||
'error' if problems were encountered.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
jobDef: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
jobResponse: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
toolName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
inputs() {
|
||||
const inputs = [];
|
||||
const index = {};
|
||||
for (const i in this.jobDef.inputs) {
|
||||
const input = this.jobDef.inputs[i];
|
||||
if (input && Array.isArray(input.values)) {
|
||||
for (const j of input.values) {
|
||||
if (j.src && !index[j.id]) {
|
||||
inputs.push(j);
|
||||
index[j.id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return inputs;
|
||||
},
|
||||
nInputs() {
|
||||
return this.inputs.length;
|
||||
},
|
||||
nOutputs() {
|
||||
return this.jobResponse && this.jobResponse.outputs ? this.jobResponse.outputs.length : 0;
|
||||
},
|
||||
nJobs() {
|
||||
return this.jobResponse && this.jobResponse.jobs ? this.jobResponse.jobs.length : 0;
|
||||
},
|
||||
nJobsText() {
|
||||
return this.nJobs > 1 ? `${this.nJobs} jobs` : `1 job`;
|
||||
},
|
||||
nInputsText() {
|
||||
return this.nInputs > 1 ? `${this.nInputs} inputs` : `this input`;
|
||||
},
|
||||
nOutputsText() {
|
||||
return this.nOutputs > 1 ? `${this.nOutputs} outputs` : `this output`;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -46,6 +46,7 @@ import Sharing from "components/Sharing/Sharing";
|
||||
import StoredWorkflowInvocations from "components/Workflow/StoredWorkflowInvocations";
|
||||
import ToolsJson from "components/ToolsView/ToolsSchemaJson/ToolsJson";
|
||||
import ToolsList from "components/ToolsList/ToolsList";
|
||||
import ToolSuccess from "components/Tool/ToolSuccess";
|
||||
import TourList from "components/Tour/TourList";
|
||||
import TourRunner from "components/Tour/TourRunner";
|
||||
import TrsImport from "components/Workflow/Import/TrsImport";
|
||||
@@ -252,6 +253,11 @@ export function getRouter(Galaxy) {
|
||||
path: "interactivetool_entry_points/list",
|
||||
component: InteractiveTools,
|
||||
},
|
||||
{
|
||||
path: "jobs/:jobId/success",
|
||||
component: ToolSuccess,
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: "jobs/:jobId/view",
|
||||
component: JobDetails,
|
||||
|
||||
@@ -21,7 +21,6 @@ import { configStore } from "./configStore";
|
||||
import { toolStore } from "./toolStore";
|
||||
import { datasetPathDestinationStore } from "./datasetPathDestinationStore";
|
||||
import { datasetExtFilesStore } from "./datasetExtFilesStore";
|
||||
import { jobStore } from "./jobStore";
|
||||
import { collectionAttributesStore } from "./collectionAttributesStore";
|
||||
import { panelStore } from "./panelStore";
|
||||
|
||||
@@ -61,7 +60,6 @@ export function createStore() {
|
||||
dataset: datasetStore,
|
||||
datasetExtFiles: datasetExtFilesStore,
|
||||
datasetPathDestination: datasetPathDestinationStore,
|
||||
informationStore: jobStore,
|
||||
invocations: invocationStore,
|
||||
jobMetrics: jobMetricsStore,
|
||||
gridSearch: gridSearchStore,
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
export const state = {
|
||||
job: {},
|
||||
};
|
||||
|
||||
import Vue from "vue";
|
||||
import { getAppRoot } from "onload/loadConfig";
|
||||
import axios from "axios";
|
||||
|
||||
const getters = {
|
||||
job: (state) => (jobId) => {
|
||||
return state.job[jobId];
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
fetchJob: async ({ commit }, jobId) => {
|
||||
const { data } = await axios.get(`${getAppRoot()}api/jobs/${jobId}?full=true`);
|
||||
commit("saveJobForJobId", { jobId, job: data });
|
||||
},
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
saveJobForJobId: (state, { jobId, job }) => {
|
||||
Vue.set(state.job, jobId, job);
|
||||
},
|
||||
};
|
||||
|
||||
export const jobStore = {
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations,
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Requests jobs
|
||||
* Requests response generated by a tool run
|
||||
*/
|
||||
|
||||
import { defineStore } from "pinia";
|
||||
import Vue from "vue";
|
||||
import { getAppRoot } from "onload/loadConfig";
|
||||
import axios from "axios";
|
||||
|
||||
export const useJobStore = defineStore("jobStore", {
|
||||
state: () => ({
|
||||
job: {},
|
||||
responses: {},
|
||||
}),
|
||||
getters: {
|
||||
getJob: (state) => {
|
||||
return (jobId) => state.job[jobId];
|
||||
},
|
||||
getResponseForJobId: (state) => {
|
||||
return (jobId) => state.responses[jobId];
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async fetchJob(jobId) {
|
||||
const { data } = await axios.get(`${getAppRoot()}api/jobs/${jobId}?full=true`);
|
||||
this.saveJobForJobId(jobId, data);
|
||||
},
|
||||
// Setters
|
||||
saveJobForJobId(jobId, job) {
|
||||
Vue.set(this.job, jobId, job);
|
||||
},
|
||||
saveResponseForJobId(jobId, response) {
|
||||
Vue.set(this.responses, jobId, response);
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -251,6 +251,7 @@ def app_pair(global_conf, load_app_kwds=None, wsgi_preflight=True, **kwargs):
|
||||
webapp.add_client_route("/datasets/{dataset_id}/preview")
|
||||
webapp.add_client_route("/datasets/{dataset_id}/show_params")
|
||||
webapp.add_client_route("/collection/{collection_id}/edit")
|
||||
webapp.add_client_route("/jobs/{job_id}/success")
|
||||
webapp.add_client_route("/jobs/{job_id}/view")
|
||||
webapp.add_client_route("/workflows/list")
|
||||
webapp.add_client_route("/workflows/list_published")
|
||||
|
||||
Reference in New Issue
Block a user