Unverified Commit 007bfb06 authored by Marius van den Beek's avatar Marius van den Beek Committed by GitHub
Browse files

Merge pull request #14182 from assuntad23/bug/14131/14136/improve-collection-progress-bar

[22.05] Show job progress bar while there are non-terminal jobs, declutter text
parents acb321bf f169f8e7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
        <h6 class="description mt-1">
            a {{ collectionLabel }} with {{ elementCount }}<b>{{ homogeneousDatatype }}</b> {{ pluralizedItem }}
        </h6>
        <CollectionProgress :summary="jobStateSummary" />
        <CollectionProgress v-if="jobStateSummary.size != 0" :summary="jobStateSummary" />
    </div>
</template>

+20 −7
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ describe("CollectionProgress", () => {
            localVue,
        });
        await wrapper.vm.$nextTick();
        expect(wrapper.find(".progress").find(".bg-warning").text()).toBe("3");
        expect(wrapper.find(".progress").find(".bg-warning").attributes("aria-valuenow")).toBe("3");
    });

    it("should correctly display states", async () => {
@@ -31,9 +31,9 @@ describe("CollectionProgress", () => {
            localVue,
        });
        await wrapper.vm.$nextTick();
        expect(wrapper.find(".progress").find(".bg-warning").text()).toBe("3");
        expect(wrapper.find(".progress").find(".bg-success").text()).toBe("1");
        expect(wrapper.find(".progress").find(".bg-danger").text()).toBe("1");
        expect(wrapper.find(".progress").find(".bg-warning").attributes("aria-valuenow")).toBe("3");
        expect(wrapper.find(".progress").find(".bg-success").attributes("aria-valuenow")).toBe("1");
        expect(wrapper.find(".progress").find(".bg-danger").attributes("aria-valuenow")).toBe("1");
    });

    it("should update as dataset states change", async () => {
@@ -46,13 +46,26 @@ describe("CollectionProgress", () => {
            localVue,
        });
        await wrapper.vm.$nextTick();
        expect(wrapper.find(".progress").find(".bg-warning").text()).toBe("3");
        expect(wrapper.find(".progress").find(".bg-warning").attributes("aria-valuenow")).toBe("3");
        dsc["job_state_summary"]["ok"] = 2;
        dsc["job_state_summary"]["running"] = 1;
        jobStateSummary = new JobStateSummary(dsc);
        await wrapper.setProps({ summary: jobStateSummary });
        await wrapper.vm.$nextTick();
        expect(wrapper.find(".progress").find(".bg-warning").text()).toBe("1");
        expect(wrapper.find(".progress").find(".bg-success").text()).toBe("2");
        expect(wrapper.find(".progress").find(".bg-warning").attributes("aria-valuenow")).toBe("1");
        expect(wrapper.find(".progress").find(".bg-success").attributes("aria-valuenow")).toBe("2");
    });

    it("should be visible when all jobs are queued", async () => {
        const dsc = { job_state_summary: { all_jobs: 3, queued: 3 }, populated_state: {} };
        const jobStateSummary = new JobStateSummary(dsc);
        wrapper = mount(CollectionProgress, {
            propsData: {
                summary: jobStateSummary,
            },
            localVue,
        });
        await wrapper.vm.$nextTick();
        expect(wrapper.find(".progress").find(".bg-secondary").attributes("aria-valuenow")).toBe("3");
    });
});
+21 −26
Original line number Diff line number Diff line
@@ -3,11 +3,27 @@ at components/JobStates/CollectionJobStates but it relies on the backbone data
model, so probably has to go eventually.-->
<template>
    <div class="collection-progress">
        <b-progress v-if="maxJobs && runningJobs" :max="maxJobs" show-value>
            <b-progress-bar v-if="errorJobs" :value="errorJobs" variant="danger" />
            <b-progress-bar v-if="okJobs" :value="okJobs" variant="success" />
            <b-progress-bar v-if="runningJobs" :value="runningJobs" variant="warning" />
            <b-progress-bar v-if="waitingJobs" :value="waitingJobs" variant="secondary" />
        <b-progress v-if="!summary.isTerminal" :max="summary.jobCount">
            <b-progress-bar
                v-if="summary.errorCount"
                v-b-tooltip.hover="summary.errorCountText"
                :value="summary.errorCount"
                variant="danger" />
            <b-progress-bar
                v-if="summary.okCount"
                v-b-tooltip.hover="summary.okCountText"
                :value="summary.okCount"
                variant="success" />
            <b-progress-bar
                v-if="summary.runningCount"
                v-b-tooltip.hover="summary.runningCountText"
                :value="summary.runningCount"
                variant="warning" />
            <b-progress-bar
                v-if="summary.waitingCount"
                v-b-tooltip.hover="summary.waitingCountText"
                :value="summary.waitingCount"
                variant="secondary" />
        </b-progress>
    </div>
</template>
@@ -18,26 +34,5 @@ export default {
    props: {
        summary: { type: JobStateSummary, required: true },
    },
    computed: {
        maxJobs() {
            return this.summary.get("all_jobs");
        },
        okJobs() {
            return this.summary.get("ok");
        },
        runningJobs() {
            return this.summary.get("running");
        },
        errorJobs() {
            const failed = this.summary.get("failed") || 0;
            const error = this.summary.get("error") || 0;
            return failed + error;
        },
        waitingJobs() {
            const queued = this.summary.get("queued") || 0;
            const waiting = this.summary.get("waiting") || 0;
            return queued + waiting;
        },
    },
};
</script>
+40 −12
Original line number Diff line number Diff line
@@ -6,8 +6,8 @@
 */
import { STATES } from "../model/states";

const NON_TERMINAL_STATES = [STATES.NEW, STATES.WAITING, STATES.QUEUED, STATES.RUNNING];
const ERROR_STATES = [STATES.ERROR, STATES.DELETED];
const NON_TERMINAL_STATES = ["new", "waiting", "queued", "running", "resubmitted", "upload"];
const ERROR_STATES = ["error", "failed", "deleted"];

export class JobStateSummary extends Map {
    constructor(dsc = {}) {
@@ -28,18 +28,18 @@ export class JobStateSummary extends Map {
    get state() {
        if (this.jobCount) {
            if (this.isErrored) {
                return STATES.ERROR;
                return STATES.error;
            }
            if (this.isRunning) {
                return STATES.RUNNING;
                return STATES.running;
            }
            if (this.isNew) {
                return STATES.LOADING;
                return STATES.loading;
            }
            if (this.isTerminal) {
                return STATES.OK;
                return STATES.ok;
            }
            return STATES.QUEUED;
            return STATES.queued;
        }
        return this.populated_state;
    }
@@ -47,11 +47,11 @@ export class JobStateSummary extends Map {
    // Flags

    get isNew() {
        return !this.populated_state || this.populated_state == STATES.NEW;
        return !this.populated_state || this.populated_state == STATES.new;
    }

    get isErrored() {
        return this.populated_state == STATES.ERROR || this.anyHasJobs(...ERROR_STATES);
        return this.populated_state == STATES.error || this.anyHasJobs(...ERROR_STATES);
    }

    get isTerminal() {
@@ -62,20 +62,48 @@ export class JobStateSummary extends Map {
    }

    get isRunning() {
        return this.hasJobs(STATES.RUNNING);
        return this.hasJobs(STATES.running);
    }

    // Counts

    get okCount() {
        return this.get("ok");
    }

    get okCountText() {
        return `${this.okCount} OK`;
    }

    get jobCount() {
        return this.get("all_jobs");
    }

    get jobCountText() {
        return `${this.jobCount} Total Jobs`;
    }

    get errorCount() {
        return this.get(STATES.ERROR);
        return (this.get("error") || 0) + (this.get("failed") || 0) + (this.get("deleted") || 0);
    }

    get errorCountText() {
        return `${this.errorCount} Error`;
    }

    get runningCount() {
        return this.get(STATES.RUNNING);
        return this.get("running");
    }

    get runningCountText() {
        return `${this.runningCount} Running`;
    }

    get waitingCount() {
        return (this.get("queued") || 0) + (this.get("waiting") || 0) + (this.get("paused") || 0);
    }

    get waitingCountText() {
        return `${this.waitingCount} Waiting`;
    }
}