mirror of
https://github.com/sismics/docs.git
synced 2024-11-22 14:07:55 +01:00
Closes #93: Edit tag color and title in #/tag/id
This commit is contained in:
parent
26685334a1
commit
e234440ce6
@ -97,6 +97,14 @@ public class TagResource extends BaseResource {
|
|||||||
.add("name", tagDto.getName())
|
.add("name", tagDto.getName())
|
||||||
.add("color", tagDto.getColor());
|
.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
|
// Add ACL
|
||||||
AclUtil.addAcls(tag, id, getTargetIdList(null));
|
AclUtil.addAcls(tag, id, getTargetIdList(null));
|
||||||
|
|
||||||
|
@ -3,13 +3,20 @@
|
|||||||
/**
|
/**
|
||||||
* Tag controller.
|
* 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' };
|
$scope.tag = { name: '', color: '#3a87ad' };
|
||||||
|
|
||||||
// Retrieve tags
|
// Retrieve tags
|
||||||
Restangular.one('tag/list').get().then(function(data) {
|
Restangular.one('tag/list').get().then(function(data) {
|
||||||
$scope.tags = data.tags;
|
$scope.tags = data.tags;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a tag.
|
||||||
|
*/
|
||||||
|
$scope.viewTag = function(id) {
|
||||||
|
$state.go('tag.edit', { id: id });
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a tag.
|
* 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);
|
|
||||||
};
|
|
||||||
});
|
});
|
@ -4,7 +4,23 @@
|
|||||||
* Tag edit controller.
|
* Tag edit controller.
|
||||||
*/
|
*/
|
||||||
angular.module('docs').controller('TagEdit', function($scope, $stateParams, Restangular) {
|
angular.module('docs').controller('TagEdit', function($scope, $stateParams, Restangular) {
|
||||||
|
// Retrieve the tag
|
||||||
Restangular.one('tag', $stateParams.id).get().then(function(data) {
|
Restangular.one('tag', $stateParams.id).get().then(function(data) {
|
||||||
$scope.tag = 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);
|
||||||
|
};
|
||||||
});
|
});
|
@ -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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
@ -81,7 +81,6 @@
|
|||||||
<script src="app/docs/directive/SelectTag.js" type="text/javascript"></script>
|
<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/SelectRelation.js" type="text/javascript"></script>
|
||||||
<script src="app/docs/directive/AuditLog.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/ImgError.js" type="text/javascript"></script>
|
||||||
<script src="app/docs/directive/Acl.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>
|
<script src="app/docs/directive/AclEdit.js" type="text/javascript"></script>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<h1>Tags</h1>
|
<h1>Tags</h1>
|
||||||
<p><strong>Tags</strong> are labels associated to documents.</p>
|
<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>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>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>
|
<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>
|
@ -1,8 +1,54 @@
|
|||||||
<h1>{{ tag.name }}</h1>
|
<h1>{{ tag.name }} </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"
|
<div class="col-sm-6">
|
||||||
acls="tag.acls"
|
<input type="text" name="name" class="form-control" id="inputName"
|
||||||
writable="tag.writable"
|
ng-maxlength="36" required ng-model="tag.name" ui-validate="{ space: '!$value || $value.indexOf(\' \') == -1' }">
|
||||||
creator="tag.creator"></acl-edit>
|
</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 }"> </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>
|
@ -16,22 +16,24 @@
|
|||||||
<input type="search" class="form-control" placeholder="Search" ng-model="search.name">
|
<input type="search" class="form-control" placeholder="Search" ng-model="search.name">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<table class="row table table-striped table-hover">
|
<table class="row table table-striped table-hover table-tags">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="tag in tags | filter:search">
|
<tr ng-repeat="tag in tags | filter:search" class="pointer"
|
||||||
<td><inline-edit value="tag.name" on-edit="updateTag(tag)" ></inline-edit></td>
|
ng-class="{ active: $stateParams.id == tag.id }" ng-click="viewTag(tag.id)">
|
||||||
<td class="col-xs-4">
|
<td>
|
||||||
<select class="form-control" ng-model="tag.parent" ng-change="updateTag(tag)">
|
<span class="glyphicon glyphicon-tag"></span>
|
||||||
<option value="" ng-selected="!tag.parent"></option>
|
<span class="label label-info" ng-style="{ 'background': tag.color }">{{ tag.name }}</span>
|
||||||
<option ng-repeat="tag0 in tags"
|
</td>
|
||||||
ng-if="tag0.id != tag.id"
|
<td class="col-xs-1">
|
||||||
ng-selected="tag.parent == tag0.id"
|
<a href="#/tag/{{ tag.id }}" class="btn btn-primary pull-right" title="Edit tag">
|
||||||
value="{{ tag0.id }}">Parent: {{ tag0.name }}</option>
|
<span class="glyphicon glyphicon-pencil"></span>
|
||||||
</select>
|
</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>
|
||||||
<td class="col-xs-1"><span colorpicker class="btn" on-hide="updateTag(tag)" data-color="" ng-model="tag.color" ng-style="{ 'background': tag.color }"> </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>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -21,6 +21,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tags list
|
||||||
|
.table-tags {
|
||||||
|
td {
|
||||||
|
vertical-align: middle !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Documents list
|
// Documents list
|
||||||
.table-documents {
|
.table-documents {
|
||||||
thead th {
|
thead th {
|
||||||
|
@ -54,6 +54,7 @@ public class TestTagResource extends BaseJerseyTest {
|
|||||||
Assert.assertEquals("Tag4", json.getString("name"));
|
Assert.assertEquals("Tag4", json.getString("name"));
|
||||||
Assert.assertEquals("tag1", json.getString("creator"));
|
Assert.assertEquals("tag1", json.getString("creator"));
|
||||||
Assert.assertEquals("#00ff00", json.getString("color"));
|
Assert.assertEquals("#00ff00", json.getString("color"));
|
||||||
|
Assert.assertEquals(tag3Id, json.getString("parent"));
|
||||||
Assert.assertTrue(json.getBoolean("writable"));
|
Assert.assertTrue(json.getBoolean("writable"));
|
||||||
JsonArray acls = json.getJsonArray("acls");
|
JsonArray acls = json.getJsonArray("acls");
|
||||||
Assert.assertEquals(2, acls.size());
|
Assert.assertEquals(2, acls.size());
|
||||||
|
Loading…
Reference in New Issue
Block a user