mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Maintain expanded state of JobStep during polling
The InvocationStepProvider updates the invocation state in 3 second intervals, and with it the jobs array. The new jobs in the array don't have the _showDetails attribute, so all expanded view will be reset. This fixes that by keeping a component local state for the _showDetails attribute.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import BootstrapVue from "bootstrap-vue";
|
||||
import JobStep from "./JobStep";
|
||||
import { mount } from "@vue/test-utils";
|
||||
import jobs from "./test/json/jobs.json";
|
||||
|
||||
jest.mock("../History/caching");
|
||||
|
||||
import { createLocalVue } from "@vue/test-utils";
|
||||
|
||||
// create an extended `Vue` constructor
|
||||
const localVue = createLocalVue();
|
||||
|
||||
// install plugins as normal
|
||||
localVue.use(BootstrapVue);
|
||||
|
||||
describe("DatasetUIWrapper.vue with Dataset", () => {
|
||||
let wrapper;
|
||||
let propsData;
|
||||
|
||||
beforeEach(async () => {
|
||||
propsData = {
|
||||
jobs: jobs,
|
||||
};
|
||||
wrapper = mount(JobStep, {
|
||||
localVue,
|
||||
propsData,
|
||||
stubs: {
|
||||
JobProvider: { template: "<div class='expanded'>I am expanded</div>" },
|
||||
},
|
||||
});
|
||||
});
|
||||
test("it renders a table with 2 jobs", async () => {
|
||||
expect(wrapper.find("tbody").findAll("tr").length).toBe(2);
|
||||
});
|
||||
test("it expands on row click", async () => {
|
||||
// verify no item is expanded
|
||||
expect(wrapper.vm.toggledItems["1"]).toBe(undefined);
|
||||
expect(wrapper.find(".expanded").exists()).toBeFalsy();
|
||||
// expand
|
||||
wrapper.find("tbody").find("tbody").find("tr").trigger("click");
|
||||
await localVue.nextTick();
|
||||
expect(wrapper.vm.toggledItems["1"]).toBeTruthy();
|
||||
expect(wrapper.find(".expanded").exists()).toBeTruthy();
|
||||
wrapper.find("tbody").find("tbody").find("tr").trigger("click");
|
||||
// close again
|
||||
await localVue.nextTick();
|
||||
expect(wrapper.vm.toggledItems["1"]).toBeFalsy();
|
||||
expect(wrapper.find(".expanded").exists()).toBeFalsy();
|
||||
});
|
||||
test("it sustains expanded on prop update", async () => {
|
||||
// verify no item is expanded
|
||||
expect(wrapper.vm.toggledItems["1"]).toBe(undefined);
|
||||
expect(wrapper.find(".expanded").exists()).toBeFalsy();
|
||||
// expand
|
||||
wrapper.find("tbody").find("tbody").find("tr").trigger("click");
|
||||
await localVue.nextTick();
|
||||
expect(wrapper.vm.toggledItems["1"]).toBeTruthy();
|
||||
expect(wrapper.find(".expanded").exists()).toBeTruthy();
|
||||
// 2 collapsed rows, plus 1 expanded row
|
||||
expect(wrapper.find("tbody").findAll("tr").length).toBe(3);
|
||||
// update data
|
||||
const additionalJob = { ...jobs[0], id: 3 };
|
||||
wrapper.setProps({ jobs: [...jobs, additionalJob] });
|
||||
await localVue.nextTick();
|
||||
// verify new data is displayed
|
||||
expect(wrapper.find("tbody").findAll("tr").length).toBe(4);
|
||||
// verify first row is still expanded
|
||||
expect(wrapper.vm.toggledItems["1"]).toBeTruthy();
|
||||
expect(wrapper.find(".expanded").exists()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,13 +1,6 @@
|
||||
<template>
|
||||
<b-card v-if="jobs">
|
||||
<b-table
|
||||
small
|
||||
caption-top
|
||||
:items="jobs"
|
||||
:fields="fields"
|
||||
v-if="jobs"
|
||||
@row-clicked="(item) => $set(item, '_showDetails', !item._showDetails)"
|
||||
>
|
||||
<b-table small caption-top :items="jobsProvider" :fields="fields" primary-key="id" @row-clicked="toggleDetails">
|
||||
<template v-slot:row-details="row">
|
||||
<job-provider
|
||||
:id="row.item.id"
|
||||
@@ -53,6 +46,31 @@ export default {
|
||||
props: {
|
||||
jobs: { type: Array, required: true },
|
||||
},
|
||||
methods: {
|
||||
jobsProvider(ctx, callback) {
|
||||
// It may seem unnecessary to use a provider here, since the jobs prop
|
||||
// is being updated externally. However we need to keep track of the
|
||||
// _showDetails attribute which determines whether the row is shown as expanded
|
||||
this.$watch(
|
||||
"jobs",
|
||||
function () {
|
||||
// update new jobs array with current state
|
||||
const toggledJobs = this.jobs.map((e) => {
|
||||
return { ...e, _showDetails: !!this.toggledItems[e.id] };
|
||||
});
|
||||
callback(toggledJobs);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
return null;
|
||||
},
|
||||
toggleDetails(item) {
|
||||
// toggle item
|
||||
item._showDetails = !item._showDetails;
|
||||
// update state
|
||||
this.toggledItems[item.id] = item._showDetails;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fields: [
|
||||
@@ -60,6 +78,7 @@ export default {
|
||||
{ key: "update_time", label: "Updated", sortable: true },
|
||||
{ key: "create_time", label: "Created", sortable: true },
|
||||
],
|
||||
toggledItems: {},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
[
|
||||
{
|
||||
"model_class": "Job",
|
||||
"id": "1",
|
||||
"state": "new",
|
||||
"exit_code": 0,
|
||||
"update_time": "2021-01-15T10:38:36.015269",
|
||||
"create_time": "2021-01-15T10:38:21.462106",
|
||||
"galaxy_version": "21.01",
|
||||
"tool_id": "cat_data_and_sleep",
|
||||
"history_id": "b6aaf20167e56df2"
|
||||
},
|
||||
{
|
||||
"model_class": "Job",
|
||||
"id": "2",
|
||||
"state": "new",
|
||||
"exit_code": 0,
|
||||
"update_time": "2021-01-15T10:38:36.015269",
|
||||
"create_time": "2021-01-15T10:38:21.462106",
|
||||
"galaxy_version": "21.01",
|
||||
"tool_id": "cat_data_and_sleep",
|
||||
"history_id": "b6aaf20167e56df2"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user