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 @@
+
+ {{ file.status }} +
++ + Drag & drop files here to upload +
+- {{ file.status }} -
-- - Drag & drop files here to upload -
-For | -Permission | -
---|---|
{{ acl[0].type == 'SHARE' ? 'Shared' : 'User' }} {{ acl[0].name }} | -- - {{ a.perm }} - - - | -
For | +Permission | +
---|---|
{{ acl[0].type == 'SHARE' ? 'Shared' : 'User' }} {{ acl[0].name }} | ++ + {{ a.perm }} + + + | +