Closes #93: Edit tag color and title in #/tag/id

This commit is contained in:
jendib 2016-05-08 23:05:44 +02:00
parent 26685334a1
commit e234440ce6
No known key found for this signature in database
GPG Key ID: 06EE7F699579166F
10 changed files with 114 additions and 94 deletions

View File

@ -97,6 +97,14 @@ public class TagResource extends BaseResource {
.add("name", tagDto.getName())
.add("color", tagDto.getColor());
// Add the parent if its visible
if (tagDto.getParentId() != null) {
AclDao aclDao = new AclDao();
if (aclDao.checkPermission(tagDto.getParentId(), PermType.READ, getTargetIdList(null))) {
tag.add("parent", tagDto.getParentId());
}
}
// Add ACL
AclUtil.addAcls(tag, id, getTargetIdList(null));

View File

@ -3,13 +3,20 @@
/**
* Tag controller.
*/
angular.module('docs').controller('Tag', function($scope, $dialog, Restangular) {
angular.module('docs').controller('Tag', function($scope, $dialog, Restangular, $state) {
$scope.tag = { name: '', color: '#3a87ad' };
// Retrieve tags
Restangular.one('tag/list').get().then(function(data) {
$scope.tags = data.tags;
});
/**
* Display a tag.
*/
$scope.viewTag = function(id) {
$state.go('tag.edit', { id: id });
};
/**
* Add a tag.
@ -42,12 +49,4 @@ angular.module('docs').controller('Tag', function($scope, $dialog, Restangular)
}
});
};
/**
* Update a tag.
*/
$scope.updateTag = function(tag) {
// Update the server
return Restangular.one('tag', tag.id).post('', tag);
};
});

View File

@ -4,7 +4,23 @@
* Tag edit controller.
*/
angular.module('docs').controller('TagEdit', function($scope, $stateParams, Restangular) {
// Retrieve the tag
Restangular.one('tag', $stateParams.id).get().then(function(data) {
$scope.tag = data;
})
// Replace the tag from the list with this reference
_.each($scope.tags, function(tag, i) {
if (tag.id == $scope.tag.id) {
$scope.tags[i] = $scope.tag;
}
});
});
/**
* Update a tag.
*/
$scope.edit = function() {
// Update the server
Restangular.one('tag', $scope.tag.id).post('', $scope.tag);
};
});

View File

@ -1,62 +0,0 @@
'use strict';
/**
* Inline edition directive.
* Thanks to http://jsfiddle.net/joshdmiller/NDFHg/
*/
angular.module('docs').directive('inlineEdit', function() {
return {
restrict: 'E',
scope: {
value: '=',
editCallback: '&onEdit'
},
template: '<span ng-click="edit()" ng-bind="value"></span><input type="text" class="form-control" ng-model="value" />',
link: function (scope, element, attrs) {
// Let's get a reference to the input element, as we'll want to reference it.
var inputElement = angular.element(element.children()[1]);
var el = inputElement[0];
// This directive should have a set class so we can style it.
element.addClass('inline-edit');
// Initially, we're not editing.
scope.editing = false;
// ng-click handler to activate edit-in-place
scope.edit = function () {
scope.editing = true;
scope.oldValue = el.value;
// We control display through a class on the directive itself. See the CSS.
element.addClass('active');
// And we must focus the element.
// `angular.element()` provides a chainable array, like jQuery so to access a native DOM function,
// we have to reference the first element in the array.
el.focus();
el.selectionStart = 0;
el.selectionEnd = el.value.length;
};
// When we leave the input, we're done editing.
inputElement.on('blur', function() {
scope.editing = false;
element.removeClass('active');
// Invoke parent scope callback
if (scope.editCallback && scope.oldValue != el.value) {
scope.$apply(function() {
if (scope.value) {
scope.editCallback().then(null, function() {
scope.value = scope.oldValue;
});
} else {
scope.value = scope.oldValue;
}
});
}
});
}
};
});

View File

@ -81,7 +81,6 @@
<script src="app/docs/directive/SelectTag.js" type="text/javascript"></script>
<script src="app/docs/directive/SelectRelation.js" type="text/javascript"></script>
<script src="app/docs/directive/AuditLog.js" type="text/javascript"></script>
<script src="app/docs/directive/InlineEdit.js" type="text/javascript"></script>
<script src="app/docs/directive/ImgError.js" type="text/javascript"></script>
<script src="app/docs/directive/Acl.js" type="text/javascript"></script>
<script src="app/docs/directive/AclEdit.js" type="text/javascript"></script>

View File

@ -1,6 +1,6 @@
<h1>Tags</h1>
<p><strong>Tags</strong> are labels associated to documents.</p>
<p>A document can be tagged by multiple tags, and a tag can be applied to multiple documents.</p>
<p>Using the <span class="glyphicon glyphicon-user"></span> button, you can edit permissions on a tag.</p>
<p>Using the <span class="glyphicon glyphicon-pencil"></span> button, you can edit permissions on a tag.</p>
<p>If a tag can be read by another user or group, associated documents can also be read by those people.</p>
<p>For example, tag your company documents with a tag <span class="label label-info">MyCompany</span> and add the permission <strong>Read</strong> to a group <span class="btn btn-default">employees</span></p>

View File

@ -1,8 +1,54 @@
<h1>{{ tag.name }}</h1>
<h1>{{ tag.name }}&nbsp;</h1>
<p>Permissions on this tag will also be applied to documents tagged <span class="label label-info" ng-style="{ 'background': tag.color }">{{ tag.name }}</span></p>
<div class="well col-lg-8">
<form class="form-horizontal" name="editTagForm" novalidate>
<div class="form-group" ng-class="{ 'has-error': !editTagForm.name.$valid, success: editTagForm.name.$valid }">
<label class="col-sm-2 control-label" for="inputName">Name</label>
<acl-edit source="tag.id"
acls="tag.acls"
writable="tag.writable"
creator="tag.creator"></acl-edit>
<div class="col-sm-6">
<input type="text" name="name" class="form-control" id="inputName"
ng-maxlength="36" required ng-model="tag.name" ui-validate="{ space: '!$value || $value.indexOf(\' \') == -1' }">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="inputColor">Color</label>
<div class="col-sm-2">
<span colorpicker class="btn" data-color="" id="inputColor"
ng-model="tag.color" ng-style="{ 'background': tag.color }">&nbsp;</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="inputParent">Parent</label>
<div class="col-sm-6">
<select class="form-control" ng-model="tag.parent" id="inputParent">
<option value="" ng-selected="!tag.parent"></option>
<option ng-repeat="tag0 in tags"
ng-if="tag0.id != tag.id"
ng-selected="tag.parent == tag0.id"
value="{{ tag0.id }}">Parent: {{ tag0.name }}</option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary" ng-click="edit()" ng-disabled="!editTagForm.$valid">
<span class="glyphicon glyphicon-pencil"></span> Save
</button>
</div>
</div>
</form>
</div>
<div class="well col-lg-8">
<p>Permissions on this tag will also be applied to documents tagged <span class="label label-info" ng-style="{ 'background': tag.color }">{{ tag.name }}</span></p>
<acl-edit source="tag.id"
acls="tag.acls"
writable="tag.writable"
creator="tag.creator"></acl-edit>
</div>

View File

@ -16,22 +16,24 @@
<input type="search" class="form-control" placeholder="Search" ng-model="search.name">
</p>
<table class="row table table-striped table-hover">
<table class="row table table-striped table-hover table-tags">
<tbody>
<tr ng-repeat="tag in tags | filter:search">
<td><inline-edit value="tag.name" on-edit="updateTag(tag)" ></inline-edit></td>
<td class="col-xs-4">
<select class="form-control" ng-model="tag.parent" ng-change="updateTag(tag)">
<option value="" ng-selected="!tag.parent"></option>
<option ng-repeat="tag0 in tags"
ng-if="tag0.id != tag.id"
ng-selected="tag.parent == tag0.id"
value="{{ tag0.id }}">Parent: {{ tag0.name }}</option>
</select>
<tr ng-repeat="tag in tags | filter:search" class="pointer"
ng-class="{ active: $stateParams.id == tag.id }" ng-click="viewTag(tag.id)">
<td>
<span class="glyphicon glyphicon-tag"></span>&nbsp;
<span class="label label-info" ng-style="{ 'background': tag.color }">{{ tag.name }}</span>
</td>
<td class="col-xs-1">
<a href="#/tag/{{ tag.id }}" class="btn btn-primary pull-right" title="Edit tag">
<span class="glyphicon glyphicon-pencil"></span>
</a>
</td>
<td class="col-xs-1">
<button class="btn btn-danger pull-right" ng-click="deleteTag(tag)" title="Delete this tag">
<span class="glyphicon glyphicon-trash"></span>
</button>
</td>
<td class="col-xs-1"><span colorpicker class="btn" on-hide="updateTag(tag)" data-color="" ng-model="tag.color" ng-style="{ 'background': tag.color }">&nbsp;</span></td>
<td class="col-xs-1"><a href="#/tag/{{ tag.id }}" class="btn btn-default pull-right" title="Edit permissions"><span class="glyphicon glyphicon-user"></span></a></td>
<td class="col-xs-1"><button class="btn btn-danger pull-right" ng-click="deleteTag(tag)" title="Delete this tag"><span class="glyphicon glyphicon-trash"></span></button></td>
</tr>
</tbody>
</table>

View File

@ -21,6 +21,17 @@
}
}
// Tags list
.table-tags {
td {
vertical-align: middle !important;
}
.label {
font-size: 100%;
}
}
// Documents list
.table-documents {
thead th {

View File

@ -54,6 +54,7 @@ public class TestTagResource extends BaseJerseyTest {
Assert.assertEquals("Tag4", json.getString("name"));
Assert.assertEquals("tag1", json.getString("creator"));
Assert.assertEquals("#00ff00", json.getString("color"));
Assert.assertEquals(tag3Id, json.getString("parent"));
Assert.assertTrue(json.getBoolean("writable"));
JsonArray acls = json.getJsonArray("acls");
Assert.assertEquals(2, acls.size());