blob: 985ee85ee39c5f5791eb253819cbe0699cdf8c8b [file] [log] [blame]
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001'use strict';
2
3/**
4 * © OpenCORD
5 *
6 * Visit http://guide.xosproject.org/devguide/addview/ for more information
7 *
8 * Created by teone on 3/24/16.
9 */
10
11(function () {
12 'use strict';
13
14 /**
15 * @ngdoc overview
16 * @name xos.uiComponents
17 * @description
18 * # xos.uiComponents
19 * A collection of UI components useful for Dashboard development. <br/>
20 * Currently available components are:
21 * - [xosAlert](/#/module/xos.uiComponents.directive:xosAlert)
22 * - [xosForm](/#/module/xos.uiComponents.directive:xosForm)
23 * - [xosPagination](/#/module/xos.uiComponents.directive:xosPagination)
24 * - [xosSmartTable](/#/module/xos.uiComponents.directive:xosSmartTable)
25 * - [xosTable](/#/module/xos.uiComponents.directive:xosTable)
26 * - [xosValidation](/#/module/xos.uiComponents.directive:xosValidation)
27 **/
28
29 angular.module('xos.uiComponents', ['chart.js', 'RecursionHelper']);
30})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -070031'use strict';
32
Arpit Agarwal43978742016-08-09 15:38:25 -070033function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
Arpit Agarwal34b63832016-08-08 11:59:45 -070034
35/**
36 * © OpenCORD
37 *
38 * Visit http://guide.xosproject.org/devguide/addview/ for more information
39 *
Arpit Agarwal43978742016-08-09 15:38:25 -070040 * Created by teone on 5/25/16.
41 */
42
43(function () {
44 'use strict';
45
46 angular.module('xos.uiComponents')
47 /**
48 * @ngdoc directive
49 * @name xos.uiComponents.directive:xosField
50 * @restrict E
51 * @description The xos-field directive.
52 * This component decide, give a field wich kind of input it need to print.
53 * @param {string} name The field name
54 * @param {object} field The field configuration:
55 * ```
56 * {
57 * label: 'Label',
58 * type: 'number', //typeof field
59 * validators: {} // see xosForm for more details
60 * }
61 * ```
62 * @param {mixed} ngModel The field value
63 *
64 * @example
65
66 # Basic Example
67
68 <example module="sampleField1">
69 <file name="script.js">
70 angular.module('sampleField1', ['xos.uiComponents'])
71 .factory('_', function($window){
72 return $window._;
73 })
74 .controller('SampleCtrl', function(){
75 this.name = 'input-name';
76 this.field = {label: 'My String Value:', type: 'string'};
77 this.model = 'my string';
78 });
79 </file>
80 <file name="index.html">
81 <div ng-controller="SampleCtrl as vm">
82 <xos-field ng-model="vm.model" name="vm.name" field="vm.field"></xos-field>
83 </div>
84 </file>
85 </example>
86
87 # Possible Values
88 <example module="sampleField2">
89 <file name="script.js">
90 angular.module('sampleField2', ['xos.uiComponents'])
91 .factory('_', function($window){
92 return $window._;
93 })
94 .controller('SampleCtrl', function(){
95 this.field1 = {
96 name: 'number-field',
97 field: {label: 'My Number Value:', type: 'number'},
98 model: 2
99 };
100 this.field2 = {
101 name: 'date-field',
102 field: {label: 'My Date Value:', type: 'date'},
103 model: new Date()
104 };
105 this.field3 = {
106 name: 'boolean-field',
107 field: {label: 'My Boolean Value:', type: 'boolean'},
108 model: true
109 };
110 this.field4 = {
111 name: 'email-field',
112 field: {label: 'My Email Value:', type: 'email'},
113 model: 'sample@domain.us'
114 };
115 });
116 </file>
117 <file name="index.html">
118 <div ng-controller="SampleCtrl as vm">
119 <xos-field ng-model="vm.field1.model" name="vm.field1.name" field="vm.field1.field"></xos-field>
120 <xos-field ng-model="vm.field2.model" name="vm.field2.name" field="vm.field2.field"></xos-field>
121 <xos-field ng-model="vm.field3.model" name="vm.field3.name" field="vm.field3.field"></xos-field>
122 <xos-field ng-model="vm.field4.model" name="vm.field4.name" field="vm.field4.field"></xos-field>
123 </div>
124 </file>
125 </example>
126 # This element is recursive
127 <example module="sampleField3">
128 <file name="script.js">
129 angular.module('sampleField3', ['xos.uiComponents'])
130 .factory('_', function($window){
131 return $window._;
132 })
133 .controller('SampleCtrl', function(){
134 this.name1 = 'input-name';
135 this.field1 = {label: 'My Object Field:', type: 'object'};
136 this.model1 = {
137 name: 'Jhon',
138 age: '25',
139 email: 'jhon@thewall.ru',
140 active: true
141 };
142 this.name2 = 'another-name';
143 this.field2 = {
144 label: 'Empty Object Field',
145 type: 'object',
146 properties: {
147 foo: {
148 label: 'FooLabel:',
149 type: 'string',
150 validators: {
151 required: true
152 }
153 },
154 bar: {
155 type: 'number'
156 }
157 }
158 }
159 });
160 </file>
161 <file name="index.html">
162 <div ng-controller="SampleCtrl as vm">
163 <h4>Autogenerated object field</h4>
164 <xos-field ng-model="vm.model1" name="vm.name1" field="vm.field1"></xos-field>
165 <h4>Configured object field</h4>
166 <xos-field ng-model="vm.model2" name="vm.name2" field="vm.field2"></xos-field>
167 </div>
168 </file>
169 </example>
170 */
171 .component('xosField', {
172 restrict: 'E',
173 bindings: {
174 name: '=',
175 field: '=',
176 ngModel: '='
177 },
178 template: '\n <label ng-if="vm.field.type !== \'object\'">{{vm.field.label}}</label>\n <input\n xos-custom-validator custom-validator="vm.field.validators.custom || null"\n ng-if="vm.field.type !== \'boolean\' && vm.field.type !== \'object\' && vm.field.type !== \'select\'"\n type="{{vm.field.type}}"\n name="{{vm.name}}"\n class="form-control"\n ng-model="vm.ngModel"\n ng-minlength="vm.field.validators.minlength || 0"\n ng-maxlength="vm.field.validators.maxlength || 2000"\n ng-required="vm.field.validators.required || false" />\n <select class="form-control" ng-if ="vm.field.type === \'select\'"\n name = "{{vm.name}}"\n ng-options="item.id as item.label for item in vm.field.options"\n ng-model="vm.ngModel"\n ng-required="vm.field.validators.required || false">\n </select>\n <span class="boolean-field" ng-if="vm.field.type === \'boolean\'">\n <a href="#"\n class="btn btn-success"\n ng-show="vm.ngModel"\n ng-click="vm.ngModel = false">\n <i class="glyphicon glyphicon-ok"></i>\n </a>\n <a href="#"\n class="btn btn-danger"\n ng-show="!vm.ngModel"\n ng-click="vm.ngModel = true">\n <i class="glyphicon glyphicon-remove"></i>\n </a>\n </span>\n <div\n class="panel panel-default object-field"\n ng-if="vm.field.type == \'object\' && (!vm.isEmptyObject(vm.ngModel) || !vm.isEmptyObject(vm.field.properties))"\n >\n <div class="panel-heading">{{vm.field.label}}</div>\n <div class="panel-body">\n <div ng-if="!vm.field.properties" ng-repeat="(k, v) in vm.ngModel">\n <xos-field\n name="k"\n field="{label: vm.formatLabel(k), type: vm.getType(v)}"\n ng-model="v">\n </xos-field>\n </div>\n <div ng-if="vm.field.properties" ng-repeat="(k, v) in vm.field.properties">\n <xos-field\n name="k"\n field="{\n label: v.label || vm.formatLabel(k),\n type: v.type,\n validators: v.validators\n }"\n ng-model="vm.ngModel[k]">\n </xos-field>\n </div>\n </div>\n </div>\n ',
179 bindToController: true,
180 controllerAs: 'vm',
181 // the compile cicle is needed to support recursion
182 //compile: function (element) {
183 // return RecursionHelper.compile(element);
184 //},
185 controller: ["$attrs", "XosFormHelpers", "LabelFormatter", function controller($attrs, XosFormHelpers, LabelFormatter) {
186
187 if (!this.name) {
188 throw new Error('[xosField] Please provide a field name');
189 }
190 if (!this.field) {
191 throw new Error('[xosField] Please provide a field definition');
192 }
193 if (!this.field.type) {
194 throw new Error('[xosField] Please provide a type in the field definition');
195 }
196 if (!$attrs.ngModel) {
197 throw new Error('[xosField] Please provide an ng-model');
198 }
199 this.getType = XosFormHelpers._getFieldFormat;
200 this.formatLabel = LabelFormatter.format;
201
202 this.isEmptyObject = function (o) {
203 return o ? Object.keys(o).length === 0 : true;
204 };
205 }]
206 })
207
208 /**
209 * @ngdoc directive
210 * @name xos.uiComponents.directive:xosCustomValidator
211 * @restrict A
212 * @description The xosCustomValidator directive.
213 * This component apply a custom validation function
214 * @param {function} customValidator The function that execute the validation.
215 *
216 * You should do your validation here and return true | false,
217 * or alternatively you can return an array [errorName, true|false]
218 */
219 .directive('xosCustomValidator', function () {
220 return {
221 restrict: 'A',
222 scope: {
223 fn: '=customValidator'
224 },
225 require: 'ngModel',
226 link: function link(scope, element, attr, ctrl) {
227 if (!angular.isFunction(scope.fn)) {
228 return;
229 }
230
231 function customValidatorWrapper(ngModelValue) {
232 var valid = scope.fn(ngModelValue);
233 if (angular.isArray(valid)) {
234 // ES6 spread rocks over fn.apply()
235 ctrl.$setValidity.apply(ctrl, _toConsumableArray(valid));
236 } else {
237 ctrl.$setValidity('custom', valid);
238 }
239 return ngModelValue;
240 }
241
242 ctrl.$parsers.push(customValidatorWrapper);
243 }
244 };
245 });
246})();
247'use strict';
248
249/**
250 * © OpenCORD
251 *
252 * Visit http://guide.xosproject.org/devguide/addview/ for more information
253 *
254 * Created by teone on 4/15/16.
Arpit Agarwal34b63832016-08-08 11:59:45 -0700255 */
256
257(function () {
258 'use strict';
259
260 angular.module('xos.uiComponents')
261
262 /**
Arpit Agarwal43978742016-08-09 15:38:25 -0700263 * @ngdoc directive
264 * @name xos.uiComponents.directive:xosValidation
265 * @restrict E
266 * @description The xos-validation directive
267 * @param {Object} errors The error object
268 * @element ANY
269 * @scope
Arpit Agarwal34b63832016-08-08 11:59:45 -0700270 * @example
Arpit Agarwal43978742016-08-09 15:38:25 -0700271 <example module="sampleValidation">
Arpit Agarwal34b63832016-08-08 11:59:45 -0700272 <file name="index.html">
273 <div ng-controller="SampleCtrl as vm">
Arpit Agarwal43978742016-08-09 15:38:25 -0700274 <div class="row">
275 <div class="col-xs-12">
276 <label>Set an error type:</label>
277 </div>
278 <div class="col-xs-2">
279 <a class="btn"
280 ng-click="vm.field.$error.required = !vm.field.$error.required"
281 ng-class="{'btn-default': !vm.field.$error.required, 'btn-success': vm.field.$error.required}">
282 Required
283 </a>
284 </div>
285 <div class="col-xs-2">
286 <a class="btn"
287 ng-click="vm.field.$error.email = !vm.field.$error.email"
288 ng-class="{'btn-default': !vm.field.$error.email, 'btn-success': vm.field.$error.email}">
289 Email
290 </a>
291 </div>
292 <div class="col-xs-2">
293 <a class="btn"
294 ng-click="vm.field.$error.minlength = !vm.field.$error.minlength"
295 ng-class="{'btn-default': !vm.field.$error.minlength, 'btn-success': vm.field.$error.minlength}">
296 Min Length
297 </a>
298 </div>
299 <div class="col-xs-2">
300 <a class="btn"
301 ng-click="vm.field.$error.maxlength = !vm.field.$error.maxlength"
302 ng-class="{'btn-default': !vm.field.$error.maxlength, 'btn-success': vm.field.$error.maxlength}">
303 Max Length
304 </a>
305 </div>
306 </div>
307 <xos-validation field ="vm.field" form = "vm.form"></xos-validation>
Arpit Agarwal34b63832016-08-08 11:59:45 -0700308 </div>
309 </file>
310 <file name="script.js">
Arpit Agarwal43978742016-08-09 15:38:25 -0700311 angular.module('sampleValidation', ['xos.uiComponents'])
Arpit Agarwal34b63832016-08-08 11:59:45 -0700312 .controller('SampleCtrl', function(){
Arpit Agarwal43978742016-08-09 15:38:25 -0700313 this.field = {
314 $error: {}
Arpit Agarwal34b63832016-08-08 11:59:45 -0700315 };
Arpit Agarwal43978742016-08-09 15:38:25 -0700316 this.form= {
317 $submitted:true
318 }
Arpit Agarwal34b63832016-08-08 11:59:45 -0700319 });
320 </file>
321 </example>
Arpit Agarwal43978742016-08-09 15:38:25 -0700322 */
Arpit Agarwal34b63832016-08-08 11:59:45 -0700323
Arpit Agarwal43978742016-08-09 15:38:25 -0700324 .component('xosValidation', {
Arpit Agarwal34b63832016-08-08 11:59:45 -0700325 restrict: 'E',
326 bindings: {
Arpit Agarwal43978742016-08-09 15:38:25 -0700327 field: '=',
328 form: '='
Arpit Agarwal34b63832016-08-08 11:59:45 -0700329 },
Arpit Agarwal43978742016-08-09 15:38:25 -0700330 template: '\n <div ng-cloak>\n <xos-alert config="vm.config" show="vm.field.$error.required !== undefined && vm.field.$error.required !== false && (vm.field.$touched || vm.form.$submitted)">\n Field required\n </xos-alert>\n <xos-alert config="vm.config" show="vm.field.$error.email !== undefined && vm.field.$error.email !== false && (vm.field.$touched || vm.form.$submitted)">\n This is not a valid email\n </xos-alert>\n <xos-alert config="vm.config" show="vm.field.$error.minlength !== undefined && vm.field.$error.minlength !== false && (vm.field.$touched || vm.form.$submitted)">\n Too short\n </xos-alert>\n <xos-alert config="vm.config" show="vm.field.$error.maxlength !== undefined && vm.field.$error.maxlength !== false && (vm.field.$touched || vm.form.$submitted)">\n Too long\n </xos-alert>\n <xos-alert config="vm.config" show="vm.field.$error.custom !== undefined && vm.field.$error.custom !== false && (vm.field.$touched || vm.form.$submitted)">\n Field invalid\n </xos-alert>\n </div>\n ',
331 transclude: true,
Arpit Agarwal34b63832016-08-08 11:59:45 -0700332 bindToController: true,
333 controllerAs: 'vm',
Arpit Agarwal43978742016-08-09 15:38:25 -0700334 controller: function controller() {
335 this.config = {
336 type: 'danger'
337 };
338 }
339 });
340})();
341'use strict';
342
343/**
344 * © OpenCORD
345 *
346 * Visit http://guide.xosproject.org/devguide/addview/ for more information
347 *
348 * Created by teone on 4/15/16.
349 */
350
351(function () {
352 'use strict';
353
354 angular.module('xos.uiComponents')
355
356 /**
357 * @ngdoc directive
358 * @name xos.uiComponents.directive:xosPagination
359 * @restrict E
360 * @description The xos-table directive
361 * @param {Number} pageSize Number of elements per page
362 * @param {Number} totalElements Number of total elements in the collection
363 * @param {Function} change The callback to be triggered on page change.
364 * * @element ANY
365 * @scope
366 * @example
367 <example module="samplePagination">
368 <file name="index.html">
369 <div ng-controller="SampleCtrl1 as vm">
370 <xos-pagination
371 page-size="vm.pageSize"
372 total-elements="vm.totalElements"
373 change="vm.change">
374 </xos-pagination>
375 </div>
376 </file>
377 <file name="script.js">
378 angular.module('samplePagination', ['xos.uiComponents'])
379 .controller('SampleCtrl1', function(){
380 this.pageSize = 10;
381 this.totalElements = 35;
382 this.change = (pageNumber) => {
383 console.log(pageNumber);
384 }
385 });
386 </file>
387 </example>
388 **/
389
390 .component('xosPagination', {
391 restrict: 'E',
392 bindings: {
393 pageSize: '=',
394 totalElements: '=',
395 change: '='
396 },
397 template: '\n <div class="row" ng-if="vm.pageList.length > 1">\n <div class="col-xs-12 text-center">\n <ul class="pagination">\n <li\n ng-click="vm.goToPage(vm.currentPage - 1)"\n ng-class="{disabled: vm.currentPage == 0}">\n <a href="" aria-label="Previous">\n <span aria-hidden="true">&laquo;</span>\n </a>\n </li>\n <li ng-repeat="i in vm.pageList" ng-class="{active: i === vm.currentPage}">\n <a href="" ng-click="vm.goToPage(i)">{{i + 1}}</a>\n </li>\n <li\n ng-click="vm.goToPage(vm.currentPage + 1)"\n ng-class="{disabled: vm.currentPage == vm.pages - 1}">\n <a href="" aria-label="Next">\n <span aria-hidden="true">&raquo;</span>\n </a>\n </li>\n </ul>\n </div>\n </div>\n ',
398 bindToController: true,
399 controllerAs: 'vm',
400 controller: ["$scope", function controller($scope) {
Arpit Agarwal34b63832016-08-08 11:59:45 -0700401 var _this = this;
402
Arpit Agarwal43978742016-08-09 15:38:25 -0700403 this.currentPage = 0;
Arpit Agarwal34b63832016-08-08 11:59:45 -0700404
Arpit Agarwal43978742016-08-09 15:38:25 -0700405 this.goToPage = function (n) {
406 if (n < 0 || n === _this.pages) {
407 return;
Arpit Agarwal34b63832016-08-08 11:59:45 -0700408 }
Arpit Agarwal43978742016-08-09 15:38:25 -0700409 _this.currentPage = n;
410 _this.change(n);
Arpit Agarwal34b63832016-08-08 11:59:45 -0700411 };
412
Arpit Agarwal43978742016-08-09 15:38:25 -0700413 this.createPages = function (pages) {
414 var arr = [];
415 for (var i = 0; i < pages; i++) {
416 arr.push(i);
417 }
418 return arr;
Arpit Agarwal34b63832016-08-08 11:59:45 -0700419 };
420
Arpit Agarwal43978742016-08-09 15:38:25 -0700421 // watch for data changes
422 $scope.$watch(function () {
423 return _this.totalElements;
424 }, function () {
425 if (_this.totalElements) {
426 _this.pages = Math.ceil(_this.totalElements / _this.pageSize);
427 _this.pageList = _this.createPages(_this.pages);
428 }
429 });
Arpit Agarwal34b63832016-08-08 11:59:45 -0700430 }]
Arpit Agarwal43978742016-08-09 15:38:25 -0700431 }).filter('pagination', function () {
432 return function (input, start) {
433 if (!input || !angular.isArray(input)) {
434 return input;
435 }
436 start = parseInt(start, 10);
437 return input.slice(start);
438 };
Arpit Agarwal34b63832016-08-08 11:59:45 -0700439 });
440})();
Arpit Agarwal34b63832016-08-08 11:59:45 -0700441'use strict';
442
443/**
444 * © OpenCORD
445 *
446 * Visit http://guide.xosproject.org/devguide/addview/ for more information
447 *
448 * Created by teone on 3/24/16.
449 */
450
451(function () {
452 'use strict';
453
454 angular.module('xos.uiComponents')
455 /**
456 * @ngdoc directive
457 * @name xos.uiComponents.directive:xosSmartPie
458 * @restrict E
459 * @description The xos-table directive
460 * @param {Object} config The configuration for the component,
461 * it is composed by the name of an angular [$resource](https://docs.angularjs.org/api/ngResource/service/$resource)
462 * and a field name that is used to group the data.
463 * ```
464 * {
465 resource: 'Users',
466 groupBy: 'fieldName',
467 classes: 'my-custom-class',
468 labelFormatter: (labels) => {
469 // here you can format your label,
470 // you should return an array with the same order
471 return labels;
472 }
473 }
474 * ```
475 * @scope
476 * @example
477
478 Displaying Local data
479 <example module="sampleSmartPieLocal">
480 <file name="index.html">
481 <div ng-controller="SampleCtrlLocal as vm">
482 <xos-smart-pie config="vm.configLocal"></xos-smart-pie>
483 </div>
484 </file>
485 <file name="script.js">
486 angular.module('sampleSmartPieLocal', ['xos.uiComponents'])
487 .factory('_', function($window){
488 return $window._;
489 })
490 .controller('SampleCtrlLocal', function($timeout){
491
492 this.datas = [
493 {id: 1, first_name: 'Jon', last_name: 'aaa', category: 2},
494 {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 1},
495 {id: 3, first_name: 'Aria', last_name: 'Stark', category: 2}
496 ];
497 this.configLocal = {
498 data: [],
499 groupBy: 'category',
500 classes: 'local',
501 labelFormatter: (labels) => {
502 return labels.map(l => l === '1' ? 'North' : 'Dragon');
503 }
504 };
505
506 $timeout(() => {
507 // this need to be triggered in this way just because of ngDoc,
508 // otherwise you can assign data directly in the config
509 this.configLocal.data = this.datas;
510 }, 1)
511 });
512 </file>
513 </example>
514 Fetching data from API
515 <example module="sampleSmartPieResource">
516 <file name="index.html">
517 <div ng-controller="SampleCtrl as vm">
518 <xos-smart-pie config="vm.config"></xos-smart-pie>
519 </div>
520 </file>
521 <file name="script.js">
522 angular.module('sampleSmartPieResource', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
523 .controller('SampleCtrl', function(){
524 this.config = {
525 resource: 'SampleResource',
526 groupBy: 'category',
527 classes: 'resource',
528 labelFormatter: (labels) => {
529 return labels.map(l => l === '1' ? 'North' : 'Dragon');
530 }
531 };
532 });
533 </file>
534 <file name="backendPoll.js">
535 angular.module('sampleSmartPieResource')
536 .run(function($httpBackend, _){
537 let datas = [
538 {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
539 {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
540 {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1}
541 ];
542 $httpBackend.whenGET('/test').respond(200, datas)
543 })
544 .factory('_', function($window){
545 return $window._;
546 })
547 .service('SampleResource', function($resource){
548 return $resource('/test/:id', {id: '@id'});
549 })
550 </file>
551 </example>
552 Polling data from API
553 <example module="sampleSmartPiePoll">
554 <file name="index.html">
555 <div ng-controller="SampleCtrl as vm">
556 <xos-smart-pie config="vm.config"></xos-smart-pie>
557 </div>
558 </file>
559 <file name="script.js">
560 angular.module('sampleSmartPiePoll', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
561 .controller('SampleCtrl', function(){
562 this.config = {
563 resource: 'SampleResource',
564 groupBy: 'category',
565 poll: 2,
566 labelFormatter: (labels) => {
567 return labels.map(l => l === '1' ? 'Active' : 'Banned');
568 }
569 };
570 });
571 </file>
572 <file name="backend.js">
573 angular.module('sampleSmartPiePoll')
574 .run(function($httpBackend, _){
575 let mock = [
576 [
577 {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
578 {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
579 {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1},
580 {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 1}
581 ],
582 [
583 {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
584 {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
585 {id: 3, first_name: 'Aria', last_name: 'Stark', category: 2},
586 {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 2}
587 ],
588 [
589 {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
590 {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
591 {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1},
592 {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 2}
593 ]
594 ];
595 $httpBackend.whenGET('/test').respond(function(method, url, data, headers, params) {
596 return [200, mock[Math.round(Math.random() * 3)]];
597 });
598 })
599 .factory('_', function($window){
600 return $window._;
601 })
602 .service('SampleResource', function($resource){
603 return $resource('/test/:id', {id: '@id'});
604 })
605 </file>
606 </example>
607 */
608 .component('xosSmartPie', {
609 restrict: 'E',
610 bindings: {
611 config: '='
612 },
613 template: '\n <canvas\n class="chart chart-pie {{vm.config.classes}}"\n chart-data="vm.data" chart-labels="vm.labels"\n chart-legend="{{vm.config.legend}}">\n </canvas>\n ',
614 bindToController: true,
615 controllerAs: 'vm',
616 controller: ["$injector", "$interval", "$scope", "$timeout", "_", function controller($injector, $interval, $scope, $timeout, _) {
617 var _this = this;
618
619 if (!this.config.resource && !this.config.data) {
620 throw new Error('[xosSmartPie] Please provide a resource or an array of data in the configuration');
621 }
622
623 var groupData = function groupData(data) {
624 return _.groupBy(data, _this.config.groupBy);
625 };
626 var formatData = function formatData(data) {
627 return _.reduce(Object.keys(data), function (list, group) {
628 return list.concat(data[group].length);
629 }, []);
630 };
631 var formatLabels = function formatLabels(data) {
632 return angular.isFunction(_this.config.labelFormatter) ? _this.config.labelFormatter(Object.keys(data)) : Object.keys(data);
633 };
634
635 var prepareData = function prepareData(data) {
636 // group data
637 var grouped = groupData(data);
638 _this.data = formatData(grouped);
639 // create labels
640 _this.labels = formatLabels(grouped);
641 };
642
643 if (this.config.resource) {
644 (function () {
645
646 _this.Resource = $injector.get(_this.config.resource);
647 var getData = function getData() {
648 _this.Resource.query().$promise.then(function (res) {
649
650 if (!res[0]) {
651 return;
652 }
653
654 prepareData(res);
655 });
656 };
657
658 getData();
659
660 if (_this.config.poll) {
661 $interval(function () {
662 getData();
663 }, _this.config.poll * 1000);
664 }
665 })();
666 } else {
667 $scope.$watch(function () {
668 return _this.config.data;
669 }, function (data) {
670 if (data) {
671 prepareData(_this.config.data);
672 }
673 }, true);
674 }
675
676 $scope.$on('create', function (event, chart) {
677 console.log('create: ' + chart.id);
678 });
679
680 $scope.$on('destroy', function (event, chart) {
681 console.log('destroy: ' + chart.id);
682 });
683 }]
684 });
685})();
Arpit Agarwal34b63832016-08-08 11:59:45 -0700686'use strict';
687
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -0700688/**
689 * © OpenCORD
690 *
691 * Visit http://guide.xosproject.org/devguide/addview/ for more information
692 *
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -0700693 * Created by teone on 3/24/16.
694 */
695
696(function () {
697 'use strict';
698
699 angular.module('xos.uiComponents')
700
701 /**
702 * @ngdoc directive
703 * @name xos.uiComponents.directive:xosTable
704 * @restrict E
705 * @description The xos-table directive
706 * @param {Object} config The configuration for the component.
707 * ```
708 * {
709 * columns: [
710 * {
711 * label: 'Human readable name',
712 * prop: 'Property to read in the model object',
713 * type: 'boolean'| 'array'| 'object'| 'custom'| 'date' | 'icon' // see examples for more details
714 formatter: fn(), // receive the whole item if tipe is custom and return a string
715 link: fn() // receive the whole item and return an url
716 * }
717 * ],
718 * classes: 'table table-striped table-bordered',
719 * actions: [ // if defined add an action column
720 {
721 label: 'delete',
722 icon: 'remove', // refers to bootstraps glyphicon
723 cb: (user) => { // receive the model
724 console.log(user);
725 },
726 color: 'red'
727 }
728 ],
729 filter: 'field', // can be by `field` or `fulltext`
730 order: true | {field: 'property name', reverse: true | false} // whether to show ordering arrows, or a configuration for a default ordering
731 * }
732 * ```
733 * @param {Array} data The data that should be rendered
734 * @element ANY
735 * @scope
736 * @example
737 # Basic usage
738 <example module="sampleTable1">
739 <file name="index.html">
740 <div ng-controller="SampleCtrl1 as vm">
741 <xos-table data="vm.data" config="vm.config"></xos-table>
742 </div>
743 </file>
744 <file name="script.js">
745 angular.module('sampleTable1', ['xos.uiComponents'])
746 .factory('_', function($window){
747 return $window._;
748 })
749 .controller('SampleCtrl1', function(){
750 this.config = {
751 columns: [
752 {
753 label: 'First Name', // column title
754 prop: 'name' // property to read in the data array
755 },
756 {
757 label: 'Last Name',
758 prop: 'lastname'
759 }
760 ]
761 };
762 this.data = [
763 {
764 name: 'John',
765 lastname: 'Doe'
766 },
767 {
768 name: 'Gili',
769 lastname: 'Fereydoun'
770 }
771 ]
772 });
773 </file>
774 </example>
775 # Filtering
776 <example module="sampleTable2" animations="true">
777 <file name="index.html">
778 <div ng-controller="SampleCtrl2 as vm">
779 <xos-table data="vm.data" config="vm.config"></xos-table>
780 </div>
781 </file>
782 <file name="script.js">
783 angular.module('sampleTable2', ['xos.uiComponents', 'ngAnimate'])
784 .factory('_', function($window){
785 return $window._;
786 })
787 .controller('SampleCtrl2', function(){
788 this.config = {
789 columns: [
790 {
791 label: 'First Name', // column title
792 prop: 'name' // property to read in the data array
793 },
794 {
795 label: 'Last Name',
796 prop: 'lastname'
797 }
798 ],
799 classes: 'table table-striped table-condensed', // table classes, default to `table table-striped table-bordered`
800 actions: [ // if defined add an action column
801 {
802 label: 'delete', // label
803 icon: 'remove', // icons, refers to bootstraps glyphicon
804 cb: (user) => { // callback, get feeded with the full object
805 console.log(user);
806 },
807 color: 'red' // icon color
808 }
809 ],
810 filter: 'field', // can be by `field` or `fulltext`
811 order: true
812 };
813 this.data = [
814 {
815 name: 'John',
816 lastname: 'Doe'
817 },
818 {
819 name: 'Gili',
820 lastname: 'Fereydoun'
821 }
822 ]
823 });
824 </file>
825 </example>
826 # Pagination
827 <example module="sampleTable3">
828 <file name="index.html">
829 <div ng-controller="SampleCtrl3 as vm">
830 <xos-table data="vm.data" config="vm.config"></xos-table>
831 </div>
832 </file>
833 <file name="script.js">
834 angular.module('sampleTable3', ['xos.uiComponents'])
835 .factory('_', function($window){
836 return $window._;
837 })
838 .controller('SampleCtrl3', function(){
839 this.config = {
840 columns: [
841 {
842 label: 'First Name', // column title
843 prop: 'name' // property to read in the data array
844 },
845 {
846 label: 'Last Name',
847 prop: 'lastname'
848 }
849 ],
850 pagination: {
851 pageSize: 2
852 }
853 };
854 this.data = [
855 {
856 name: 'John',
857 lastname: 'Doe'
858 },
859 {
860 name: 'Gili',
861 lastname: 'Fereydoun'
862 },
863 {
864 name: 'Lucky',
865 lastname: 'Clarkson'
866 },
867 {
868 name: 'Tate',
869 lastname: 'Spalding'
870 }
871 ]
872 });
873 </file>
874 </example>
875 # Field formatter
876 <example module="sampleTable4">
877 <file name="index.html">
878 <div ng-controller="SampleCtrl as vm">
879 <xos-table data="vm.data" config="vm.config"></xos-table>
880 </div>
881 </file>
882 <file name="script.js">
883 angular.module('sampleTable4', ['xos.uiComponents'])
884 .factory('_', function($window){
885 return $window._;
886 })
887 .controller('SampleCtrl', function(){
888 this.config = {
889 columns: [
890 {
891 label: 'First Name',
892 prop: 'name',
893 link: item => `https://www.google.it/#q=${item.name}`
894 },
895 {
896 label: 'Enabled',
897 prop: 'enabled',
898 type: 'boolean'
899 },
900 {
901 label: 'Services',
902 prop: 'services',
903 type: 'array'
904 },
905 {
906 label: 'Details',
907 prop: 'details',
908 type: 'object'
909 },
910 {
911 label: 'Created',
912 prop: 'created',
913 type: 'date'
914 },
915 {
916 label: 'Icon',
917 type: 'icon',
918 formatter: item => item.icon //note that this refer to [Bootstrap Glyphicon](http://getbootstrap.com/components/#glyphicons)
919 }
920 ]
921 };
922 this.data = [
923 {
924 name: 'John',
925 enabled: true,
926 services: ['Cdn', 'IpTv'],
927 details: {
928 c_tag: '243',
929 s_tag: '444'
930 },
931 created: new Date('December 17, 1995 03:24:00'),
932 icon: 'music'
933 },
934 {
935 name: 'Gili',
936 enabled: false,
937 services: ['Cdn', 'IpTv', 'Cache'],
938 details: {
939 c_tag: '675',
940 s_tag: '893'
941 },
942 created: new Date(),
943 icon: 'camera'
944 }
945 ]
946 });
947 </file>
948 </example>
949 # Custom formatter
950 <example module="sampleTable5">
951 <file name="index.html">
952 <div ng-controller="SampleCtrl as vm">
953 <xos-table data="vm.data" config="vm.config"></xos-table>
954 </div>
955 </file>
956 <file name="script.js">
957 angular.module('sampleTable5', ['xos.uiComponents'])
958 .factory('_', function($window){
959 return $window._;
960 })
961 .controller('SampleCtrl', function(){
962 this.config = {
963 columns: [
964 {
965 label: 'Username',
966 prop: 'username'
967 },
968 {
969 label: 'Features',
970 type: 'custom',
971 formatter: (val) => {
972
973 let cdnEnabled = val.features.cdn ? 'enabled' : 'disabled';
974 return `
975 Cdn is ${cdnEnabled},
976 uplink speed is ${val.features.uplink_speed}
977 and downlink speed is ${val.features.downlink_speed}
978 `;
979 }
980 }
981 ]
982 };
983 this.data = [
984 {
985 username: 'John',
986 features: {
987 "cdn": false,
988 "uplink_speed": 1000000000,
989 "downlink_speed": 1000000000,
990 "uverse": true,
991 "status": "enabled"
992 }
993 },
994 {
995 username: 'Gili',
996 features: {
997 "cdn": true,
998 "uplink_speed": 3000000000,
999 "downlink_speed": 2000000000,
1000 "uverse": true,
1001 "status": "enabled"
1002 }
1003 }
1004 ]
1005 });
1006 </file>
1007 </example>
1008 **/
1009
Arpit Agarwal34b63832016-08-08 11:59:45 -07001010 .component('xosTable', {
1011 restrict: 'E',
1012 bindings: {
1013 data: '=',
1014 config: '='
1015 },
1016 template: '\n <div ng-show="vm.data.length > 0 && vm.loader == false">\n <div class="row" ng-if="vm.config.filter == \'fulltext\'">\n <div class="col-xs-12">\n <input\n class="form-control"\n placeholder="Type to search.."\n type="text"\n ng-model="vm.query"/>\n </div>\n </div>\n <table ng-class="vm.classes" ng-hide="vm.data.length == 0">\n <thead>\n <tr>\n <th ng-repeat="col in vm.columns">\n {{col.label}}\n <span ng-if="vm.config.order">\n <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = false">\n <i class="glyphicon glyphicon-chevron-up"></i>\n </a>\n <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = true">\n <i class="glyphicon glyphicon-chevron-down"></i>\n </a>\n </span>\n </th>\n <th ng-if="vm.config.actions">Actions:</th>\n </tr>\n </thead>\n <tbody ng-if="vm.config.filter == \'field\'">\n <tr>\n <td ng-repeat="col in vm.columns">\n <input\n ng-if="col.type !== \'boolean\' && col.type !== \'array\' && col.type !== \'object\' && col.type !== \'custom\'"\n class="form-control"\n placeholder="Type to search by {{col.label}}"\n type="text"\n ng-model="vm.query[col.prop]"/>\n <select\n ng-if="col.type === \'boolean\'"\n class="form-control"\n ng-model="vm.query[col.prop]">\n <option value="">-</option>\n <option value="true">True</option>\n <option value="false">False</option>\n </select>\n </td>\n <td ng-if="vm.config.actions"></td>\n </tr>\n </tbody>\n <tbody>\n <tr ng-repeat="item in vm.data | filter:vm.query:vm.comparator | orderBy:vm.orderBy:vm.reverse | pagination:vm.currentPage * vm.config.pagination.pageSize | limitTo: (vm.config.pagination.pageSize || vm.data.length) track by $index">\n <td ng-repeat="col in vm.columns" xos-link-wrapper>\n <span ng-if="!col.type">{{item[col.prop]}}</span>\n <span ng-if="col.type === \'boolean\'">\n <i class="glyphicon"\n ng-class="{\'glyphicon-ok\': item[col.prop], \'glyphicon-remove\': !item[col.prop]}">\n </i>\n </span>\n <span ng-if="col.type === \'date\'">\n {{item[col.prop] | date:\'H:mm MMM d, yyyy\'}}\n </span>\n <span ng-if="col.type === \'array\'">\n {{item[col.prop] | arrayToList}}\n </span>\n <span ng-if="col.type === \'object\'">\n <dl class="dl-horizontal">\n <span ng-repeat="(k,v) in item[col.prop]">\n <dt>{{k}}</dt>\n <dd>{{v}}</dd>\n </span>\n </dl>\n </span>\n <span ng-if="col.type === \'custom\'">\n {{col.formatter(item)}}\n </span>\n <span ng-if="col.type === \'icon\'">\n <i class="glyphicon glyphicon-{{col.formatter(item)}}">\n </i>\n </span>\n </td>\n <td ng-if="vm.config.actions">\n <a href=""\n ng-repeat="action in vm.config.actions"\n ng-click="action.cb(item)"\n title="{{action.label}}">\n <i\n class="glyphicon glyphicon-{{action.icon}}"\n style="color: {{action.color}};"></i>\n </a>\n </td>\n </tr>\n </tbody>\n </table>\n <xos-pagination\n ng-if="vm.config.pagination"\n page-size="vm.config.pagination.pageSize"\n total-elements="vm.data.length"\n change="vm.goToPage">\n </xos-pagination>\n </div>\n <div ng-show="(vm.data.length == 0 || !vm.data) && vm.loader == false">\n <xos-alert config="{type: \'info\'}">\n No data to show.\n </xos-alert>\n </div>\n <div ng-show="vm.loader == true">\n <div class="loader"></div>\n </div>\n ',
1017 bindToController: true,
1018 controllerAs: 'vm',
1019 controller: ["_", "$scope", "Comparator", function controller(_, $scope, Comparator) {
1020 var _this = this;
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001021
Arpit Agarwal34b63832016-08-08 11:59:45 -07001022 this.comparator = Comparator;
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001023
Arpit Agarwal34b63832016-08-08 11:59:45 -07001024 this.loader = true;
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001025
Arpit Agarwal34b63832016-08-08 11:59:45 -07001026 $scope.$watch(function () {
1027 return _this.data;
1028 }, function (data) {
1029 if (angular.isDefined(data)) {
1030 _this.loader = false;
1031 }
1032 });
1033
1034 if (!this.config) {
1035 throw new Error('[xosTable] Please provide a configuration via the "config" attribute');
1036 }
1037
1038 if (!this.config.columns) {
1039 throw new Error('[xosTable] Please provide a columns list in the configuration');
1040 }
1041
1042 // handle default ordering
1043 if (this.config.order && angular.isObject(this.config.order)) {
1044 this.reverse = this.config.order.reverse || false;
1045 this.orderBy = this.config.order.field || 'id';
1046 }
1047
1048 // if columns with type 'custom' are provided
1049 // check that a custom formatte3 is provided too
1050 var customCols = _.filter(this.config.columns, { type: 'custom' });
1051 if (angular.isArray(customCols) && customCols.length > 0) {
1052 _.forEach(customCols, function (col) {
1053 if (!col.formatter || !angular.isFunction(col.formatter)) {
1054 throw new Error('[xosTable] You have provided a custom field type, a formatter function should provided too.');
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001055 }
1056 });
Arpit Agarwal34b63832016-08-08 11:59:45 -07001057 }
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001058
Arpit Agarwal34b63832016-08-08 11:59:45 -07001059 // if columns with type 'icon' are provided
1060 // check that a custom formatte3 is provided too
1061 var iconCols = _.filter(this.config.columns, { type: 'icon' });
1062 if (angular.isArray(iconCols) && iconCols.length > 0) {
1063 _.forEach(iconCols, function (col) {
1064 if (!col.formatter || !angular.isFunction(col.formatter)) {
1065 throw new Error('[xosTable] You have provided an icon field type, a formatter function should provided too.');
1066 }
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001067 });
Arpit Agarwal34b63832016-08-08 11:59:45 -07001068 }
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001069
Arpit Agarwal34b63832016-08-08 11:59:45 -07001070 // if a link property is passed,
1071 // it should be a function
1072 var linkedColumns = _.filter(this.config.columns, function (col) {
1073 return angular.isDefined(col.link);
1074 });
1075 if (angular.isArray(linkedColumns) && linkedColumns.length > 0) {
1076 _.forEach(linkedColumns, function (col) {
1077 if (!angular.isFunction(col.link)) {
1078 throw new Error('[xosTable] The link property should be a function.');
1079 }
1080 });
1081 }
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001082
Arpit Agarwal34b63832016-08-08 11:59:45 -07001083 this.columns = this.config.columns;
1084 this.classes = this.config.classes || 'table table-striped table-bordered';
1085
1086 if (this.config.actions) {
1087 // TODO validate action format
1088 }
1089 if (this.config.pagination) {
1090 this.currentPage = 0;
1091 this.goToPage = function (n) {
1092 _this.currentPage = n;
1093 };
1094 }
1095 }]
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001096 })
1097 // TODO move in separate files
1098 // TODO test
1099 .filter('arrayToList', function () {
1100 return function (input) {
1101 if (!angular.isArray(input)) {
1102 return input;
1103 }
1104 return input.join(', ');
1105 };
1106 })
1107 // TODO test
1108 .directive('xosLinkWrapper', function () {
1109 return {
1110 restrict: 'A',
1111 transclude: true,
1112 template: '\n <a ng-if="col.link" href="{{col.link(item)}}">\n <div ng-transclude></div>\n </a>\n <div ng-transclude ng-if="!col.link"></div>\n '
1113 };
1114 });
1115})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001116'use strict';
1117
1118/**
1119 * © OpenCORD
1120 *
1121 * Visit http://guide.xosproject.org/devguide/addview/ for more information
1122 *
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001123 * Created by teone on 4/18/16.
1124 */
1125
1126(function () {
1127 'use strict';
1128
1129 angular.module('xos.uiComponents')
1130
1131 /**
1132 * @ngdoc directive
1133 * @name xos.uiComponents.directive:xosForm
1134 * @restrict E
1135 * @description The xos-form directive.
1136 * This components have two usage, given a model it is able to autogenerate a form or it can be configured to create a custom form.
1137 * @param {Object} config The configuration object
1138 * ```
1139 * {
1140 * exclude: ['id', 'validators', 'created', 'updated', 'deleted'], //field to be skipped in the form, the provide values are concatenated
1141 * actions: [ // define the form buttons with related callback
1142 * {
1143 label: 'save',
1144 icon: 'ok', // refers to bootstraps glyphicon
1145 cb: (user) => { // receive the model
1146 console.log(user);
1147 },
1148 class: 'success'
1149 }
1150 * ],
1151 * feedback: {
1152 show: false,
1153 message: 'Form submitted successfully !!!',
1154 type: 'success' //refers to bootstrap class
1155 },
1156 * fields: {
1157 * field_name: {
1158 * label: 'Field Label',
1159 * type: 'string' // options are: [date, boolean, number, email, string, select],
1160 * validators: {
1161 * minlength: number,
1162 maxlength: number,
1163 required: boolean,
1164 min: number,
1165 max: number,
1166 custom: (value) => {
1167 // do your validation here and return true | false
1168 // alternatively you can return an array [errorName, true|false]
1169 }
1170 * }
1171 * }
1172 * }
1173 * }
1174 * ```
1175 * @element ANY
1176 * @scope
1177 * @requires xos.uiComponents.directive:xosField
1178 * @requires xos.uiComponents.XosFormHelpers
1179 * @requires xos.helpers._
1180 * @example
1181
1182 Autogenerated form
1183 <example module="sampleForm">
1184 <file name="script.js">
1185 angular.module('sampleForm', ['xos.uiComponents'])
1186 .factory('_', function($window){
1187 return $window._;
1188 })
1189 .controller('SampleCtrl', function(){
1190 this.model = {
1191 first_name: 'Jhon',
1192 last_name: 'Doe',
1193 email: 'jhon.doe@sample.com',
1194 active: true,
1195 birthDate: '2015-02-17T22:06:38.059000Z'
1196 }
1197 this.config = {
1198 exclude: ['password', 'last_login'],
1199 formName: 'sampleForm',
1200 actions: [
1201 {
1202 label: 'Save',
1203 icon: 'ok', // refers to bootstraps glyphicon
1204 cb: (user) => { // receive the model
1205 console.log(user);
1206 },
1207 class: 'success'
1208 }
1209 ]
1210 };
1211 });
1212 </file>
1213 <file name="index.html">
1214 <div ng-controller="SampleCtrl as vm">
1215 <xos-form ng-model="vm.model" config="vm.config"></xos-form>
1216 </div>
1217 </file>
1218 </example>
1219 Configuration defined form
1220 <example module="sampleForm1">
1221 <file name="script.js">
1222 angular.module('sampleForm1', ['xos.uiComponents','ngResource', 'ngMockE2E'])
1223 .factory('_', function($window){
1224 return $window._;
1225 })
1226 .controller('SampleCtrl1', function(SampleResource){
1227 this.model = {
1228 };
1229 this.config = {
1230 exclude: ['password', 'last_login'],
1231 formName: 'sampleForm1',
1232 feedback: {
1233 show: false,
1234 message: 'Form submitted successfully !!!',
1235 type: 'success'
1236 },
1237 actions: [
1238 {
1239 label: 'Save',
1240 icon: 'ok', // refers to bootstraps glyphicon
1241 cb: (user) => { // receive the model
1242 console.log(user);
1243 this.config.feedback.show = true;
1244 this.config.feedback.type='success';
1245 },
1246 class: 'success'
1247 }
1248 ],
1249 fields: {
1250 first_name: {
1251 type: 'string',
1252 validators: {
1253 required: true
1254 }
1255 },
1256 last_name: {
1257 label: 'Surname',
1258 type: 'string',
1259 validators: {
1260 required: true,
1261 minlength: 10
1262 }
1263 },
1264 age: {
1265 type: 'number',
1266 validators: {
1267 required: true,
1268 min: 21
1269 }
1270 },
1271 site: {
1272 label: 'Site',
1273 type: 'select',
1274 validators: { required: true},
1275 hint: 'The Site this Slice belongs to',
1276 options: []
1277 },
1278 }
1279 };
1280 SampleResource.query().$promise
1281 .then((users) => {
1282 //this.users_site = users;
1283 //console.log(users);
1284 this.optionVal = users;
1285 this.config.fields['site'].options = this.optionVal;
1286 //= this.optionVal;
1287 })
1288 .catch((e) => {
1289 throw new Error(e);
1290 });
1291 });
1292 </file>
1293 <file name="backend.js">
1294 angular.module('sampleForm1')
1295 .run(function($httpBackend, _){
1296 let datas = [{id: 1, label: 'site1'},{id: 4, label: 'site4'},{id: 3, label: 'site3'}];
1297 let paramsUrl = new RegExp(/\/test\/(.+)/);
1298 $httpBackend.whenGET('/test').respond(200, datas)
1299 })
1300 .service('SampleResource', function($resource){
1301 return $resource('/test/:id', {id: '@id'});
1302 });
1303 </file>
1304 <file name="index.html">
1305 <div ng-controller="SampleCtrl1 as vm">
1306 <xos-form ng-model="vm.model" config="vm.config"></xos-form>
1307 </div>
1308 </file>
1309 </example>
1310 **/
1311
Arpit Agarwal34b63832016-08-08 11:59:45 -07001312 .component('xosForm', {
1313 restrict: 'E',
1314 bindings: {
1315 config: '=',
1316 ngModel: '='
1317 },
1318 template: '\n <form name="vm.{{vm.config.formName || \'form\'}}" novalidate>\n <div class="form-group" ng-repeat="(name, field) in vm.formField">\n <xos-field name="name" field="field" ng-model="vm.ngModel[name]"></xos-field>\n <xos-validation field="vm[vm.config.formName || \'form\'][name]" form = "vm[vm.config.formName || \'form\']"></xos-validation>\n <div class="alert alert-info" ng-show="(field.hint).length >0" role="alert">{{field.hint}}</div>\n </div>\n <div class="form-group" ng-if="vm.config.actions">\n <xos-alert config="vm.config.feedback" show="vm.config.feedback.show">{{vm.config.feedback.message}}</xos-alert>\n\n <button role="button" href=""\n ng-repeat="action in vm.config.actions"\n ng-click="action.cb(vm.ngModel, vm[vm.config.formName || \'form\'])"\n class="btn btn-{{action.class}}"\n title="{{action.label}}">\n <i class="glyphicon glyphicon-{{action.icon}}"></i>\n {{action.label}}\n </button>\n </div>\n </form>\n ',
1319 bindToController: true,
1320 controllerAs: 'vm',
1321 controller: ["$scope", "$log", "_", "XosFormHelpers", function controller($scope, $log, _, XosFormHelpers) {
1322 var _this = this;
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001323
Arpit Agarwal34b63832016-08-08 11:59:45 -07001324 if (!this.config) {
1325 throw new Error('[xosForm] Please provide a configuration via the "config" attribute');
1326 }
1327
1328 if (!this.config.actions) {
1329 throw new Error('[xosForm] Please provide an action list in the configuration');
1330 }
1331
1332 if (!this.config.feedback) {
1333 this.config.feedback = {
1334 show: false,
1335 message: 'Form submitted successfully !!!',
1336 type: 'success'
1337 };
1338 }
1339
1340 this.excludedField = ['id', 'validators', 'created', 'updated', 'deleted', 'backend_status'];
1341 if (this.config && this.config.exclude) {
1342 this.excludedField = this.excludedField.concat(this.config.exclude);
1343 }
1344
1345 this.formField = [];
1346
1347 $scope.$watch(function () {
1348 return _this.config;
1349 }, function () {
1350 if (!_this.ngModel) {
1351 return;
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001352 }
Arpit Agarwal34b63832016-08-08 11:59:45 -07001353 var diff = _.difference(Object.keys(_this.ngModel), _this.excludedField);
1354 var modelField = XosFormHelpers.parseModelField(diff);
1355 _this.formField = XosFormHelpers.buildFormStructure(modelField, _this.config.fields, _this.ngModel);
1356 }, true);
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001357
Arpit Agarwal34b63832016-08-08 11:59:45 -07001358 $scope.$watch(function () {
1359 return _this.ngModel;
1360 }, function (model) {
1361 // empty from old stuff
1362 _this.formField = {};
1363 if (!model) {
1364 return;
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001365 }
Arpit Agarwal34b63832016-08-08 11:59:45 -07001366 var diff = _.difference(Object.keys(model), _this.excludedField);
1367 var modelField = XosFormHelpers.parseModelField(diff);
1368 _this.formField = XosFormHelpers.buildFormStructure(modelField, _this.config.fields, model);
1369 });
1370 }]
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001371 });
1372})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001373'use strict';
1374
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001375/**
1376 * © OpenCORD
1377 *
1378 * Visit http://guide.xosproject.org/devguide/addview/ for more information
1379 *
1380 * Created by teone on 4/15/16.
1381 */
1382
1383(function () {
1384 'use strict';
1385
1386 angular.module('xos.uiComponents')
1387
1388 /**
1389 * @ngdoc directive
1390 * @name xos.uiComponents.directive:xosAlert
1391 * @restrict E
1392 * @description The xos-alert directive
1393 * @param {Object} config The configuration object
1394 * ```
1395 * {
1396 * type: 'danger', //info, success, warning
1397 * closeBtn: true, //default false
1398 * autoHide: 3000 //delay to automatically hide the alert
1399 * }
1400 * ```
1401 * @param {Boolean=} show Binding to show and hide the alert, default to true
1402 * @element ANY
1403 * @scope
1404 * @example
1405 <example module="sampleAlert1">
1406 <file name="index.html">
1407 <div ng-controller="SampleCtrl1 as vm">
1408 <xos-alert config="vm.config1">
1409 A sample alert message
1410 </xos-alert>
1411 <xos-alert config="vm.config2">
1412 A sample alert message (with close button)
1413 </xos-alert>
1414 <xos-alert config="vm.config3">
1415 A sample info message
1416 </xos-alert>
1417 <xos-alert config="vm.config4">
1418 A sample success message
1419 </xos-alert>
1420 <xos-alert config="vm.config5">
1421 A sample warning message
1422 </xos-alert>
1423 </div>
1424 </file>
1425 <file name="script.js">
1426 angular.module('sampleAlert1', ['xos.uiComponents'])
1427 .controller('SampleCtrl1', function(){
1428 this.config1 = {
1429 type: 'danger'
1430 };
1431 this.config2 = {
1432 type: 'danger',
1433 closeBtn: true
1434 };
1435 this.config3 = {
1436 type: 'info'
1437 };
1438 this.config4 = {
1439 type: 'success'
1440 };
1441 this.config5 = {
1442 type: 'warning'
1443 };
1444 });
1445 </file>
1446 </example>
1447 <example module="sampleAlert2" animations="true">
1448 <file name="index.html">
1449 <div ng-controller="SampleCtrl as vm" class="row">
1450 <div class="col-sm-4">
1451 <a class="btn btn-default btn-block" ng-show="!vm.show" ng-click="vm.show = true">Show Alert</a>
1452 <a class="btn btn-default btn-block" ng-show="vm.show" ng-click="vm.show = false">Hide Alert</a>
1453 </div>
1454 <div class="col-sm-8">
1455 <xos-alert config="vm.config1" show="vm.show">
1456 A sample alert message, not displayed by default.
1457 </xos-alert>
1458 </div>
1459 </div>
1460 </file>
1461 <file name="script.js">
1462 angular.module('sampleAlert2', ['xos.uiComponents', 'ngAnimate'])
1463 .controller('SampleCtrl', function(){
1464 this.config1 = {
1465 type: 'success'
1466 };
1467 this.show = false;
1468 });
1469 </file>
1470 </example>
1471 **/
1472
Arpit Agarwal34b63832016-08-08 11:59:45 -07001473 .component('xosAlert', {
1474 restrict: 'E',
1475 bindings: {
1476 config: '=',
1477 show: '=?'
1478 },
1479 template: '\n <div ng-cloak class="alert alert-{{vm.config.type}}" ng-hide="!vm.show">\n <button type="button" class="close" ng-if="vm.config.closeBtn" ng-click="vm.dismiss()">\n <span aria-hidden="true">&times;</span>\n </button>\n <p ng-transclude></p>\n </div>\n ',
1480 transclude: true,
1481 bindToController: true,
1482 controllerAs: 'vm',
1483 controller: ["$timeout", function controller($timeout) {
1484 var _this = this;
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001485
Arpit Agarwal34b63832016-08-08 11:59:45 -07001486 if (!this.config) {
1487 throw new Error('[xosAlert] Please provide a configuration via the "config" attribute');
1488 }
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001489
Arpit Agarwal34b63832016-08-08 11:59:45 -07001490 // default the value to true
1491 this.show = this.show !== false;
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001492
Arpit Agarwal34b63832016-08-08 11:59:45 -07001493 this.dismiss = function () {
1494 _this.show = false;
1495 };
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001496
Arpit Agarwal34b63832016-08-08 11:59:45 -07001497 if (this.config.autoHide) {
1498 (function () {
1499 var to = $timeout(function () {
1500 _this.dismiss();
1501 $timeout.cancel(to);
1502 }, _this.config.autoHide);
1503 })();
1504 }
1505 }]
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001506 });
1507})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001508'use strict';
1509
Arpit Agarwal43978742016-08-09 15:38:25 -07001510var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
1511
1512/**
1513 * © OpenCORD
1514 *
1515 * Visit http://guide.xosproject.org/devguide/addview/ for more information
1516 *
1517 * Created by teone on 3/24/16.
1518 */
1519
1520(function () {
1521 'use strict';
1522
1523 angular.module('xos.uiComponents')
1524
1525 /**
1526 * @ngdoc directive
1527 * @name xos.uiComponents.directive:xosSmartTable
1528 * @link xos.uiComponents.directive:xosTable xosTable
1529 * @link xos.uiComponents.directive:xosForm xosForm
1530 * @restrict E
1531 * @description The xos-table directive
1532 * @param {Object} config The configuration for the component,
1533 * it is composed by the name of an angular [$resource](https://docs.angularjs.org/api/ngResource/service/$resource)
1534 * and an array of fields that shouldn't be printed.
1535 * ```
1536 * {
1537 resource: 'Users',
1538 hiddenFields: []
1539 }
1540 * ```
1541 * @scope
1542 * @example
1543 <example module="sampleSmartTable">
1544 <file name="index.html">
1545 <div ng-controller="SampleCtrl as vm">
1546 <xos-smart-table config="vm.config"></xos-smart-table>
1547 </div>
1548 </file>
1549 <file name="script.js">
1550 angular.module('sampleSmartTable', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
1551 // This is only for documentation purpose
1552 .run(function($httpBackend, _){
1553 let datas = [{id: 1, name: 'Jhon', surname: 'Doe'}];
1554 let count = 1;
1555 let paramsUrl = new RegExp(/\/test\/(.+)/);
1556 $httpBackend.whenDELETE(paramsUrl, undefined, ['id']).respond((method, url, data, headers, params) => {
1557 data = angular.fromJson(data);
1558 let id = url.match(paramsUrl)[1];
1559 _.remove(datas, (d) => {
1560 return d.id === parseInt(id);
1561 })
1562 return [204];
1563 });
1564 $httpBackend.whenGET('/test').respond(200, datas)
1565 $httpBackend.whenPOST('/test').respond((method, url, data) => {
1566 data = angular.fromJson(data);
1567 data.id = ++count;
1568 datas.push(data);
1569 return [201, data, {}];
1570 });
1571 })
1572 .factory('_', function($window){
1573 return $window._;
1574 })
1575 .service('SampleResource', function($resource){
1576 return $resource('/test/:id', {id: '@id'});
1577 })
1578 // End of documentation purpose, example start
1579 .controller('SampleCtrl', function(){
1580 this.config = {
1581 resource: 'SampleResource'
1582 };
1583 });
1584 </file>
1585 </example>
1586 */
1587
1588 .component('xosSmartTable', {
1589 restrict: 'E',
1590 bindings: {
1591 config: '='
1592 },
1593 template: '\n <div class="row" ng-show="vm.data.length > 0">\n <div class="col-xs-12 text-right">\n <a href="" class="btn btn-success" ng-click="vm.createItem()">\n Add\n </a>\n </div>\n </div>\n <div class="row">\n <div class="col-xs-12 table-responsive">\n <xos-table config="vm.tableConfig" data="vm.data"></xos-table>\n </div>\n </div>\n <div class="panel panel-default" ng-show="vm.detailedItem">\n <div class="panel-heading">\n <div class="row">\n <div class="col-xs-11">\n <h3 class="panel-title" ng-show="vm.detailedItem.id">Update {{vm.config.resource}} {{vm.detailedItem.id}}</h3>\n <h3 class="panel-title" ng-show="!vm.detailedItem.id">Create {{vm.config.resource}} item</h3>\n </div>\n <div class="col-xs-1">\n <a href="" ng-click="vm.cleanForm()">\n <i class="glyphicon glyphicon-remove pull-right"></i>\n </a>\n </div>\n </div>\n </div>\n <div class="panel-body">\n <xos-form config="vm.formConfig" ng-model="vm.detailedItem"></xos-form>\n </div>\n </div>\n <xos-alert config="{type: \'success\', closeBtn: true}" show="vm.responseMsg">{{vm.responseMsg}}</xos-alert>\n <xos-alert config="{type: \'danger\', closeBtn: true}" show="vm.responseErr">{{vm.responseErr}}</xos-alert>\n ',
1594 bindToController: true,
1595 controllerAs: 'vm',
1596 controller: ["$injector", "LabelFormatter", "_", "XosFormHelpers", function controller($injector, LabelFormatter, _, XosFormHelpers) {
1597 var _this = this;
1598
1599 // TODO
1600 // - Validate the config (what if resource does not exist?)
1601
1602 // NOTE
1603 // Corner case
1604 // - if response is empty, how can we generate a form ?
1605
1606 this.responseMsg = false;
1607 this.responseErr = false;
1608
1609 this.tableConfig = {
1610 columns: [],
1611 actions: [{
1612 label: 'delete',
1613 icon: 'remove',
1614 cb: function cb(item) {
1615 _this.Resource.delete({ id: item.id }).$promise.then(function () {
1616 _.remove(_this.data, function (d) {
1617 return d.id === item.id;
1618 });
1619 _this.responseMsg = _this.config.resource + ' with id ' + item.id + ' successfully deleted';
1620 }).catch(function (err) {
1621 _this.responseErr = err.data.detail || 'Error while deleting ' + _this.config.resource + ' with id ' + item.id;
1622 });
1623 },
1624 color: 'red'
1625 }, {
1626 label: 'details',
1627 icon: 'search',
1628 cb: function cb(item) {
1629 _this.detailedItem = item;
1630 }
1631 }],
1632 classes: 'table table-striped table-bordered table-responsive',
1633 filter: 'field',
1634 order: true,
1635 pagination: {
1636 pageSize: 10
1637 }
1638 };
1639
1640 this.formConfig = {
1641 exclude: this.config.hiddenFields,
1642 fields: {},
1643 formName: this.config.resource + 'Form',
1644 actions: [{
1645 label: 'Save',
1646 icon: 'ok',
1647 cb: function cb(item) {
1648 var p = void 0;
1649 var isNew = true;
1650
1651 if (item.id) {
1652 p = item.$update();
1653 isNew = false;
1654 } else {
1655 p = item.$save();
1656 }
1657
1658 p.then(function (res) {
1659 if (isNew) {
1660 _this.data.push(angular.copy(res));
1661 }
1662 delete _this.detailedItem;
1663 _this.responseMsg = _this.config.resource + ' with id ' + item.id + ' successfully saved';
1664 }).catch(function (err) {
1665 _this.responseErr = err.data.detail || 'Error while saving ' + _this.config.resource + ' with id ' + item.id;
1666 });
1667 },
1668 class: 'success'
1669 }]
1670 };
1671
1672 this.cleanForm = function () {
1673 delete _this.detailedItem;
1674 };
1675
1676 this.createItem = function () {
1677 _this.detailedItem = new _this.Resource();
1678 };
1679
1680 this.Resource = $injector.get(this.config.resource);
1681
1682 var getData = function getData() {
1683 _this.Resource.query().$promise.then(function (res) {
1684
1685 if (!res[0]) {
1686 _this.data = res;
1687 return;
1688 }
1689
1690 var item = res[0];
1691 var props = Object.keys(item);
1692
1693 _.remove(props, function (p) {
1694 return p === 'id' || p === 'validators';
1695 });
1696
1697 // TODO move out cb, non sense triggering a lot of times
1698 if (angular.isArray(_this.config.hiddenFields)) {
1699 props = _.difference(props, _this.config.hiddenFields);
1700 }
1701
1702 var labels = props.map(function (p) {
1703 return LabelFormatter.format(p);
1704 });
1705
1706 props.forEach(function (p, i) {
1707 var fieldConfig = {
1708 label: labels[i],
1709 prop: p
1710 };
1711
1712 if (angular.isString(item[p]) && typeof item[p] !== 'undefined') {
1713 fieldConfig.type = _typeof(item[p]);
1714 }
1715
1716 _this.tableConfig.columns.push(fieldConfig);
1717 });
1718
1719 // build form structure
1720 // TODO move in a pure function for testing purposes
1721 props.forEach(function (p, i) {
1722 _this.formConfig.fields[p] = {
1723 label: LabelFormatter.format(labels[i]).replace(':', ''),
1724 type: XosFormHelpers._getFieldFormat(item[p])
1725 };
1726 });
1727
1728 _this.data = res;
1729 });
1730 };
1731
1732 getData();
1733 }]
1734 });
1735})();
1736'use strict';
1737
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001738(function () {
1739 'use strict';
1740
1741 /**
1742 * @ngdoc service
1743 * @name xos.uiComponents.LabelFormatter
1744 * @description This factory define a set of helper function to format label started from an object property
1745 **/
1746
1747 angular.module('xos.uiComponents').factory('LabelFormatter', labelFormatter);
1748
1749 function labelFormatter() {
1750
1751 /**
1752 * @ngdoc method
1753 * @name xos.uiComponents.LabelFormatter#_formatByUnderscore
1754 * @methodOf xos.uiComponents.LabelFormatter
1755 * @description
1756 * Convert a `snake_case` string to readable string.<br/>
1757 * Eg: `this_string` will became `this string`
1758 * @param {string} string The string to be converted
1759 * @returns {string} The converten string
1760 **/
1761
1762 var _formatByUnderscore = function _formatByUnderscore(string) {
1763 return string.split('_').join(' ').trim();
1764 };
1765
1766 /**
1767 * @ngdoc method
1768 * @name xos.uiComponents.LabelFormatter#_formatByUppercase
1769 * @methodOf xos.uiComponents.LabelFormatter
1770 * @description
1771 * Convert a `camelCase` string to readable string.<br/>
1772 * Eg: `thisString` will became `this string`
1773 * @param {string} string The string to be converted
1774 * @returns {string} The converten string
1775 **/
1776
1777 var _formatByUppercase = function _formatByUppercase(string) {
1778 return string.split(/(?=[A-Z])/).map(function (w) {
1779 return w.toLowerCase();
1780 }).join(' ');
1781 };
1782
1783 /**
1784 * @ngdoc method
1785 * @name xos.uiComponents.LabelFormatter#_capitalize
1786 * @methodOf xos.uiComponents.LabelFormatter
1787 * @description
1788 * Capitalize the first letter of a string.<br/>
1789 * Eg: `this string` will became `This string`
1790 * @param {string} string The string to be converted
1791 * @returns {string} The converten string
1792 **/
1793
1794 var _capitalize = function _capitalize(string) {
1795 return string.slice(0, 1).toUpperCase() + string.slice(1);
1796 };
1797
1798 /**
1799 * @ngdoc method
1800 * @name xos.uiComponents.LabelFormatter#format
1801 * @methodOf xos.uiComponents.LabelFormatter
1802 * @description
1803 * Apply in order:
1804 * - _formatByUnderscore
1805 * - _formatByUppercase
1806 * - _capitalize
1807 * - replace multiple space with a single one
1808 * - append `:` at the end
1809 * <br/>
1810 * Eg: `this_string` will became `This string:`<br/>
1811 * Eg: `thisString` will became `This string:`
1812 * @param {string} string The string to be converted
1813 * @returns {string} The converten string
1814 **/
1815
1816 var format = function format(string) {
1817 string = _formatByUnderscore(string);
1818 string = _formatByUppercase(string);
1819
1820 string = _capitalize(string).replace(/\s\s+/g, ' ') + ':';
1821 return string.replace('::', ':');
1822 };
1823
1824 return {
1825 // test export
1826 _formatByUnderscore: _formatByUnderscore,
1827 _formatByUppercase: _formatByUppercase,
1828 _capitalize: _capitalize,
1829 // export to use
1830 format: format
1831 };
1832 }
1833})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001834'use strict';
1835
1836var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
1837
1838(function () {
1839
1840 angular.module('xos.uiComponents')
1841
1842 /**
1843 * @ngdoc service
1844 * @name xos.uiComponents.XosFormHelpers
1845 * @requires xos.uiComponents.LabelFormatter
1846 * @requires xos.helpers._
1847 **/
1848
1849 .service('XosFormHelpers', ["_", "LabelFormatter", function (_, LabelFormatter) {
1850 var _this = this;
1851
1852 /**
1853 * @ngdoc method
1854 * @name xos.uiComponents.XosFormHelpers#_isEmail
1855 * @methodOf xos.uiComponents.XosFormHelpers
1856 * @description
1857 * Return true if the string is an email address
1858 * @param {string} text The string to be evaluated
1859 * @returns {boolean} If the string match an email format
1860 **/
1861
1862 this._isEmail = function (text) {
1863 var re = /(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/;
1864 return re.test(text);
1865 };
1866
1867 /**
1868 * @ngdoc method
1869 * @name xos.uiComponents.XosFormHelpers#_getFieldFormat
1870 * @methodOf xos.uiComponents.XosFormHelpers
1871 * @description
1872 * Return the type of the input
1873 * @param {mixed} value The data to be evaluated
1874 * @returns {string} The type of the input
1875 **/
1876
1877 this._getFieldFormat = function (value) {
1878
1879 if (angular.isArray(value)) {
1880 return 'array';
1881 }
1882
1883 // check if is date
1884 if (_.isDate(value) || !Number.isNaN(Date.parse(value)) && new Date(value).getTime() > 631180800000) {
1885 return 'date';
1886 }
1887
1888 // check if is boolean
1889 // isNaN(false) = false, false is a number (0), true is a number (1)
1890 if (typeof value === 'boolean') {
1891 return 'boolean';
1892 }
1893
1894 // check if a string is an email
1895 if (_this._isEmail(value)) {
1896 return 'email';
1897 }
1898
1899 // if null return string
1900 if (angular.isString(value) || value === null) {
1901 return 'text';
1902 }
1903
1904 return typeof value === 'undefined' ? 'undefined' : _typeof(value);
1905 };
1906
1907 /**
1908 * @ngdoc method
1909 * @name xos.uiComponents.XosFormHelpers#buildFormStructure
1910 * @methodOf xos.uiComponents.XosFormHelpers
1911 * @description
1912 * Return the type of the input
1913 * @param {object} modelField An object containing one property for each field of the model
1914 * @param {object} customField An object containing one property for each field custom field
1915 * @param {object} model The actual model on wich build the form structure (it is used to determine the type of the input)
1916 * @returns {object} An object describing the form structure in the form of:
1917 * ```
1918 * {
1919 * 'field-name': {
1920 * label: 'Label',
1921 * type: 'number', //typeof field
1922 * validators: {}, // see xosForm for more details
1923 * hint: 'A Custom hint for the field'
1924 * }
1925 * }
1926 * ```
1927 **/
1928
1929 this.buildFormStructure = function (modelField, customField, model) {
1930
1931 modelField = angular.extend(modelField, customField);
1932 customField = customField || {};
1933
1934 return _.reduce(Object.keys(modelField), function (form, f) {
1935
1936 form[f] = {
1937 label: customField[f] && customField[f].label ? customField[f].label + ':' : LabelFormatter.format(f),
1938 type: customField[f] && customField[f].type ? customField[f].type : _this._getFieldFormat(model[f]),
1939 validators: customField[f] && customField[f].validators ? customField[f].validators : {},
1940 hint: customField[f] && customField[f].hint ? customField[f].hint : ''
1941 };
1942
1943 if (customField[f] && customField[f].options) {
1944 form[f].options = customField[f].options;
1945 }
1946 if (customField[f] && customField[f].properties) {
1947 form[f].properties = customField[f].properties;
1948 }
1949 if (form[f].type === 'date') {
1950 model[f] = new Date(model[f]);
1951 }
1952
1953 if (form[f].type === 'number') {
1954 model[f] = parseInt(model[f], 10);
1955 }
1956
1957 return form;
1958 }, {});
1959 };
1960
1961 /**
1962 * @ngdoc method
1963 * @name xos.uiComponents.XosFormHelpers#parseModelField
1964 * @methodOf xos.uiComponents.XosFormHelpers
1965 * @description
1966 * Helpers for buildFormStructure, convert a list of model properties in an object used to build the form structure, eg:
1967 * ```
1968 * // input:
1969 * ['id', 'name'm 'mail']
1970 *
1971 * // output
1972 * {
1973 * id: {},
1974 * name: {},
1975 * mail: {}
1976 * }
1977 * ```
1978 * @param {array} fields An array of fields representing the model properties
1979 * @returns {object} An object containing one property for each field of the model
1980 **/
1981
1982 this.parseModelField = function (fields) {
1983 return _.reduce(fields, function (form, f) {
1984 form[f] = {};
1985 return form;
1986 }, {});
1987 };
1988 }]);
1989})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07001990'use strict';
1991
1992(function () {
1993 'use strict';
1994
1995 /**
1996 * @ngdoc service
1997 * @name xos.uiComponents.Comparator
1998 * @description
1999 * This factory define a function that replace the native angular.filter comparator.
2000 *
2001 * It is done to allow the comparation between (0|1) values with booleans.
2002 * >Note that this factory return a single function, not an object.
2003 *
2004 * The tipical usage of this factory is inside an `ng-repeat`
2005 * @example
2006 * <example module="comparator">
2007 * <file name="index.html">
2008 * <div ng-controller="sample as vm">
2009 * <div class="row">
2010 * <div class="col-xs-6">
2011 * <label>Filter by name:</label>
2012 * <input class="form-control" type="text" ng-model="vm.query.name"/>
2013 * </div>
2014 * <div class="col-xs-6">
2015 * <label>Filter by status:</label>
2016 * <select
2017 * ng-model="vm.query.status"
2018 * ng-options="i for i in [true, false]">
2019 * </select>
2020 * </div>
2021 * </div>
2022 * <div ng-repeat="item in vm.data | filter:vm.query:vm.comparator">
2023 * <div class="row">
2024 * <div class="col-xs-6">{{item.name}}</div>
2025 * <div class="col-xs-6">{{item.status}}</div>
2026 * </div>
2027 * </div>
2028 * </div>
2029 * </file>
2030 * <file name="script.js">
2031 * angular.module('comparator', ['xos.uiComponents'])
2032 * .controller('sample', function(Comparator){
2033 * this.comparator = Comparator;
2034 * this.data = [
2035 * {name: 'Jhon', status: 1},
2036 * {name: 'Jack', status: 0},
2037 * {name: 'Mike', status: 1},
2038 * {name: 'Scott', status: 0}
2039 * ];
2040 * });
2041 * </file>
2042 * </example>
2043 **/
2044
2045 comparator.$inject = ["_"];
2046 angular.module('xos.uiComponents').factory('Comparator', comparator);
2047
2048 function comparator(_) {
2049
2050 return function (actual, expected) {
2051
2052 if (angular.isUndefined(actual)) {
2053 // No substring matching against `undefined`
2054 return false;
2055 }
2056 if (actual === null || expected === null) {
2057 // No substring matching against `null`; only match against `null`
2058 return actual === expected;
2059 }
2060 if (angular.isObject(expected) || angular.isObject(actual)) {
2061 return angular.equals(expected, actual);
2062 }
2063
2064 if (_.isBoolean(actual) || _.isBoolean(expected)) {
2065 if (actual === 0 || actual === 1) {
2066 actual = !!actual;
2067 }
2068 return angular.equals(expected, actual);
2069 }
2070
2071 if (!angular.isString(actual) || !angular.isString(expected)) {
2072 if (angular.isDefined(actual.toString) && angular.isDefined(expected.toString)) {
2073 actual = actual.toString();
2074 expected = expected.toString();
2075 } else {
2076 return actual === expected;
2077 }
2078 }
2079
2080 actual = actual.toLowerCase() + '';
2081 expected = expected.toLowerCase() + '';
2082 return actual.indexOf(expected) !== -1;
2083 };
2084 }
2085})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002086'use strict';
2087
2088(function () {
2089 'use strict';
2090
2091 /**
2092 * @ngdoc overview
2093 * @name xos.helpers
2094 * @description
2095 * # xos.Helpers
2096 * A collection of helpers to work with XOS <br/>
2097 * Currently available components are:
2098 * - [NoHyperlinks](/#/module/xos.helpers.NoHyperlinks)
2099 * - [SetCSRFToken](/#/module/xos.helpers.SetCSRFToken)
2100 * - [xosNotification](/#/module/xos.helpers.xosNotification)
2101 * - [XosUserPrefs](/#/module/xos.helpers.XosUserPrefs)
2102 * <br/><br/>
2103 * A set of angular [$resource](https://docs.angularjs.org/api/ngResource/service/$resource) is provided to work with the API.<br>
2104 * You can find the documentation [here](#/rest-api)
2105 **/
2106
2107 config.$inject = ["$httpProvider", "$interpolateProvider", "$resourceProvider"];
2108 angular.module('xos.helpers', ['ngCookies', 'ngResource', 'ngAnimate', 'xos.uiComponents']).config(config)
2109
2110 /**
2111 * @ngdoc service
2112 * @name xos.helpers._
2113 * @description Wrap [lodash](https://lodash.com/docs) in an Angular Service
2114 **/
2115
2116 .factory('_', ["$window", function ($window) {
2117 return $window._;
2118 }]);
2119
2120 function config($httpProvider, $interpolateProvider, $resourceProvider) {
2121 $httpProvider.interceptors.push('SetCSRFToken');
2122
2123 // NOTE http://www.masnun.com/2013/09/18/django-rest-framework-angularjs-resource-trailing-slash-problem.html
2124 $resourceProvider.defaults.stripTrailingSlashes = false;
2125 }
2126})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002127'use strict';
2128
2129(function () {
2130 'use strict';
2131
2132 angular.module('xos.helpers')
2133 /**
2134 * @ngdoc service
2135 * @name xos.helpers.vSG-Collection
2136 * @description Angular resource to fetch /api/service/vsg/
2137 **/
2138 .service('vSG-Collection', ["$resource", function ($resource) {
2139 return $resource('/api/service/vsg/');
2140 }]);
2141})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002142'use strict';
2143
2144(function () {
2145 'use strict';
2146
2147 angular.module('xos.helpers')
2148 /**
2149 * @ngdoc service
2150 * @name xos.helpers.vOLT-Collection
2151 * @description Angular resource to fetch /api/tenant/cord/volt/:volt_id/
2152 **/
2153 .service('vOLT-Collection', ["$resource", function ($resource) {
2154 return $resource('/api/tenant/cord/volt/:volt_id/', { volt_id: '@id' }, {
2155 update: { method: 'PUT' }
2156 });
2157 }]);
2158})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002159'use strict';
2160
2161(function () {
2162 'use strict';
2163
2164 angular.module('xos.helpers')
2165 /**
2166 * @ngdoc service
2167 * @name xos.helpers.Login
2168 * @description Angular resource to fetch /api/utility/login/
2169 **/
2170 .service('Login', ["$resource", function ($resource) {
2171 return $resource('/api/utility/login/');
2172 }])
2173 /**
2174 * @ngdoc service
2175 * @name xos.helpers.Logout
2176 * @description Angular resource to fetch /api/utility/logout/
2177 **/
2178 .service('Logout', ["$resource", function ($resource) {
2179 return $resource('/api/utility/logout/');
2180 }]);
2181})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002182'use strict';
2183
2184(function () {
2185 'use strict';
2186
2187 angular.module('xos.helpers')
2188 /**
2189 * @ngdoc service
2190 * @name xos.helpers.Users
2191 * @description Angular resource to fetch /api/core/users/:id/
2192 **/
2193 .service('Users', ["$resource", function ($resource) {
2194 return $resource('/api/core/users/:id/', { id: '@id' }, {
2195 update: { method: 'PUT' }
2196 });
2197 }]);
2198})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002199'use strict';
2200
2201(function () {
2202 'use strict';
2203
2204 angular.module('xos.helpers')
2205 /**
2206 * @ngdoc service
2207 * @name xos.helpers.Truckroll
2208 * @description Angular resource to fetch /api/tenant/truckroll/:id/
2209 **/
2210 .service('Truckroll', ["$resource", function ($resource) {
2211 return $resource('/api/tenant/truckroll/:id/', { id: '@id' }, {
2212 update: { method: 'PUT' }
2213 });
2214 }]);
2215})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002216'use strict';
2217
2218(function () {
2219 'use strict';
2220
2221 angular.module('xos.helpers')
2222 /**
2223 * @ngdoc service
2224 * @name xos.helpers.Tenant
2225 * @description Angular resource to fetch /api/core/tenant/:id/
2226 **/
2227 .service('Tenants', ["$resource", function ($resource) {
2228 return $resource('/api/core/tenants/:id/', { id: '@id' }, {
2229 update: { method: 'PUT' }
2230 });
2231 }]);
2232})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002233'use strict';
2234
2235(function () {
2236 'use strict';
2237
2238 angular.module('xos.helpers')
2239 /**
2240 * @ngdoc service
2241 * @name xos.helpers.Subscribers
2242 * @description Angular resource to fetch Subscribers
2243 **/
2244 .service('Subscribers', ["$resource", function ($resource) {
2245 return $resource('/api/tenant/cord/subscriber/:id/', { id: '@id' }, {
2246 update: { method: 'PUT' },
2247 /**
2248 * @ngdoc method
2249 * @name xos.helpers.Subscribers#View-a-Subscriber-Features-Detail
2250 * @methodOf xos.helpers.Subscribers
2251 * @description
2252 * View-a-Subscriber-Features-Detail
2253 **/
2254 'View-a-Subscriber-Features-Detail': {
2255 method: 'GET',
2256 isArray: false,
2257 url: '/api/tenant/cord/subscriber/:id/features/'
2258 },
2259 /**
2260 * @ngdoc method
2261 * @name xos.helpers.Subscribers#Read-Subscriber-uplink_speed
2262 * @methodOf xos.helpers.Subscribers
2263 * @description
2264 * Read-Subscriber-uplink_speed
2265 **/
2266 'Read-Subscriber-uplink_speed': {
2267 method: 'GET',
2268 isArray: false,
2269 url: '/api/tenant/cord/subscriber/:id/features/uplink_speed/'
2270 },
2271 /**
2272 * @ngdoc method
2273 * @name xos.helpers.Subscribers#Update-Subscriber-uplink_speed
2274 * @methodOf xos.helpers.Subscribers
2275 * @description
2276 * Update-Subscriber-uplink_speed
2277 **/
2278 'Update-Subscriber-uplink_speed': {
2279 method: 'PUT',
2280 isArray: false,
2281 url: '/api/tenant/cord/subscriber/:id/features/uplink_speed/'
2282 },
2283 /**
2284 * @ngdoc method
2285 * @name xos.helpers.Subscribers#Read-Subscriber-downlink_speed
2286 * @methodOf xos.helpers.Subscribers
2287 * @description
2288 * Read-Subscriber-downlink_speed
2289 **/
2290 'Read-Subscriber-downlink_speed': {
2291 method: 'GET',
2292 isArray: false,
2293 url: '/api/tenant/cord/subscriber/:id/features/downlink_speed/'
2294 },
2295 /**
2296 * @ngdoc method
2297 * @name xos.helpers.Subscribers#Update-Subscriber-downlink_speed
2298 * @methodOf xos.helpers.Subscribers
2299 * @description
2300 * Update-Subscriber-downlink_speed
2301 **/
2302 'Update-Subscriber-downlink_speed': {
2303 method: 'PUT',
2304 isArray: false,
2305 url: '/api/tenant/cord/subscriber/:id/features/downlink_speed/'
2306 },
2307 /**
2308 * @ngdoc method
2309 * @name xos.helpers.Subscribers#Read-Subscriber-cdn
2310 * @methodOf xos.helpers.Subscribers
2311 * @description
2312 * Read-Subscriber-cdn
2313 **/
2314 'Read-Subscriber-cdn': {
2315 method: 'GET',
2316 isArray: false,
2317 url: '/api/tenant/cord/subscriber/:id/features/cdn/'
2318 },
2319 /**
2320 * @ngdoc method
2321 * @name xos.helpers.Subscribers#Update-Subscriber-cdn
2322 * @methodOf xos.helpers.Subscribers
2323 * @description
2324 * Update-Subscriber-cdn
2325 **/
2326 'Update-Subscriber-cdn': {
2327 method: 'PUT',
2328 isArray: false,
2329 url: '/api/tenant/cord/subscriber/:id/features/cdn/'
2330 },
2331 /**
2332 * @ngdoc method
2333 * @name xos.helpers.Subscribers#Read-Subscriber-uverse
2334 * @methodOf xos.helpers.Subscribers
2335 * @description
2336 * Read-Subscriber-uverse
2337 **/
2338 'Read-Subscriber-uverse': {
2339 method: 'GET',
2340 isArray: false,
2341 url: '/api/tenant/cord/subscriber/:id/features/uverse/'
2342 },
2343 /**
2344 * @ngdoc method
2345 * @name xos.helpers.Subscribers#Update-Subscriber-uverse
2346 * @methodOf xos.helpers.Subscribers
2347 * @description
2348 * Update-Subscriber-uverse
2349 **/
2350 'Update-Subscriber-uverse': {
2351 method: 'PUT',
2352 isArray: false,
2353 url: '/api/tenant/cord/subscriber/:id/features/uverse/'
2354 },
2355 /**
2356 * @ngdoc method
2357 * @name xos.helpers.Subscribers#Read-Subscriber-status
2358 * @methodOf xos.helpers.Subscribers
2359 * @description
2360 * Read-Subscriber-status
2361 **/
2362 'Read-Subscriber-status': {
2363 method: 'GET',
2364 isArray: false,
2365 url: '/api/tenant/cord/subscriber/:id/features/status/'
2366 },
2367 /**
2368 * @ngdoc method
2369 * @name xos.helpers.Subscribers#Update-Subscriber-status
2370 * @methodOf xos.helpers.Subscribers
2371 * @description
2372 * Update-Subscriber-status
2373 **/
2374 'Update-Subscriber-status': {
2375 method: 'PUT',
2376 isArray: false,
2377 url: '/api/tenant/cord/subscriber/:id/features/status/'
2378 }
2379 });
2380 }]);
2381})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002382'use strict';
2383
2384(function () {
2385 'use strict';
2386
2387 angular.module('xos.helpers')
2388 /**
2389 * @ngdoc service
2390 * @name xos.helpers.SlicesPlus
2391 * @description Angular resource to fetch /api/utility/slicesplus/
2392 * This is a read-only API and only the `query` method is currently supported.
2393 **/
2394 .service('SlicesPlus', ["$http", "$q", function ($http, $q) {
2395 this.query = function (params) {
2396 var deferred = $q.defer();
2397
2398 $http.get('/api/utility/slicesplus/', { params: params }).then(function (res) {
2399 deferred.resolve(res.data);
2400 }).catch(function (res) {
2401 deferred.reject(res.data);
2402 });
2403
2404 return { $promise: deferred.promise };
2405 };
2406
2407 this.get = function (id, params) {
2408 var deferred = $q.defer();
2409
2410 $http.get('/api/utility/slicesplus/' + id, { params: params }).then(function (res) {
2411 deferred.resolve(res.data);
2412 }).catch(function (res) {
2413 deferred.reject(res.data);
2414 });
2415 return { $promise: deferred.promise };
2416 };
2417 }]);
2418})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002419'use strict';
2420
2421(function () {
2422 'use strict';
2423
2424 angular.module('xos.helpers')
2425 /**
2426 * @ngdoc service
2427 * @name xos.helpers.Slices
2428 * @description Angular resource to fetch /api/core/slices/:id/
2429 **/
2430 .service('Slices', ["$resource", function ($resource) {
2431 return $resource('/api/core/slices/:id/', { id: '@id' }, {
2432 update: { method: 'PUT' }
2433 });
2434 }]);
2435})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002436'use strict';
2437
2438(function () {
2439 'use strict';
2440
2441 angular.module('xos.helpers')
2442 /**
2443 * @ngdoc service
2444 * @name xos.helpers.Sites
2445 * @description Angular resource to fetch /api/core/sites/:id/
2446 **/
2447 .service('Sites', ["$resource", function ($resource) {
2448 return $resource('/api/core/sites/:id/', { id: '@id' }, {
2449 update: { method: 'PUT' }
2450 });
2451 }]);
2452})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002453'use strict';
2454
2455(function () {
2456 'use strict';
2457
2458 angular.module('xos.helpers')
2459 /**
2460 * @ngdoc service
2461 * @name xos.helpers.Services
2462 * @description Angular resource to fetch /api/core/services/:id/
2463 **/
2464 .service('Services', ["$resource", function ($resource) {
2465 return $resource('/api/core/services/:id/', { id: '@id' }, {
2466 update: { method: 'PUT' }
2467 });
2468 }]);
2469})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002470'use strict';
2471
2472(function () {
2473 'use strict';
2474
2475 angular.module('xos.helpers')
2476 /**
2477 * @ngdoc service
2478 * @name xos.helpers.ONOS-Services-Collection
2479 * @description Angular resource to fetch /api/service/onos/
2480 **/
2481 .service('ONOS-Services-Collection', ["$resource", function ($resource) {
2482 return $resource('/api/service/onos/');
2483 }]);
2484})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002485'use strict';
2486
2487(function () {
2488 'use strict';
2489
2490 angular.module('xos.helpers')
2491 /**
2492 * @ngdoc service
2493 * @name xos.helpers.ONOS-App-Collection
2494 * @description Angular resource to fetch /api/tenant/onos/app/
2495 **/
2496 .service('ONOS-App-Collection', ["$resource", function ($resource) {
2497 return $resource('/api/tenant/onos/app/');
2498 }]);
2499})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002500'use strict';
2501
2502(function () {
2503 'use strict';
2504
2505 angular.module('xos.helpers')
2506 /**
2507 * @ngdoc service
2508 * @name xos.helpers.Nodes
2509 * @description Angular resource to fetch /api/core/nodes/:id/
2510 **/
2511 .service('Nodes', ["$resource", function ($resource) {
2512 return $resource('/api/core/nodes/:id/', { id: '@id' }, {
2513 update: { method: 'PUT' }
2514 });
2515 }]);
2516})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002517'use strict';
2518
2519(function () {
2520 'use strict';
2521
2522 angular.module('xos.helpers')
2523 /**
2524 * @ngdoc service
2525 * @name xos.helpers.Networkstemplates
2526 * @description Angular resource to fetch /api/core/networktemplates/:id/
2527 **/
2528 .service('Networkstemplates', ["$resource", function ($resource) {
2529 return $resource('/api/core/networktemplates/:id/', { id: '@id' }, {
2530 update: { method: 'PUT' }
2531 });
2532 }]);
2533})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002534'use strict';
2535
2536(function () {
2537 'use strict';
2538
2539 angular.module('xos.helpers')
2540 /**
2541 * @ngdoc service
2542 * @name xos.helpers.Networks
2543 * @description Angular resource to fetch /api/core/networks/:id/
2544 **/
2545 .service('Networks', ["$resource", function ($resource) {
2546 return $resource('/api/core/networks/:id/', { id: '@id' }, {
2547 update: { method: 'PUT' }
2548 });
2549 }]);
2550})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002551'use strict';
2552
2553(function () {
2554 'use strict';
2555
2556 angular.module('xos.helpers')
2557 /**
2558 * @ngdoc service
2559 * @name xos.helpers.Me
2560 * @description Http read-only api to fetch /api/utility/me/
2561 **/
2562 .service('Me', ["$q", "$http", function ($q, $http) {
2563
2564 this.get = function () {
2565 var deferred = $q.defer();
2566
2567 $http.get('/api/utility/me/').then(function (res) {
2568 deferred.resolve(res.data);
2569 }).catch(function (e) {
2570 deferred.reject(e);
2571 });
2572 return deferred.promise;
2573 };
2574 }]);
2575})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002576'use strict';
2577
2578(function () {
2579 'use strict';
2580
2581 angular.module('xos.helpers')
2582 /**
2583 * @ngdoc service
2584 * @name xos.helpers.Instances
2585 * @description Angular resource to fetch /api/core/instances/:id/
2586 **/
2587 .service('Instances', ["$resource", function ($resource) {
2588 return $resource('/api/core/instances/:id/', { id: '@id' }, {
2589 update: { method: 'PUT' }
2590 });
2591 }]);
2592})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002593'use strict';
2594
2595(function () {
2596 'use strict';
2597
2598 angular.module('xos.helpers')
2599 /**
2600 * @ngdoc service
2601 * @name xos.helpers.Images
2602 * @description Angular resource to fetch /api/core/images/
2603 **/
2604 .service('Images', ["$resource", function ($resource) {
2605 return $resource('/api/core/images/:id/', { id: '@id' }, {
2606 update: { method: 'PUT' }
2607 });
2608 }]);
2609})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002610'use strict';
2611
2612(function () {
2613 'use strict';
2614
2615 angular.module('xos.helpers')
2616 /**
2617 * @ngdoc service
2618 * @name xos.helpers.Flavors
2619 * @description Angular resource to fetch /api/core/flavors/:id/
2620 **/
2621 .service('Flavors', ["$resource", function ($resource) {
2622 return $resource('/api/core/flavors/:id/', { id: '@id' }, {
2623 update: { method: 'PUT' }
2624 });
2625 }]);
2626})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002627'use strict';
2628
2629(function () {
2630 'use strict';
2631
2632 angular.module('xos.helpers')
2633 /**
2634 * @ngdoc service
2635 * @name xos.helpers.Example-Services-Collection
2636 * @description Angular resource to fetch /api/service/exampleservice/
2637 **/
2638 .service('Example-Services-Collection', ["$resource", function ($resource) {
2639 return $resource('/api/service/exampleservice/');
2640 }]);
2641})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002642'use strict';
2643
2644(function () {
2645 'use strict';
2646
2647 angular.module('xos.helpers')
2648 /**
2649 * @ngdoc service
2650 * @name xos.helpers.Deployments
2651 * @description Angular resource to fetch /api/core/deployments/:id/
2652 **/
2653 .service('Deployments', ["$resource", function ($resource) {
2654 return $resource('/api/core/deployments/:id/', { id: '@id' }, {
2655 update: { method: 'PUT' }
2656 });
2657 }]);
2658})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002659'use strict';
2660
2661(function () {
2662 'use strict';
2663
2664 angular.module('xos.helpers')
2665 /**
2666 * @ngdoc service
2667 * @name xos.helpers.Dashboards
2668 * @description Angular resource to fetch /api/core/dashboardviews/:id/
2669 **/
2670 .service('Dashboards', ["$resource", "$q", "$http", function ($resource, $q, $http) {
2671 var r = $resource('/api/core/dashboardviews/:id/', { id: '@id' }, {
2672 update: { method: 'PUT' }
2673 });
2674
2675 r.prototype.$save = function () {
2676 var d = $q.defer();
2677
2678 $http.put('/api/core/dashboardviews/' + this.id + '/', this).then(function (res) {
2679 d.resolve(res.data);
2680 }).catch(function (e) {
2681 d.reject(e.data);
2682 });
2683
2684 return d.promise;
2685 };
2686
2687 return r;
2688 }]);
2689})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002690'use strict';
2691
2692(function () {
2693
2694 angular.module('xos.helpers')
2695
2696 /**
2697 * @ngdoc service
2698 * @name xos.helpers.XosUserPrefs
2699 * @description
2700 * This service is used to store the user preferences in cookies, so that they survive to page changes.
2701 * The structure of the user preference is:
2702 * ```
2703 * {
2704 * synchronizers: {
2705 * notification: {
2706 * 'volt': boolean,
2707 * 'openstack': boolean,
2708 * ...
2709 * }
2710 * }
2711 * userData: {
2712 * current_user_site_id: Number,
2713 * current_user_site_user_names: Array[1],
2714 * ...
2715 * }
2716 * }
2717 * ```
2718 **/
2719
2720 .service('XosUserPrefs', ["$cookies", "Me", "$q", function ($cookies, Me, $q) {
2721 var _this = this;
2722
2723 var userPrefs = $cookies.get('xosUserPrefs') ? angular.fromJson($cookies.get('xosUserPrefs')) : {};
2724
2725 /**
2726 * @ngdoc method
2727 * @name xos.helpers.XosUserPrefs#getAll
2728 * @methodOf xos.helpers.XosUserPrefs
2729 * @description
2730 * Return all the user preferences stored in cookies
2731 * @returns {object} The user preferences
2732 **/
2733 this.getAll = function () {
2734 userPrefs = $cookies.get('xosUserPrefs') ? angular.fromJson($cookies.get('xosUserPrefs')) : {};
2735 return userPrefs;
2736 };
2737
2738 /**
2739 * @ngdoc method
2740 * @name xos.helpers.XosUserPrefs#setAll
2741 * @methodOf xos.helpers.XosUserPrefs
2742 * @description
2743 * Override all user preferences
2744 * @param {object} prefs The user preferences
2745 **/
2746 this.setAll = function (prefs) {
2747 $cookies.put('xosUserPrefs', angular.toJson(prefs));
2748 };
2749
2750 /**
2751 * @ngdoc method
2752 * @name xos.helpers.XosUserPrefs#getSynchronizerNotificationStatus
2753 * @methodOf xos.helpers.XosUserPrefs
2754 * @description
2755 * Return the synchronizer notification status, if name is not provided return the status for all synchronizers
2756 * @param {string=} prefs The synchronizer name
2757 * @returns {object | string} The synchronizer status
2758 **/
2759 this.getSynchronizerNotificationStatus = function () {
2760 var name = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0];
2761
2762 if (name) {
2763 return _this.getAll().synchronizers.notification[name];
2764 }
2765 return _this.getAll().synchronizers.notification;
2766 };
2767
2768 /**
2769 * @ngdoc method
2770 * @name xos.helpers.XosUserPrefs#getUserDetailsCookie
2771 * @methodOf xos.helpers.XosUserPrefs
2772 * @description
2773 * Return all the user details stored in cookies or call the service
2774 * @returns {object} The user details
2775 **/
2776 this.getUserDetailsCookie = function () {
2777 var defer = $q.defer();
2778 var localPref = _this.getAll();
2779 if (!localPref.userData) {
2780 _this.setUserDetailsCookie().$promise.then(function (data) {
2781 defer.resolve(data);
2782 });
2783 } else {
2784 defer.resolve(localPref.userData);
2785 }
2786 return { $promise: defer.promise };
2787 };
2788
2789 /**
2790 * @ngdoc method
2791 * @name xos.helpers.XosUserPrefs#setUserDetailsCookie
2792 * @methodOf xos.helpers.XosUserPrefs
2793 * @description
2794 * Save the user details in the cookie
2795 * @param {object} details stored in cookie
2796 * @param {objects} returns the user details as a promise
2797 **/
2798 this.setUserDetailsCookie = function () {
2799 var userData = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
2800
2801
2802 var defer = $q.defer();
2803 var cookies = _this.getAll();
2804 if (!userData) {
2805 Me.get().then(function (user) {
2806 cookies.userData = user;
2807 _this.setAll(cookies);
2808 defer.resolve(user);
2809 }).catch(function (e) {
2810 defer.reject(e);
2811 });
2812 } else {
2813 cookies.userData = userData;
2814 _this.setAll(cookies);
2815 defer.resolve(userData);
2816 }
2817 return { $promise: defer.promise };
2818 };
2819
2820 /**
2821 * @ngdoc method
2822 * @name xos.helpers.XosUserPrefs#setSynchronizerNotificationStatus
2823 * @methodOf xos.helpers.XosUserPrefs
2824 * @description
2825 * Update the notification status for a single synchronizer
2826 * @param {string} name The synchronizer name
2827 * @param {boolean} value The notification status (true means that it has been sent)
2828 **/
2829
2830 this.setSynchronizerNotificationStatus = function () {
2831 var name = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0];
2832 var value = arguments[1];
2833
2834 if (!name) {
2835 throw new Error('[XosUserPrefs] When updating a synchronizer is mandatory to provide a name.');
2836 }
2837
2838 var cookies = _this.getAll();
2839
2840 if (!cookies.synchronizers) {
2841 cookies.synchronizers = {
2842 notification: {}
2843 };
2844 }
2845 cookies.synchronizers.notification[name] = value;
2846 _this.setAll(cookies);
2847 };
2848 }]);
2849})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002850'use strict';
2851
2852(function () {
2853 'use strict';
2854
2855 /**
2856 * @ngdoc service
2857 * @name xos.helpers.ServiceGraph
2858 * @description This factory define a set of helper function to query the service tenancy graph
2859 **/
2860
2861 angular.module('xos.helpers').service('GraphService', ["$q", "Tenants", "Services", function ($q, Tenants, Services) {
2862 var _this = this;
2863
2864 this.loadCoarseData = function () {
2865
2866 var services = void 0;
2867
2868 var deferred = $q.defer();
2869
2870 Services.query().$promise.then(function (res) {
2871 services = res;
2872 return Tenants.query({ kind: 'coarse' }).$promise;
2873 }).then(function (tenants) {
2874 deferred.resolve({
2875 tenants: tenants,
2876 services: services
2877 });
2878 });
2879
2880 return deferred.promise;
2881 };
2882
2883 this.getCoarseGraph = function () {
2884 _this.loadCoarseData().then(function (res) {
2885 console.log(res);
2886 });
2887 return 'ciao';
2888 };
2889 }]);
2890})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002891'use strict';
2892
2893/* eslint-disable angular/ng_window_service*/
2894(function () {
2895 'use strict';
2896
2897 angular.module('xos.helpers').factory('Notification', function () {
2898 return window.Notification;
2899 })
2900 /**
2901 * @ngdoc service
2902 * @name xos.helpers.xosNotification
2903 * @description This factory define a set of helper function to trigger desktop notification
2904 **/
2905 .service('xosNotification', ["$q", "$log", "Notification", function ($q, $log, Notification) {
2906 var _this = this;
2907
2908 this.checkPermission = function () {
2909 var deferred = $q.defer();
2910 Notification.requestPermission().then(function (permission) {
2911 if (permission === 'granted') {
2912 deferred.resolve(permission);
2913 } else {
2914 deferred.reject(permission);
2915 }
2916 });
2917 return deferred.promise;
2918 };
2919
2920 this.sendNotification = function (title, options) {
2921 var notification = new Notification(title, options);
2922 notification.onerror = function (err) {
2923 $log.error(err);
2924 };
2925 };
2926
2927 /**
2928 * @ngdoc method
2929 * @name xos.helpers.xosNotification#notify
2930 * @methodOf xos.helpers.xosNotification
2931 * @description
2932 * This method will check for user permission and if granted will send a browser notification.
2933 * @param {string} title The notification title
2934 * @param {object} options The notification options: `{icon: 'url', body: 'Notification body'}`
2935 **/
2936
2937 this.notify = function (title, options) {
2938 if (!('Notification' in window)) {
2939 $log.info('This browser does not support desktop notification');
2940 } else if (Notification.permission !== 'granted') {
2941 _this.checkPermission().then(function () {
2942 return _this.sendNotification(title, options);
2943 });
2944 } else if (Notification.permission === 'granted') {
2945 _this.sendNotification(title, options);
2946 }
2947 };
2948 }]);
2949})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002950'use strict';
2951
2952(function () {
2953 'use strict';
2954
2955 /**
2956 * @ngdoc service
2957 * @name xos.helpers.NoHyperlinks
2958 * @description This factory is automatically loaded trough xos.helpers and will add an $http interceptor that will add ?no_hyperlinks=1 to your api request, that is required by django
2959 **/
2960
2961 angular.module('xos.helpers').factory('NoHyperlinks', noHyperlinks);
2962
2963 function noHyperlinks() {
2964 return {
2965 request: function request(_request) {
2966 if (_request.url.indexOf('.html') === -1) {
2967 _request.url += '?no_hyperlinks=1';
2968 }
2969 return _request;
2970 }
2971 };
2972 }
2973})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07002974'use strict';
2975
2976// TODO write tests for log
2977
2978/* eslint-disable angular/ng_window_service*/
2979
2980angular.module('xos.helpers').config(['$provide', function ($provide) {
2981 // Use the `decorator` solution to substitute or attach behaviors to
2982 // original service instance; @see angular-mocks for more examples....
2983
2984 $provide.decorator('$log', ['$delegate', function ($delegate) {
2985
2986 var isLogEnabled = function isLogEnabled() {
2987 return window.location.href.indexOf('debug=true') >= 0;
2988 };
2989 // Save the original $log.debug()
2990 var logFn = $delegate.log;
2991 var infoFn = $delegate.info;
2992 var warnFn = $delegate.warn;
2993 //let errorFn = $delegate.error;
2994 var debugFn = $delegate.debug;
2995
2996 // create the replacement function
2997 var replacement = function replacement(fn) {
2998 return function () {
2999 //console.log(`Is Log Enabled: ${isLogEnabled()}`)
3000 if (!isLogEnabled()) {
3001 // console.log('logging is disabled');
3002 return;
3003 }
3004
3005 var args = [].slice.call(arguments);
3006 var now = new Date();
3007
3008 // Prepend timestamp
3009 args[0] = '[' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '] ' + args[0];
3010
3011 // HACK awfull fix for angular mock implementation whithin jasmine test failing issue
3012 if (angular.isFunction($delegate.reset) && !($delegate.debug.logs instanceof Array)) {
3013 // if we are within the mock and did not reset yet, we call it to avoid issue
3014 // console.log('mock log impl fix to avoid logs array not existing...');
3015 $delegate.reset();
3016 }
3017
3018 // Call the original with the output prepended with formatted timestamp
3019
3020 return fn.apply(null, args);
3021 };
3022 };
3023
3024 $delegate.info = replacement(infoFn);
3025 $delegate.log = replacement(logFn);
3026 $delegate.warn = replacement(warnFn);
3027 //$delegate.error = replacement(errorFn); // note this will prevent errors to be printed
3028 $delegate.debug = replacement(debugFn);
3029
3030 return $delegate;
3031 }]);
3032}]);
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07003033'use strict';
3034
3035(function () {
3036 'use strict';
3037
3038 /**
3039 * @ngdoc service
3040 * @name xos.helpers.SetCSRFToken
3041 * @description This factory is automatically loaded trough xos.helpers and will add an $http interceptor that will the CSRF-Token to your request headers
3042 **/
3043
3044 setCSRFToken.$inject = ["$cookies"];
3045 angular.module('xos.helpers').factory('SetCSRFToken', setCSRFToken);
3046
3047 function setCSRFToken($cookies) {
3048 return {
3049 request: function request(_request) {
3050 if (_request.method !== 'GET') {
3051 _request.headers['X-CSRFToken'] = $cookies.get('xoscsrftoken');
3052 }
3053 return _request;
3054 }
3055 };
3056 }
3057})();
Matteo Scandoloa71ccfd2016-07-22 10:19:15 -07003058/**
3059* @ngdoc overview
3060* @name ngXosLib
3061* @id index
3062* @description
3063* # Welcome to the ngXosLib documentation! <br/>
3064* This is the module that group all the helpers service and UI components for XOS.
3065* <br/><br/>
3066* You can find all the documentation related to the UI Component Library here: <a href="#/module/xos.uiComponents"> xos.uiComponents</a> <br/>
3067* and the documentation related to all the other helpers here: <a href="#/module/xos.helpers"> xos.helpers</a> <br/>
3068* ## Issues
3069* Please report issues at https://jira.opencord.org
3070**/
Matteo Scandolo1516f882016-08-08 16:51:55 -07003071"use strict";