From 66cb7333c1c9159a6e51c114e1481b2d0b8a06e8 Mon Sep 17 00:00:00 2001 From: jendib Date: Sun, 1 Nov 2015 14:48:07 +0100 Subject: [PATCH] Closes #33: subviews for /document/view/id --- .../com/sismics/docs/core/util/FileUtil.java | 4 +- docs-web/src/main/webapp/src/app/docs/app.js | 42 ++++ .../src/app/docs/controller/DocumentView.js | 197 +----------------- .../docs/controller/DocumentViewActivity.js | 13 ++ .../docs/controller/DocumentViewContent.js | 119 +++++++++++ .../controller/DocumentViewPermissions.js | 81 +++++++ .../webapp/src/app/docs/controller/Main.js | 8 +- docs-web/src/main/webapp/src/index.html | 3 + .../partial/docs/document.view.activity.html | 1 + .../partial/docs/document.view.content.html | 37 ++++ .../src/partial/docs/document.view.html | 125 ++--------- .../docs/document.view.permissions.html | 53 +++++ 12 files changed, 373 insertions(+), 310 deletions(-) create mode 100644 docs-web/src/main/webapp/src/app/docs/controller/DocumentViewActivity.js create mode 100644 docs-web/src/main/webapp/src/app/docs/controller/DocumentViewContent.js create mode 100644 docs-web/src/main/webapp/src/app/docs/controller/DocumentViewPermissions.js create mode 100644 docs-web/src/main/webapp/src/partial/docs/document.view.activity.html create mode 100644 docs-web/src/main/webapp/src/partial/docs/document.view.content.html create mode 100644 docs-web/src/main/webapp/src/partial/docs/document.view.permissions.html diff --git a/docs-core/src/main/java/com/sismics/docs/core/util/FileUtil.java b/docs-core/src/main/java/com/sismics/docs/core/util/FileUtil.java index 702160b3..40e04e15 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/util/FileUtil.java +++ b/docs-core/src/main/java/com/sismics/docs/core/util/FileUtil.java @@ -105,7 +105,7 @@ public class FileUtil { PDDocument pdfDocument = null; try { PDFTextStripper stripper = new PDFTextStripper(); - pdfDocument = PDDocument.load(inputStream, true); + pdfDocument = PDDocument.load(inputStream); content = stripper.getText(pdfDocument); } catch (IOException e) { log.error("Error while extracting text from the PDF", e); @@ -157,7 +157,7 @@ public class FileUtil { // Generate preview from the first page of the PDF PDDocument pdfDocument = null; try { - pdfDocument = PDDocument.load(inputStream, true); + pdfDocument = PDDocument.load(inputStream); PDFRenderer renderer = new PDFRenderer(pdfDocument); image = renderer.renderImage(0); } finally { diff --git a/docs-web/src/main/webapp/src/app/docs/app.js b/docs-web/src/main/webapp/src/app/docs/app.js index ab3a7c9a..5a1860c3 100644 --- a/docs-web/src/main/webapp/src/app/docs/app.js +++ b/docs-web/src/main/webapp/src/app/docs/app.js @@ -156,6 +156,7 @@ angular.module('docs', }) .state('document.view', { url: '/view/:id', + redirectTo: 'document.view.content', views: { 'document': { templateUrl: 'partial/docs/document.view.html', @@ -163,6 +164,33 @@ angular.module('docs', } } }) + .state('document.view.content', { + url: '/content', + views: { + 'tab': { + templateUrl: 'partial/docs/document.view.content.html', + controller: 'DocumentViewContent' + } + } + }) + .state('document.view.permissions', { + url: '/permissions', + views: { + 'tab': { + templateUrl: 'partial/docs/document.view.permissions.html', + controller: 'DocumentViewPermissions' + } + } + }) + .state('document.view.activity', { + url: '/activity', + views: { + 'tab': { + templateUrl: 'partial/docs/document.view.activity.html', + controller: 'DocumentViewActivity' + } + } + }) .state('document.view.file', { url: '/file/:fileId', views: { @@ -231,4 +259,18 @@ angular.module('docs', $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; $rootScope.pageTitle = 'Sismics Docs'; +}) +/** + * Redirection support for ui-router. + * Thanks to https://github.com/acollard + * See https://github.com/angular-ui/ui-router/issues/1584#issuecomment-76993045 + */ +.run(function($rootScope, $state){ + $rootScope.$on('$stateChangeStart', function(event, toState, toParams) { + var redirect = toState.redirectTo; + if (redirect) { + event.preventDefault(); + $state.go(redirect, toParams); + } + }); }); \ No newline at end of file diff --git a/docs-web/src/main/webapp/src/app/docs/controller/DocumentView.js b/docs-web/src/main/webapp/src/app/docs/controller/DocumentView.js index dbe473d5..bf71478d 100644 --- a/docs-web/src/main/webapp/src/app/docs/controller/DocumentView.js +++ b/docs-web/src/main/webapp/src/app/docs/controller/DocumentView.js @@ -3,7 +3,7 @@ /** * Document view controller. */ -angular.module('docs').controller('DocumentView', function ($scope, $state, $stateParams, $location, $dialog, $modal, Restangular, $upload, $q) { +angular.module('docs').controller('DocumentView', function ($scope, $state, $stateParams, $location, $dialog, $modal, Restangular, $timeout) { // Load document data from server Restangular.one('document', $stateParams.id).get().then(function(data) { $scope.document = data; @@ -11,60 +11,6 @@ angular.module('docs').controller('DocumentView', function ($scope, $state, $sta $scope.error = response; }); - // Load audit log data from server - Restangular.one('auditlog').get({ - document: $stateParams.id - }).then(function(data) { - $scope.logs = data.logs; - }); - - // Watch for ACLs change and group them for easy displaying - $scope.$watch('document.acls', function(acls) { - $scope.acls = _.groupBy(acls, function(acl) { - return acl.id; - }); - }); - - // Initialize add ACL - $scope.acl = { perm: 'READ' }; - - /** - * Configuration for file sorting. - */ - $scope.fileSortableOptions = { - forceHelperSize: true, - forcePlaceholderSize: true, - tolerance: 'pointer', - handle: '.handle', - stop: function () { - // Send new positions to server - $scope.$apply(function () { - Restangular.one('file').post('reorder', { - id: $stateParams.id, - order: _.pluck($scope.files, 'id') - }); - }); - } - }; - - /** - * Load files from server. - */ - $scope.loadFiles = function () { - Restangular.one('file').getList('list', { id: $stateParams.id }).then(function (data) { - $scope.files = data.files; - // TODO Keep currently uploading files - }); - }; - $scope.loadFiles(); - - /** - * Navigate to the selected file. - */ - $scope.openFile = function (file) { - $state.go('document.view.file', { id: $stateParams.id, fileId: file.id }) - }; - /** * Delete a document. */ @@ -86,26 +32,6 @@ angular.module('docs').controller('DocumentView', function ($scope, $state, $sta }); }; - /** - * Delete a file. - */ - $scope.deleteFile = function (file) { - var title = 'Delete file'; - var msg = 'Do you really want to delete this file?'; - var btns = [ - {result: 'cancel', label: 'Cancel'}, - {result: 'ok', label: 'OK', cssClass: 'btn-primary'} - ]; - - $dialog.messageBox(title, msg, btns, function (result) { - if (result == 'ok') { - Restangular.one('file', file.id).remove().then(function () { - $scope.loadFiles(); - }); - } - }); - }; - /** * Open the share dialog. */ @@ -157,125 +83,4 @@ angular.module('docs').controller('DocumentView', function ($scope, $state, $sta } }); }; - - /** - * File has been drag & dropped. - */ - $scope.fileDropped = function(files) { - if (!$scope.document.writable) { - return; - } - - if (files && files.length) { - // Adding files to the UI - var newfiles = []; - _.each(files, function(file) { - var newfile = { - progress: 0, - name: file.name, - create_date: new Date().getTime(), - mimetype: file.type, - status: 'Pending...' - }; - $scope.files.push(newfile); - newfiles.push(newfile); - }); - - // Uploading files sequentially - var key = 0; - var then = function() { - if (files[key]) { - $scope.uploadFile(files[key], newfiles[key++]).then(then); - } - }; - then(); - } - }; - - /** - * Upload a file. - */ - $scope.uploadFile = function(file, newfile) { - // Upload the file - newfile.status = 'Uploading...'; - return $upload.upload({ - method: 'PUT', - url: '../api/file', - file: file, - fields: { - id: $stateParams.id - } - }) - .progress(function (e) { - newfile.progress = parseInt(100.0 * e.loaded / e.total); - }) - .success(function (data) { - newfile.id = data.id; - }); - }; - - /** - * Delete an ACL. - */ - $scope.deleteAcl = function(acl) { - Restangular.one('acl/' + $stateParams.id + '/' + acl.perm + '/' + acl.id, null).remove().then(function () { - $scope.document.acls = _.reject($scope.document.acls, function(s) { - return angular.equals(acl, s); - }); - }); - }; - - /** - * Add an ACL. - */ - $scope.addAcl = function() { - // Compute ACLs to add - $scope.acl.source = $stateParams.id; - var acls = []; - if ($scope.acl.perm == 'READWRITE') { - acls = [{ - source: $stateParams.id, - username: $scope.acl.username, - perm: 'READ' - }, { - source: $stateParams.id, - username: $scope.acl.username, - perm: 'WRITE' - }]; - } else { - acls = [{ - source: $stateParams.id, - username: $scope.acl.username, - perm: $scope.acl.perm - }]; - } - - // Add ACLs - _.each(acls, function(acl) { - Restangular.one('acl').put(acl).then(function(acl) { - if (_.isUndefined(acl.id)) { - return; - } - $scope.document.acls.push(acl); - $scope.document.acls = angular.copy($scope.document.acls); - }); - }); - - // Reset form - $scope.acl = { perm: 'READ' }; - }; - - /** - * Auto-complete on ACL target. - */ - $scope.getTargetAclTypeahead = function($viewValue) { - var deferred = $q.defer(); - Restangular.one('acl/target/search') - .get({ - search: $viewValue - }).then(function(data) { - deferred.resolve(_.pluck(data.users, 'username'), true); - }); - return deferred.promise; - }; }); \ No newline at end of file diff --git a/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewActivity.js b/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewActivity.js new file mode 100644 index 00000000..09e702fb --- /dev/null +++ b/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewActivity.js @@ -0,0 +1,13 @@ +'use strict'; + +/** + * Document view activity controller. + */ +angular.module('docs').controller('DocumentViewActivity', function ($scope, $stateParams, Restangular) { + // Load audit log data from server + Restangular.one('auditlog').get({ + document: $stateParams.id + }).then(function(data) { + $scope.logs = data.logs; + }); +}); \ No newline at end of file diff --git a/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewContent.js b/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewContent.js new file mode 100644 index 00000000..bab5b48d --- /dev/null +++ b/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewContent.js @@ -0,0 +1,119 @@ +'use strict'; + +/** + * Document view content controller. + */ +angular.module('docs').controller('DocumentViewContent', function ($scope, $stateParams, Restangular, $dialog, $state, $upload) { + /** + * Configuration for file sorting. + */ + $scope.fileSortableOptions = { + forceHelperSize: true, + forcePlaceholderSize: true, + tolerance: 'pointer', + handle: '.handle', + stop: function () { + // Send new positions to server + $scope.$apply(function () { + Restangular.one('file').post('reorder', { + id: $stateParams.id, + order: _.pluck($scope.files, 'id') + }); + }); + } + }; + + /** + * Load files from server. + */ + $scope.loadFiles = function () { + Restangular.one('file').getList('list', { id: $stateParams.id }).then(function (data) { + $scope.files = data.files; + // TODO Keep currently uploading files + }); + }; + $scope.loadFiles(); + + /** + * Navigate to the selected file. + */ + $scope.openFile = function (file) { + $state.go('document.view.file', { id: $stateParams.id, fileId: file.id }) + }; + + /** + * Delete a file. + */ + $scope.deleteFile = function (file) { + var title = 'Delete file'; + var msg = 'Do you really want to delete this file?'; + var btns = [ + {result: 'cancel', label: 'Cancel'}, + {result: 'ok', label: 'OK', cssClass: 'btn-primary'} + ]; + + $dialog.messageBox(title, msg, btns, function (result) { + if (result == 'ok') { + Restangular.one('file', file.id).remove().then(function () { + $scope.loadFiles(); + }); + } + }); + }; + + /** + * File has been drag & dropped. + */ + $scope.fileDropped = function(files) { + if (!$scope.document.writable) { + return; + } + + if (files && files.length) { + // Adding files to the UI + var newfiles = []; + _.each(files, function(file) { + var newfile = { + progress: 0, + name: file.name, + create_date: new Date().getTime(), + mimetype: file.type, + status: 'Pending...' + }; + $scope.files.push(newfile); + newfiles.push(newfile); + }); + + // Uploading files sequentially + var key = 0; + var then = function() { + if (files[key]) { + $scope.uploadFile(files[key], newfiles[key++]).then(then); + } + }; + then(); + } + }; + + /** + * Upload a file. + */ + $scope.uploadFile = function(file, newfile) { + // Upload the file + newfile.status = 'Uploading...'; + return $upload.upload({ + method: 'PUT', + url: '../api/file', + file: file, + fields: { + id: $stateParams.id + } + }) + .progress(function (e) { + newfile.progress = parseInt(100.0 * e.loaded / e.total); + }) + .success(function (data) { + newfile.id = data.id; + }); + }; +}); \ No newline at end of file diff --git a/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewPermissions.js b/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewPermissions.js new file mode 100644 index 00000000..2c6ecb5f --- /dev/null +++ b/docs-web/src/main/webapp/src/app/docs/controller/DocumentViewPermissions.js @@ -0,0 +1,81 @@ +'use strict'; + +/** + * Document view permissions controller. + */ +angular.module('docs').controller('DocumentViewPermissions', function ($scope, $stateParams, Restangular, $q) { + // Watch for ACLs change and group them for easy displaying + $scope.$watch('document.acls', function(acls) { + $scope.acls = _.groupBy(acls, function(acl) { + return acl.id; + }); + }); + + // Initialize add ACL + $scope.acl = { perm: 'READ' }; + + /** + * Delete an ACL. + */ + $scope.deleteAcl = function(acl) { + Restangular.one('acl/' + $stateParams.id + '/' + acl.perm + '/' + acl.id, null).remove().then(function () { + $scope.document.acls = _.reject($scope.document.acls, function(s) { + return angular.equals(acl, s); + }); + }); + }; + + /** + * Add an ACL. + */ + $scope.addAcl = function() { + // Compute ACLs to add + $scope.acl.source = $stateParams.id; + var acls = []; + if ($scope.acl.perm == 'READWRITE') { + acls = [{ + source: $stateParams.id, + username: $scope.acl.username, + perm: 'READ' + }, { + source: $stateParams.id, + username: $scope.acl.username, + perm: 'WRITE' + }]; + } else { + acls = [{ + source: $stateParams.id, + username: $scope.acl.username, + perm: $scope.acl.perm + }]; + } + + // Add ACLs + _.each(acls, function(acl) { + Restangular.one('acl').put(acl).then(function(acl) { + if (_.isUndefined(acl.id)) { + return; + } + $scope.document.acls.push(acl); + $scope.document.acls = angular.copy($scope.document.acls); + }); + }); + + // Reset form + $scope.acl = { perm: 'READ' }; + }; + + /** + * Auto-complete on ACL target. + */ + $scope.getTargetAclTypeahead = function($viewValue) { + var deferred = $q.defer(); + Restangular.one('acl/target/search') + .get({ + search: $viewValue + }).then(function(data) { + deferred.resolve(_.pluck(data.users, 'username'), true); + }); + return deferred.promise; + }; +}); \ No newline at end of file diff --git a/docs-web/src/main/webapp/src/app/docs/controller/Main.js b/docs-web/src/main/webapp/src/app/docs/controller/Main.js index 18e04ce7..5dc8ad0d 100644 --- a/docs-web/src/main/webapp/src/app/docs/controller/Main.js +++ b/docs-web/src/main/webapp/src/app/docs/controller/Main.js @@ -6,9 +6,13 @@ angular.module('docs').controller('Main', function($scope, $rootScope, $state, User) { User.userInfo().then(function(data) { if (data.anonymous) { - $state.go('login'); + $state.go('login', {}, { + location: 'replace' + }); } else { - $state.go('document.default'); + $state.go('document.default', {}, { + location: 'replace' + }); } }); }); \ 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 6247f46b..9fb47b64 100644 --- a/docs-web/src/main/webapp/src/index.html +++ b/docs-web/src/main/webapp/src/index.html @@ -43,6 +43,9 @@ + + + diff --git a/docs-web/src/main/webapp/src/partial/docs/document.view.activity.html b/docs-web/src/main/webapp/src/partial/docs/document.view.activity.html new file mode 100644 index 00000000..6726c5ed --- /dev/null +++ b/docs-web/src/main/webapp/src/partial/docs/document.view.activity.html @@ -0,0 +1 @@ + \ No newline at end of file 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 new file mode 100644 index 00000000..9e1a3021 --- /dev/null +++ b/docs-web/src/main/webapp/src/partial/docs/document.view.content.html @@ -0,0 +1,37 @@ +

+ +
+
+
+
+ + + +
+
+
+
+
+ +
+
+
+
+ +
+

+ {{ file.status }} +

+
+ +
+
+
+ +

+ + Drag & drop files here to upload +

+
+
\ No newline at end of file diff --git a/docs-web/src/main/webapp/src/partial/docs/document.view.html b/docs-web/src/main/webapp/src/partial/docs/document.view.html index 2643b426..82a608f4 100644 --- a/docs-web/src/main/webapp/src/partial/docs/document.view.html +++ b/docs-web/src/main/webapp/src/partial/docs/document.view.html @@ -38,119 +38,24 @@ - - - + +
\ No newline at end of file diff --git a/docs-web/src/main/webapp/src/partial/docs/document.view.permissions.html b/docs-web/src/main/webapp/src/partial/docs/document.view.permissions.html new file mode 100644 index 00000000..c8921061 --- /dev/null +++ b/docs-web/src/main/webapp/src/partial/docs/document.view.permissions.html @@ -0,0 +1,53 @@ + + + + + + + + + + +
ForPermission
{{ acl[0].type == 'SHARE' ? 'Shared' : 'User' }} {{ acl[0].name }} + + {{ a.perm }} + + +
+ +
+

Add a permission

+ +
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+
+
\ No newline at end of file