This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository coselmar. See http://git.codelutin.com/coselmar.git commit c88a0b07c6a348bb6bd94c314bc3523e7741c6d3 Author: Yannick Martel <martel@©odelutin.com> Date: Mon Dec 8 17:25:01 2014 +0100 add question view page --- .../src/main/xmi/coselmar-model.properties | 3 +- .../coselmar/services/v1/QuestionsWebService.java | 41 ++++++ coselmar-rest/src/main/resources/mapping | 2 +- .../src/main/webapp/js/coselmar-controllers.js | 42 +++++- .../main/webapp/js/coselmar-questions-services.js | 5 + coselmar-ui/src/main/webapp/js/coselmar.js | 4 + .../main/webapp/views/questions/editquestion.html | 4 +- .../src/main/webapp/views/questions/question.html | 30 ++++ .../main/webapp/views/questions/viewquestion.html | 151 +++++++++++++++++++++ 9 files changed, 278 insertions(+), 4 deletions(-) diff --git a/coselmar-persistence/src/main/xmi/coselmar-model.properties b/coselmar-persistence/src/main/xmi/coselmar-model.properties index 1835e8e..6f8eef4 100644 --- a/coselmar-persistence/src/main/xmi/coselmar-model.properties +++ b/coselmar-persistence/src/main/xmi/coselmar-model.properties @@ -27,4 +27,5 @@ package.fr.ifremer.coselmar.persistence.entity.stereotype=entity model.tagvalue.useEnumerationName=true # Text -fr.ifremer.coselmar.persistence.entity.Document.attribute.summary.tagValue.hibernateAttributeType=text \ No newline at end of file +fr.ifremer.coselmar.persistence.entity.Document.attribute.summary.tagValue.hibernateAttributeType=text +fr.ifremer.coselmar.persistence.entity.Question.attribute.summary.tagValue.hibernateAttributeType=text \ No newline at end of file diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java index adb7cbb..13939d0 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java @@ -264,6 +264,47 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { commit(); } + public QuestionBean getQuestion(String questionId) throws InvalidCredentialException, UnauthorizedException { + + // Check authentication + String authorization = getContext().getHeader("Authorization"); + UserWebToken userWebToken = checkAuthentication(authorization); + + // Only Supervisor can add question + String userRole = userWebToken.getRole(); + + if (!StringUtils.equalsIgnoreCase(CoselmarUserRole.SUPERVISOR.name(), userRole) + && StringUtils.equalsIgnoreCase(CoselmarUserRole.ADMIN.name(), userRole)) { + String message = String.format("User %s %s ('%s') is not allowed to delete question", + userWebToken.getFirstName(), userWebToken.getLastName(), userWebToken.getUserId()); + if (log.isWarnEnabled()) { + log.warn(message); + } + throw new UnauthorizedException(message); + + } + + String fullUserId = getFullIdFromShort(CoselmarUser.class, userWebToken.getUserId()); + + try { + getCoselmarUserDao().forTopiaIdEquals(fullUserId).findUnique(); + } catch (TopiaNoResultException tnre) { + // Should not happened, cause user are not really deleted + String message = String.format("Logged user ('%s') does not exist.", fullUserId); + if (log.isErrorEnabled()) { + log.error(message); + } + throw new InvalidCredentialException(message); + } + + // Retrieve Question + String fullQuestionId = getFullIdFromShort(Question.class, questionId); + Question question = getQuestionDao().forTopiaIdEquals(fullQuestionId).findUnique(); + + QuestionBean result = BeanEntityConverter.toBean(getPersistenceContext().getTopiaIdFactory(), question); + return result; + } + //////////////////////////////////////////////////////////////////////////// /////////////////////// Internal Parts ///////////////////////////// diff --git a/coselmar-rest/src/main/resources/mapping b/coselmar-rest/src/main/resources/mapping index 173dc88..fe16e65 100644 --- a/coselmar-rest/src/main/resources/mapping +++ b/coselmar-rest/src/main/resources/mapping @@ -46,7 +46,7 @@ DELETE /v1/users/{userId} UsersWebService.deleteUser # Questions Api GET /v1/questions QuestionsWebService.getQuestions -#GET /v1/questions/{questionId} QuestionsWebService.getQuestion +GET /v1/questions/{questionId} QuestionsWebService.getQuestion #POST /v1/questions/{questionId} QuestionsWebService.saveQuestion #POST /v1/questions/{questionId}/documents QuestionsWebService.addDocuments POST /v1/questions QuestionsWebService.addQuestion diff --git a/coselmar-ui/src/main/webapp/js/coselmar-controllers.js b/coselmar-ui/src/main/webapp/js/coselmar-controllers.js index 0d03c42..13e9f77 100644 --- a/coselmar-ui/src/main/webapp/js/coselmar-controllers.js +++ b/coselmar-ui/src/main/webapp/js/coselmar-controllers.js @@ -373,7 +373,7 @@ coselmarControllers.controller("NewQuestionCtrl", ['$scope', '$route', '$locatio }]); -// Controller for All User View +// Controller for All Question View coselmarControllers.controller("QuestionsCtrl", ['$scope', '$route', '$routeParams', '$location', 'questionsService', function($scope, $route, $routeParams, $location, questionsService){ @@ -422,6 +422,46 @@ coselmarControllers.controller("QuestionsCtrl", ['$scope', '$route', '$routePara }]); +// Controller for All User View +coselmarControllers.controller("QuestionViewCtrl", ['$scope', '$route', '$routeParams', '$location', 'questionsService', + function($scope, $route, $routeParams, $location, questionsService){ + + $scope.editMode = $routeParams.edit ? $routeParams.edit : false; + + $scope.edit = function() { + $location.search("edit"); + } + + questionsService.getQuestion($routeParams.questionId, + function(question) { + // success : just get the questions + $scope.question = question; + + }, function(error) { + // Fail function : TODO + console.log("error during request"); + console.log(error); + }); + + + $scope.saveQuestion = function(isValidForm){ + console.log($scope.question); + }; + + $scope.deleteQuestion = function(){ + questionsService.deleteQuestion($routeParams.questionId, function() { + // success : goto questions list + $location('#/questions'); + + }, function(error) { + // Fail function : TODO + console.log(error); + }); + }; + + +}]); + coselmarControllers.controller('ModalSearchDocumentsCtrl', function ($scope, $modalInstance, documentService) { $scope.searchKeywords = []; diff --git a/coselmar-ui/src/main/webapp/js/coselmar-questions-services.js b/coselmar-ui/src/main/webapp/js/coselmar-questions-services.js index 2675751..60c219f 100644 --- a/coselmar-ui/src/main/webapp/js/coselmar-questions-services.js +++ b/coselmar-ui/src/main/webapp/js/coselmar-questions-services.js @@ -47,4 +47,9 @@ function Question(resource, config){ var questionResource = resource(baseURL + "/" + questionId); questionResource.delete().$promise.then(successFunction, failFunction); } + + this.getQuestion = function(questionId, successFunction, failFunction) { + var questionResource = resource(baseURL + "/" + questionId); + questionResource.get().$promise.then(successFunction, failFunction); + } }; \ No newline at end of file diff --git a/coselmar-ui/src/main/webapp/js/coselmar.js b/coselmar-ui/src/main/webapp/js/coselmar.js index 15fe537..38b2605 100644 --- a/coselmar-ui/src/main/webapp/js/coselmar.js +++ b/coselmar-ui/src/main/webapp/js/coselmar.js @@ -60,6 +60,10 @@ coselmarApp.config(['$routeProvider', function($routeProvider) { controller : 'NewQuestionCtrl', templateUrl : 'views/questions/newquestion.html' + }).when('/questions/:questionId', { + controller : 'QuestionViewCtrl', + templateUrl : 'views/questions/question.html' + }).otherwise({ redirectTo: '/', diff --git a/coselmar-ui/src/main/webapp/views/questions/editquestion.html b/coselmar-ui/src/main/webapp/views/questions/editquestion.html index 745cc33..c43759d 100644 --- a/coselmar-ui/src/main/webapp/views/questions/editquestion.html +++ b/coselmar-ui/src/main/webapp/views/questions/editquestion.html @@ -239,7 +239,9 @@ <td>{{document.ownerName}}</td> <td><span ng-repeat="keyword in document.keywords">{{keyword}}, </span></td> <td>{{document.depositDate | date:'mediumDate'}}</td> - <td><a class="btn fa fa-minus" title="Remove document" ng-click="removeDocument(document)"/></td> + <td><a class="btn fa fa-minus" title="Remove document" + ng-click="removeDocument(document)" + ng-if="currentUser.role == 'SUPERVISOR'"/></td> </tr> </table> </div> diff --git a/coselmar-ui/src/main/webapp/views/questions/question.html b/coselmar-ui/src/main/webapp/views/questions/question.html new file mode 100644 index 0000000..33225d5 --- /dev/null +++ b/coselmar-ui/src/main/webapp/views/questions/question.html @@ -0,0 +1,30 @@ +<div style="padding: 0px 0px 0px 30px"> + <div class="page-header" style="margin: 0"> + <h2>{{question.title}} + <a class="btn btn-action btn-edit pull-right" ng-click="edit()" ng-if="editMode != true"> + <span class="fa fa-edit" aria-hidden="true"></span>Edit + </a></h2> + </div> + + <div style="padding-bottom: 50px" ng-include="src='views/questions/viewquestion.html'" ng-if="editMode == false"> + </div> + + <div class="text-center" ng-if="question.closingDate"> + Closed on {{question.closingDate}}. + </div> + + <div class="text-center" ng-if="!question.closingDate && currentUser.role == 'SUPERVISOR'"> + <a class="btn btn-action btn-success" ng-click="closeQuestion()"> + <span class="fa fa-check-square-o" aria-hidden="true"></span>Close + </a> + - + <a class="btn btn-action btn-edit" ng-click="adjournQuestion()"> + <span class="fa fa-edit" aria-hidden="true"></span>Adjourn + </a> + - + <a class="btn btn-action btn-disable" ng-click="deleteQuestion()"> + <span class="fa fa-remove" aria-hidden="true"></span>Delete + </a> + </div> + +</div> \ No newline at end of file diff --git a/coselmar-ui/src/main/webapp/views/questions/viewquestion.html b/coselmar-ui/src/main/webapp/views/questions/viewquestion.html new file mode 100644 index 0000000..69e088c --- /dev/null +++ b/coselmar-ui/src/main/webapp/views/questions/viewquestion.html @@ -0,0 +1,151 @@ + +<div class=""> + + <div class="form-group col-md-12"> + <div class="col-md-3"> + <dl> + <dt>Question Type</dt> + <dd>{{question.type}}</dd> + </dl> + </div> + <div class="col-md-3"> + <dl> + <dt>Privacy</dt> + <dd>{{question.privacy | lowercase}}</dd> + </dl> + </div> + <div class="col-md-3"> + <dl> + <dt>Submission Date</dt> + <dd>{{question.submissionDate | date:'mediumDate'}}</dd> + </dl> + </div> + <div class="col-md-3" ng-if="question.deadline"> + <dl> + <dt>Deadline</dt> + <dd>{{question.deadline | date:'mediumDate'}}</dd> + </dl> + </div> + </div> + + <div class="form-group col-md-12"> + <div class="col-md-12" > + <dl> + <dt>Summary</dt> + <dd>{{question.summary}}</dd> + </dl> + </div> + </div> + + <div class="form-group col-md-12"> + <div class="col-md-4"> + <dl> + <dt>Themes</dt> + <dd> + <ul> + <li ng-if="question.themes" ng-repeat="theme in question.themes"> + {{theme}} + </li> + </ul> + </dd> + </dl> + </div> + + <div class="col-md-4"> + <dl> + <dt>Supervisors</dt> + <dd> + <ul> + <li ng-if="question.supervisors" ng-repeat="supervisor in question.supervisors"> + <a href="#/users/{{supervisor.id}}" target="_blank">{{supervisor.firstName}} {{supervisor.name}} ({{supervisor.organization}})</a> + </li> + </ul> + </dd> + </dl> + </div> + + <div class="cold-md-4"> + <dl> + <dt>Status</dt> + <dd>{{question.status}}</dd> + </dl> + </div> + </div> + + <div class="form-group col-md-12"> + <div class="col-md-4"> + <dl> + <dt>Experts</dt> + <dd> + <ul> + <li ng-if="question.participants" ng-repeat="participant in question.participants"> + <a href="#/users/{{participant.id}}" target="_blank">{{participant.firstName}} {{participant.name}} ({{participant.organization}})</a> + </li> + <li ng-if="question.externalExperts" ng-repeat="participant in question.externalExperts"> + {{participant}} + </ul> + </dd> + </dl> + </div> + + <div class="col-md-4"> + <dl> + <dt>Clients</dt> + <dd> + <ul> + <li ng-if="question.clients" ng-repeat="client in question.clients"> + <a href="#/users/{{client.id}}" target="_blank">{{client.firstName}} {{client.name}} ({{client.organization}})</a> + </li> + </ul> + </dd> + </dl> + </div> + + <div class="col-md-4"> + <dl> + <dt>Contributors</dt> + <dd> + <ul> + <li ng-if="question.contributors" ng-repeat="contributor in question.contributors"> + <a href="#/users/{{contributor.id}}" target="_blank">{{contributor.firstName}} {{contributor.name}} ({{contributor.organization}})</a> + </li> + </ul> + </dd> + </dl> + </div> + </div> + + <div class="form-group col-md-12" + ng-if="currentUser.role == 'SUPERVISOR' || currentUser.role == 'EXPERT'"> + + <dl> + <dt>Related Documents</dt> + + <dd> + <table class="table table-bordered table-condensed"> + <tr> + <th>Name</th> + <th>Owner</th> + <th>Keywords</th> + <th>Deposit Date</th> + </tr> + <tr ng-repeat="document in question.relatedDocuments"> + <td><a href="#/documents/{{document.id}}" target="_blank">{{document.name}}</a></td> + <td>{{document.ownerName}}</td> + <td><span ng-repeat="keyword in document.keywords">{{keyword}}, </span></td> + <td>{{document.depositDate | date:'mediumDate'}}</td> + </tr> + </table> + </dd> + </dl> + + </div> + + <!-- TODO ymartel 20141208 : manage parents and children + <div class="form-group col-md-12"> + <div class="col-md-6">TODO Parents</div> + <div class="col-md-6">TODO Children</div> + </div> + --> + +</div> \ No newline at end of file -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.