Commit 3aac16a7 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Completed download CSV status feature

parent 6ec6bcc5
<template>
<nav aria-label="breadcrumb">
<nav aria-label="breadcrumb" id="groups-breadcrumbs">
<ol class="breadcrumb">
<li class="breadcrumb-item" v-for="group in groups" v-bind:class="{ active: group.active }" v-bind:key="group.groupId">
<a href="#" v-on:click="changeBreadcrumb(group.groupId)" v-if="!group.active">{{group.groupName}}</a>
<span v-if="group.active">{{group.groupName}}</span>
</li>
</ol>
<a :href="'group/status/' + currentGroup.groupId" :download="currentGroup.groupName + '.csv'" id="csv-status-download" title="Download CSV">
<font-awesome-icon icon="download"></font-awesome-icon>
</a>
</nav>
</template>
......@@ -35,7 +38,9 @@ export default {
computed: mapState({
model: state => state.model,
input: state => state.input,
groups: state => buildItems(state.model.breadcrumbs)
groups: state => buildItems(state.model.breadcrumbs),
isAdmin: state => state.model.permission === 'ADMIN',
currentGroup: state => state.model.breadcrumbs[state.model.breadcrumbs.length - 1]
}),
methods: {
changeBreadcrumb: function(groupId) {
......@@ -55,7 +60,14 @@ export default {
</script>
<style scoped>
nav {
#groups-breadcrumbs {
margin-top: 10px;
position: relative;
}
#csv-status-download {
position: absolute;
right: 18px;
top: 12px;
}
</style>
......@@ -5,14 +5,14 @@ import store from './store.js'
import './plugins/bootstrap-vue'
import App from './App.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faTrash, faEdit, faSpinner, faFolder, faUser, faSave } from '@fortawesome/free-solid-svg-icons'
import { faTrash, faEdit, faSpinner, faFolder, faUser, faSave, faDownload } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import router from './router.js';
library.add(faTrash, faEdit, faSpinner, faFolder, faUser, faSave);
library.add(faTrash, faEdit, faSpinner, faFolder, faUser, faSave, faDownload);
Vue.component('font-awesome-icon', FontAwesomeIcon);
......
package it.inaf.ia2.gms.controller;
import com.opencsv.CSVWriter;
import it.inaf.ia2.gms.authn.SessionData;
import it.inaf.ia2.gms.manager.GroupStatusManager;
import it.inaf.ia2.gms.manager.GroupsManager;
import it.inaf.ia2.gms.model.request.AddGroupRequest;
import it.inaf.ia2.gms.model.GroupNode;
......@@ -12,6 +14,9 @@ import it.inaf.ia2.gms.model.request.RenameGroupRequest;
import it.inaf.ia2.gms.model.request.SearchFilterRequest;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.service.GroupsTreeBuilder;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
......@@ -40,6 +45,9 @@ public class GroupsController {
@Autowired
private GroupsTabResponseBuilder groupsTabResponseBuilder;
@Autowired
private GroupStatusManager groupStatusManager;
@GetMapping(value = "/groups", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> getGroupsTab(@Valid GroupsRequest request) {
if (request.isOnlyPanel()) {
......@@ -85,6 +93,20 @@ public class GroupsController {
return ResponseEntity.ok(groupsPanel);
}
@GetMapping(value = "/group/status/{groupId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public void downloadStatus(@PathVariable("groupId") String groupId, HttpServletResponse response) throws Exception {
try (OutputStream out = response.getOutputStream();
CSVWriter writer = new CSVWriter(new OutputStreamWriter(out))) {
writer.writeNext(new String[]{"program", "email"});
for (String[] row : groupStatusManager.generateStatus(groupId)) {
writer.writeNext(row);
}
}
}
private <T extends PaginatedModelRequest & SearchFilterRequest> PaginatedData<GroupNode> getGroupsPanel(GroupEntity parentGroup, T request) {
return groupsTreeBuilder.listSubGroups(parentGroup, request, session.getUserId());
}
......
......@@ -9,7 +9,9 @@ import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.persistence.model.MembershipEntity;
import it.inaf.ia2.gms.rap.RapClient;
import it.inaf.ia2.gms.service.GroupNameService;
import it.inaf.ia2.gms.service.GroupsService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -27,6 +29,9 @@ public class GroupStatusManager extends UserAwareComponent {
@Autowired
private PermissionsManager permissionsManager;
@Autowired
private GroupsService groupsService;
@Autowired
private GroupsDAO groupsDAO;
......@@ -39,7 +44,9 @@ public class GroupStatusManager extends UserAwareComponent {
@Autowired
private RapClient rapClient;
public List<Object[]> generateStatus(GroupEntity parentGroup) {
public List<String[]> generateStatus(String groupId) {
GroupEntity parentGroup = groupsService.getGroupById(groupId);
Permission groupPermission = permissionsManager.getCurrentUserPermission(parentGroup);
......@@ -72,7 +79,7 @@ public class GroupStatusManager extends UserAwareComponent {
usersMap.put(user.getId(), user.getPrimaryEmail());
}
List<Object[]> rows = new ArrayList<>();
List<String[]> rows = new ArrayList<>();
for (int i = 0; i < groups.size(); i++) {
GroupEntity group = groups.get(i);
......@@ -85,12 +92,14 @@ public class GroupStatusManager extends UserAwareComponent {
LOG.warn("Unable to retrieve information about user " + userId);
continue;
}
Object[] row = new Object[]{groupName, email};
String[] row = new String[]{groupName, email};
rows.add(row);
}
}
}
Collections.sort(rows, (r1, r2) -> (r1[0]).compareTo(r2[0]));
return rows;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment