qa: New service to handle QA testing by students
This commit is contained in:
parent
a0155c6deb
commit
a237936feb
37 changed files with 1476 additions and 0 deletions
15
qa/static/js/angular-resource.min.js
vendored
Normal file
15
qa/static/js/angular-resource.min.js
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
AngularJS v1.7.9
|
||||
(c) 2010-2018 Google, Inc. http://angularjs.org
|
||||
License: MIT
|
||||
*/
|
||||
(function(T,a){'use strict';function M(m,f){f=f||{};a.forEach(f,function(a,d){delete f[d]});for(var d in m)!m.hasOwnProperty(d)||"$"===d.charAt(0)&&"$"===d.charAt(1)||(f[d]=m[d]);return f}var B=a.$$minErr("$resource"),H=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;a.module("ngResource",["ng"]).info({angularVersion:"1.7.9"}).provider("$resource",function(){var m=/^https?:\/\/\[[^\]]*][^/]*/,f=this;this.defaults={stripTrailingSlashes:!0,cancellable:!1,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",
|
||||
isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}};this.$get=["$http","$log","$q","$timeout",function(d,F,G,N){function C(a,d){this.template=a;this.defaults=n({},f.defaults,d);this.urlParams={}}var O=a.noop,r=a.forEach,n=a.extend,R=a.copy,P=a.isArray,D=a.isDefined,x=a.isFunction,I=a.isNumber,y=a.$$encodeUriQuery,S=a.$$encodeUriSegment;C.prototype={setUrlParams:function(a,d,f){var g=this,c=f||g.template,s,h,n="",b=g.urlParams=Object.create(null);r(c.split(/\W/),function(a){if("hasOwnProperty"===
|
||||
a)throw B("badname");!/^\d+$/.test(a)&&a&&(new RegExp("(^|[^\\\\]):"+a+"(\\W|$)")).test(c)&&(b[a]={isQueryParamValue:(new RegExp("\\?.*=:"+a+"(?:\\W|$)")).test(c)})});c=c.replace(/\\:/g,":");c=c.replace(m,function(b){n=b;return""});d=d||{};r(g.urlParams,function(b,a){s=d.hasOwnProperty(a)?d[a]:g.defaults[a];D(s)&&null!==s?(h=b.isQueryParamValue?y(s,!0):S(s),c=c.replace(new RegExp(":"+a+"(\\W|$)","g"),function(b,a){return h+a})):c=c.replace(new RegExp("(/?):"+a+"(\\W|$)","g"),function(b,a,e){return"/"===
|
||||
e.charAt(0)?e:a+e})});g.defaults.stripTrailingSlashes&&(c=c.replace(/\/+$/,"")||"/");c=c.replace(/\/\.(?=\w+($|\?))/,".");a.url=n+c.replace(/\/(\\|%5C)\./,"/.");r(d,function(b,c){g.urlParams[c]||(a.params=a.params||{},a.params[c]=b)})}};return function(m,y,z,g){function c(b,c){var d={};c=n({},y,c);r(c,function(c,f){x(c)&&(c=c(b));var e;if(c&&c.charAt&&"@"===c.charAt(0)){e=b;var k=c.substr(1);if(null==k||""===k||"hasOwnProperty"===k||!H.test("."+k))throw B("badmember",k);for(var k=k.split("."),h=0,
|
||||
n=k.length;h<n&&a.isDefined(e);h++){var g=k[h];e=null!==e?e[g]:void 0}}else e=c;d[f]=e});return d}function s(b){return b.resource}function h(b){M(b||{},this)}var Q=new C(m,g);z=n({},f.defaults.actions,z);h.prototype.toJSON=function(){var b=n({},this);delete b.$promise;delete b.$resolved;delete b.$cancelRequest;return b};r(z,function(b,a){var f=!0===b.hasBody||!1!==b.hasBody&&/^(POST|PUT|PATCH)$/i.test(b.method),g=b.timeout,m=D(b.cancellable)?b.cancellable:Q.defaults.cancellable;g&&!I(g)&&(F.debug("ngResource:\n Only numeric values are allowed as `timeout`.\n Promises are not supported in $resource, because the same value would be used for multiple requests. If you are looking for a way to cancel requests, you should use the `cancellable` option."),
|
||||
delete b.timeout,g=null);h[a]=function(e,k,J,y){function z(a){p.catch(O);null!==u&&u.resolve(a)}var K={},v,t,w;switch(arguments.length){case 4:w=y,t=J;case 3:case 2:if(x(k)){if(x(e)){t=e;w=k;break}t=k;w=J}else{K=e;v=k;t=J;break}case 1:x(e)?t=e:f?v=e:K=e;break;case 0:break;default:throw B("badargs",arguments.length);}var E=this instanceof h,l=E?v:b.isArray?[]:new h(v),q={},C=b.interceptor&&b.interceptor.request||void 0,D=b.interceptor&&b.interceptor.requestError||void 0,F=b.interceptor&&b.interceptor.response||
|
||||
s,H=b.interceptor&&b.interceptor.responseError||G.reject,I=t?function(a){t(a,A.headers,A.status,A.statusText)}:void 0;w=w||void 0;var u,L,A;r(b,function(a,b){switch(b){default:q[b]=R(a);case "params":case "isArray":case "interceptor":case "cancellable":}});!E&&m&&(u=G.defer(),q.timeout=u.promise,g&&(L=N(u.resolve,g)));f&&(q.data=v);Q.setUrlParams(q,n({},c(v,b.params||{}),K),b.url);var p=G.resolve(q).then(C).catch(D).then(d),p=p.then(function(c){var e=c.data;if(e){if(P(e)!==!!b.isArray)throw B("badcfg",
|
||||
a,b.isArray?"array":"object",P(e)?"array":"object",q.method,q.url);if(b.isArray)l.length=0,r(e,function(a){"object"===typeof a?l.push(new h(a)):l.push(a)});else{var d=l.$promise;M(e,l);l.$promise=d}}c.resource=l;A=c;return F(c)},function(a){a.resource=l;A=a;return H(a)}),p=p["finally"](function(){l.$resolved=!0;!E&&m&&(l.$cancelRequest=O,N.cancel(L),u=L=q.timeout=null)});p.then(I,w);return E?p:(l.$promise=p,l.$resolved=!1,m&&(l.$cancelRequest=z),l)};h.prototype["$"+a]=function(b,c,d){x(b)&&(d=c,c=
|
||||
b,b={});b=h[a].call(this,b,this,c,d);return b.$promise||b}});return h}}]})})(window,window.angular);
|
||||
//# sourceMappingURL=angular-resource.min.js.map
|
||||
1
qa/static/js/angular-route.min.js
vendored
Symbolic link
1
qa/static/js/angular-route.min.js
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../frontend/static/js/angular-route.min.js
|
||||
1
qa/static/js/angular-sanitize.min.js
vendored
Symbolic link
1
qa/static/js/angular-sanitize.min.js
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../frontend/static/js/angular-sanitize.min.js
|
||||
1
qa/static/js/angular.min.js
vendored
Symbolic link
1
qa/static/js/angular.min.js
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../frontend/static/js/angular.min.js
|
||||
1
qa/static/js/bootstrap.min.js
vendored
Symbolic link
1
qa/static/js/bootstrap.min.js
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../frontend/static/js/bootstrap.min.js
|
||||
1
qa/static/js/common.js
Symbolic link
1
qa/static/js/common.js
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../frontend/static/js/common.js
|
||||
1
qa/static/js/d3.v3.min.js
vendored
Symbolic link
1
qa/static/js/d3.v3.min.js
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../frontend/static/js/d3.v3.min.js
|
||||
1
qa/static/js/i18n
Symbolic link
1
qa/static/js/i18n
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../frontend/static/js/i18n/
|
||||
1
qa/static/js/jquery.min.js
vendored
Symbolic link
1
qa/static/js/jquery.min.js
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../frontend/static/js/jquery.min.js
|
||||
414
qa/static/js/qa.js
Normal file
414
qa/static/js/qa.js
Normal file
|
|
@ -0,0 +1,414 @@
|
|||
angular.module("FICApp", ["ngRoute", "ngResource", "ngSanitize"])
|
||||
.config(function($routeProvider, $locationProvider) {
|
||||
$routeProvider
|
||||
.when("/themes", {
|
||||
controller: "ThemesListController",
|
||||
templateUrl: "views/theme-list.html"
|
||||
})
|
||||
.when("/themes/:themeId", {
|
||||
controller: "ThemeController",
|
||||
templateUrl: "views/theme.html"
|
||||
})
|
||||
.when("/themes/:themeId/exercices/:exerciceId", {
|
||||
controller: "ExerciceController",
|
||||
templateUrl: "views/exercice.html"
|
||||
})
|
||||
.when("/exercices", {
|
||||
controller: "AllExercicesListController",
|
||||
templateUrl: "views/exercice-list.html"
|
||||
})
|
||||
.when("/exercices/:exerciceId", {
|
||||
controller: "ExerciceController",
|
||||
templateUrl: "views/exercice.html"
|
||||
})
|
||||
.when("/", {
|
||||
templateUrl: "views/home.html"
|
||||
});
|
||||
$locationProvider.html5Mode(true);
|
||||
});
|
||||
|
||||
angular.module("FICApp")
|
||||
.directive('autofocus', ['$timeout', function($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link : function($scope, $element) {
|
||||
$timeout(function() {
|
||||
$element[0].focus();
|
||||
});
|
||||
}
|
||||
}
|
||||
}])
|
||||
|
||||
.component('toast', {
|
||||
bindings: {
|
||||
date: '=',
|
||||
msg: '=',
|
||||
timeout: '=',
|
||||
title: '=',
|
||||
variant: '=',
|
||||
yesNo: '=',
|
||||
onyes: '=',
|
||||
onno: '=',
|
||||
},
|
||||
controller: function($element) {
|
||||
if (this.timeout === 0)
|
||||
$element.children(0).toast({autohide: false});
|
||||
else if (!this.timeout && this.timeout !== 0)
|
||||
$element.children(0).toast({delay: 7000});
|
||||
else
|
||||
$element.children(0).toast({delay: this.timeout});
|
||||
$element.children(0).toast('show');
|
||||
this.yesFunc = function() {
|
||||
$element.children(0).toast('dispose');
|
||||
if (this.onyes)
|
||||
this.onyes();
|
||||
}
|
||||
this.noFunc = function() {
|
||||
$element.children(0).toast('dispose');
|
||||
if (this.onno)
|
||||
this.onno();
|
||||
}
|
||||
},
|
||||
template: `<div class="toast mb-2" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header">
|
||||
<span ng-if="$ctrl.variant" class="badge badge-pill badge-{{ $ctrl.variant }}" style="padding: .25em .66em"> </span>
|
||||
<strong class="mr-auto" ng-bind="$ctrl.title"></strong>
|
||||
<small class="text-muted" ng-bind="$ctrl.date">just now</small>
|
||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="toast-body" ng-bind-html="$ctrl.msg" ng-if="$ctrl.msg"></div>
|
||||
<div class="d-flex justify-content-around mb-1" ng-if="$ctrl.yesNo">
|
||||
<button type="button" class="ml-2 btn btn-sm btn-success" ng-click="$ctrl.yesFunc()">Yes</button>
|
||||
<button type="button" class="btn btn-sm btn-danger" ng-click="$ctrl.noFunc()">No</button>
|
||||
</div>
|
||||
</div>`
|
||||
});
|
||||
|
||||
angular.module("FICApp")
|
||||
.factory("Version", function($resource) {
|
||||
return $resource("/api/version")
|
||||
})
|
||||
.factory("Team", function($resource) {
|
||||
return $resource("/api/teams/:teamId", { teamId: '@id' }, {
|
||||
'update': {method: 'PUT'},
|
||||
})
|
||||
})
|
||||
.factory("Teams", function($resource) {
|
||||
return $resource("/api/teams.json")
|
||||
})
|
||||
.factory("Theme", function($resource) {
|
||||
return $resource("/api/themes/:themeId", { themeId: '@id' }, {
|
||||
update: {method: 'PUT'}
|
||||
});
|
||||
})
|
||||
.factory("Themes", function($resource) {
|
||||
return $resource("/api/themes.json", null, {
|
||||
'get': {method: 'GET'},
|
||||
})
|
||||
})
|
||||
.factory("ThemedExercice", function($resource) {
|
||||
return $resource("/api/themes/:themeId/exercices/:exerciceId", { themeId: '@id', exerciceId: '@idExercice' }, {
|
||||
update: {method: 'PUT'}
|
||||
})
|
||||
})
|
||||
.factory("Exercice", function($resource) {
|
||||
return $resource("/api/exercices/:exerciceId", { exerciceId: '@id' }, {
|
||||
update: {method: 'PUT'},
|
||||
patch: {method: 'PATCH'}
|
||||
})
|
||||
})
|
||||
.factory("ExerciceQA", function($resource) {
|
||||
return $resource("/api/qa/:exerciceId/:qaId", { exerciceId: '@idExercice', qaId: '@id' }, {
|
||||
update: {method: 'PUT'},
|
||||
patch: {method: 'PATCH'}
|
||||
})
|
||||
});
|
||||
|
||||
angular.module("FICApp")
|
||||
.filter("toColor", function() {
|
||||
return function(num) {
|
||||
num >>>= 0;
|
||||
var b = num & 0xFF,
|
||||
g = (num & 0xFF00) >>> 8,
|
||||
r = (num & 0xFF0000) >>> 16,
|
||||
a = ( (num & 0xFF000000) >>> 24 ) / 255 ;
|
||||
return "#" + r.toString(16) + g.toString(16) + b.toString(16);
|
||||
}
|
||||
})
|
||||
.filter("cksum", function() {
|
||||
return function(input) {
|
||||
if (input == undefined)
|
||||
return input;
|
||||
var raw = atob(input).toString(16);
|
||||
var hex = '';
|
||||
for (var i = 0; i < raw.length; i++ ) {
|
||||
var _hex = raw.charCodeAt(i).toString(16)
|
||||
hex += (_hex.length == 2 ? _hex : '0' + _hex);
|
||||
}
|
||||
return hex
|
||||
}
|
||||
})
|
||||
|
||||
.directive('color', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, ele, attr, ctrl){
|
||||
ctrl.$formatters.unshift(function(num){
|
||||
num >>>= 0;
|
||||
var b = num & 0xFF,
|
||||
g = (num & 0xFF00) >>> 8,
|
||||
r = (num & 0xFF0000) >>> 16,
|
||||
a = ( (num & 0xFF000000) >>> 24 ) / 255 ;
|
||||
return "#" + r.toString(16) + g.toString(16) + b.toString(16);
|
||||
});
|
||||
ctrl.$parsers.unshift(function(viewValue){
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(viewValue);
|
||||
return result ? (
|
||||
parseInt(result[1], 16) * 256 * 256 +
|
||||
parseInt(result[2], 16) * 256 +
|
||||
parseInt(result[3], 16)
|
||||
|
||||
) : 0;
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
.directive('integer', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, ele, attr, ctrl){
|
||||
ctrl.$parsers.unshift(function(viewValue){
|
||||
return parseInt(viewValue, 10);
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
.directive('float', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, ele, attr, ctrl){
|
||||
ctrl.$parsers.unshift(function(viewValue){
|
||||
return parseFloat(viewValue, 10);
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
.run(function($rootScope, $http, $interval) {
|
||||
$rootScope.toasts = [];
|
||||
$rootScope.addToast = function(kind, title, msg, yesFunc, noFunc, tmout) {
|
||||
$rootScope.toasts.unshift({
|
||||
variant: kind,
|
||||
title: title,
|
||||
msg: msg,
|
||||
timeout: tmout,
|
||||
yesFunc: yesFunc,
|
||||
noFunc: noFunc,
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
.controller("VersionController", function($scope, Version) {
|
||||
$scope.v = Version.get();
|
||||
})
|
||||
|
||||
.controller("ThemesListController", function($scope, Theme, $location, $rootScope, $http) {
|
||||
$scope.themes = Theme.query();
|
||||
$scope.fields = ["name", "authors", "headline"];
|
||||
|
||||
$scope.validateSearch = function(keyEvent) {
|
||||
if (keyEvent.which === 13) {
|
||||
var myTheme = null;
|
||||
$scope.themes.forEach(function(theme) {
|
||||
if (String(theme.name.toLowerCase()).indexOf($scope.query.toLowerCase()) >= 0) {
|
||||
if (myTheme === null)
|
||||
myTheme = theme;
|
||||
else
|
||||
myTheme = false;
|
||||
}
|
||||
});
|
||||
if (myTheme)
|
||||
$location.url("themes/" + myTheme.id);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.show = function(id) {
|
||||
$location.url("/themes/" + id);
|
||||
};
|
||||
})
|
||||
.controller("ThemeController", function($scope, Theme, $routeParams, $location, $rootScope, $http) {
|
||||
$scope.theme = Theme.get({ themeId: $routeParams.themeId });
|
||||
$scope.fields = ["name", "urlid", "authors", "headline", "intro", "image"];
|
||||
})
|
||||
|
||||
.controller("AllExercicesListController", function($scope, Exercice, Theme, $routeParams, $location, $rootScope, $http, $filter) {
|
||||
$http({
|
||||
url: "/api/themes.json",
|
||||
method: "GET"
|
||||
}).then(function(response) {
|
||||
$scope.themes = response.data
|
||||
});
|
||||
|
||||
$scope.exercices = Exercice.query();
|
||||
$scope.exercice = {}; // Array used to save fields to updates in selected exercices
|
||||
$scope.fields = ["title", "headline"];
|
||||
|
||||
$scope.validateSearch = function(keyEvent) {
|
||||
if (keyEvent.which === 13) {
|
||||
var myExercice = null;
|
||||
$scope.exercices.forEach(function(exercice) {
|
||||
if (String(exercice.title.toLowerCase()).indexOf($scope.query.toLowerCase()) >= 0) {
|
||||
if (myExercice === null)
|
||||
myExercice = exercice;
|
||||
else
|
||||
myExercice = false;
|
||||
}
|
||||
});
|
||||
if (myExercice)
|
||||
$location.url("exercices/" + myExercice.id);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.show = function(id) {
|
||||
$location.url("/exercices/" + id);
|
||||
};
|
||||
})
|
||||
.controller("ExercicesListController", function($scope, ThemedExercice, $location, $rootScope, $http) {
|
||||
$scope.exercices = ThemedExercice.query({ themeId: $scope.theme.id });
|
||||
$scope.fields = ["title", "headline"];
|
||||
|
||||
$scope.show = function(id) {
|
||||
$location.url("/themes/" + $scope.theme.id + "/exercices/" + id);
|
||||
};
|
||||
})
|
||||
|
||||
.controller("ExerciceController", function($scope, $rootScope, Exercice, ThemedExercice, $routeParams, $location, $http) {
|
||||
if ($routeParams.themeId && $routeParams.exerciceId == "new") {
|
||||
$scope.exercice = new ThemedExercice();
|
||||
} else {
|
||||
$scope.exercice = Exercice.get({ exerciceId: $routeParams.exerciceId });
|
||||
}
|
||||
$http({
|
||||
url: "/api/themes.json",
|
||||
method: "GET"
|
||||
}).then(function(response) {
|
||||
$scope.themes = response.data
|
||||
var last_exercice = null;
|
||||
angular.forEach($scope.themes[$scope.exercice.id_theme].exercices, function(exercice, k) {
|
||||
if (last_exercice != null) {
|
||||
$scope.themes[$scope.exercice.id_theme].exercices[last_exercice].next = k;
|
||||
exercice.previous = last_exercice;
|
||||
}
|
||||
last_exercice = k;
|
||||
exercice.id = k;
|
||||
});
|
||||
});
|
||||
$scope.exercices = Exercice.query();
|
||||
})
|
||||
|
||||
.controller("ExerciceQAController", function($scope, $rootScope, ExerciceQA, $routeParams, $location, $http) {
|
||||
$scope.queries = ExerciceQA.query({ exerciceId: $routeParams.exerciceId });
|
||||
$scope.fields = ["state", "subject", "user", "creation"];
|
||||
$scope.namedFields = {
|
||||
"state": "État",
|
||||
"subject": "Sujet",
|
||||
"content": "Description",
|
||||
};
|
||||
$scope.states = {
|
||||
"ok": "OK",
|
||||
"orthograph": "Orthographe et grammaire",
|
||||
"issue-statement": "Pas compris",
|
||||
"issue-flag": "Problème de flag",
|
||||
"issue-mcq": "Problème de QCM/QCU",
|
||||
"issue-hint": "Problème d'indice",
|
||||
"issue-file": "Problème de fichier",
|
||||
"issue": "Problème autre",
|
||||
"suggest": "Suggestion",
|
||||
"too-hard": "Trop dur",
|
||||
"too-easy": "Trop facile",
|
||||
};
|
||||
|
||||
$scope.newQuery = new ExerciceQA();
|
||||
|
||||
$scope.query_comments = null
|
||||
$scope.query_selected = null
|
||||
$scope.showComments = function(qid) {
|
||||
if ($scope.query_selected == qid) {
|
||||
$scope.query_selected = null
|
||||
$scope.queries_comments = null
|
||||
} else {
|
||||
$scope.query_selected = qid
|
||||
$http({
|
||||
url: "/api/qa/" + $routeParams.exerciceId + "/" + $scope.queries[$scope.query_selected].id + "/comments"
|
||||
}).then(function(response) {
|
||||
$scope.queries_comments = response.data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$scope.newComment = {content: ""}
|
||||
$scope.addComment = function() {
|
||||
$http({
|
||||
url: "/api/qa/" + $routeParams.exerciceId + "/" + $scope.queries[$scope.query_selected].id + "/comments",
|
||||
method: "POST",
|
||||
data: $scope.newComment,
|
||||
}).then(function(response) {
|
||||
$scope.newComment = {content: ""}
|
||||
$http({
|
||||
url: "/api/qa/" + $routeParams.exerciceId + "/" + $scope.queries[$scope.query_selected].id + "/comments"
|
||||
}).then(function(response) {
|
||||
$scope.queries_comments = response.data
|
||||
})
|
||||
}, function(response) {
|
||||
$scope.addToast('danger', 'An error occurs when trying to respond to QA entry:', response.data.errmsg);
|
||||
})
|
||||
}
|
||||
|
||||
$scope.updateQA = function(qid) {
|
||||
$scope.newQuery = $scope.queries[$scope.query_selected]
|
||||
}
|
||||
|
||||
$scope.deleteQA = function(qid) {
|
||||
var myq = $scope.queries[$scope.query_selected]
|
||||
myq.$delete(
|
||||
{ exerciceId: $routeParams.exerciceId, qaId: qid },
|
||||
function() {
|
||||
$scope.queries = ExerciceQA.query({ exerciceId: $routeParams.exerciceId });
|
||||
$scope.query_selected = null
|
||||
}, function(response) {
|
||||
$scope.addToast('danger', 'An error occurs when trying to delete QA query:', response.data.errmsg);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
$scope.solveQA = function(qid) {
|
||||
var myq = $scope.queries[$scope.query_selected]
|
||||
myq.solved = (new Date()).toISOString()
|
||||
myq.$update({ exerciceId: $routeParams.exerciceId, qaId: qid })
|
||||
}
|
||||
|
||||
$scope.closeQA = function(qid) {
|
||||
var myq = $scope.queries[$scope.query_selected]
|
||||
myq.closed = (new Date()).toISOString()
|
||||
myq.$update({ exerciceId: $routeParams.exerciceId, qaId: qid })
|
||||
}
|
||||
|
||||
$scope.saveQuery = function() {
|
||||
if (this.newQuery.id) {
|
||||
this.newQuery.$update({ exerciceId: $routeParams.exerciceId, qaId: this.newQuery.id });
|
||||
} else {
|
||||
this.newQuery.$save({ exerciceId: $routeParams.exerciceId }, function() {
|
||||
//$scope.saveComment();
|
||||
$scope.addToast('success', 'QA query created!');
|
||||
$scope.queries = ExerciceQA.query({ exerciceId: $routeParams.exerciceId });
|
||||
$scope.newQuery = new ExerciceQA();
|
||||
}, function(response) {
|
||||
$scope.addToast('danger', 'An error occurs when trying to create QA query:', response.data.errmsg);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in a new issue