diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/DocumentDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/DocumentDao.java index 7bf5dcd8..4397b7f6 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/DocumentDao.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/DocumentDao.java @@ -123,17 +123,9 @@ public class DocumentDao { Map parameterMap = new HashMap(); List criteriaList = new ArrayList(); - StringBuilder sb = new StringBuilder("select d.DOC_ID_C c0, d.DOC_TITLE_C c1, d.DOC_DESCRIPTION_C c2, d.DOC_CREATEDATE_D c3"); + StringBuilder sb = new StringBuilder("select d.DOC_ID_C c0, d.DOC_TITLE_C c1, d.DOC_DESCRIPTION_C c2, d.DOC_CREATEDATE_D c3, s.SHA_ID_C is not null c4 "); sb.append(" from T_DOCUMENT d "); - if (criteria.getTagIdList() != null && !criteria.getTagIdList().isEmpty()) { - int index = 0; - for (String tagId : criteria.getTagIdList()) { - sb.append(" left join T_DOCUMENT_TAG dt" + index + " on dt" + index + ".DOT_IDDOCUMENT_C = d.DOC_ID_C and dt" + index + ".DOT_IDTAG_C = :tagId" + index + " "); - criteriaList.add("dt" + index + ".DOT_ID_C is not null"); - parameterMap.put("tagId" + index, tagId); - index++; - } - } + sb.append(" left join T_SHARE s on s.SHA_IDDOCUMENT_C = d.DOC_ID_C and s.SHA_DELETEDATE_D is null "); // Adds search criteria if (criteria.getUserId() != null) { @@ -152,6 +144,18 @@ public class DocumentDao { criteriaList.add("d.DOC_CREATEDATE_D <= :createDateMax"); parameterMap.put("createDateMax", criteria.getCreateDateMax()); } + if (criteria.getTagIdList() != null && !criteria.getTagIdList().isEmpty()) { + int index = 0; + for (String tagId : criteria.getTagIdList()) { + sb.append(" left join T_DOCUMENT_TAG dt" + index + " on dt" + index + ".DOT_IDDOCUMENT_C = d.DOC_ID_C and dt" + index + ".DOT_IDTAG_C = :tagId" + index + " "); + criteriaList.add("dt" + index + ".DOT_ID_C is not null"); + parameterMap.put("tagId" + index, tagId); + index++; + } + } + if (criteria.getShared() != null && criteria.getShared()) { + criteriaList.add("s.SHA_ID_C is not null"); + } criteriaList.add("d.DOC_DELETEDATE_D is null"); @@ -173,6 +177,7 @@ public class DocumentDao { documentDto.setTitle((String) o[i++]); documentDto.setDescription((String) o[i++]); documentDto.setCreateTimestamp(((Timestamp) o[i++]).getTime()); + documentDto.setShared((Boolean) o[i++]); documentDtoList.add(documentDto); } diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/DocumentCriteria.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/DocumentCriteria.java index 250b1ddc..0419afc8 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/DocumentCriteria.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/DocumentCriteria.java @@ -35,6 +35,11 @@ public class DocumentCriteria { */ private List tagIdList; + /** + * Shared status. + */ + private Boolean shared; + /** * Getter of userId. * @@ -124,4 +129,22 @@ public class DocumentCriteria { public void setTagIdList(List tagIdList) { this.tagIdList = tagIdList; } + + /** + * Getter of shared. + * + * @return the shared + */ + public Boolean getShared() { + return shared; + } + + /** + * Setter of shared. + * + * @param shared shared + */ + public void setShared(Boolean shared) { + this.shared = shared; + } } diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/DocumentDto.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/DocumentDto.java index 2bca5d21..e083965e 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/DocumentDto.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/DocumentDto.java @@ -28,6 +28,11 @@ public class DocumentDto { * Creation date. */ private Long createTimestamp; + + /** + * Shared status. + */ + private Boolean shared; /** * Getter de id. @@ -100,4 +105,22 @@ public class DocumentDto { public void setCreateTimestamp(Long createTimestamp) { this.createTimestamp = createTimestamp; } + + /** + * Getter of shared. + * + * @return the shared + */ + public Boolean getShared() { + return shared; + } + + /** + * Setter of shared. + * + * @param shared shared + */ + public void setShared(Boolean shared) { + this.shared = shared; + } } diff --git a/docs-parent/TODO b/docs-parent/TODO index cf943063..79fc21bf 100644 --- a/docs-parent/TODO +++ b/docs-parent/TODO @@ -1 +1,2 @@ -- Advanced search: shared documents (client/server) \ No newline at end of file +- Advanced search: shared documents (client) +- Show shared status in documents list (client) \ No newline at end of file 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 f13d7141..425f70a5 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 @@ -129,7 +129,8 @@ public class DocumentResource extends BaseResource { @QueryParam("search") String search, @QueryParam("create_date_min") String createDateMinStr, @QueryParam("create_date_max") String createDateMaxStr, - @QueryParam("tags") List tagIdList) throws JSONException { + @QueryParam("tags") List tagIdList, + @QueryParam("shared") Boolean shared) throws JSONException { if (!authenticate()) { throw new ForbiddenClientException(); } @@ -150,6 +151,7 @@ public class DocumentResource extends BaseResource { documentCriteria.setCreateDateMin(createDateMin); documentCriteria.setCreateDateMax(createDateMax); documentCriteria.setTagIdList(tagIdList); + documentCriteria.setShared(shared); if (!Strings.isNullOrEmpty(search)) { documentCriteria.setSearch(search); } @@ -161,6 +163,7 @@ public class DocumentResource extends BaseResource { document.put("title", documentDto.getTitle()); document.put("description", documentDto.getDescription()); document.put("create_date", documentDto.getCreateTimestamp()); + document.put("shared", documentDto.getShared()); // Get tags List tagDtoList = tagDao.getByDocumentId(documentDto.getId()); diff --git a/docs-web/src/main/webapp/app/docs/app.js b/docs-web/src/main/webapp/app/docs/app.js index b86b40e1..422187be 100644 --- a/docs-web/src/main/webapp/app/docs/app.js +++ b/docs-web/src/main/webapp/app/docs/app.js @@ -5,14 +5,14 @@ */ var App = angular.module('docs', // Dependencies - ['ui.state', 'ui.bootstrap', 'ui.route', 'ui.keypress', 'ui.validate', + ['ui.state', 'ui.bootstrap', 'ui.keypress', 'ui.validate', 'ui.sortable', 'restangular', 'ngSanitize', 'ngMobile', 'colorpicker.module'] ) /** * Configuring modules. */ -.config(function($stateProvider, $httpProvider, $routeProvider, RestangularProvider) { +.config(function($stateProvider, $httpProvider, RestangularProvider) { // Configuring UI Router $stateProvider .state('main', { diff --git a/docs-web/src/main/webapp/app/share/app.js b/docs-web/src/main/webapp/app/share/app.js index 177585a5..3a407e3e 100644 --- a/docs-web/src/main/webapp/app/share/app.js +++ b/docs-web/src/main/webapp/app/share/app.js @@ -5,13 +5,13 @@ */ var App = angular.module('share', // Dependencies - ['ui.state', 'ui.bootstrap', 'ui.route', 'restangular', 'ngSanitize', 'ngMobile'] + ['ui.state', 'ui.bootstrap', 'restangular', 'ngSanitize', 'ngMobile'] ) /** * Configuring modules. */ -.config(function($stateProvider, $httpProvider, $routeProvider, RestangularProvider) { +.config(function($stateProvider, $httpProvider, RestangularProvider) { // Configuring UI Router $stateProvider .state('main', { diff --git a/docs-web/src/main/webapp/app/share/controller/FileView.js b/docs-web/src/main/webapp/app/share/controller/FileView.js new file mode 100644 index 00000000..322813da --- /dev/null +++ b/docs-web/src/main/webapp/app/share/controller/FileView.js @@ -0,0 +1,83 @@ +'use strict'; + +/** + * File view controller. + */ +App.controller('FileView', function($dialog, $state, $stateParams) { + var dialog = $dialog.dialog({ + keyboard: true, + templateUrl: 'partial/share/file.view.html', + controller: function($scope, $state, $stateParams, Restangular, dialog) { + // Load files + Restangular.one('file').getList('list', { id: $stateParams.documentId, share: $stateParams.shareId }).then(function(data) { + $scope.files = data.files; + + // Search current file + _.each($scope.files, function(value) { + if (value.id == $stateParams.fileId) { + $scope.file = value; + } + }); + }); + + /** + * Navigate to the next file. + */ + $scope.nextFile = function() { + _.each($scope.files, function(value, key) { + if (value.id == $stateParams.fileId) { + var next = $scope.files[key + 1]; + if (next) { + dialog.close({}); + $state.transitionTo('share.file', { documentId: $stateParams.documentId, shareId: $stateParams.shareId, fileId: next.id }); + } + } + }); + }; + + /** + * Navigate to the previous file. + */ + $scope.previousFile = function() { + _.each($scope.files, function(value, key) { + if (value.id == $stateParams.fileId) { + var previous = $scope.files[key - 1]; + if (previous) { + dialog.close({}); + $state.transitionTo('share.file', { documentId: $stateParams.documentId, shareId: $stateParams.shareId, fileId: previous.id }); + } + } + }); + }; + + /** + * Open the file in a new window. + */ + $scope.openFile = function() { + window.open('api/file/' + $stateParams.fileId + '/data?share=' + $stateParams.shareId); + }; + + /** + * Close the file preview. + */ + $scope.closeFile = function () { + dialog.close(); + }; + + // Close the dialog when the user exits this state + var off = $scope.$on('$stateChangeStart', function(event, toState){ + if (dialog.isOpen()) { + dialog.close(toState.name == 'share.file' ? {} : null); + } + off(); + }); + } + }); + + // Returns to share view on file close + dialog.open().then(function(result) { + if (result == null) { + $state.transitionTo('share', { documentId: $stateParams.documentId, shareId: $stateParams.shareId }); + } + }); +}); \ No newline at end of file diff --git a/docs-web/src/main/webapp/partial/share/file.view.html b/docs-web/src/main/webapp/partial/share/file.view.html new file mode 100644 index 00000000..bd345ebf --- /dev/null +++ b/docs-web/src/main/webapp/partial/share/file.view.html @@ -0,0 +1,21 @@ +
+
+ +
+ +
+ + +
+ +
+ +
+
+ + + + +
+ +
diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java index 0266edfa..9c2f09ca 100644 --- a/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java @@ -58,6 +58,15 @@ public class TestDocumentResource extends BaseJerseyTest { String document1Id = json.optString("id"); Assert.assertNotNull(document1Id); + // Share this document + WebResource fileShareResource = resource().path("/share"); + fileShareResource.addFilter(new CookieAuthenticationFilter(document1Token)); + postParams = new MultivaluedMapImpl(); + postParams.add("id", document1Id); + response = fileShareResource.put(ClientResponse.class, postParams); + Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); + json = response.getEntity(JSONObject.class); + // List all documents documentResource = resource().path("/document/list"); documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); @@ -114,6 +123,19 @@ public class TestDocumentResource extends BaseJerseyTest { Assert.assertTrue(documents.length() == 1); Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id")); + // Search documents by shared status + documentResource = resource().path("/document/list"); + documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); + getParams = new MultivaluedMapImpl(); + getParams.putSingle("shared", true); + response = documentResource.queryParams(getParams).get(ClientResponse.class); + json = response.getEntity(JSONObject.class); + Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); + documents = json.getJSONArray("documents"); + Assert.assertTrue(documents.length() == 1); + Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id")); + Assert.assertEquals(true, documents.getJSONObject(0).getBoolean("shared")); + // Search documents (nothing) documentResource = resource().path("/document/list"); documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestShareResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestShareResource.java index a4cbca01..0086a49d 100644 --- a/docs-web/src/test/java/com/sismics/docs/rest/TestShareResource.java +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestShareResource.java @@ -64,12 +64,12 @@ public class TestShareResource extends BaseJerseyTest { String file1Id = json.getString("id"); // Share this document - WebResource fileShareResource = resource().path("/share"); - fileShareResource.addFilter(new CookieAuthenticationFilter(share1AuthenticationToken)); + WebResource shareResource = resource().path("/share"); + shareResource.addFilter(new CookieAuthenticationFilter(share1AuthenticationToken)); postParams = new MultivaluedMapImpl(); postParams.add("id", document1Id); postParams.add("name", "4 All"); - response = fileShareResource.put(ClientResponse.class, postParams); + response = shareResource.put(ClientResponse.class, postParams); Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); json = response.getEntity(JSONObject.class); String share1Id = json.getString("id"); @@ -109,9 +109,9 @@ public class TestShareResource extends BaseJerseyTest { Assert.assertEquals(163510, fileBytes.length); // Deletes the share - fileShareResource = resource().path("/share/" + share1Id); - fileShareResource.addFilter(new CookieAuthenticationFilter(share1AuthenticationToken)); - response = fileShareResource.delete(ClientResponse.class); + shareResource = resource().path("/share/" + share1Id); + shareResource.addFilter(new CookieAuthenticationFilter(share1AuthenticationToken)); + response = shareResource.delete(ClientResponse.class); Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); json = response.getEntity(JSONObject.class); Assert.assertEquals("ok", json.getString("status"));