1
0
Fork 0

added some userManagement functionality

This commit is contained in:
gschwab 2014-02-19 08:38:04 +01:00
parent e17c4c870a
commit dfb352a23c
12 changed files with 424 additions and 17 deletions

View File

@ -1,6 +1,7 @@
/* Sets the default values shared for content views*/
#content {
background-color: rgba(0, 0, 0, 0.0675);
/*background-color: rgba(0, 0, 0, 0.0675);*/
background-color: #D6D6D6;
min-height: 80px;
height: 100%;
width: 100%;

View File

@ -63,8 +63,14 @@ window.ArangoUsers = Backbone.Collection.extend({
error: function(data) {
}
});
},
parse: function(response) {
var result = [];
_.each(response.result, function(object) {
result.push(object);
});
return result;
}
});

View File

@ -3,11 +3,15 @@
window.Users = Backbone.Model.extend({
defaults: {
sessionId: "",
userName: "",
password: "",
userId: "",
data: {}
},
idAttribute : "user",
url: function () {
if (this.get("user") !== "") {
return "/_api/user/" + this.get("user");
}
return "/_api/user";
},
initialize: function () {

View File

@ -4,8 +4,8 @@
</div>
</ul>
<div id="databaseDiv" class="thumbnails">
<table id="databaseTable" class="arangoDataTable">
<div class="thumbnails contentDiv">
<table id="databaseTable" class="arangoDataTable contentTables">
<thead>
<tr>
<td class="dbThFirst">Name</td>
@ -19,7 +19,7 @@
</table>
</div>
<div id="createDatabaseModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display:none">
<div id="createDatabaseModal" class="modal hide fade createModalDialog" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display:none">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<a class="arangoHeader">Create Database</a>

View File

@ -0,0 +1,103 @@
<ul class="thumbnails2" id="userManagementHeader">
<div class="headerBar">
<a class="arangoHeader">User Management</a>
</div>
</ul>
<div class="thumbnails contentDiv">
<table id="userManagementTable" class="arangoDataTable contentTables">
<thead>
<tr>
<td>Username</td>
<td>Avatar</td>
<td>Name</td>
<td>Active</td>
<td class="dbThSecond">
<span id="createUser" class="icon_arangodb_roundplus" data-original-title="Create new user"></span>
</td>
</tr>
</thead>
<tbody id="userManagementTableBody">
</tbody>
</table>
</div>
<div id="createUserModal" class="modal hide fade createModalDialog" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display:none">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<a class="arangoHeader">Create new user</a>
</div>
<div class="modal-body">
<table>
<tr>
<th>Username*:</th>
<th><input type="text" id="newUsername" name="username" value="" placeholder="Username"/></th>
</tr>
<tr>
<th>Name:</th>
<th><input type="text" id="newName" name="name" value="" placeholder="Name"/></th>
</tr>
<tr>
<th>Password:</th>
<th><input type="password" id="newPassword" name="password" value=""/></th>
</tr>
<tr>
<th>Active:</th>
<th><input type="checkbox" id="newStatus" name="status" value="active"/></th>
</tr>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-close" data-dismiss="modal" aria-hidden="true">Close</button>
<button id="submitCreateUser" class="btn btn-success pull-right">Create</button>
</div>
</div>
<div id="deleteUserModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display:none">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<a class="arangoHeader">Delete User</a>
</div>
<div class="modal-body">
<table>
<tr>
<th>Really delete?</th>
<th></th>
</tr>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-close" data-dismiss="modal" aria-hidden="true">Close</button>
<button id="submitDeleteUser" class="btn btn-danger pull-right">Delete</button>
</div>
</div>
<div id="editUserModal" class="modal hide fade createModalDialog" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display:none">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<a class="arangoHeader">Edit user</a>
</div>
<div class="modal-body">
<table>
<tr>
<th>Username:</th>
<th id="editUsername"></th>
</tr>
<tr>
<th>Name:</th>
<th><input type="text" id="editName" name="name" value="" placeholder="Name"/></th>
</tr>
<tr>
<th>Active:</th>
<th><input type="checkbox" id="editStatus" name="status" value="active"/></th>
</tr>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-close" data-dismiss="modal" aria-hidden="true">Close</button>
<button id="submitEditUser" class="btn btn-success pull-right">Save</button>
</div>
</div>

View File

@ -63,6 +63,7 @@
return this;
},
events: {
"keydown #searchInput" : "restrictToSearchPhraseKey",
"change #searchInput" : "restrictToSearchPhrase",

View File

@ -10,15 +10,208 @@
template: templateEngine.createTemplate("userManagementView.ejs"),
events: {
"click #createUser" : "createUser",
"click #submitCreateUser" : "submitCreateUser",
"click #userManagementTable .icon_arangodb_roundminus" : "removeUser",
"click #submitDeleteUser" : "submitDeleteUser",
// "click .editUser" : "editUser",
"click #submitEditUser" : "submitEditUser"
},
initialize: function() {
//this.collection.fetch({async:false});
//fetch collection defined in router
this.collection.fetch({async:false});
},
render: function(){
$(this.el).html(this.template.render({}));
$(this.el).html(this.template.render({
collection: this.collection
}));
this.renderTable();
//this.selectCurrentUser(); //selectCurrentUser not implemented yet
return this;
},
renderTable: function () {
this.collection.forEach(function(user) {
$("#userManagementTable tbody").append(
'<tr class="editUser" id="' + user.get("user") + '">' +
'<td><a>' + user.get("user") + '</a></td>' +//username
'<td><a>' + "" + '</a></td>' +//avatar
'<td><a>' + "" + '</a></td>' +//name
'<td><a>' + user.get("active") + '</a></td>' +//active
'<td><span class="arangoicon icon_arangodb_roundminus"' +
'data-original-title="Delete user"></span></td>' +
'</tr>'
);
});
},
selectCurrentUser : function() {
$('#userManagementTableBody tr').addClass('userInactive');
var tr = $('#userManagementTableBody td:contains('+this.currentUser+')').parent();
$(tr).removeClass('userInactive').addClass('userActive');
},
createUser : function() {
this.showModal();
},
showModal: function() {
$('#createUserModal').modal('show');
},
hideModal: function() {
$('#createUserModal').modal('hide');
},
submitCreateUser: function() {
var self = this;
var userName = $('#newUsername').val();
var name = $('#newName').val();
var userPassword = $('#newPassword').val();
var status = $('#newStatus').is(':checked');
if (!this.validateUserInfo(name, userName, userPassword, status)) {
return;
}
var options = {
username: userName,
passwd: userPassword,
active: status
};
this.collection.create(options, {
wait:true,
error: function(data, err) {
self.handleError(err.status, err.statusText, name);
},
success: function(data) {
self.hideModal();
self.updateUserManagement();
}
});
},
validateUserInfo: function (name, username, pw, status) {
if (username === "") {
arangoHelper.arangoError("You have to define an username");
$('#newUsername').closest("th").css("backgroundColor", "red");
return false;
}
/* if (!username.match(/^[a-zA-Z][a-zA-Z0-9_\-]*$/)) {
arangoHelper.arangoError("Name may only contain numbers, letters, _ and -");
return false;
}
if (!user.match(/^[a-zA-Z][a-zA-Z\-]*$/)) {
arangoHelper.arangoError("Name may only letters and -");
return false;
}*/
return true;
},
updateUserManagement: function() {
var self = this;
this.collection.fetch({
success: function() {
self.render();
// window.App.handleSelectDatabase();
}
});
},
removeUser : function(e) {
this.userToDelete = $(e.currentTarget).parent().parent().children().first().text();
$('#deleteUserModal').modal('show');
e.stopPropagation();
},
submitDeleteUser : function(e) {
var toDelete = this.collection.findWhere({user: this.userToDelete});
toDelete.destroy({wait: true});
// arangoHelper.arangoNotification("User " + this.userToDelete + " deleted.");
this.userToDelete = '';
$('#deleteUserModal').modal('hide');
this.updateUserManagement();
},
editUser : function(e) {
this.userToEdit = $(e.currentTarget).attr("id");
console.log(this.userToEdit);
$('#editUserModal').modal('show');
var user = this.collection.findWhere({user: this.userToEdit});
$('#editUsername').html(user.get("user"));
// $('#editName').val(user.get("user"));
$('#editStatus').attr("checked", user.get("active"));
},
submitEditUser : function() {
console.log("submitEditUser");
var self = this;
var userName = this.userToEdit;
var name = $('#editName').val();
var status = $('#editStatus').is(':checked');
console.log(userName);
console.log(name);
console.log(status);
if (!this.validateStatus(status)) {
$('#editStatus').closest("th").css("backgroundColor", "red");
return;
}
if (!this.validateName(name)) {
$('#editName').closest("th").css("backgroundColor", "red");
return;
}
var options = {
username: userName,
//name: name,
active: status
};
//TODO
this.collection.set(options, {
wait:true,
error: function(data, err) {
self.handleError(err.status, err.statusText, name);
},
success: function(data) {
self.hideModal();
self.updateUserManagement();
}
});
},
validateUsername: function (username) {
if (username === "") {
arangoHelper.arangoError("You have to define an username");
$('#newUsername').closest("th").css("backgroundColor", "red");
return false;
}
if (!username.match(/^[a-zA-Z][a-zA-Z0-9_\-]*$/)) {
arangoHelper.arangoError("Username may only contain numbers, letters, _ and -");
return false;
}
return true;
},
validatePassword: function (passwordw) {
return true;
},
validateName: function (name) {
if (name === "") {
return true;
}
if (!name.match(/^[a-zA-Z][a-zA-Z0-9_\-]*$/)) {
arangoHelper.arangoError("Username may only contain numbers, letters, _ and -");
return false;
}
return true;
},
validateStatus: function (status) {
if (status === "") {
return false;
}
return true;
}
});

View File

@ -14,6 +14,8 @@ $c_header_btn_border: #222222;
$c_black: #000000;
$c_white: #FFFFFF;
$c_c2grey: #C2C2C2;
$c_nav_bg: #333232;
$c_bar_bg: #686766;
@ -23,3 +25,8 @@ $c_dark_grey: #999999;
$c_transp: transparent;
$c_semi_transp: rgba(0, 0, 0, 0.2);
$c_very_transp: rgba(0, 0, 0, 0.05);
$c_contentRowActive: #BDCC92;
$c_odd : #D9D9D9;
$c_even : #FFFFFF;

View File

@ -0,0 +1,91 @@
//#databaseDiv => .contentDiv
.contentDiv {
padding: 13px 5px 0px 5px;
}
//.databaseButtons => .contentButtons
.contentButtons {
clear:both;
width: 100%;
margin-bottom: 10px;
#createDatabase, #createUser {
margin-left: 0;
}
}
// #databaseTable => .contentTables
.contentTables {
width: 100%;
margin-bottom: 10px;
thead {
text-align: left;
tr {
border-bottom: 1px solid $c_c2grey;
background-color: $c_white;
}
}
tbody {
tr {
&:nth-child(odd){
background-color: $c_odd;
};
&:nth-child(even){
background-color: $c_even;
};
}
}
tr {
&.contentRowActive {
background-color: $c_contentRowActive !important;
font-weight: 400;
a {
color: $c_black !important;
}
span {
display:none;
}
}
//.databaseInactive => .contentRowInactive
&.contentRowInactive {
a {
@extend %clickable;
color: $c_black !important;
}
}
}
.dbThFirst {
width: 90%;
}
.dbThSecond {
width: 10%;
}
td {
padding:12px 18px;
span {
float: right;
@extend %icon-negative;
font-size: 22px;
}
&.dbThSecond {
span {
@extend %icon-positive;
}
}
}
.collectionThSec {
width: 80%;
margin-right: 0;
}
.collectionTh {
width: 5%;
margin-right: 0;
}
}
//#createDatabaseModal => .createModalDialog
.createModalDialog table {
width: 100%;
}

View File

@ -20,3 +20,5 @@
@import "tiles";
// Notifications
@import "notification";
//contentTables
@import "contentTables";

View File

@ -124,7 +124,6 @@
"frontend/css/collectionView.css",
"frontend/css/documentsView.css",
"frontend/css/documentView.css",
"frontend/css/databaseView.css",
"frontend/css/documentSourceView.css",
"frontend/css/swaggerView.css",
"frontend/css/foxxView.css",

View File

@ -6,8 +6,8 @@
"use strict";
describe("The router", function() {
var
var
jQueryDummy,
fakeDB,
graphDummy,
@ -110,7 +110,7 @@
});
spyOn(window, "CurrentDatabase").andReturn(fakeDB);
spyOn(fakeDB, "fetch").andCallFake(function(options) {
expect(options.async).toBeFalsy();
expect(options.async).toBeFalsy();
});
spyOn(window, "DBSelectionView");
spyOn(window, "StatisticBarView").andReturn(statisticBarDummy);