From ff91521a67c687e0dc767cc48380c90a09ffe7ae Mon Sep 17 00:00:00 2001 From: jendib Date: Sat, 12 Mar 2016 20:29:02 +0100 Subject: [PATCH] Closes #67: Relations between document (client-side) --- .../docs/core/dao/jpa/RelationDao.java | 4 +- .../docs/core/dao/jpa/dto/RelationDto.java | 13 ++++ .../docs/rest/resource/DocumentResource.java | 6 +- .../src/app/docs/controller/DocumentEdit.js | 4 ++ .../src/app/docs/directive/SelectRelation.js | 68 +++++++++++++++++++ docs-web/src/main/webapp/src/index.html | 1 + .../docs/directive.selectrelation.html | 13 ++++ .../src/partial/docs/document.edit.html | 6 ++ .../partial/docs/document.view.content.html | 12 +++- .../docs/rest/TestDocumentResource.java | 2 + 10 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 docs-web/src/main/webapp/src/app/docs/directive/SelectRelation.js create mode 100644 docs-web/src/main/webapp/src/partial/docs/directive.selectrelation.html diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RelationDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RelationDao.java index ea483c53..5061cf82 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RelationDao.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RelationDao.java @@ -28,7 +28,7 @@ public class RelationDao { @SuppressWarnings("unchecked") public List 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; diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/RelationDto.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/RelationDto.java index c44e4ec9..eeba9cca 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/RelationDto.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/RelationDto.java @@ -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; + } } diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java index 09be3262..4c25953e 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java @@ -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 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); } diff --git a/docs-web/src/main/webapp/src/app/docs/controller/DocumentEdit.js b/docs-web/src/main/webapp/src/app/docs/controller/DocumentEdit.js index 653133a0..e13839f9 100644 --- a/docs-web/src/main/webapp/src/app/docs/controller/DocumentEdit.js +++ b/docs-web/src/main/webapp/src/app/docs/controller/DocumentEdit.js @@ -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); diff --git a/docs-web/src/main/webapp/src/app/docs/directive/SelectRelation.js b/docs-web/src/main/webapp/src/app/docs/directive/SelectRelation.js new file mode 100644 index 00000000..df0cdce6 --- /dev/null +++ b/docs-web/src/main/webapp/src/app/docs/directive/SelectRelation.js @@ -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) { + } + } +}); \ No newline at end of file diff --git a/docs-web/src/main/webapp/src/index.html b/docs-web/src/main/webapp/src/index.html index a2b48b69..8edaaecf 100644 --- a/docs-web/src/main/webapp/src/index.html +++ b/docs-web/src/main/webapp/src/index.html @@ -70,6 +70,7 @@ + diff --git a/docs-web/src/main/webapp/src/partial/docs/directive.selectrelation.html b/docs-web/src/main/webapp/src/partial/docs/directive.selectrelation.html new file mode 100644 index 00000000..c4ec6a53 --- /dev/null +++ b/docs-web/src/main/webapp/src/partial/docs/directive.selectrelation.html @@ -0,0 +1,13 @@ +
+
    +
  • + {{ relation.title }} + + +
  • +
+ +
\ No newline at end of file diff --git a/docs-web/src/main/webapp/src/partial/docs/document.edit.html b/docs-web/src/main/webapp/src/partial/docs/document.edit.html index 5a147655..f057e0eb 100644 --- a/docs-web/src/main/webapp/src/partial/docs/document.edit.html +++ b/docs-web/src/main/webapp/src/partial/docs/document.edit.html @@ -118,6 +118,12 @@ +
+ +
+ +
+
diff --git a/docs-web/src/main/webapp/src/partial/docs/document.view.content.html b/docs-web/src/main/webapp/src/partial/docs/document.view.content.html index 5b4f68ee..699ccd49 100644 --- a/docs-web/src/main/webapp/src/partial/docs/document.view.content.html +++ b/docs-web/src/main/webapp/src/partial/docs/document.view.content.html @@ -19,13 +19,23 @@
Contributors
- + {{ contributor.username }}
+
Relations
+
+ + + + {{ relation.title }} + + + +