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 bcaa03b7..b7cc62c3 100644 --- a/docs-web/src/main/webapp/src/app/docs/app.js +++ b/docs-web/src/main/webapp/src/app/docs/app.js @@ -13,7 +13,7 @@ angular.module('docs', /** * Configuring modules. */ -.config(function($locationProvider, $urlRouterProvider, $stateProvider, $httpProvider, +.config(function($locationProvider, $urlRouterProvider, $stateProvider, $httpProvider, $qProvider, RestangularProvider, $translateProvider, timeAgoSettings, tmhDynamicLocaleProvider) { $locationProvider.hashPrefix(''); @@ -417,6 +417,9 @@ angular.module('docs', return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data; }]; + + // Silence unhandled rejections + $qProvider.errorOnUnhandledRejections(false); }) /** diff --git a/docs-web/src/main/webapp/src/app/docs/controller/Login.js b/docs-web/src/main/webapp/src/app/docs/controller/Login.js index 32b3a000..d48a5f57 100644 --- a/docs-web/src/main/webapp/src/app/docs/controller/Login.js +++ b/docs-web/src/main/webapp/src/app/docs/controller/Login.js @@ -45,7 +45,7 @@ angular.module('docs').controller('Login', function(Restangular, $scope, $rootSc $scope.openPasswordLost = function () { $uibModal.open({ templateUrl: 'partial/docs/passwordlost.html', - controller: 'LoginModalPasswordLost' + controller: 'ModalPasswordLost' }).result.then(function (username) { if (username === null) { return; diff --git a/docs-web/src/main/webapp/src/app/docs/controller/LoginModalPasswordLost.js b/docs-web/src/main/webapp/src/app/docs/controller/LoginModalPasswordLost.js deleted file mode 100644 index 16517457..00000000 --- a/docs-web/src/main/webapp/src/app/docs/controller/LoginModalPasswordLost.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -/** - * Login modal password lost controller. - */ -angular.module('docs').controller('LoginModalPasswordLost', function ($scope, $uibModalInstance) { - $scope.username = ''; - $scope.close = function(username) { - $uibModalInstance.close(username); - } -}); \ No newline at end of file diff --git a/docs-web/src/main/webapp/src/app/docs/controller/ModalFeedback.js b/docs-web/src/main/webapp/src/app/docs/controller/ModalFeedback.js new file mode 100644 index 00000000..f55705d3 --- /dev/null +++ b/docs-web/src/main/webapp/src/app/docs/controller/ModalFeedback.js @@ -0,0 +1,11 @@ +'use strict'; + +/** + * Modal feedback controller. + */ +angular.module('docs').controller('ModalFeedback', function ($scope, $uibModalInstance) { + $scope.content = ''; + $scope.close = function(content) { + $uibModalInstance.close(content); + } +}); \ No newline at end of file diff --git a/docs-web/src/main/webapp/src/app/docs/controller/ModalPasswordLost.js b/docs-web/src/main/webapp/src/app/docs/controller/ModalPasswordLost.js new file mode 100644 index 00000000..59dec913 --- /dev/null +++ b/docs-web/src/main/webapp/src/app/docs/controller/ModalPasswordLost.js @@ -0,0 +1,11 @@ +'use strict'; + +/** + * Modal password lost controller. + */ +angular.module('docs').controller('ModalPasswordLost', function ($scope, $uibModalInstance) { + $scope.username = ''; + $scope.close = function(username) { + $uibModalInstance.close(username); + } +}); \ No newline at end of file diff --git a/docs-web/src/main/webapp/src/app/docs/controller/document/DocumentDefault.js b/docs-web/src/main/webapp/src/app/docs/controller/document/DocumentDefault.js index 21ad90e5..20997c39 100644 --- a/docs-web/src/main/webapp/src/app/docs/controller/document/DocumentDefault.js +++ b/docs-web/src/main/webapp/src/app/docs/controller/document/DocumentDefault.js @@ -3,16 +3,14 @@ /** * Document default controller. */ -angular.module('docs').controller('DocumentDefault', function($scope, $rootScope, $state, Restangular, Upload, $translate) { +angular.module('docs').controller('DocumentDefault', function ($scope, $rootScope, $state, Restangular, Upload, $translate, $uibModal, $dialog) { // Load user audit log - Restangular.one('auditlog').get().then(function(data) { + Restangular.one('auditlog').get().then(function (data) { $scope.logs = data.logs; }); - /** - * Load unlinked files. - */ - $scope.loadFiles = function() { + // Load unlinked files + $scope.loadFiles = function () { Restangular.one('file/list').get().then(function (data) { $scope.files = data.files; // TODO Keep currently uploading files @@ -20,15 +18,12 @@ angular.module('docs').controller('DocumentDefault', function($scope, $rootScope }; $scope.loadFiles(); - /** - * File has been drag & dropped. - * @param files - */ - $scope.fileDropped = function(files) { + // File has been drag & dropped + $scope.fileDropped = function (files) { if (files && files.length) { // Adding files to the UI var newfiles = []; - _.each(files, function(file) { + _.each(files, function (file) { var newfile = { progress: 0, name: file.name, @@ -42,7 +37,7 @@ angular.module('docs').controller('DocumentDefault', function($scope, $rootScope // Uploading files sequentially var key = 0; - var then = function() { + var then = function () { if (files[key]) { $scope.uploadFile(files[key], newfiles[key++]).then(then); } @@ -51,12 +46,8 @@ angular.module('docs').controller('DocumentDefault', function($scope, $rootScope } }; - /** - * Upload a file. - * @param file - * @param newfile - */ - $scope.uploadFile = function(file, newfile) { + // Upload a file + $scope.uploadFile = function (file, newfile) { // Upload the file newfile.status = $translate.instant('document.default.upload_progress'); return Upload.upload({ @@ -83,20 +74,16 @@ angular.module('docs').controller('DocumentDefault', function($scope, $rootScope }); }; - /** - * Navigate to the selected file. - */ + //Navigate to the selected file $scope.openFile = function (file) { $state.go('document.default.file', { fileId: file.id }) }; - /** - * Delete a file. - */ + // Delete a file $scope.deleteFile = function ($event, file) { $event.stopPropagation(); - Restangular.one('file', file.id).remove().then(function() { + Restangular.one('file', file.id).remove().then(function () { // File deleted, decrease used quota $rootScope.userInfo.storage_current -= file.size; @@ -106,17 +93,36 @@ angular.module('docs').controller('DocumentDefault', function($scope, $rootScope return false; }; - /** - * Returns checked files. - */ - $scope.checkedFiles = function() { + // Returns checked files + $scope.checkedFiles = function () { return _.where($scope.files, { checked: true }); }; - /** - * Add a document with checked files. - */ - $scope.addDocument = function() { + // Add a document with checked files + $scope.addDocument = function () { $state.go('document.add', { files: _.pluck($scope.checkedFiles(), 'id') }); }; + + // Open the feedback modal + $scope.openFeedback = function () { + $uibModal.open({ + templateUrl: 'partial/docs/feedback.html', + controller: 'ModalFeedback' + }).result.then(function (content) { + if (content === null) { + return; + } + + Restangular.withConfig(function (RestangularConfigurer) { + RestangularConfigurer.setBaseUrl('https://api.sismicsdocs.com'); + }).one('api').post('feedback', { + content: content + }).then(function () { + var title = $translate.instant('feedback.sent_title'); + var msg = $translate.instant('feedback.sent_message'); + var btns = [{result: 'ok', label: $translate.instant('ok'), cssClass: 'btn-primary'}]; + $dialog.messageBox(title, msg, btns); + }); + }); + }; }); \ 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 73af3dd6..86796c0b 100644 --- a/docs-web/src/main/webapp/src/index.html +++ b/docs-web/src/main/webapp/src/index.html @@ -48,7 +48,8 @@ - + + diff --git a/docs-web/src/main/webapp/src/locale/en.json b/docs-web/src/main/webapp/src/locale/en.json index a8c9a227..cbd2d079 100644 --- a/docs-web/src/main/webapp/src/locale/en.json +++ b/docs-web/src/main/webapp/src/locale/en.json @@ -146,7 +146,8 @@ "add_new_document": "Add to new document", "latest_activity": "Latest activity", "footer_sismics": "Crafted with by Sismics", - "api_documentation": "API Documentation" + "api_documentation": "API Documentation", + "feedback": "Give us a feedback" }, "pdf": { "export_title": "Export to PDF", @@ -339,6 +340,12 @@ "new_entry": "New entry" } }, + "feedback": { + "title": "Give us a feedback", + "message": "Any suggestion or question about Sismics Docs? We listen to you!", + "sent_title": "Feedback sent", + "sent_message": "Thank you for your feedback! It will help us make Sismics Docs even better." + }, "app_share": { "main": "Ask a shared document link to access it", "403": { diff --git a/docs-web/src/main/webapp/src/partial/docs/document.default.html b/docs-web/src/main/webapp/src/partial/docs/document.default.html index 4db49c57..2ed71792 100644 --- a/docs-web/src/main/webapp/src/partial/docs/document.default.html +++ b/docs-web/src/main/webapp/src/partial/docs/document.default.html @@ -67,4 +67,8 @@ - \ No newline at end of file + + + + {{ 'document.default.feedback' | translate }} + \ No newline at end of file diff --git a/docs-web/src/main/webapp/src/partial/docs/feedback.html b/docs-web/src/main/webapp/src/partial/docs/feedback.html new file mode 100644 index 00000000..7c849c0c --- /dev/null +++ b/docs-web/src/main/webapp/src/partial/docs/feedback.html @@ -0,0 +1,17 @@ +
+ + + +
\ No newline at end of file diff --git a/docs-web/src/main/webapp/src/style/main.less b/docs-web/src/main/webapp/src/style/main.less index fdae4870..0a582242 100644 --- a/docs-web/src/main/webapp/src/style/main.less +++ b/docs-web/src/main/webapp/src/style/main.less @@ -310,6 +310,35 @@ input[readonly].share-link { padding-bottom: 0; } +// Feedback +.feedback { + display: block; + position: fixed; + right: 0; + top: 200px; + transform: rotate(-90deg) translateY(-100%); + background: #ccc; + padding: 8px; + color: #fff; + font-weight: bold; + transform-origin: 100% 0; + + &:hover { + background: #aaa; + text-decoration: none; + color: #fff; + } + + &:active { + background: #444; + } + + &:active, &:focus { + text-decoration: none; + color: #fff; + } +} + // Vertical alignment .vertical-center { min-height: 100vh;