model: remove a warning :p
[nit.git] / share / nitweb / javascripts / entities.js
1 /*
2 * Copyright 2016 Alexandre Terrasa <alexandre@moz-code.org>.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 (function() {
18 angular
19 .module('entities', ['ngSanitize', 'ui'])
20
21 /* Router */
22
23 .config(function($stateProvider, $locationProvider) {
24 $stateProvider
25 .state('doc', {
26 url: '/doc/:id',
27 templateUrl: 'views/doc/index.html',
28 resolve: {
29 mentity: function(Model, $q, $stateParams, $state) {
30 var d = $q.defer();
31 Model.loadEntity($stateParams.id, d.resolve,
32 function() {
33 $state.go('404', null, { location: false })
34 });
35 return d.promise;
36 }
37 },
38 controller: function(mentity) {
39 this.mentity = mentity;
40 },
41 controllerAs: 'vm',
42 abstract: true
43 })
44 .state('doc.entity', {
45 url: '',
46 templateUrl: 'views/doc/entity.html',
47 controller: function(mentity) {
48 this.mentity = mentity;
49 },
50 controllerAs: 'vm',
51 abstract: true
52 })
53 .state('doc.entity.doc', {
54 url: '',
55 templateUrl: 'views/doc/doc.html',
56 resolve: {
57 doc: function(Model, $q, $stateParams, $state) {
58 var d = $q.defer();
59 Model.loadEntityDoc($stateParams.id, d.resolve,
60 function() {
61 $state.go('404', null, { location: false })
62 });
63 return d.promise;
64 }
65 },
66 controller: function(mentity, doc) {
67 this.mentity = mentity;
68 this.doc = doc;
69 },
70 controllerAs: 'vm',
71 })
72 .state('doc.entity.graph', {
73 url: '/graph',
74 templateUrl: 'views/doc/graph.html',
75 resolve: {
76 graph: function(Model, $q, $stateParams, $state) {
77 var d = $q.defer();
78 Model.loadEntityGraph($stateParams.id, d.resolve,
79 function() {
80 $state.go('404', null, { location: false })
81 });
82 return d.promise;
83 },
84 inh: function(Model, $q, $stateParams, $state) {
85 var d = $q.defer();
86 Model.loadEntityInh($stateParams.id, d.resolve,
87 function() {
88 $state.go('404', null, { location: false })
89 });
90 return d.promise;
91 }
92 },
93 controller: function(inh, graph, $sce) {
94 this.graph = $sce.trustAsHtml(graph);
95 this.inh = inh;
96 },
97 controllerAs: 'vm',
98 })
99 .state('doc.entity.metrics', {
100 url: '/metrics',
101 templateUrl: 'views/doc/metrics.html',
102 resolve: {
103 metrics: function(Metrics, $q, $stateParams, $state) {
104 var d = $q.defer();
105 Metrics.loadStructuralMetrics($stateParams.id, d.resolve,
106 function() {
107 $state.go('404', null, { location: false })
108 });
109 return d.promise;
110 }
111 },
112 controller: function(mentity, metrics) {
113 this.mentity = mentity;
114 this.metrics = metrics;
115 },
116 controllerAs: 'vm',
117 })
118 .state('doc.entity.code', {
119 url: '/code',
120 templateUrl: 'views/doc/code.html',
121 resolve: {
122 code: function(Model, $q, $stateParams, $state) {
123 var d = $q.defer();
124 Model.loadEntityCode($stateParams.id, d.resolve,
125 function() {
126 $state.go('404', null, { location: false })
127 });
128 return d.promise;
129 }
130 },
131 controller: function(mentity, code) {
132 this.mentity = mentity;
133 this.code = code;
134 },
135 controllerAs: 'vm',
136 })
137 .state('doc.entity.defs', {
138 url: '/defs',
139 templateUrl: 'views/doc/defs.html',
140 resolve: {
141 defs: function(Model, $q, $stateParams, $state) {
142 var d = $q.defer();
143 Model.loadEntityDefs($stateParams.id, d.resolve,
144 function() {
145 $state.go('404', null, { location: false })
146 });
147 return d.promise;
148 }
149 },
150 controller: function(mentity, defs) {
151 this.mentity = mentity;
152 this.defs = defs;
153 },
154 controllerAs: 'vm',
155 })
156 .state('doc.entity.lin', {
157 url: '/lin',
158 templateUrl: 'views/doc/lin.html',
159 resolve: {
160 lin: function(Model, $q, $stateParams, $state) {
161 var d = $q.defer();
162 Model.loadEntityLinearization($stateParams.id, d.resolve,
163 function() {
164 $state.go('404', null, { location: false })
165 });
166 return d.promise;
167 }
168 },
169 controller: function(mentity, lin, $scope, $location, $anchorScroll) {
170 var vm = this;
171 vm.focus = $location.hash() ?
172 $location.hash() : mentity.intro.full_name;
173 vm.mentity = mentity;
174 vm.linearization = lin;
175 setTimeout(function() {
176 $anchorScroll();
177 }, 400);
178 $scope.$watch(function () {
179 return $location.hash();
180 }, function (value) {
181 vm.focus = $location.hash() ?
182 $location.hash() : mentity.intro.full_name;
183 $anchorScroll();
184 });
185 },
186 controllerAs: 'vm'
187 })
188 .state('doc.entity.all', {
189 url: '/all',
190 templateUrl: 'views/doc/all.html',
191 controller: function(mentity) {
192 this.mentity = mentity;
193 },
194 controllerAs: 'vm',
195 })
196 })
197
198 /* Model */
199
200 .factory('Model', [ '$http', function($http) {
201 return {
202
203 loadEntity: function(id, cb, cbErr) {
204 $http.get('/api/entity/' + id)
205 .success(cb)
206 .error(cbErr);
207 },
208
209 loadEntityDoc: function(id, cb, cbErr) {
210 $http.get('/api/entity/' + id + '/doc')
211 .success(cb)
212 .error(cbErr);
213 },
214
215 loadEntityLinearization: function(id, cb, cbErr) {
216 $http.get('/api/linearization/' + id)
217 .success(cb)
218 .error(cbErr);
219 },
220
221 loadEntityDefs: function(id, cb, cbErr) {
222 $http.get('/api/defs/' + id)
223 .success(cb)
224 .error(cbErr);
225 },
226
227 loadEntityCode: function(id, cb, cbErr) {
228 $http.get('/api/code/' + id)
229 .success(cb)
230 .error(cbErr);
231 },
232
233 loadEntityGraph: function(id, cb, cbErr) {
234 $http.get('/api/graph/inheritance/' + id + '?cdepth=3')
235 .success(cb)
236 .error(cbErr);
237 },
238
239 loadEntityInh: function(id, cb, cbErr) {
240 $http.get('/api/inheritance/' + id)
241 .success(cb)
242 .error(cbErr);
243 },
244
245 search: function(q, n, cb, cbErr) {
246 $http.get('/api/search?q=' + q + '&n=' + n)
247 .success(cb)
248 .error(cbErr);
249 }
250 };
251 }])
252
253 /* Directives */
254
255 .directive('entityLink', function() {
256 return {
257 restrict: 'E',
258 scope: {
259 mentity: '='
260 },
261 templateUrl: '/directives/entity/link.html'
262 };
263 })
264
265 .directive('entityDoc', function() {
266 return {
267 restrict: 'E',
268 scope: {
269 mentity: '='
270 },
271 templateUrl: '/directives/entity/doc.html'
272 };
273 })
274
275 .directive('entitySignature', function() {
276 return {
277 restrict: 'E',
278 scope: {
279 mentity: '='
280 },
281 templateUrl: '/directives/entity/signature.html'
282 };
283 })
284
285 .directive('entityNamespace', function() {
286 return {
287 restrict: 'E',
288 scope: {
289 namespace: '='
290 },
291 templateUrl: '/directives/entity/namespace.html',
292 link: function ($scope, element, attrs) {
293 $scope.isObject = function(obj) {
294 return typeof obj === 'object';
295 };
296 $scope.isArray = function(obj) {
297 return Array.isArray(obj);
298 };
299 $scope.isString = function(obj) {
300 return typeof obj === 'string';
301 };
302 }
303 };
304 })
305
306 .directive('entityTag', function() {
307 return {
308 restrict: 'E',
309 scope: {
310 mentity: '='
311 },
312 replace: true,
313 templateUrl: '/directives/entity/tag.html'
314 };
315 })
316
317 .directive('entityLocation', function() {
318 return {
319 restrict: 'E',
320 scope: {
321 mentity: '='
322 },
323 templateUrl: '/directives/entity/location.html'
324 };
325 })
326
327 .directive('entityGraph', function() {
328 return {
329 restrict: 'E',
330 scope: {
331 mentity: '=',
332 graph: '='
333 },
334 replace: true,
335 templateUrl: '/directives/entity/graph.html'
336 };
337 })
338
339 .directive('entityCard', ['Feedback', function(Feedback) {
340 return {
341 restrict: 'E',
342 scope: {
343 mentity: '=',
344 defaultTab: '@',
345 noSynopsis: '='
346 },
347 replace: true,
348 templateUrl: '/directives/entity/card.html',
349 link: function ($scope, element, attrs) {
350 $scope.currentTab = $scope.defaultTab ? $scope.defaultTab : 'signature';
351
352 $scope.loadEntityStars = function() {
353 Feedback.loadEntityStars($scope.mentity.full_name,
354 function(data) {
355 $scope.ratings = data;
356 }, function(message, status) {
357 $scope.error = {message: message, status: status};
358 });
359 };
360 }
361 };
362 }])
363
364 .directive('entityList', function() {
365 return {
366 restrict: 'E',
367 scope: {
368 listEntities: '=',
369 listId: '@',
370 listTitle: '@',
371 listObjectFilter: '=',
372 },
373 templateUrl: '/directives/entity/list.html',
374 link: function ($scope, element, attrs) {
375 $scope.showFilters = false;
376 if(!$scope.listObjectFilter) {
377 $scope.listObjectFilter = {};
378 }
379 if(!$scope.visibilityFilter) {
380 $scope.visibilityFilter = {
381 public: true,
382 protected: true,
383 private: false
384 };
385 }
386 $scope.toggleFilters = function() {
387 $scope.showFilters = !$scope.showFilters;
388 };
389 }
390 };
391 })
392
393 .directive('entityLinearization', function() {
394 return {
395 restrict: 'E',
396 scope: {
397 listEntities: '=',
398 listTitle: '@',
399 listFocus: '='
400 },
401 templateUrl: '/directives/entity/linearization.html'
402 };
403 })
404
405 .directive('entityDef', ['Model', function(Model, Code) {
406 return {
407 restrict: 'E',
408 scope: {
409 definition: '=',
410 focus: '='
411 },
412 templateUrl: '/directives/entity/defcard.html',
413 link: function ($scope, element, attrs) {
414 $scope.codeId = 'code_' + $scope.definition.full_name.replace(/[^a-zA-Z0-9]/g, '_');
415
416 $scope.isActive = function() {
417 return $scope.focus == $scope.definition.full_name;
418 }
419
420 $scope.loadCardCode = function() {
421 if(!$scope.code) {
422 Model.loadEntityCode($scope.definition.full_name,
423 function(data) {
424 $scope.code = data;
425 setTimeout(function() { // smooth collapse
426 $('#' + $scope.codeId).collapse('show')
427 }, 1);
428 }, function(err) {
429 $scope.code = err;
430 });
431 } else {
432 if($('#' + $scope.codeId).hasClass('in')) {
433 $('#' + $scope.codeId).collapse('hide');
434 } else {
435 $('#' + $scope.codeId).collapse('show');
436 }
437 }
438 };
439
440 $scope.$watch('focus', function() {
441 if($scope.isActive()) $scope.loadCardCode();
442 });
443 }
444 };
445 }])
446
447 .controller('StarsCtrl', ['Feedback', '$scope', function(Feedback, $scope) {
448 $ctrl = this;
449
450 this.postStar = function(rating) {
451 Feedback.postEntityStarDimension($scope.mentity.full_name,
452 $scope.dimension, rating,
453 function(data) {
454 $scope.mean = data.mean;
455 $scope.list = data.ratings;
456 $scope.user = data.user;
457 $ctrl.loadEntityStars($scope);
458 }, function(err) {
459 $scope.err = err;
460 });
461 }
462
463 this.loadEntityStars = function($scope) {
464 Feedback.loadEntityStars($scope.mentity.full_name,
465 function(data) {
466 $scope.ratings = data;
467 }, function(message, status) {
468 $scope.error = {message: message, status: status};
469 });
470 };
471 }])
472
473 .directive('entityRating', ['Feedback', function(Feedback) {
474 return {
475 restrict: 'E',
476 scope: {
477 mentity: '=',
478 ratings: '='
479 },
480 controller: 'StarsCtrl',
481 controllerAs: 'ratingsCtrl',
482 templateUrl: '/directives/entity/rating.html'
483 };
484 }])
485
486 .directive('entityStars', ['Feedback', function(Feedback) {
487 return {
488 restrict: 'E',
489 scope: {
490 mentity: '=',
491 dimension: '@',
492 mean: '=',
493 list: '=',
494 user: '=',
495 refresh: '=',
496 ratings: '='
497 },
498 controller: 'StarsCtrl',
499 controllerAs: 'starsCtrl',
500 templateUrl: '/directives/entity/stars.html'
501 };
502 }])
503 })();