Closes #162: feedback box

This commit is contained in:
Benjamin Gamard 2017-11-21 12:01:53 +01:00
parent 2156848e4a
commit 5bc73548b3
11 changed files with 128 additions and 50 deletions

View File

@ -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);
})
/**

View File

@ -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;

View File

@ -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);
}
});

View File

@ -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);
}
});

View File

@ -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);
}
});

View File

@ -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);
});
});
};
});

View File

@ -48,7 +48,8 @@
<script src="app/docs/app.js" type="text/javascript"></script>
<script src="app/docs/controller/Main.js" type="text/javascript"></script>
<script src="app/docs/controller/Login.js" type="text/javascript"></script>
<script src="app/docs/controller/LoginModalPasswordLost.js" type="text/javascript"></script>
<script src="app/docs/controller/ModalPasswordLost.js" type="text/javascript"></script>
<script src="app/docs/controller/ModalFeedback.js" type="text/javascript"></script>
<script src="app/docs/controller/PasswordReset.js" type="text/javascript"></script>
<script src="app/docs/controller/Navigation.js" type="text/javascript"></script>
<script src="app/docs/controller/Footer.js" type="text/javascript"></script>

View File

@ -146,7 +146,8 @@
"add_new_document": "Add to new document",
"latest_activity": "Latest activity",
"footer_sismics": "Crafted with <span class=\"glyphicon glyphicon-heart\"></span> by <a href=\"https://www.sismics.com\" target=\"_blank\">Sismics</a>",
"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": {

View File

@ -67,4 +67,8 @@
</h3>
<audit-log logs="logs" />
</div>
</div>
</div>
<a href class="feedback" ng-click="openFeedback()">
{{ 'document.default.feedback' | translate }}
</a>

View File

@ -0,0 +1,17 @@
<form name="form">
<div class="modal-header">
<h3>{{ 'feedback.title' | translate }}</h3>
</div>
<div class="modal-body">
<p>
<label for="inputContent">{{ 'feedback.message' | translate }}</label>
<textarea name="content" class="form-control" required id="inputContent" ng-model="content"></textarea>
</p>
</div>
<div class="modal-footer">
<button ng-click="close(content)" class="btn btn-primary" ng-disabled="!form.$valid">
<span class="glyphicon glyphicon-send"></span> {{ 'send' | translate }}
</button>
<button ng-click="close(null)" class="btn btn-default">{{ 'cancel' | translate }}</button>
</div>
</form>

View File

@ -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;