mirror of
https://github.com/sismics/docs.git
synced 2024-11-25 15:17:57 +01:00
Closes #67: Relations between document (client-side)
This commit is contained in:
parent
0525754337
commit
ff91521a67
@ -28,7 +28,7 @@ public class RelationDao {
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<RelationDto> getByDocumentId(String documentId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
StringBuilder sb = new StringBuilder("select d.DOC_ID_C, d.DOC_TITLE_C ");
|
||||
StringBuilder sb = new StringBuilder("select d.DOC_ID_C, d.DOC_TITLE_C, r.REL_IDDOCFROM_C ");
|
||||
sb.append(" from T_RELATION r ");
|
||||
sb.append(" join T_DOCUMENT d on d.DOC_ID_C = r.REL_IDDOCFROM_C and r.REL_IDDOCFROM_C != :documentId or d.DOC_ID_C = r.REL_IDDOCTO_C and r.REL_IDDOCTO_C != :documentId ");
|
||||
sb.append(" where (r.REL_IDDOCFROM_C = :documentId or r.REL_IDDOCTO_C = :documentId) ");
|
||||
@ -47,6 +47,8 @@ public class RelationDao {
|
||||
RelationDto relationDto = new RelationDto();
|
||||
relationDto.setId((String) o[i++]);
|
||||
relationDto.setTitle((String) o[i++]);
|
||||
String fromDocId = (String) o[i++];
|
||||
relationDto.setSource(documentId.equals(fromDocId));
|
||||
relationDtoList.add(relationDto);
|
||||
}
|
||||
return relationDtoList;
|
||||
|
@ -16,6 +16,11 @@ public class RelationDto {
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* True if the document is the source of the relation.
|
||||
*/
|
||||
private boolean source;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
@ -31,4 +36,12 @@ public class RelationDto {
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public boolean isSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(boolean source) {
|
||||
this.source = source;
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,8 @@ public class DocumentResource extends BaseResource {
|
||||
for (RelationDto relationDto : relationDtoList) {
|
||||
relationList.add(Json.createObjectBuilder()
|
||||
.add("id", relationDto.getId())
|
||||
.add("title", relationDto.getTitle()));
|
||||
.add("title", relationDto.getTitle())
|
||||
.add("source", relationDto.isSource()));
|
||||
}
|
||||
document.add("relations", relationList);
|
||||
|
||||
@ -669,7 +670,8 @@ public class DocumentResource extends BaseResource {
|
||||
RelationDao relationDao = new RelationDao();
|
||||
Set<String> documentIdSet = new HashSet<>();
|
||||
for (String targetDocId : relationList) {
|
||||
Document document = documentDao.getDocument(targetDocId, PermType.READ, principal.getId());
|
||||
// ACL are not checked, because the editing user is not forced to view the target document
|
||||
Document document = documentDao.getById(targetDocId);
|
||||
if (document != null && !documentId.equals(targetDocId)) {
|
||||
documentIdSet.add(targetDocId);
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ angular.module('docs').controller('DocumentEdit', function($rootScope, $scope, $
|
||||
$scope.resetForm = function() {
|
||||
$scope.document = {
|
||||
tags: [],
|
||||
relations: [],
|
||||
language: 'fra'
|
||||
};
|
||||
$scope.newFiles = [];
|
||||
@ -71,6 +72,9 @@ angular.module('docs').controller('DocumentEdit', function($rootScope, $scope, $
|
||||
|
||||
// Extract ids from tags
|
||||
document.tags = _.pluck(document.tags, 'id');
|
||||
|
||||
// Extract ids from relations (only when our document is the source)
|
||||
document.relations = _.pluck(_.where(document.relations, { source: true }), 'id');
|
||||
|
||||
if ($scope.isEdit()) {
|
||||
promise = Restangular.one('document', $stateParams.id).post('', document);
|
||||
|
@ -0,0 +1,68 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Relation selection directive.
|
||||
*/
|
||||
angular.module('docs').directive('selectRelation', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'partial/docs/directive.selectrelation.html',
|
||||
replace: true,
|
||||
scope: {
|
||||
relations: '=',
|
||||
ref: '@',
|
||||
ngDisabled: '='
|
||||
},
|
||||
controller: function($scope, $q, Restangular) {
|
||||
/**
|
||||
* Add a relation.
|
||||
*/
|
||||
$scope.addRelation = function($item) {
|
||||
// Does the new relation is already in the model
|
||||
var duplicate = _.find($scope.relations, function(relation) {
|
||||
if ($item.id == relation.id) {
|
||||
return relation;
|
||||
}
|
||||
});
|
||||
|
||||
// Add the new relation
|
||||
if (!duplicate) {
|
||||
$scope.relations.push({
|
||||
id: $item.id,
|
||||
title: $item.title,
|
||||
source: true
|
||||
});
|
||||
}
|
||||
$scope.input = '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a relation.
|
||||
*/
|
||||
$scope.deleteRelation = function(deleteRelation) {
|
||||
$scope.relations = _.reject($scope.relations, function(relation) {
|
||||
return relation.id == deleteRelation.id;
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a promise for typeahead title.
|
||||
*/
|
||||
$scope.getDocumentTypeahead = function($viewValue) {
|
||||
var deferred = $q.defer();
|
||||
Restangular.one('document')
|
||||
.getList('list', {
|
||||
limit: 5,
|
||||
sort_column: 1,
|
||||
asc: true,
|
||||
search: $viewValue
|
||||
}).then(function(data) {
|
||||
deferred.resolve(data.documents);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
},
|
||||
link: function(scope, element, attr, ctrl) {
|
||||
}
|
||||
}
|
||||
});
|
@ -70,6 +70,7 @@
|
||||
<script src="app/docs/filter/Filesize.js" type="text/javascript"></script>
|
||||
<script src="app/docs/directive/File.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/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>
|
||||
|
@ -0,0 +1,13 @@
|
||||
<div>
|
||||
<ul class="list-inline">
|
||||
<li ng-repeat="relation in relations | filter: { source: true }">
|
||||
<span class="label label-info">{{ relation.title }}
|
||||
<span class="glyphicon glyphicon-remove" ng-click="deleteRelation(relation)" ng-show="!ngDisabled"></span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<input class="form-control" type="text" id="{{ ref }}" placeholder="Type a document title" ng-model="input" ng-disabled="ngDisabled"
|
||||
autocomplete="off"
|
||||
typeahead="document.title for document in getDocumentTypeahead($viewValue) | filter: $viewValue"
|
||||
typeahead-wait-ms="200" typeahead-on-select="addRelation($item)" />
|
||||
</div>
|
@ -118,6 +118,12 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="inputRelations">Relations</label>
|
||||
<div class="col-sm-10">
|
||||
<select-relation relations="document.relations" ref="inputRelations" ng-disabled="fileIsUploading"></select-relation>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="form-group">
|
||||
|
@ -19,13 +19,23 @@
|
||||
<dt>Contributors</dt>
|
||||
<dd>
|
||||
<span ng-repeat="contributor in document.contributors">
|
||||
<span class="btn btn-default btn-xs">
|
||||
<span class="btn btn-link btn-xs">
|
||||
<a href="#/user/{{ contributor.username }}">
|
||||
{{ contributor.username }}
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</dd>
|
||||
<dt>Relations</dt>
|
||||
<dd>
|
||||
<span ng-repeat="relation in document.relations">
|
||||
<span class="btn btn-link btn-xs">
|
||||
<a href="#/document/view/{{ relation.id }}">
|
||||
{{ relation.title }}
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<div ng-file-drop drag-over-class="bg-success" ng-multiple="true" allow-dir="false" ng-model="dropFiles"
|
||||
|
@ -238,6 +238,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
JsonArray relations = json.getJsonArray("relations");
|
||||
Assert.assertEquals(1, relations.size());
|
||||
Assert.assertEquals(document2Id, relations.getJsonObject(0).getString("id"));
|
||||
Assert.assertFalse(relations.getJsonObject(0).getBoolean("source"));
|
||||
Assert.assertEquals("My super title document 2", relations.getJsonObject(0).getString("title"));
|
||||
|
||||
// Get document 2
|
||||
@ -248,6 +249,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
relations = json.getJsonArray("relations");
|
||||
Assert.assertEquals(1, relations.size());
|
||||
Assert.assertEquals(document1Id, relations.getJsonObject(0).getString("id"));
|
||||
Assert.assertTrue(relations.getJsonObject(0).getBoolean("source"));
|
||||
Assert.assertEquals("My super title document 1", relations.getJsonObject(0).getString("title"));
|
||||
|
||||
// Export a document in PDF format
|
||||
|
Loading…
Reference in New Issue
Block a user