Skip to content
Snippets Groups Projects
Commit 9da22b03 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Added node listing mock calls; Improved notifications handling

parent 55825cc6
No related branches found
No related tags found
No related merge requests found
Showing
with 238 additions and 44 deletions
......@@ -32,7 +32,7 @@ public class NodesService {
if (node instanceof ContainerNode) {
ContainerNode folder = (ContainerNode) node;
sw.write("<tbody id=\"nodes\">");
for (Node child : folder.getNodes().getNode()) {
for (Node child : folder.getNodes()) {
sw.write(getNodeHtml(child));
}
sw.write("</tbody>");
......
VUE_APP_API_CLIENT = 'mock'
VUE_APP_API_BASE_URL = 'http://localhost:8085/'
......@@ -9039,6 +9039,40 @@
"unpipe": "1.0.0"
}
},
"raw-loader": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz",
"integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==",
"dev": true,
"requires": {
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
},
"dependencies": {
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"schema-utils": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
"integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.6",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
}
}
}
},
"read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
......
......@@ -22,6 +22,7 @@
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"raw-loader": "^4.0.2",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
......
......@@ -28,19 +28,6 @@ export default {
}),
components: {
TopMenu
},
mounted: function() {
var self = this;
document.addEventListener('apiError', function(event) {
self.$bvToast.toast(event.message.body, {
title: event.message.title,
variant: 'danger',
solid: true
});
});
document.addEventListener('loading', function(event) {
self.$store.commit('setLoading', event.value);
});
}
}
</script>
......@@ -50,7 +37,6 @@ export default {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
......
{
"id": "1234",
"status": "EXECUTING"
}
<tbody id="nodes">
<tr>
<td><input type="checkbox" class="tape" data-node="/folder1/folder2" /></td>
<td>
<span class="icon folder-x-icon"></span>
<a href="#/nodes/folder1/folder2">folder2</a>
</td>
<td>0 B</td>
<td>group1</td>
<td>group2</td>
</tr>
<tr>
<td><input type="checkbox" data-node="/folder1/file2" /></td>
<td>
<span class="icon file-icon"></span>
<a href="download/file2">file2</a>
</td>
<td>30 KB</td>
<td>group1</td>
<td>group2</td>
</tr>
<tr>
<td><input type="checkbox" class="tape" data-node="/folder1/file3" /></td>
<td>
<span class="icon file-x-icon"></span>
file3
</td>
<td>12 MB</td>
<td>group3</td>
<td>group4</td>
</tr>
</tbody>
<tbody id="nodes">
<tr>
<td><input type="checkbox" class="tape" data-node="/folder1/folder2/file4" /></td>
<td>
<span class="icon file-x-icon"></span>
file4
</td>
<td>10 KB</td>
<td>group1</td>
<td>group2</td>
</tr>
<tr>
<td><input type="checkbox" class="tape" data-node="/folder1/folder2/file5" /></td>
<td>
<span class="icon file-x-icon"></span>
file5
</td>
<td>15 MB</td>
<td>group3</td>
<td>group4</td>
</tr>
</tbody>
<tbody id="nodes">
<tr>
<td><input type="checkbox" data-node="/folder1" /></td>
<td>
<span class="icon folder-icon"></span>
<a href="#/nodes/folder1">folder1</a>
</td>
<td>0 B</td>
<td>group1</td>
<td>group2</td>
</tr>
<tr>
<td><input type="checkbox" data-node="/file1" /></td>
<td>
<span class="icon file-icon"></span>
<a href="download/file1">file1</a>
</td>
<td>12 MB</td>
<td>group1</td>
<td>group2</td>
</tr>
</tbody>
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 store from '../../store';
const fetch = (mockData, showLoading = true, time = 500) => {
return new Promise((resolve) => {
if (showLoading) {
store.commit('setLoading', true);
}
setTimeout(() => {
resolve(mockData)
if (showLoading) {
store.commit('setLoading', false);
}
}, time);
});
};
export default {
getNode(path) {
let response;
switch (path) {
case '':
response = root;
break;
case 'folder1':
response = folder1;
break;
case 'folder1/folder2':
response = folder2;
break;
}
return fetch(response);
},
startRecallFromTapeJob() {
return fetch(job);
}
}
const BASE_API_URL = process.env.VUE_APP_API_BASE_URL;
import axios from 'axios';
import store from '../../store';
import main from '../../main';
function apiRequest(options, showLoading = true, handleValidationErrors = false) {
if (showLoading) {
loading(true);
store.commit('setLoading', true);
}
return new Promise((resolve, reject) => {
axios(options)
......@@ -14,41 +16,27 @@ function apiRequest(options, showLoading = true, handleValidationErrors = false)
} else {
resolve(response.data);
}
loading(false);
store.commit('setLoading', false);
})
.catch(error => {
loading(false);
store.commit('setLoading', false);
if (handleValidationErrors && error.response && error.response.status === 400) {
reject(error.response.data);
} else {
dispatchApiErrorEvent(error);
main.showError(getErrorMessage(error));
}
});
});
}
function dispatchApiErrorEvent(error) {
let event = new CustomEvent('apiError');
let errorMessage;
function getErrorMessage(error) {
if (error.response && error.response.data && error.response.data.message) {
errorMessage = error.response.data.message;
return error.response.data.message;
} else if (error.message) {
errorMessage = error.message;
return error.message;
} else {
errorMessage = 'Unknown error';
return 'Unknown error';
}
event.message = {
title: error.error || 'Error',
body: errorMessage
};
document.dispatchEvent(event);
}
/* For loading animation */
function loading(value) {
let event = new CustomEvent('loading');
event.value = value;
document.dispatchEvent(event);
}
export default {
......
......@@ -9,6 +9,14 @@
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' width='1em' height='1em' focusable='false' role='img' aria-label='folder' xmlns='http://www.w3.org/2000/svg' fill='currentColor' %3E%3Cg%3E%3Cpath fill-rule='evenodd' d='M1 3.5A1.5 1.5 0 0 1 2.5 2h2.764c.958 0 1.76.56 2.311 1.184C7.985 3.648 8.48 4 9 4h4.5A1.5 1.5 0 0 1 15 5.5v.64c.57.265.94.876.856 1.546l-.64 5.124A2.5 2.5 0 0 1 12.733 15H3.266a2.5 2.5 0 0 1-2.481-2.19l-.64-5.124A1.5 1.5 0 0 1 1 6.14V3.5zM2 6h12v-.5a.5.5 0 0 0-.5-.5H9c-.964 0-1.71-.629-2.174-1.154C6.374 3.334 5.82 3 5.264 3H2.5a.5.5 0 0 0-.5.5V6zm-.367 1a.5.5 0 0 0-.496.562l.64 5.124A1.5 1.5 0 0 0 3.266 14h9.468a1.5 1.5 0 0 0 1.489-1.314l.64-5.124A.5.5 0 0 0 14.367 7H1.633z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
}
.folder-x-icon {
background-image: url("data:image/svg+xml,%3Csvg data-v-41be6633='' viewBox='0 0 16 16' width='1em' height='1em' focusable='false' role='img' aria-label='folder x' xmlns='http://www.w3.org/2000/svg' fill='currentColor' class='bi-folder-x mx-auto b-icon bi'%3E%3Cg data-v-41be6633=''%3E%3Cpath fill-rule='evenodd' d='M9.828 4H2.19a1 1 0 0 0-.996 1.09l.637 7a1 1 0 0 0 .995.91H9v1H2.826a2 2 0 0 1-1.991-1.819l-.637-7a1.99 1.99 0 0 1 .342-1.31L.5 3a2 2 0 0 1 2-2h3.672a2 2 0 0 1 1.414.586l.828.828A2 2 0 0 0 9.828 3h3.982a2 2 0 0 1 1.992 2.181L15.546 8H14.54l.265-2.91A1 1 0 0 0 13.81 4H9.828zm-2.95-1.707L7.587 3H2.19c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 0 1 1-.98h3.672a1 1 0 0 1 .707.293z'%3E%3C/path%3E%3Cpath fill-rule='evenodd' d='M11.146 10.146a.5.5 0 0 1 .708 0L13 11.293l1.146-1.147a.5.5 0 0 1 .708.708L13.707 12l1.147 1.146a.5.5 0 0 1-.708.708L13 12.707l-1.146 1.147a.5.5 0 0 1-.708-.708L12.293 12l-1.147-1.146a.5.5 0 0 1 0-.708z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
}
.file-icon {
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' width='1em' height='1em' focusable='false' role='img' aria-label='file earmark' xmlns='http://www.w3.org/2000/svg' fill='currentColor' class='bi-file-earmark b-icon bi'%3E%3Cg%3E%3Cpath d='M4 0h5.5v1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h1V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2z'%3E%3C/path%3E%3Cpath d='M9.5 3V0L14 4.5h-3A1.5 1.5 0 0 1 9.5 3z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
}
.file-x-icon {
background-image: url("data:image/svg+xml,%3Csvg data-v-41be6633='' viewBox='0 0 16 16' width='1em' height='1em' focusable='false' role='img' aria-label='file earmark x' xmlns='http://www.w3.org/2000/svg' fill='currentColor' class='bi-file-earmark-x mx-auto b-icon bi'%3E%3Cg data-v-41be6633=''%3E%3Cpath d='M4 0h5.5v1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h1V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2z'%3E%3C/path%3E%3Cpath d='M9.5 3V0L14 4.5h-3A1.5 1.5 0 0 1 9.5 3z'%3E%3C/path%3E%3Cpath fill-rule='evenodd' d='M6.146 7.146a.5.5 0 0 1 .708 0L8 8.293l1.146-1.147a.5.5 0 1 1 .708.708L8.707 9l1.147 1.146a.5.5 0 0 1-.708.708L8 9.707l-1.146 1.147a.5.5 0 0 1-.708-.708L7.293 9 6.146 7.854a.5.5 0 0 1 0-.708z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
}
<template>
<div class="container">
<b-breadcrumb :items="breadcrumbs"></b-breadcrumb>
<div class="mb-3">
<b-button variant="success" class="mr-2" :disabled="true">New folder</b-button>
<b-button variant="success" class="mr-2" :disabled="true">Upload files</b-button>
<b-button variant="primary" class="mr-2" v-if="tapeButtonEnabled" @click="startRecallFromTapeJob">Recall from tape</b-button>
</div>
<b-card>
<table class="table b-table table-striped table-hover">
<thead>
......@@ -50,6 +55,9 @@ export default {
}
}
return items;
},
tapeButtonEnabled() {
return this.$store.state.tapeButtonEnabled;
}
},
created() {
......@@ -69,7 +77,13 @@ export default {
this.selectInputs(false);
},
selectInputs(value) {
document.querySelectorAll('#nodes input').forEach(input => input.checked = value);
document.querySelectorAll('#nodes input').forEach(input => {
input.checked = value;
this.$store.dispatch('computeButtonVisibility');
});
},
startRecallFromTapeJob() {
this.$store.dispatch('startRecallFromTapeJob');
}
}
}
......
......@@ -12,8 +12,25 @@ import VueRouter from 'vue-router'
Vue.use(VueRouter)
import router from './router.js'
new Vue({
let vm = new Vue({
render: h => h(App),
store,
router
}).$mount('#app')
export default {
showError(message) {
vm.$bvToast.toast(message, {
title: 'Error',
variant: 'danger',
solid: true
});
},
showInfo(message) {
vm.$bvToast.toast(message, {
title: 'Info',
variant: 'info',
solid: true
});
}
}
......@@ -3,14 +3,15 @@
import Vue from 'vue';
import Vuex from 'vuex';
import client from 'api-client';
import main from './main';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
//breadcrumbs: [],
path: '',
loading: true
loading: true,
tapeButtonEnabled: false
},
mutations: {
setLoading(state, loading) {
......@@ -21,15 +22,38 @@ export default new Vuex.Store({
value = '';
}
state.path = value;
//state.breadcrumbs = value.split('/')
},
setTapeButtonEnabled(state, value) {
state.tapeButtonEnabled = value;
}
},
actions: {
setPath({ state, commit }, path) {
setPath({ state, commit, dispatch }, path) {
commit('setPath', path);
client.getNode(state.path)
.then(res => {
document.getElementById('nodes').outerHTML = res
document.getElementById('nodes').outerHTML = res;
let checkboxes = document.querySelectorAll('#nodes input[type="checkbox"]');
for (let i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener('change', function() {
dispatch('computeButtonVisibility');
});
}
dispatch('computeButtonVisibility');
});
},
computeButtonVisibility({ commit }) {
commit('setTapeButtonEnabled', document.querySelectorAll('#nodes input.tape:checked').length > 0);
},
startRecallFromTapeJob() {
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(() => {
main.showInfo('Job started');
});
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment