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

Implemented delete node modal dialog and calls

parent 13aecebc
Branches
No related tags found
No related merge requests found
Pipeline #960 failed
Showing
with 112 additions and 4 deletions
...@@ -15,7 +15,6 @@ import java.net.http.HttpClient; ...@@ -15,7 +15,6 @@ import java.net.http.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpResponse; import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers; import java.net.http.HttpResponse.BodyHandlers;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
...@@ -27,7 +26,6 @@ import javax.servlet.http.HttpSession; ...@@ -27,7 +26,6 @@ import javax.servlet.http.HttpSession;
import javax.xml.bind.JAXB; import javax.xml.bind.JAXB;
import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.uws.v1.JobSummary;
import net.ivoa.xml.uws.v1.Jobs; import net.ivoa.xml.uws.v1.Jobs;
import net.ivoa.xml.uws.v1.ShortJobDescription;
import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Node;
import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Protocol;
import net.ivoa.xml.vospace.v2.Transfer; import net.ivoa.xml.vospace.v2.Transfer;
...@@ -116,6 +114,17 @@ public class VOSpaceClient { ...@@ -116,6 +114,17 @@ public class VOSpaceClient {
return call(request, BodyHandlers.ofInputStream(), 200, res -> unmarshal(res, Node.class)); return call(request, BodyHandlers.ofInputStream(), 200, res -> unmarshal(res, Node.class));
} }
public void deleteNode(String path) {
HttpRequest request = getRequest("/nodes" + path)
.header("Accept", useJson ? "application/json" : "text/xml")
.header("Content-Type", useJson ? "application/json" : "text/xml")
.DELETE()
.build();
call(request, BodyHandlers.ofInputStream(), 200, res -> null);
}
public List<Job> getJobs() { public List<Job> getJobs() {
HttpRequest request = getRequest("/transfers?direction=pullToVoSpace") HttpRequest request = getRequest("/transfers?direction=pullToVoSpace")
......
...@@ -14,6 +14,7 @@ import org.springframework.http.HttpHeaders; ...@@ -14,6 +14,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
...@@ -50,6 +51,12 @@ public class NodesController extends BaseController { ...@@ -50,6 +51,12 @@ public class NodesController extends BaseController {
return nodesService.generateNodesHtml(path); return nodesService.generateNodesHtml(path);
} }
@DeleteMapping(value = {"/nodes", "/nodes/**"})
public void deleteNode() {
String path = getPath("/nodes/");
client.deleteNode(path);
}
@GetMapping(value = "/download/**") @GetMapping(value = "/download/**")
public ResponseEntity<?> directDownload() { public ResponseEntity<?> directDownload() {
......
...@@ -63,6 +63,7 @@ public class NodesService { ...@@ -63,6 +63,7 @@ public class NodesService {
html += "<td>" + nodeInfo.getSize() + "</td>"; html += "<td>" + nodeInfo.getSize() + "</td>";
html += "<td>" + nodeInfo.getGroupRead() + "</td>"; html += "<td>" + nodeInfo.getGroupRead() + "</td>";
html += "<td>" + nodeInfo.getGroupWrite() + "</td>"; html += "<td>" + nodeInfo.getGroupWrite() + "</td>";
html += "<td><span class=\"icon trash-icon pointer\" onclick=\"deleteNode('" + nodeInfo.getPath() + "')\"></span></td>";
html += "</tr>"; html += "</tr>";
return html; return html;
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<td>0 B</td> <td>0 B</td>
<td>group1</td> <td>group1</td>
<td>group2</td> <td>group2</td>
<td></td>
</tr> </tr>
<tr> <tr>
<td><input type="checkbox" data-node="/folder1/file2" /></td> <td><input type="checkbox" data-node="/folder1/file2" /></td>
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
<td>30 KB</td> <td>30 KB</td>
<td>group1</td> <td>group1</td>
<td>group2</td> <td>group2</td>
<td></td>
</tr> </tr>
<tr> <tr>
<td><input type="checkbox" class="async" data-node="/folder1/file3" /></td> <td><input type="checkbox" class="async" data-node="/folder1/file3" /></td>
...@@ -28,5 +30,6 @@ ...@@ -28,5 +30,6 @@
<td>12 MB</td> <td>12 MB</td>
<td>group3</td> <td>group3</td>
<td>group4</td> <td>group4</td>
<td></td>
</tr> </tr>
</tbody> </tbody>
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<td>10 KB</td> <td>10 KB</td>
<td>group1</td> <td>group1</td>
<td>group2</td> <td>group2</td>
<td></td>
</tr> </tr>
<tr> <tr>
<td><input type="checkbox" class="async" data-node="/folder1/folder2/file5" /></td> <td><input type="checkbox" class="async" data-node="/folder1/folder2/file5" /></td>
...@@ -18,5 +19,6 @@ ...@@ -18,5 +19,6 @@
<td>15 MB</td> <td>15 MB</td>
<td>group3</td> <td>group3</td>
<td>group4</td> <td>group4</td>
<td></td>
</tr> </tr>
</tbody> </tbody>
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
<td>0 B</td> <td>0 B</td>
<td>group1</td> <td>group1</td>
<td>group2</td> <td>group2</td>
<td>
<span class="icon trash-icon pointer" onclick="deleteNode('/folder1')"></span>
</td>
</tr> </tr>
<tr> <tr>
<td><input type="checkbox" data-node="/file1" /></td> <td><input type="checkbox" data-node="/file1" /></td>
...@@ -18,5 +21,6 @@ ...@@ -18,5 +21,6 @@
<td>12 MB</td> <td>12 MB</td>
<td>group1</td> <td>group1</td>
<td>group2</td> <td>group2</td>
<td></td>
</tr> </tr>
</tbody> </tbody>
...@@ -54,5 +54,8 @@ export default { ...@@ -54,5 +54,8 @@ export default {
}, },
uploadFile() { uploadFile() {
return fetch({}); return fetch({});
},
deleteNode() {
return fetch({});
} }
} }
...@@ -123,5 +123,16 @@ export default { ...@@ -123,5 +123,16 @@ export default {
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data'
} }
}) })
},
deleteNode(path) {
let url = BASE_API_URL + 'nodes' + path;
return apiRequest({
method: 'DELETE',
url: url,
withCredentials: true,
headers: {
'Cache-Control': 'no-cache'
}
}, true, true);
} }
} }
...@@ -20,3 +20,19 @@ ...@@ -20,3 +20,19 @@
.file-x-icon { .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"); 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");
} }
.trash-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='trash' xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' class='bi-trash mx-auto b-icon bi'%3E%3Cg data-v-41be6633=''%3E%3Cpath d='M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z'%3E%3C/path%3E%3Cpath fill-rule='evenodd' d='M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
}
.pencil-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='pencil' xmlns='http://www.w3.org/2000/svg' fill='currentColor' class='bi-pencil mx-auto b-icon bi'%3E%3Cg data-v-41be6633=''%3E%3Cpath d='M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5L13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175l-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
}
.folder-link-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 symlink' xmlns='http://www.w3.org/2000/svg' fill='currentColor' class='bi-folder-symlink mx-auto b-icon bi'%3E%3Cg data-v-41be6633=''%3E%3Cpath d='M11.798 8.271l-3.182 1.97c-.27.166-.616-.036-.616-.372V9.1s-2.571-.3-4 2.4c.571-4.8 3.143-4.8 4-4.8v-.769c0-.336.346-.538.616-.371l3.182 1.969c.27.166.27.576 0 .742z'%3E%3C/path%3E%3Cpath d='M.5 3l.04.87a1.99 1.99 0 0 0-.342 1.311l.637 7A2 2 0 0 0 2.826 14h10.348a2 2 0 0 0 1.991-1.819l.637-7A2 2 0 0 0 13.81 3H9.828a2 2 0 0 1-1.414-.586l-.828-.828A2 2 0 0 0 6.172 1H2.5a2 2 0 0 0-2 2zm.694 2.09A1 1 0 0 1 2.19 4h11.62a1 1 0 0 1 .996 1.09l-.636 7a1 1 0 0 1-.996.91H2.826a1 1 0 0 1-.995-.91l-.637-7zM6.172 2a1 1 0 0 1 .707.293L7.586 3H2.19c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 0 1 1-.98h3.672z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
}
.gear-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='gear' xmlns='http://www.w3.org/2000/svg' fill='currentColor' class='bi-gear mx-auto b-icon bi'%3E%3Cg data-v-41be6633=''%3E%3Cpath d='M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492zM5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0z'%3E%3C/path%3E%3Cpath d='M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52l-.094-.319zm-2.633.283c.246-.835 1.428-.835 1.674 0l.094.319a1.873 1.873 0 0 0 2.693 1.115l.291-.16c.764-.415 1.6.42 1.184 1.185l-.159.292a1.873 1.873 0 0 0 1.116 2.692l.318.094c.835.246.835 1.428 0 1.674l-.319.094a1.873 1.873 0 0 0-1.115 2.693l.16.291c.415.764-.42 1.6-1.185 1.184l-.291-.159a1.873 1.873 0 0 0-2.693 1.116l-.094.318c-.246.835-1.428.835-1.674 0l-.094-.319a1.873 1.873 0 0 0-2.692-1.115l-.292.16c-.764.415-1.6-.42-1.184-1.185l.159-.291A1.873 1.873 0 0 0 1.945 8.93l-.319-.094c-.835-.246-.835-1.428 0-1.674l.319-.094A1.873 1.873 0 0 0 3.06 4.377l-.16-.292c-.415-.764.42-1.6 1.185-1.184l.292.159a1.873 1.873 0 0 0 2.692-1.115l.094-.319z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
}
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
<th>Size</th> <th>Size</th>
<th>Group read</th> <th>Group read</th>
<th>Group write</th> <th>Group write</th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody id="nodes"></tbody> <tbody id="nodes"></tbody>
...@@ -30,6 +31,7 @@ ...@@ -30,6 +31,7 @@
</b-card> </b-card>
<CreateFolderModal /> <CreateFolderModal />
<UploadFilesModal /> <UploadFilesModal />
<ConfirmDeleteModal />
</div> </div>
</template> </template>
...@@ -37,13 +39,15 @@ ...@@ -37,13 +39,15 @@
import { BIconCheckSquare, BIconSquare } from 'bootstrap-vue' import { BIconCheckSquare, BIconSquare } from 'bootstrap-vue'
import CreateFolderModal from './modal/CreateFolderModal.vue' import CreateFolderModal from './modal/CreateFolderModal.vue'
import UploadFilesModal from './modal/UploadFilesModal.vue' import UploadFilesModal from './modal/UploadFilesModal.vue'
import ConfirmDeleteModal from './modal/ConfirmDeleteModal.vue'
export default { export default {
components: { components: {
BIconCheckSquare, BIconCheckSquare,
BIconSquare, BIconSquare,
CreateFolderModal, CreateFolderModal,
UploadFilesModal UploadFilesModal,
ConfirmDeleteModal
}, },
computed: { computed: {
breadcrumbs() { breadcrumbs() {
...@@ -111,4 +115,8 @@ th#checkboxes { ...@@ -111,4 +115,8 @@ th#checkboxes {
width: 0.1%; width: 0.1%;
white-space: nowrap; white-space: nowrap;
} }
.pointer {
cursor: pointer;
}
</style> </style>
<template>
<b-modal id="confirm-delete-modal" title="Confirm delete" okTitle="Yes, delete" @ok="deleteNode" @hidden="reset" ok-variant="danger">
<p>Do you really want to delete node at {{nodeToDelete}}?</p>
</b-modal>
</template>
<script>
export default {
name: 'ConfirmDeleteModal',
computed: {
nodeToDelete() { return this.$store.state.nodeToDelete }
},
methods: {
reset() {
this.$store.commit('setNodeToDelete', null);
},
deleteNode(event) {
// Prevent modal from closing
event.preventDefault();
this.$store.dispatch('deleteNode')
.then(() => {
this.$bvModal.hide('confirm-delete-modal');
});
}
}
}
</script>
...@@ -18,6 +18,11 @@ let vm = new Vue({ ...@@ -18,6 +18,11 @@ let vm = new Vue({
router router
}).$mount('#app') }).$mount('#app')
window.deleteNode = function(path) {
store.commit('setNodeToDelete', path);
vm.$bvModal.show('confirm-delete-modal');
}
export default { export default {
showError(message) { showError(message) {
vm.$bvToast.toast(message, { vm.$bvToast.toast(message, {
......
...@@ -13,7 +13,8 @@ export default new Vuex.Store({ ...@@ -13,7 +13,8 @@ export default new Vuex.Store({
loading: true, loading: true,
asyncButtonEnabled: false, asyncButtonEnabled: false,
jobs: [], jobs: [],
user: 'anonymous' user: 'anonymous',
nodeToDelete: null
}, },
mutations: { mutations: {
setLoading(state, loading) { setLoading(state, loading) {
...@@ -41,6 +42,9 @@ export default new Vuex.Store({ ...@@ -41,6 +42,9 @@ export default new Vuex.Store({
}, },
setUsername(state, username) { setUsername(state, username) {
state.user = username; state.user = username;
},
setNodeToDelete(state, path) {
state.nodeToDelete = path;
} }
}, },
actions: { actions: {
...@@ -103,6 +107,13 @@ export default new Vuex.Store({ ...@@ -103,6 +107,13 @@ export default new Vuex.Store({
// Reload current node // Reload current node
dispatch('setPath', state.path); dispatch('setPath', state.path);
}); });
},
deleteNode({ state, dispatch }) {
client.deleteNode(state.nodeToDelete)
.then(() => {
// Reload current node
dispatch('setPath', state.path);
});
} }
} }
}); });
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment