diff --git a/vospace-ui-frontend/src/App.vue b/vospace-ui-frontend/src/App.vue index 1aced9b4e5ba226a94d09686a6d0efa0fa6069cc..4081bffc5ea36748f96ac05a207bd3af1a5d8d33 100644 --- a/vospace-ui-frontend/src/App.vue +++ b/vospace-ui-frontend/src/App.vue @@ -28,6 +28,9 @@ export default { }), components: { TopMenu + }, + mounted() { + this.$store.dispatch('loadJobs'); } } </script> diff --git a/vospace-ui-frontend/src/api/mock/data/job.json b/vospace-ui-frontend/src/api/mock/data/job.json index 633abc9aaca6432168df723153c54d934763c4f3..946c27000747cf259c034d13481a1227c2399cff 100644 --- a/vospace-ui-frontend/src/api/mock/data/job.json +++ b/vospace-ui-frontend/src/api/mock/data/job.json @@ -1,4 +1,5 @@ { "id": "1234", - "status": "EXECUTING" + "status": "EXECUTING", + "read": true } diff --git a/vospace-ui-frontend/src/api/mock/data/jobs.json b/vospace-ui-frontend/src/api/mock/data/jobs.json new file mode 100644 index 0000000000000000000000000000000000000000..1c4c53bde5822d8555dd0b4c2602f76273534f97 --- /dev/null +++ b/vospace-ui-frontend/src/api/mock/data/jobs.json @@ -0,0 +1,11 @@ +[{ + "id": "1", + "status": "COMPLETED", + "read": true + }, + { + "id": "2", + "status": "COMPLETED", + "read": true + } +] diff --git a/vospace-ui-frontend/src/api/mock/index.js b/vospace-ui-frontend/src/api/mock/index.js index 45c0226b944d9a2062a5c3c22511da896bbb4992..ed27af48f484a5dccd3357f8d1f9a127dd4d81d9 100644 --- a/vospace-ui-frontend/src/api/mock/index.js +++ b/vospace-ui-frontend/src/api/mock/index.js @@ -2,6 +2,7 @@ import root from 'raw-loader!./data/nodes/root.html'; import folder1 from 'raw-loader!./data/nodes/folder1.html'; import folder2 from 'raw-loader!./data/nodes/folder2.html'; import job from './data/job'; +import jobs from './data/jobs'; import store from '../../store'; const fetch = (mockData, showLoading = true, time = 500) => { @@ -36,5 +37,8 @@ export default { }, startRecallFromTapeJob() { return fetch(job); + }, + loadJobs() { + return fetch(jobs, false); } } diff --git a/vospace-ui-frontend/src/components/Jobs.vue b/vospace-ui-frontend/src/components/Jobs.vue new file mode 100644 index 0000000000000000000000000000000000000000..b0abb7e7cd7863a3156e8fd2aa09ee5197c48b92 --- /dev/null +++ b/vospace-ui-frontend/src/components/Jobs.vue @@ -0,0 +1,24 @@ +<template> +<table class="table b-table table-striped table-hover"> + <thead> + <tr> + <th>Id</th> + <th>Status</th> + </tr> + </thead> + <tbody> + <tr v-for="job in jobs" :key="job.id"> + <td>{{job.id}}</td> + <td>{{job.status}}</td> + </tr> + </tbody> +</table> +</template> + +<script> +export default { + computed: { + jobs() { return this.$store.state.jobs } + } +} +</script> diff --git a/vospace-ui-frontend/src/components/JobsMenuItem.vue b/vospace-ui-frontend/src/components/JobsMenuItem.vue new file mode 100644 index 0000000000000000000000000000000000000000..688688f81a3e295a3ebe93c6ccc54fa25090445b --- /dev/null +++ b/vospace-ui-frontend/src/components/JobsMenuItem.vue @@ -0,0 +1,16 @@ +<template> +<b-navbar-nav> + <b-nav-item href="#/jobs"> + <strong>Jobs</strong> + <b-badge variant="light">{{jobs.length}} <span class="sr-only">unread messages</span></b-badge> + </b-nav-item> +</b-navbar-nav> +</template> + +<script> +export default { + computed: { + jobs() { return this.$store.state.jobs } + } +} +</script> diff --git a/vospace-ui-frontend/src/components/TopMenu.vue b/vospace-ui-frontend/src/components/TopMenu.vue index 1115343a9e7ffbd5b1defe3993f5c3dcbd617efc..813bddffec7eaebde20c57045b895b76be7a9672 100644 --- a/vospace-ui-frontend/src/components/TopMenu.vue +++ b/vospace-ui-frontend/src/components/TopMenu.vue @@ -1,11 +1,22 @@ <template> <div> <b-navbar toggleable="lg" type="dark" id="top-menu"> - <b-navbar-brand href="#" class="d-none d-md-block">VOSpace</b-navbar-brand> + <b-navbar-brand href="#/" class="d-none d-md-block">VOSpace</b-navbar-brand> + <JobsMenuItem /> </b-navbar> </div> </template> +<script> +import JobsMenuItem from './JobsMenuItem.vue'; + +export default { + components: { + JobsMenuItem + } +} +</script> + <style> #top-menu { background-color: #093784; diff --git a/vospace-ui-frontend/src/router.js b/vospace-ui-frontend/src/router.js index 2bb82a7ef9c3788e0128010afd775fa2746be2ce..6b8ab996559d50d1122319548cca7498bd7c68f8 100644 --- a/vospace-ui-frontend/src/router.js +++ b/vospace-ui-frontend/src/router.js @@ -1,6 +1,7 @@ import VueRouter from 'vue-router'; import Main from './components/Main.vue'; +import Jobs from './components/Jobs.vue'; export default new VueRouter({ routes: [{ @@ -10,5 +11,8 @@ export default new VueRouter({ name: 'nodes', path: '/nodes/:path(.*)', component: Main + }, { + path: '/jobs', + component: Jobs }] }) diff --git a/vospace-ui-frontend/src/store.js b/vospace-ui-frontend/src/store.js index f4b4a331d95c9bd753e5b293507ca1538090ccda..14255d7346a2fa59409141033bc77ac1b4e9601f 100644 --- a/vospace-ui-frontend/src/store.js +++ b/vospace-ui-frontend/src/store.js @@ -11,7 +11,8 @@ export default new Vuex.Store({ state: { path: '', loading: true, - tapeButtonEnabled: false + tapeButtonEnabled: false, + jobs: [] }, mutations: { setLoading(state, loading) { @@ -25,6 +26,17 @@ export default new Vuex.Store({ }, setTapeButtonEnabled(state, value) { state.tapeButtonEnabled = value; + }, + setJobs(state, jobs) { + // empty the array + state.jobs.splice(0, jobs.length); + // fill again + for (let i = 0; i < jobs.length; i++) { + state.jobs.push(jobs[i]); + } + }, + addJob(state, job) { + state.jobs.push(job); } }, actions: { @@ -45,16 +57,21 @@ export default new Vuex.Store({ computeButtonVisibility({ commit }) { commit('setTapeButtonEnabled', document.querySelectorAll('#nodes input.tape:checked').length > 0); }, - startRecallFromTapeJob() { + startRecallFromTapeJob({ commit }) { let tapeCheckboxes = document.querySelectorAll('#nodes input.tape:checked'); let paths = []; for (let i = 0; i < tapeCheckboxes.length; i++) { paths.push(tapeCheckboxes[i].getAttribute('data-node')); } client.startRecallFromTapeJob(paths) - .then(() => { + .then(job => { main.showInfo('Job started'); + commit('addJob', job); }); + }, + loadJobs({ commit }) { + client.loadJobs() + .then(jobs => commit('setJobs', jobs)); } } });