blob: cc08dbe92997968e361c513cb38b186c41238f55 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
/**
* © OpenCORD
*
* Visit http://guide.xosproject.org/devguide/addview/ for more information
*
* Created by teone on 3/24/16.
*/
(function () {
'use strict';
/**
* @ngdoc overview
* @name xos.uiComponents
* @description
* # xos.uiComponents
* A collection of UI components useful for Dashboard development. <br/>
* Currently available components are:
* - [xosAlert](/#/module/xos.uiComponents.directive:xosAlert)
* - [xosForm](/#/module/xos.uiComponents.directive:xosForm)
* - [xosPagination](/#/module/xos.uiComponents.directive:xosPagination)
* - [xosSmartTable](/#/module/xos.uiComponents.directive:xosSmartTable)
* - [xosTable](/#/module/xos.uiComponents.directive:xosTable)
* - [xosValidation](/#/module/xos.uiComponents.directive:xosValidation)
**/
angular.module('xos.uiComponents', ['chart.js', 'RecursionHelper', 'dndLists']);
})();
'use strict';
/**
* © OpenCORD
*
* Visit http://guide.xosproject.org/devguide/addview/ for more information
*
* Created by teone on 3/24/16.
*/
(function () {
'use strict';
angular.module('xos.uiComponents')
/**
* @ngdoc directive
* @name xos.uiComponents.directive:xosSmartTable
* @link xos.uiComponents.directive:xosTable xosTable
* @link xos.uiComponents.directive:xosForm xosForm
* @restrict E
* @description The xos-table directive
* @param {Object} config The configuration for the component,
* it is composed by the name of an angular [$resource](https://docs.angularjs.org/api/ngResource/service/$resource)
* and an array of fields that shouldn't be printed.
* ```
* {
resource: 'Users',
hiddenFields: []
}
* ```
* @scope
* @example
<example module="sampleSmartTable">
<file name="index.html">
<div ng-controller="SampleCtrl as vm">
<xos-smart-table config="vm.config"></xos-smart-table>
</div>
</file>
<file name="script.js">
angular.module('sampleSmartTable', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
// This is only for documentation purpose
.run(function($httpBackend, _){
let datas = [{id: 1, name: 'Jhon', surname: 'Doe'}];
let count = 1;
let paramsUrl = new RegExp(/\/test\/(.+)/);
$httpBackend.whenDELETE(paramsUrl, undefined, ['id']).respond((method, url, data, headers, params) => {
data = angular.fromJson(data);
let id = url.match(paramsUrl)[1];
_.remove(datas, (d) => {
return d.id === parseInt(id);
})
return [204];
});
$httpBackend.whenGET('/test').respond(200, datas)
$httpBackend.whenPOST('/test').respond((method, url, data) => {
data = angular.fromJson(data);
data.id = ++count;
datas.push(data);
return [201, data, {}];
});
})
.factory('_', function($window){
return $window._;
})
.service('SampleResource', function($resource){
return $resource('/test/:id', {id: '@id'});
})
// End of documentation purpose, example start
.controller('SampleCtrl', function(){
this.config = {
resource: 'SampleResource'
};
});
</file>
</example>
*/
.component('xosSmartTable', {
restrict: 'E',
bindings: {
config: '='
},
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 ',
bindToController: true,
controllerAs: 'vm',
controller: ["$injector", "LabelFormatter", "_", "XosFormHelpers", function controller($injector, LabelFormatter, _, XosFormHelpers) {
var _this = this;
// TODO
// - Validate the config (what if resource does not exist?)
// NOTE
// Corner case
// - if response is empty, how can we generate a form ?
this.responseMsg = false;
this.responseErr = false;
this.tableConfig = {
columns: [],
actions: [{
label: 'delete',
icon: 'remove',
cb: function cb(item) {
_this.Resource.delete({ id: item.id }).$promise.then(function () {
_.remove(_this.data, function (d) {
return d.id === item.id;
});
_this.responseMsg = _this.config.resource + ' with id ' + item.id + ' successfully deleted';
}).catch(function (err) {
_this.responseErr = err.data.detail || 'Error while deleting ' + _this.config.resource + ' with id ' + item.id;
});
},
color: 'red'
}, {
label: 'details',
icon: 'search',
cb: function cb(item) {
_this.detailedItem = item;
}
}],
classes: 'table table-striped table-bordered table-responsive',
filter: 'field',
order: true,
pagination: {
pageSize: 10
}
};
this.formConfig = {
exclude: this.config.hiddenFields,
fields: {},
formName: this.config.resource + 'Form',
actions: [{
label: 'Save',
icon: 'ok',
cb: function cb(item) {
var p = void 0;
var isNew = true;
if (item.id) {
p = item.$update();
isNew = false;
} else {
p = item.$save();
}
p.then(function (res) {
if (isNew) {
_this.data.push(angular.copy(res));
}
delete _this.detailedItem;
_this.responseMsg = _this.config.resource + ' with id ' + item.id + ' successfully saved';
}).catch(function (err) {
_this.responseErr = err.data.detail || 'Error while saving ' + _this.config.resource + ' with id ' + item.id;
});
},
class: 'success'
}]
};
this.cleanForm = function () {
delete _this.detailedItem;
};
this.createItem = function () {
_this.detailedItem = new _this.Resource();
};
this.Resource = $injector.get(this.config.resource);
var getData = function getData() {
_this.Resource.query().$promise.then(function (res) {
if (!res[0]) {
_this.data = res;
return;
}
var item = res[0];
var props = Object.keys(item);
_.remove(props, function (p) {
return p === 'id' || p === 'validators';
});
// TODO move out cb, non sense triggering a lot of times
if (angular.isArray(_this.config.hiddenFields)) {
props = _.difference(props, _this.config.hiddenFields);
}
props.forEach(function (p) {
var fieldConfig = {
label: LabelFormatter.format(p),
prop: p
};
fieldConfig.type = XosFormHelpers._getFieldFormat(item[p]);
_this.tableConfig.columns.push(fieldConfig);
});
// build form structure
// TODO move in a pure function for testing purposes
props.forEach(function (p) {
_this.formConfig.fields[p] = {
label: LabelFormatter.format(p).replace(':', ''),
type: XosFormHelpers._getFieldFormat(item[p])
};
});
_this.data = res;
});
};
getData();
}]
});
})();
'use strict';
/**
* © OpenCORD
*
* Visit http://guide.xosproject.org/devguide/addview/ for more information
*
* Created by teone on 3/24/16.
*/
(function () {
'use strict';
angular.module('xos.uiComponents')
/**
* @ngdoc directive
* @name xos.uiComponents.directive:xosSmartPie
* @restrict E
* @description The xos-table directive
* @param {Object} config The configuration for the component,
* it is composed by the name of an angular [$resource](https://docs.angularjs.org/api/ngResource/service/$resource)
* and a field name that is used to group the data.
* ```
* {
resource: 'Users',
groupBy: 'fieldName',
classes: 'my-custom-class',
labelFormatter: (labels) => {
// here you can format your label,
// you should return an array with the same order
return labels;
}
}
* ```
* @scope
* @example
Displaying Local data
<example module="sampleSmartPieLocal">
<file name="index.html">
<div ng-controller="SampleCtrlLocal as vm">
<xos-smart-pie config="vm.configLocal"></xos-smart-pie>
</div>
</file>
<file name="script.js">
angular.module('sampleSmartPieLocal', ['xos.uiComponents'])
.factory('_', function($window){
return $window._;
})
.controller('SampleCtrlLocal', function($timeout){
this.datas = [
{id: 1, first_name: 'Jon', last_name: 'aaa', category: 2},
{id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 1},
{id: 3, first_name: 'Aria', last_name: 'Stark', category: 2}
];
this.configLocal = {
data: [],
groupBy: 'category',
classes: 'local',
labelFormatter: (labels) => {
return labels.map(l => l === '1' ? 'North' : 'Dragon');
}
};
$timeout(() => {
// this need to be triggered in this way just because of ngDoc,
// otherwise you can assign data directly in the config
this.configLocal.data = this.datas;
}, 1)
});
</file>
</example>
Fetching data from API
<example module="sampleSmartPieResource">
<file name="index.html">
<div ng-controller="SampleCtrl as vm">
<xos-smart-pie config="vm.config"></xos-smart-pie>
</div>
</file>
<file name="script.js">
angular.module('sampleSmartPieResource', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
.controller('SampleCtrl', function(){
this.config = {
resource: 'SampleResource',
groupBy: 'category',
classes: 'resource',
labelFormatter: (labels) => {
return labels.map(l => l === '1' ? 'North' : 'Dragon');
}
};
});
</file>
<file name="backendPoll.js">
angular.module('sampleSmartPieResource')
.run(function($httpBackend, _){
let datas = [
{id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
{id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
{id: 3, first_name: 'Aria', last_name: 'Stark', category: 1}
];
$httpBackend.whenGET('/test').respond(200, datas)
})
.factory('_', function($window){
return $window._;
})
.service('SampleResource', function($resource){
return $resource('/test/:id', {id: '@id'});
})
</file>
</example>
Polling data from API
<example module="sampleSmartPiePoll">
<file name="index.html">
<div ng-controller="SampleCtrl as vm">
<xos-smart-pie config="vm.config"></xos-smart-pie>
</div>
</file>
<file name="script.js">
angular.module('sampleSmartPiePoll', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
.controller('SampleCtrl', function(){
this.config = {
resource: 'SampleResource',
groupBy: 'category',
poll: 2,
labelFormatter: (labels) => {
return labels.map(l => l === '1' ? 'Active' : 'Banned');
}
};
});
</file>
<file name="backend.js">
angular.module('sampleSmartPiePoll')
.run(function($httpBackend, _){
let mock = [
[
{id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
{id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
{id: 3, first_name: 'Aria', last_name: 'Stark', category: 1},
{id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 1}
],
[
{id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
{id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
{id: 3, first_name: 'Aria', last_name: 'Stark', category: 2},
{id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 2}
],
[
{id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
{id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
{id: 3, first_name: 'Aria', last_name: 'Stark', category: 1},
{id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 2}
]
];
$httpBackend.whenGET('/test').respond(function(method, url, data, headers, params) {
return [200, mock[Math.round(Math.random() * 3)]];
});
})
.factory('_', function($window){
return $window._;
})
.service('SampleResource', function($resource){
return $resource('/test/:id', {id: '@id'});
})
</file>
</example>
*/
.component('xosSmartPie', {
restrict: 'E',
bindings: {
config: '='
},
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 ',
bindToController: true,
controllerAs: 'vm',
controller: ["$injector", "$interval", "$scope", "$timeout", "_", function controller($injector, $interval, $scope, $timeout, _) {
var _this = this;
if (!this.config.resource && !this.config.data) {
throw new Error('[xosSmartPie] Please provide a resource or an array of data in the configuration');
}
var groupData = function groupData(data) {
return _.groupBy(data, _this.config.groupBy);
};
var formatData = function formatData(data) {
return _.reduce(Object.keys(data), function (list, group) {
return list.concat(data[group].length);
}, []);
};
var formatLabels = function formatLabels(data) {
return angular.isFunction(_this.config.labelFormatter) ? _this.config.labelFormatter(Object.keys(data)) : Object.keys(data);
};
var prepareData = function prepareData(data) {
// group data
var grouped = groupData(data);
_this.data = formatData(grouped);
// create labels
_this.labels = formatLabels(grouped);
};
if (this.config.resource) {
(function () {
_this.Resource = $injector.get(_this.config.resource);
var getData = function getData() {
_this.Resource.query().$promise.then(function (res) {
if (!res[0]) {
return;
}
prepareData(res);
});
};
getData();
if (_this.config.poll) {
$interval(function () {
getData();
}, _this.config.poll * 1000);
}
})();
} else {
$scope.$watch(function () {
return _this.config.data;
}, function (data) {
if (data) {
prepareData(_this.config.data);
}
}, true);
}
$scope.$on('create', function (event, chart) {
console.log('create: ' + chart.id);
});
$scope.$on('destroy', function (event, chart) {
console.log('destroy: ' + chart.id);
});
}]
});
})();
'use strict';
/**
* © OpenCORD
*
* Visit http://guide.xosproject.org/devguide/addview/ for more information
*
* Created by teone on 4/15/16.
*/
(function () {
'use strict';
angular.module('xos.uiComponents')
/**
* @ngdoc directive
* @name xos.uiComponents.directive:xosValidation
* @restrict E
* @description The xos-validation directive
* @param {Object} errors The error object
* @element ANY
* @scope
* @example
<example module="sampleValidation">
<file name="index.html">
<div ng-controller="SampleCtrl as vm">
<div class="row">
<div class="col-xs-12">
<label>Set an error type:</label>
</div>
<div class="col-xs-2">
<a class="btn"
ng-click="vm.field.$error.required = !vm.field.$error.required"
ng-class="{'btn-default': !vm.field.$error.required, 'btn-success': vm.field.$error.required}">
Required
</a>
</div>
<div class="col-xs-2">
<a class="btn"
ng-click="vm.field.$error.email = !vm.field.$error.email"
ng-class="{'btn-default': !vm.field.$error.email, 'btn-success': vm.field.$error.email}">
Email
</a>
</div>
<div class="col-xs-2">
<a class="btn"
ng-click="vm.field.$error.minlength = !vm.field.$error.minlength"
ng-class="{'btn-default': !vm.field.$error.minlength, 'btn-success': vm.field.$error.minlength}">
Min Length
</a>
</div>
<div class="col-xs-2">
<a class="btn"
ng-click="vm.field.$error.maxlength = !vm.field.$error.maxlength"
ng-class="{'btn-default': !vm.field.$error.maxlength, 'btn-success': vm.field.$error.maxlength}">
Max Length
</a>
</div>
</div>
<xos-validation field ="vm.field" form = "vm.form"></xos-validation>
</div>
</file>
<file name="script.js">
angular.module('sampleValidation', ['xos.uiComponents'])
.controller('SampleCtrl', function(){
this.field = {
$error: {}
};
this.form= {
$submitted:true
}
});
</file>
</example>
*/
.component('xosValidation', {
restrict: 'E',
bindings: {
field: '=',
form: '='
},
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 ',
transclude: true,
bindToController: true,
controllerAs: 'vm',
controller: function controller() {
this.config = {
type: 'danger'
};
}
});
})();
'use strict';
/**
* © OpenCORD
*
* Visit http://guide.xosproject.org/devguide/addview/ for more information
*
* Created by teone on 3/24/16.
*/
(function () {
'use strict';
angular.module('xos.uiComponents')
/**
* @ngdoc directive
* @name xos.uiComponents.directive:xosTable
* @restrict E
* @description The xos-table directive
* @param {Object} config The configuration for the component.
* ```
* {
* columns: [
* {
* label: 'Human readable name',
* prop: 'Property to read in the model object',
* type: 'boolean'| 'array'| 'object'| 'custom'| 'date' | 'icon' // see examples for more details
formatter: fn(), // receive the whole item if tipe is custom and return a string
link: fn() // receive the whole item and return an url
* }
* ],
* classes: 'table table-striped table-bordered',
* actions: [ // if defined add an action column
{
label: 'delete',
icon: 'remove', // refers to bootstraps glyphicon
cb: (user) => { // receive the model
console.log(user);
},
color: 'red'
}
],
filter: 'field', // can be by `field` or `fulltext`
order: true | {field: 'property name', reverse: true | false} // whether to show ordering arrows, or a configuration for a default ordering
* }
* ```
* @param {Array} data The data that should be rendered
* @element ANY
* @scope
* @example
# Basic usage
<example module="sampleTable1">
<file name="index.html">
<div ng-controller="SampleCtrl1 as vm">
<xos-table data="vm.data" config="vm.config"></xos-table>
</div>
</file>
<file name="script.js">
angular.module('sampleTable1', ['xos.uiComponents'])
.factory('_', function($window){
return $window._;
})
.controller('SampleCtrl1', function(){
this.config = {
columns: [
{
label: 'First Name', // column title
prop: 'name' // property to read in the data array
},
{
label: 'Last Name',
prop: 'lastname'
}
]
};
this.data = [
{
name: 'John',
lastname: 'Doe'
},
{
name: 'Gili',
lastname: 'Fereydoun'
}
]
});
</file>
</example>
# Filtering
<example module="sampleTable2" animations="true">
<file name="index.html">
<div ng-controller="SampleCtrl2 as vm">
<xos-table data="vm.data" config="vm.config"></xos-table>
</div>
</file>
<file name="script.js">
angular.module('sampleTable2', ['xos.uiComponents', 'ngAnimate'])
.factory('_', function($window){
return $window._;
})
.controller('SampleCtrl2', function(){
this.config = {
columns: [
{
label: 'First Name', // column title
prop: 'name' // property to read in the data array
},
{
label: 'Last Name',
prop: 'lastname'
}
],
classes: 'table table-striped table-condensed', // table classes, default to `table table-striped table-bordered`
actions: [ // if defined add an action column
{
label: 'delete', // label
icon: 'remove', // icons, refers to bootstraps glyphicon
cb: (user) => { // callback, get feeded with the full object
console.log(user);
},
color: 'red' // icon color
}
],
filter: 'field', // can be by `field` or `fulltext`
order: true
};
this.data = [
{
name: 'John',
lastname: 'Doe'
},
{
name: 'Gili',
lastname: 'Fereydoun'
}
]
});
</file>
</example>
# Pagination
<example module="sampleTable3">
<file name="index.html">
<div ng-controller="SampleCtrl3 as vm">
<xos-table data="vm.data" config="vm.config"></xos-table>
</div>
</file>
<file name="script.js">
angular.module('sampleTable3', ['xos.uiComponents'])
.factory('_', function($window){
return $window._;
})
.controller('SampleCtrl3', function(){
this.config = {
columns: [
{
label: 'First Name', // column title
prop: 'name' // property to read in the data array
},
{
label: 'Last Name',
prop: 'lastname'
}
],
pagination: {
pageSize: 2
}
};
this.data = [
{
name: 'John',
lastname: 'Doe'
},
{
name: 'Gili',
lastname: 'Fereydoun'
},
{
name: 'Lucky',
lastname: 'Clarkson'
},
{
name: 'Tate',
lastname: 'Spalding'
}
]
});
</file>
</example>
# Field formatter
<example module="sampleTable4">
<file name="index.html">
<div ng-controller="SampleCtrl as vm">
<xos-table data="vm.data" config="vm.config"></xos-table>
</div>
</file>
<file name="script.js">
angular.module('sampleTable4', ['xos.uiComponents'])
.factory('_', function($window){
return $window._;
})
.controller('SampleCtrl', function(){
this.config = {
columns: [
{
label: 'First Name',
prop: 'name',
link: item => `https://www.google.it/#q=${item.name}`
},
{
label: 'Enabled',
prop: 'enabled',
type: 'boolean'
},
{
label: 'Services',
prop: 'services',
type: 'array'
},
{
label: 'Details',
prop: 'details',
type: 'object'
},
{
label: 'Created',
prop: 'created',
type: 'date'
},
{
label: 'Icon',
type: 'icon',
formatter: item => item.icon //note that this refer to [Bootstrap Glyphicon](http://getbootstrap.com/components/#glyphicons)
}
]
};
this.data = [
{
name: 'John',
enabled: true,
services: ['Cdn', 'IpTv'],
details: {
c_tag: '243',
s_tag: '444'
},
created: new Date('December 17, 1995 03:24:00'),
icon: 'music'
},
{
name: 'Gili',
enabled: false,
services: ['Cdn', 'IpTv', 'Cache'],
details: {
c_tag: '675',
s_tag: '893'
},
created: new Date(),
icon: 'camera'
}
]
});
</file>
</example>
# Custom formatter
<example module="sampleTable5">
<file name="index.html">
<div ng-controller="SampleCtrl as vm">
<xos-table data="vm.data" config="vm.config"></xos-table>
</div>
</file>
<file name="script.js">
angular.module('sampleTable5', ['xos.uiComponents'])
.factory('_', function($window){
return $window._;
})
.controller('SampleCtrl', function(){
this.config = {
columns: [
{
label: 'Username',
prop: 'username'
},
{
label: 'Features',
type: 'custom',
formatter: (val) => {
let cdnEnabled = val.features.cdn ? 'enabled' : 'disabled';
return `
Cdn is ${cdnEnabled},
uplink speed is ${val.features.uplink_speed}
and downlink speed is ${val.features.downlink_speed}
`;
}
}
]
};
this.data = [
{
username: 'John',
features: {
"cdn": false,
"uplink_speed": 1000000000,
"downlink_speed": 1000000000,
"uverse": true,
"status": "enabled"
}
},
{
username: 'Gili',
features: {
"cdn": true,
"uplink_speed": 3000000000,
"downlink_speed": 2000000000,
"uverse": true,
"status": "enabled"
}
}
]
});
</file>
</example>
**/
.component('xosTable', {
restrict: 'E',
bindings: {
data: '=',
config: '='
},
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 || col.type === \'text\'">{{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 ',
bindToController: true,
controllerAs: 'vm',
controller: ["_", "$scope", "Comparator", function controller(_, $scope, Comparator) {
var _this = this;
this.comparator = Comparator;
this.loader = true;
$scope.$watch(function () {
return _this.data;
}, function (data) {
if (angular.isDefined(data)) {
_this.loader = false;
}
});
if (!this.config) {
throw new Error('[xosTable] Please provide a configuration via the "config" attribute');
}
if (!this.config.columns) {
throw new Error('[xosTable] Please provide a columns list in the configuration');
}
// handle default ordering
if (this.config.order && angular.isObject(this.config.order)) {
this.reverse = this.config.order.reverse || false;
this.orderBy = this.config.order.field || 'id';
}
// if columns with type 'custom' are provided
// check that a custom formatte3 is provided too
var customCols = _.filter(this.config.columns, { type: 'custom' });
if (angular.isArray(customCols) && customCols.length > 0) {
_.forEach(customCols, function (col) {
if (!col.formatter || !angular.isFunction(col.formatter)) {
throw new Error('[xosTable] You have provided a custom field type, a formatter function should provided too.');
}
});
}
// if columns with type 'icon' are provided
// check that a custom formatte3 is provided too
var iconCols = _.filter(this.config.columns, { type: 'icon' });
if (angular.isArray(iconCols) && iconCols.length > 0) {
_.forEach(iconCols, function (col) {
if (!col.formatter || !angular.isFunction(col.formatter)) {
throw new Error('[xosTable] You have provided an icon field type, a formatter function should provided too.');
}
});
}
// if a link property is passed,
// it should be a function
var linkedColumns = _.filter(this.config.columns, function (col) {
return angular.isDefined(col.link);
});
if (angular.isArray(linkedColumns) && linkedColumns.length > 0) {
_.forEach(linkedColumns, function (col) {
if (!angular.isFunction(col.link)) {
throw new Error('[xosTable] The link property should be a function.');
}
});
}
this.columns = this.config.columns;
this.classes = this.config.classes || 'table table-striped table-bordered';
if (this.config.actions) {
// TODO validate action format
}
if (this.config.pagination) {
this.currentPage = 0;
this.goToPage = function (n) {
_this.currentPage = n;
};
}
}]
})
// TODO move in separate files
// TODO test
.filter('arrayToList', function () {
return function (input) {
if (!angular.isArray(input)) {
return input;
}
return input.join(', ');
};
})
// TODO test
.directive('xosLinkWrapper', function () {
return {
restrict: 'A',
transclude: true,
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 '
};
});
})();
'use strict';
/**
* © OpenCORD
*
* Visit http://guide.xosproject.org/devguide/addview/ for more information
*
* Created by teone on 4/18/16.
*/
(function () {
'use strict';
angular.module('xos.uiComponents')
/**
* @ngdoc directive
* @name xos.uiComponents.directive:xosForm
* @restrict E
* @description The xos-form directive.
* 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.
* @param {Object} config The configuration object
* ```
* {
* exclude: ['id', 'validators', 'created', 'updated', 'deleted'], //field to be skipped in the form, the provide values are concatenated
* order: ['field1', 'field2'], // ordering the fields (missing ones are attached at the end)
* actions: [ // define the form buttons with related callback
* {
label: 'save',
icon: 'ok', // refers to bootstraps glyphicon
cb: (user) => { // receive the model
console.log(user);
},
class: 'success'
}
* ],
* feedback: {
show: false,
message: 'Form submitted successfully !!!',
type: 'success' //refers to bootstrap class
},
* fields: {
* field_name: {
* label: 'Field Label',
* type: 'string' // options are: [date, boolean, number, email, string, select],
* validators: {
* minlength: number,
maxlength: number,
required: boolean,
min: number,
max: number,
custom: (value) => {
// do your validation here and return true | false
// alternatively you can return an array [errorName, true|false]
}
* }
* }
* }
* }
* ```
* @param {Object} ngModel The model object (it is mandatory to specify at least an empty object)
* @element ANY
* @scope
* @requires xos.uiComponents.directive:xosField
* @requires xos.uiComponents.XosFormHelpers
* @requires xos.helpers._
* @example
Autogenerated form
<example module="sampleForm">
<file name="script.js">
angular.module('sampleForm', ['xos.uiComponents'])
.factory('_', function($window){
return $window._;
})
.controller('SampleCtrl', function(){
this.model = {
first_name: 'Jhon',
last_name: 'Doe',
email: 'jhon.doe@sample.com',
active: true,
birthDate: '2015-02-17T22:06:38.059000Z'
}
this.config = {
exclude: ['password', 'last_login'],
formName: 'sampleForm',
actions: [
{
label: 'Save',
icon: 'ok', // refers to bootstraps glyphicon
cb: (user) => { // receive the model
console.log(user);
},
class: 'success'
}
]
};
});
</file>
<file name="index.html">
<div ng-controller="SampleCtrl as vm">
<xos-form ng-model="vm.model" config="vm.config"></xos-form>
</div>
</file>
</example>
Configuration defined form
<example module="sampleForm1">
<file name="script.js">
angular.module('sampleForm1', ['xos.uiComponents','ngResource', 'ngMockE2E'])
.factory('_', function($window){
return $window._;
})
.controller('SampleCtrl1', function(SampleResource){
this.model = {};
this.config = {
exclude: ['password', 'last_login'],
formName: 'sampleForm1',
feedback: {
show: false,
message: 'Form submitted successfully!',
type: 'success'
},
actions: [
{
label: 'Save',
icon: 'ok',
cb: (user) => {
console.log(user);
this.config.feedback.show = true;
this.config.feedback.type='success';
},
class: 'success'
}
],
order: ['site', 'last_name', 'first_name', 'age'],
fields: {
first_name: {
type: 'string',
validators: {
required: true
}
},
last_name: {
label: 'Surname',
type: 'string',
validators: {
required: true,
minlength: 10
}
},
age: {
type: 'number',
validators: {
required: true,
min: 21
}
},
site: {
label: 'Site',
type: 'select',
validators: { required: true},
hint: 'The Site this Slice belongs to',
options: []
},
}
};
SampleResource.query().$promise
.then((users) => {
this.optionVal = users;
this.config.fields['site'].options = this.optionVal;
})
.catch((e) => {
throw new Error(e);
});
});
</file>
<file name="backend.js">
angular.module('sampleForm1')
.run(function($httpBackend, _){
let datas = [{id: 1, label: 'site1'},{id: 4, label: 'site4'},{id: 3, label: 'site3'}];
let paramsUrl = new RegExp(/\/test\/(.+)/);
$httpBackend.whenGET('/test').respond(200, datas)
})
.service('SampleResource', function($resource){
return $resource('/test/:id', {id: '@id'});
});
</file>
<file name="index.html">
<div ng-controller="SampleCtrl1 as vm">
<xos-form ng-model="vm.model" config="vm.config"></xos-form>
</div>
</file>
</example>
**/
.component('xosForm', {
restrict: 'E',
bindings: {
config: '=',
ngModel: '='
},
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 ',
bindToController: true,
controllerAs: 'vm',
controller: ["$scope", "$log", "_", "XosFormHelpers", function controller($scope, $log, _, XosFormHelpers) {
var _this = this;
if (!this.config) {
throw new Error('[xosForm] Please provide a configuration via the "config" attribute');
}
if (!this.config.actions) {
throw new Error('[xosForm] Please provide an action list in the configuration');
}
if (!this.config.feedback) {
this.config.feedback = {
show: false,
message: 'Form submitted successfully !!!',
type: 'success'
};
}
this.excludedField = ['id', 'validators', 'created', 'updated', 'deleted', 'backend_status'];
if (this.config && this.config.exclude) {
this.excludedField = this.excludedField.concat(this.config.exclude);
}
this.formField = [];
$scope.$watch(function () {
return _this.config;
}, function () {
if (!_this.ngModel) {
return;
}
var diff = _.difference(Object.keys(_this.ngModel), _this.excludedField);
var modelField = XosFormHelpers.parseModelField(diff);
_this.formField = XosFormHelpers.buildFormStructure(modelField, _this.config.fields, _this.ngModel, _this.config.order);
}, true);
$scope.$watch(function () {
return _this.ngModel;
}, function (model) {
// empty from old stuff
_this.formField = {};
if (!model) {
return;
}
var diff = _.difference(Object.keys(model), _this.excludedField);
var modelField = XosFormHelpers.parseModelField(diff);
_this.formField = XosFormHelpers.buildFormStructure(modelField, _this.config.fields, model, _this.config.order);
});
}]
});
})();
'use strict';
/**
* © OpenCORD
*
* Visit http://guide.xosproject.org/devguide/addview/ for more information
*
* Created by teone on 4/15/16.
*/
(function () {
'use strict';
angular.module('xos.uiComponents')
/**
* @ngdoc directive
* @name xos.uiComponents.directive:xosPagination
* @restrict E
* @description The xos-table directive
* @param {Number} pageSize Number of elements per page
* @param {Number} totalElements Number of total elements in the collection
* @param {Function} change The callback to be triggered on page change.
* * @element ANY
* @scope
* @example
<example module="samplePagination">
<file name="index.html">
<div ng-controller="SampleCtrl1 as vm">
<xos-pagination
page-size="vm.pageSize"
total-elements="vm.totalElements"
change="vm.change">
</xos-pagination>
</div>
</file>
<file name="script.js">
angular.module('samplePagination', ['xos.uiComponents'])
.controller('SampleCtrl1', function(){
this.pageSize = 10;
this.totalElements = 35;
this.change = (pageNumber) => {
console.log(pageNumber);
}
});
</file>
</example>
**/
.component('xosPagination', {
restrict: 'E',
bindings: {
pageSize: '=',
totalElements: '=',
change: '='
},
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 ',
bindToController: true,
controllerAs: 'vm',
controller: ["$scope", function controller($scope) {
var _this = this;
this.currentPage = 0;
this.goToPage = function (n) {
if (n < 0 || n === _this.pages) {
return;
}
_this.currentPage = n;
_this.change(n);
};
this.createPages = function (pages) {
var arr = [];
for (var i = 0; i < pages; i++) {
arr.push(i);
}
return arr;
};
// watch for data changes
$scope.$watch(function () {
return _this.totalElements;
}, function () {
if (_this.totalElements) {
_this.pages = Math.ceil(_this.totalElements / _this.pageSize);
_this.pageList = _this.createPages(_this.pages);
}
});
}]
}).filter('pagination', function () {
return function (input, start) {
if (!input || !angular.isArray(input)) {
return input;
}
start = parseInt(start, 10);
return input.slice(start);
};
});
})();
'use strict';
function _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); } }
/**
* © OpenCORD
*
* Visit http://guide.xosproject.org/devguide/addview/ for more information
*
* Created by teone on 5/25/16.
*/
(function () {
'use strict';
angular.module('xos.uiComponents')
/**
* @ngdoc directive
* @name xos.uiComponents.directive:xosField
* @restrict E
* @description The xos-field directive.
* This component decide, give a field wich kind of input it need to print.
* @param {string} name The field name
* @param {object} field The field configuration:
* ```
* {
* label: 'Label',
* type: 'number', //typeof field
* validators: {} // see xosForm for more details
* }
* ```
* @param {mixed} ngModel The field value
*
* @example
# Basic Example
<example module="sampleField1">
<file name="script.js">
angular.module('sampleField1', ['xos.uiComponents'])
.factory('_', function($window){
return $window._;
})
.controller('SampleCtrl', function(){
this.name = 'input-name';
this.field = {label: 'My String Value:', type: 'string'};
this.model = 'my string';
});
</file>
<file name="index.html">
<div ng-controller="SampleCtrl as vm">
<xos-field ng-model="vm.model" name="vm.name" field="vm.field"></xos-field>
</div>
</file>
</example>
# Possible Values
<example module="sampleField2">
<file name="script.js">
angular.module('sampleField2', ['xos.uiComponents'])
.factory('_', function($window){
return $window._;
})
.controller('SampleCtrl', function(){
this.field1 = {
name: 'number-field',
field: {label: 'My Number Value:', type: 'number'},
model: 2
};
this.field2 = {
name: 'date-field',
field: {label: 'My Date Value:', type: 'date'},
model: new Date()
};
this.field3 = {
name: 'boolean-field',
field: {label: 'My Boolean Value:', type: 'boolean'},
model: true
};
this.field4 = {
name: 'email-field',
field: {label: 'My Email Value:', type: 'email'},
model: 'sample@domain.us'
};
this.field5 = {
name: 'select',
field: {
label: 'Select field:',
type: 'select',
options: [
{id: 1, label: 'One'},
{id: 2, label: 'Two'},
{id: 3, label: 'Three'},
]
},
model: 1
};
this.arrayField = {
name: 'array',
field: {
label: 'Array field:',
type: 'array',
options: ['one', 'two', 'three', 'four']
},
model: ['one', 'two'],
};
});
</file>
<file name="index.html">
<div ng-controller="SampleCtrl as vm">
<xos-field ng-model="vm.field1.model" name="vm.field1.name" field="vm.field1.field"></xos-field>
<xos-field ng-model="vm.field2.model" name="vm.field2.name" field="vm.field2.field"></xos-field>
<xos-field ng-model="vm.field3.model" name="vm.field3.name" field="vm.field3.field"></xos-field>
<xos-field ng-model="vm.field4.model" name="vm.field4.name" field="vm.field4.field"></xos-field>
<xos-field ng-model="vm.field5.model" name="vm.field5.name" field="vm.field5.field"></xos-field>
<xos-field ng-model="vm.arrayField.model" name="vm.arrayField.name" field="vm.arrayField.field"></xos-field>
</div>
</file>
</example>
# This element is recursive
<example module="sampleField3">
<file name="script.js">
angular.module('sampleField3', ['xos.uiComponents'])
.factory('_', function($window){
return $window._;
})
.controller('SampleCtrl', function(){
this.name1 = 'input-name';
this.field1 = {label: 'My Object Field:', type: 'object'};
this.model1 = {
name: 'Jhon',
age: '25',
email: 'jhon@thewall.ru',
active: true
};
this.name2 = 'another-name';
this.field2 = {
label: 'Empty Object Field',
type: 'object',
properties: {
foo: {
label: 'FooLabel:',
type: 'string',
validators: {
required: true
}
},
bar: {
type: 'number'
}
}
}
});
</file>
<file name="index.html">
<div ng-controller="SampleCtrl as vm">
<h4>Autogenerated object field</h4>
<xos-field ng-model="vm.model1" name="vm.name1" field="vm.field1"></xos-field>
<h4>Configured object field</h4>
<xos-field ng-model="vm.model2" name="vm.name2" field="vm.field2"></xos-field>
</div>
</file>
</example>
*/
.component('xosField', {
restrict: 'E',
bindings: {
name: '=',
field: '=',
ngModel: '='
},
template: '\n <label ng-if="vm.field.type !== \'object\' && vm.field.type !== \'array\'">{{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\' && vm.field.type !== \'array\'"\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 <div\n class="panel panel-default array-field"\n ng-if="vm.field.type == \'array\'">\n <div class="panel-heading">{{vm.field.label}}</div>\n <div class="panel-body selected">\n <ul class="draggable" dnd-list="vm.ngModel">\n <li\n class="array-element"\n ng-repeat="item in vm.ngModel"\n dnd-draggable="item"\n dnd-moved="vm.ngModel.splice($index, 1)"\n dnd-effect-allowed="move"\n dnd-selected="models.selected = item"\n >\n <div class="well well-sm text-center">\n {{item}}\n </div>\n </li>\n <div class="clearfix"></div>\n </ul>\n </div>\n <div class="panel-body unselected">\n <ul class="draggable" dnd-list="vm.field.availableOptions">\n <li\n class="array-element"\n ng-repeat="item in vm.field.availableOptions"\n dnd-draggable="item"\n dnd-moved="vm.field.availableOptions.splice($index, 1)"\n dnd-effect-allowed="move"\n dnd-selected="models.selected = item"\n >\n <div class="well well-sm text-center">\n {{item}}\n </div>\n </li>\n <div class="clearfix"></div>\n </ul>\n </div>\n </div>\n ',
bindToController: true,
controllerAs: 'vm',
controller: ["$attrs", "$scope", "XosFormHelpers", "LabelFormatter", "_", function controller($attrs, $scope, XosFormHelpers, LabelFormatter, _) {
var _this = this;
if (!this.name) {
throw new Error('[xosField] Please provide a field name');
}
if (!this.field) {
throw new Error('[xosField] Please provide a field definition');
}
if (!this.field.type) {
throw new Error('[xosField] Please provide a type in the field definition');
}
if (!$attrs.ngModel) {
throw new Error('[xosField] Please provide an ng-model');
}
this.getType = XosFormHelpers._getFieldFormat;
this.formatLabel = LabelFormatter.format;
this.isEmptyObject = function (o) {
return o ? Object.keys(o).length === 0 : true;
};
if (this.field.type === 'array') {
$scope.$watch(function () {
return _this.ngModel.length;
}, function () {
_this.field.availableOptions = _.difference(_this.field.options, _this.ngModel);
});
}
}]
})
/**
* @ngdoc directive
* @name xos.uiComponents.directive:xosCustomValidator
* @restrict A
* @description The xosCustomValidator directive.
* This component apply a custom validation function
* @param {function} customValidator The function that execute the validation.
*
* You should do your validation here and return true | false,
* or alternatively you can return an array [errorName, true|false]
*/
.directive('xosCustomValidator', function () {
return {
restrict: 'A',
scope: {
fn: '=customValidator'
},
require: 'ngModel',
link: function link(scope, element, attr, ctrl) {
if (!angular.isFunction(scope.fn)) {
return;
}
function customValidatorWrapper(ngModelValue) {
var valid = scope.fn(ngModelValue);
if (angular.isArray(valid)) {
// ES6 spread rocks over fn.apply()
ctrl.$setValidity.apply(ctrl, _toConsumableArray(valid));
} else {
ctrl.$setValidity('custom', valid);
}
return ngModelValue;
}
ctrl.$parsers.push(customValidatorWrapper);
}
};
});
})();
'use strict';
/**
* © OpenCORD
*
* Visit http://guide.xosproject.org/devguide/addview/ for more information
*
* Created by teone on 4/15/16.
*/
(function () {
'use strict';
angular.module('xos.uiComponents')
/**
* @ngdoc directive
* @name xos.uiComponents.directive:xosAlert
* @restrict E
* @description The xos-alert directive
* @param {Object} config The configuration object
* ```
* {
* type: 'danger', //info, success, warning
* closeBtn: true, //default false
* autoHide: 3000 //delay to automatically hide the alert
* }
* ```
* @param {Boolean=} show Binding to show and hide the alert, default to true
* @element ANY
* @scope
* @example
<example module="sampleAlert1">
<file name="index.html">
<div ng-controller="SampleCtrl1 as vm">
<xos-alert config="vm.config1">
A sample alert message
</xos-alert>
<xos-alert config="vm.config2">
A sample alert message (with close button)
</xos-alert>
<xos-alert config="vm.config3">
A sample info message
</xos-alert>
<xos-alert config="vm.config4">
A sample success message
</xos-alert>
<xos-alert config="vm.config5">
A sample warning message
</xos-alert>
</div>
</file>
<file name="script.js">
angular.module('sampleAlert1', ['xos.uiComponents'])
.controller('SampleCtrl1', function(){
this.config1 = {
type: 'danger'
};
this.config2 = {
type: 'danger',
closeBtn: true
};
this.config3 = {
type: 'info'
};
this.config4 = {
type: 'success'
};
this.config5 = {
type: 'warning'
};
});
</file>
</example>
<example module="sampleAlert2" animations="true">
<file name="index.html">
<div ng-controller="SampleCtrl as vm" class="row">
<div class="col-sm-4">
<a class="btn btn-default btn-block" ng-show="!vm.show" ng-click="vm.show = true">Show Alert</a>
<a class="btn btn-default btn-block" ng-show="vm.show" ng-click="vm.show = false">Hide Alert</a>
</div>
<div class="col-sm-8">
<xos-alert config="vm.config1" show="vm.show">
A sample alert message, not displayed by default.
</xos-alert>
</div>
</div>
</file>
<file name="script.js">
angular.module('sampleAlert2', ['xos.uiComponents', 'ngAnimate'])
.controller('SampleCtrl', function(){
this.config1 = {
type: 'success'
};
this.show = false;
});
</file>
</example>
**/
.component('xosAlert', {
restrict: 'E',
bindings: {
config: '=',
show: '=?'
},
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 ',
transclude: true,
bindToController: true,
controllerAs: 'vm',
controller: ["$timeout", function controller($timeout) {
var _this = this;
if (!this.config) {
throw new Error('[xosAlert] Please provide a configuration via the "config" attribute');
}
// default the value to true
this.show = this.show !== false;
this.dismiss = function () {
_this.show = false;
};
if (this.config.autoHide) {
(function () {
var to = $timeout(function () {
_this.dismiss();
$timeout.cancel(to);
}, _this.config.autoHide);
})();
}
}]
});
})();
'use strict';
(function () {
'use strict';
/**
* @ngdoc service
* @name xos.uiComponents.LabelFormatter
* @description This factory define a set of helper function to format label started from an object property
**/
angular.module('xos.uiComponents').factory('LabelFormatter', labelFormatter);
function labelFormatter() {
/**
* @ngdoc method
* @name xos.uiComponents.LabelFormatter#_formatByUnderscore
* @methodOf xos.uiComponents.LabelFormatter
* @description
* Convert a `snake_case` string to readable string.<br/>
* Eg: `this_string` will became `this string`
* @param {string} string The string to be converted
* @returns {string} The converten string
**/
var _formatByUnderscore = function _formatByUnderscore(string) {
return string.split('_').join(' ').trim();
};
/**
* @ngdoc method
* @name xos.uiComponents.LabelFormatter#_formatByUppercase
* @methodOf xos.uiComponents.LabelFormatter
* @description
* Convert a `camelCase` string to readable string.<br/>
* Eg: `thisString` will became `this string`
* @param {string} string The string to be converted
* @returns {string} The converten string
**/
var _formatByUppercase = function _formatByUppercase(string) {
return string.split(/(?=[A-Z])/).map(function (w) {
return w.toLowerCase();
}).join(' ');
};
/**
* @ngdoc method
* @name xos.uiComponents.LabelFormatter#_capitalize
* @methodOf xos.uiComponents.LabelFormatter
* @description
* Capitalize the first letter of a string.<br/>
* Eg: `this string` will became `This string`
* @param {string} string The string to be converted
* @returns {string} The converten string
**/
var _capitalize = function _capitalize(string) {
return string.slice(0, 1).toUpperCase() + string.slice(1);
};
/**
* @ngdoc method
* @name xos.uiComponents.LabelFormatter#format
* @methodOf xos.uiComponents.LabelFormatter
* @description
* Apply in order:
* - _formatByUnderscore
* - _formatByUppercase
* - _capitalize
* - replace multiple space with a single one
* - append `:` at the end
* <br/>
* Eg: `this_string` will became `This string:`<br/>
* Eg: `thisString` will became `This string:`
* @param {string} string The string to be converted
* @returns {string} The converten string
**/
var format = function format(string) {
string = _formatByUnderscore(string);
string = _formatByUppercase(string);
string = _capitalize(string).replace(/\s\s+/g, ' ') + ':';
return string.replace('::', ':');
};
return {
// test export
_formatByUnderscore: _formatByUnderscore,
_formatByUppercase: _formatByUppercase,
_capitalize: _capitalize,
// export to use
format: format
};
}
})();
'use strict';
var _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; };
(function () {
angular.module('xos.uiComponents')
/**
* @ngdoc service
* @name xos.uiComponents.XosFormHelpers
* @requires xos.uiComponents.LabelFormatter
* @requires xos.helpers._
**/
.service('XosFormHelpers', ["_", "LabelFormatter", function (_, LabelFormatter) {
var _this = this;
/**
* @ngdoc method
* @name xos.uiComponents.XosFormHelpers#_isEmail
* @methodOf xos.uiComponents.XosFormHelpers
* @description
* Return true if the string is an email address
* @param {string} text The string to be evaluated
* @returns {boolean} If the string match an email format
**/
this._isEmail = function (text) {
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,}))/;
return re.test(text);
};
/**
* @ngdoc method
* @name xos.uiComponents.XosFormHelpers#_getFieldFormat
* @methodOf xos.uiComponents.XosFormHelpers
* @description
* Return the type of the input
* @param {mixed} value The data to be evaluated
* @returns {string} The type of the input
**/
this._getFieldFormat = function (value) {
if (angular.isArray(value)) {
return 'array';
}
// check if is date
if (angular.isDate(value) || !Number.isNaN(Date.parse(value)) && // Date.parse is a number
/^\d+-\d+-\d+\D\d+:\d+:\d+\.\d+\D/.test(value) // the format match ISO dates
) {
return 'date';
}
// check if is boolean
// isNaN(false) = false, false is a number (0), true is a number (1)
if (typeof value === 'boolean') {
return 'boolean';
}
// check if a string is an email
if (_this._isEmail(value)) {
return 'email';
}
// if null return string
if (angular.isString(value) || value === null) {
return 'text';
}
return typeof value === 'undefined' ? 'undefined' : _typeof(value);
};
/**
* @ngdoc method
* @name xos.uiComponents.XosFormHelpers#buildFormStructure
* @methodOf xos.uiComponents.XosFormHelpers
* @description
* Return the type of the input
* @param {object} modelField An object containing one property for each field of the model
* @param {object} customField An object containing one property for each field custom field
* @param {object} model The actual model on wich build the form structure (it is used to determine the type of the input)
* @returns {object} An object describing the form structure in the form of:
* ```
* {
* 'field-name': {
* label: 'Label',
* type: 'number', //typeof field
* validators: {}, // see xosForm for more details
* hint: 'A Custom hint for the field'
* }
* }
* ```
**/
this.buildFormStructure = function (modelField, customField, model, order) {
var orderedForm = {};
modelField = angular.extend(modelField, customField);
customField = customField || {};
if (order) {
_.each(order, function (key) {
orderedForm[key] = {};
});
}
_.each(Object.keys(modelField), function (f) {
orderedForm[f] = {
label: customField[f] && customField[f].label ? customField[f].label + ':' : LabelFormatter.format(f),
type: customField[f] && customField[f].type ? customField[f].type : _this._getFieldFormat(model[f]),
validators: customField[f] && customField[f].validators ? customField[f].validators : {},
hint: customField[f] && customField[f].hint ? customField[f].hint : ''
};
if (customField[f] && customField[f].options) {
orderedForm[f].options = customField[f].options;
}
if (customField[f] && customField[f].properties) {
orderedForm[f].properties = customField[f].properties;
}
if (orderedForm[f].type === 'date') {
model[f] = new Date(model[f]);
}
if (orderedForm[f].type === 'number') {
model[f] = parseInt(model[f], 10);
}
});
return orderedForm;
};
/**
* @ngdoc method
* @name xos.uiComponents.XosFormHelpers#parseModelField
* @methodOf xos.uiComponents.XosFormHelpers
* @description
* Helpers for buildFormStructure, convert a list of model properties in an object used to build the form structure, eg:
* ```
* // input:
* ['id', 'name'm 'mail']
*
* // output
* {
* id: {},
* name: {},
* mail: {}
* }
* ```
* @param {array} fields An array of fields representing the model properties
* @returns {object} An object containing one property for each field of the model
**/
this.parseModelField = function (fields) {
return _.reduce(fields, function (form, f) {
form[f] = {};
return form;
}, {});
};
}]);
})();
'use strict';
(function () {
'use strict';
/**
* @ngdoc service
* @name xos.uiComponents.Comparator
* @description
* This factory define a function that replace the native angular.filter comparator.
*
* It is done to allow the comparation between (0|1) values with booleans.
* >Note that this factory return a single function, not an object.
*
* The tipical usage of this factory is inside an `ng-repeat`
* @example
* <example module="comparator">
* <file name="index.html">
* <div ng-controller="sample as vm">
* <div class="row">
* <div class="col-xs-6">
* <label>Filter by name:</label>
* <input class="form-control" type="text" ng-model="vm.query.name"/>
* </div>
* <div class="col-xs-6">
* <label>Filter by status:</label>
* <select
* ng-model="vm.query.status"
* ng-options="i for i in [true, false]">
* </select>
* </div>
* </div>
* <div ng-repeat="item in vm.data | filter:vm.query:vm.comparator">
* <div class="row">
* <div class="col-xs-6">{{item.name}}</div>
* <div class="col-xs-6">{{item.status}}</div>
* </div>
* </div>
* </div>
* </file>
* <file name="script.js">
* angular.module('comparator', ['xos.uiComponents'])
* .controller('sample', function(Comparator){
* this.comparator = Comparator;
* this.data = [
* {name: 'Jhon', status: 1},
* {name: 'Jack', status: 0},
* {name: 'Mike', status: 1},
* {name: 'Scott', status: 0}
* ];
* });
* </file>
* </example>
**/
comparator.$inject = ["_"];
angular.module('xos.uiComponents').factory('Comparator', comparator);
function comparator(_) {
return function (actual, expected) {
if (angular.isUndefined(actual)) {
// No substring matching against `undefined`
return false;
}
if (actual === null || expected === null) {
// No substring matching against `null`; only match against `null`
return actual === expected;
}
if (angular.isObject(expected) || angular.isObject(actual)) {
return angular.equals(expected, actual);
}
if (_.isBoolean(actual) || _.isBoolean(expected)) {
if (actual === 0 || actual === 1) {
actual = !!actual;
}
return angular.equals(expected, actual);
}
if (!angular.isString(actual) || !angular.isString(expected)) {
if (angular.isDefined(actual.toString) && angular.isDefined(expected.toString)) {
actual = actual.toString();
expected = expected.toString();
} else {
return actual === expected;
}
}
actual = actual.toLowerCase() + '';
expected = expected.toLowerCase() + '';
return actual.indexOf(expected) !== -1;
};
}
})();
'use strict';
(function () {
'use strict';
/**
* @ngdoc overview
* @name xos.helpers
* @description
* # xos.Helpers
* A collection of helpers to work with XOS <br/>
* Currently available components are:
* - [NoHyperlinks](/#/module/xos.helpers.NoHyperlinks)
* - [SetCSRFToken](/#/module/xos.helpers.SetCSRFToken)
* - [xosNotification](/#/module/xos.helpers.xosNotification)
* - [XosUserPrefs](/#/module/xos.helpers.XosUserPrefs)
* <br/><br/>
* A set of angular [$resource](https://docs.angularjs.org/api/ngResource/service/$resource) is provided to work with the API.<br>
* You can find the documentation [here](#/rest-api)
**/
config.$inject = ["$httpProvider", "$interpolateProvider", "$resourceProvider"];
angular.module('xos.helpers', ['ngCookies', 'ngResource', 'ngAnimate', 'xos.uiComponents']).config(config)
/**
* @ngdoc service
* @name xos.helpers._
* @description Wrap [lodash](https://lodash.com/docs) in an Angular Service
**/
.factory('_', ["$window", function ($window) {
return $window._;
}]);
function config($httpProvider, $interpolateProvider, $resourceProvider) {
$httpProvider.interceptors.push('SetCSRFToken');
// NOTE http://www.masnun.com/2013/09/18/django-rest-framework-angularjs-resource-trailing-slash-problem.html
$resourceProvider.defaults.stripTrailingSlashes = false;
}
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.vSG-Collection
* @description Angular resource to fetch /api/service/vsg/
**/
.service('vSG-Collection', ["$resource", function ($resource) {
return $resource('/api/service/vsg/');
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.vOLT-Collection
* @description Angular resource to fetch /api/tenant/cord/volt/:volt_id/
**/
.service('vOLT-Collection', ["$resource", function ($resource) {
return $resource('/api/tenant/cord/volt/:volt_id/', { volt_id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Login
* @description Angular resource to fetch /api/utility/login/
**/
.service('Login', ["$resource", function ($resource) {
return $resource('/api/utility/login/');
}])
/**
* @ngdoc service
* @name xos.helpers.Logout
* @description Angular resource to fetch /api/utility/logout/
**/
.service('Logout', ["$resource", function ($resource) {
return $resource('/api/utility/logout/');
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Users
* @description Angular resource to fetch /api/core/users/:id/
**/
.service('Users', ["$resource", function ($resource) {
return $resource('/api/core/users/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Truckroll
* @description Angular resource to fetch /api/tenant/truckroll/:id/
**/
.service('Truckroll', ["$resource", function ($resource) {
return $resource('/api/tenant/truckroll/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Tenant
* @description Angular resource to fetch /api/core/tenant/:id/
**/
.service('Tenants', ["$resource", function ($resource) {
return $resource('/api/core/tenants/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Subscribers
* @description Angular resource to fetch Subscribers
**/
.service('Subscribers', ["$resource", function ($resource) {
return $resource('/api/tenant/cord/subscriber/:id/', { id: '@id' }, {
update: { method: 'PUT' },
/**
* @ngdoc method
* @name xos.helpers.Subscribers#View-a-Subscriber-Features-Detail
* @methodOf xos.helpers.Subscribers
* @description
* View-a-Subscriber-Features-Detail
**/
'View-a-Subscriber-Features-Detail': {
method: 'GET',
isArray: false,
url: '/api/tenant/cord/subscriber/:id/features/'
},
/**
* @ngdoc method
* @name xos.helpers.Subscribers#Read-Subscriber-uplink_speed
* @methodOf xos.helpers.Subscribers
* @description
* Read-Subscriber-uplink_speed
**/
'Read-Subscriber-uplink_speed': {
method: 'GET',
isArray: false,
url: '/api/tenant/cord/subscriber/:id/features/uplink_speed/'
},
/**
* @ngdoc method
* @name xos.helpers.Subscribers#Update-Subscriber-uplink_speed
* @methodOf xos.helpers.Subscribers
* @description
* Update-Subscriber-uplink_speed
**/
'Update-Subscriber-uplink_speed': {
method: 'PUT',
isArray: false,
url: '/api/tenant/cord/subscriber/:id/features/uplink_speed/'
},
/**
* @ngdoc method
* @name xos.helpers.Subscribers#Read-Subscriber-downlink_speed
* @methodOf xos.helpers.Subscribers
* @description
* Read-Subscriber-downlink_speed
**/
'Read-Subscriber-downlink_speed': {
method: 'GET',
isArray: false,
url: '/api/tenant/cord/subscriber/:id/features/downlink_speed/'
},
/**
* @ngdoc method
* @name xos.helpers.Subscribers#Update-Subscriber-downlink_speed
* @methodOf xos.helpers.Subscribers
* @description
* Update-Subscriber-downlink_speed
**/
'Update-Subscriber-downlink_speed': {
method: 'PUT',
isArray: false,
url: '/api/tenant/cord/subscriber/:id/features/downlink_speed/'
},
/**
* @ngdoc method
* @name xos.helpers.Subscribers#Read-Subscriber-cdn
* @methodOf xos.helpers.Subscribers
* @description
* Read-Subscriber-cdn
**/
'Read-Subscriber-cdn': {
method: 'GET',
isArray: false,
url: '/api/tenant/cord/subscriber/:id/features/cdn/'
},
/**
* @ngdoc method
* @name xos.helpers.Subscribers#Update-Subscriber-cdn
* @methodOf xos.helpers.Subscribers
* @description
* Update-Subscriber-cdn
**/
'Update-Subscriber-cdn': {
method: 'PUT',
isArray: false,
url: '/api/tenant/cord/subscriber/:id/features/cdn/'
},
/**
* @ngdoc method
* @name xos.helpers.Subscribers#Read-Subscriber-uverse
* @methodOf xos.helpers.Subscribers
* @description
* Read-Subscriber-uverse
**/
'Read-Subscriber-uverse': {
method: 'GET',
isArray: false,
url: '/api/tenant/cord/subscriber/:id/features/uverse/'
},
/**
* @ngdoc method
* @name xos.helpers.Subscribers#Update-Subscriber-uverse
* @methodOf xos.helpers.Subscribers
* @description
* Update-Subscriber-uverse
**/
'Update-Subscriber-uverse': {
method: 'PUT',
isArray: false,
url: '/api/tenant/cord/subscriber/:id/features/uverse/'
},
/**
* @ngdoc method
* @name xos.helpers.Subscribers#Read-Subscriber-status
* @methodOf xos.helpers.Subscribers
* @description
* Read-Subscriber-status
**/
'Read-Subscriber-status': {
method: 'GET',
isArray: false,
url: '/api/tenant/cord/subscriber/:id/features/status/'
},
/**
* @ngdoc method
* @name xos.helpers.Subscribers#Update-Subscriber-status
* @methodOf xos.helpers.Subscribers
* @description
* Update-Subscriber-status
**/
'Update-Subscriber-status': {
method: 'PUT',
isArray: false,
url: '/api/tenant/cord/subscriber/:id/features/status/'
}
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.SlicesPlus
* @description Angular resource to fetch /api/utility/slicesplus/
* This is a read-only API and only the `query` method is currently supported.
**/
.service('SlicesPlus', ["$http", "$q", function ($http, $q) {
this.query = function (params) {
var deferred = $q.defer();
$http.get('/api/utility/slicesplus/', { params: params }).then(function (res) {
deferred.resolve(res.data);
}).catch(function (res) {
deferred.reject(res.data);
});
return { $promise: deferred.promise };
};
this.get = function (id, params) {
var deferred = $q.defer();
$http.get('/api/utility/slicesplus/' + id, { params: params }).then(function (res) {
deferred.resolve(res.data);
}).catch(function (res) {
deferred.reject(res.data);
});
return { $promise: deferred.promise };
};
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Slices
* @description Angular resource to fetch /api/core/slices/:id/
**/
.service('Slices', ["$resource", function ($resource) {
return $resource('/api/core/slices/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Sites
* @description Angular resource to fetch /api/core/sites/:id/
**/
.service('Sites', ["$resource", function ($resource) {
return $resource('/api/core/sites/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Services
* @description Angular resource to fetch /api/core/services/:id/
**/
.service('Services', ["$resource", function ($resource) {
return $resource('/api/core/services/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.ONOS-Services-Collection
* @description Angular resource to fetch /api/service/onos/
**/
.service('ONOS-Services-Collection', ["$resource", function ($resource) {
return $resource('/api/service/onos/');
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.ONOS-App-Collection
* @description Angular resource to fetch /api/tenant/onos/app/
**/
.service('ONOS-App-Collection', ["$resource", function ($resource) {
return $resource('/api/tenant/onos/app/');
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Nodes
* @description Angular resource to fetch /api/core/nodes/:id/
**/
.service('Nodes', ["$resource", function ($resource) {
return $resource('/api/core/nodes/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Networkstemplates
* @description Angular resource to fetch /api/core/networktemplates/:id/
**/
.service('Networkstemplates', ["$resource", function ($resource) {
return $resource('/api/core/networktemplates/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Networks
* @description Angular resource to fetch /api/core/networks/:id/
**/
.service('Networks', ["$resource", function ($resource) {
return $resource('/api/core/networks/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Me
* @description Http read-only api to fetch /api/utility/me/
**/
.service('Me', ["$q", "$http", function ($q, $http) {
this.get = function () {
var deferred = $q.defer();
$http.get('/api/utility/me/').then(function (res) {
deferred.resolve(res.data);
}).catch(function (e) {
deferred.reject(e);
});
return deferred.promise;
};
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Instances
* @description Angular resource to fetch /api/core/instances/:id/
**/
.service('Instances', ["$resource", function ($resource) {
return $resource('/api/core/instances/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Images
* @description Angular resource to fetch /api/core/images/
**/
.service('Images', ["$resource", function ($resource) {
return $resource('/api/core/images/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Flavors
* @description Angular resource to fetch /api/core/flavors/:id/
**/
.service('Flavors', ["$resource", function ($resource) {
return $resource('/api/core/flavors/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Example-Services-Collection
* @description Angular resource to fetch /api/service/exampleservice/
**/
.service('Example-Services-Collection', ["$resource", function ($resource) {
return $resource('/api/service/exampleservice/');
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Deployments
* @description Angular resource to fetch /api/core/deployments/:id/
**/
.service('Deployments', ["$resource", function ($resource) {
return $resource('/api/core/deployments/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
}]);
})();
'use strict';
(function () {
'use strict';
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.Dashboards
* @description Angular resource to fetch /api/core/dashboardviews/:id/
**/
.service('Dashboards', ["$resource", "$q", "$http", function ($resource, $q, $http) {
var r = $resource('/api/core/dashboardviews/:id/', { id: '@id' }, {
update: { method: 'PUT' }
});
r.prototype.$save = function () {
var d = $q.defer();
$http.put('/api/core/dashboardviews/' + this.id + '/', this).then(function (res) {
d.resolve(res.data);
}).catch(function (e) {
d.reject(e.data);
});
return d.promise;
};
return r;
}]);
})();
'use strict';
(function () {
angular.module('xos.helpers')
/**
* @ngdoc service
* @name xos.helpers.XosUserPrefs
* @description
* This service is used to store the user preferences in cookies, so that they survive to page changes.
* The structure of the user preference is:
* ```
* {
* synchronizers: {
* notification: {
* 'volt': boolean,
* 'openstack': boolean,
* ...
* }
* }
* userData: {
* current_user_site_id: Number,
* current_user_site_user_names: Array[1],
* ...
* }
* }
* ```
**/
.service('XosUserPrefs', ["$cookies", "Me", "$q", function ($cookies, Me, $q) {
var _this = this;
var userPrefs = $cookies.get('xosUserPrefs') ? angular.fromJson($cookies.get('xosUserPrefs')) : {};
/**
* @ngdoc method
* @name xos.helpers.XosUserPrefs#getAll
* @methodOf xos.helpers.XosUserPrefs
* @description
* Return all the user preferences stored in cookies
* @returns {object} The user preferences
**/
this.getAll = function () {
userPrefs = $cookies.get('xosUserPrefs') ? angular.fromJson($cookies.get('xosUserPrefs')) : {};
return userPrefs;
};
/**
* @ngdoc method
* @name xos.helpers.XosUserPrefs#setAll
* @methodOf xos.helpers.XosUserPrefs
* @description
* Override all user preferences
* @param {object} prefs The user preferences
**/
this.setAll = function (prefs) {
$cookies.put('xosUserPrefs', angular.toJson(prefs));
};
/**
* @ngdoc method
* @name xos.helpers.XosUserPrefs#getSynchronizerNotificationStatus
* @methodOf xos.helpers.XosUserPrefs
* @description
* Return the synchronizer notification status, if name is not provided return the status for all synchronizers
* @param {string=} prefs The synchronizer name
* @returns {object | string} The synchronizer status
**/
this.getSynchronizerNotificationStatus = function () {
var name = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0];
if (name) {
return _this.getAll().synchronizers.notification[name];
}
return _this.getAll().synchronizers.notification;
};
/**
* @ngdoc method
* @name xos.helpers.XosUserPrefs#getUserDetailsCookie
* @methodOf xos.helpers.XosUserPrefs
* @description
* Return all the user details stored in cookies or call the service
* @returns {object} The user details
**/
this.getUserDetailsCookie = function () {
var defer = $q.defer();
var localPref = _this.getAll();
if (!localPref.userData) {
_this.setUserDetailsCookie().$promise.then(function (data) {
defer.resolve(data);
});
} else {
defer.resolve(localPref.userData);
}
return { $promise: defer.promise };
};
/**
* @ngdoc method
* @name xos.helpers.XosUserPrefs#setUserDetailsCookie
* @methodOf xos.helpers.XosUserPrefs
* @description
* Save the user details in the cookie
* @param {object} details stored in cookie
* @param {objects} returns the user details as a promise
**/
this.setUserDetailsCookie = function () {
var userData = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
var defer = $q.defer();
var cookies = _this.getAll();
if (!userData) {
Me.get().then(function (user) {
cookies.userData = user;
_this.setAll(cookies);
defer.resolve(user);
}).catch(function (e) {
defer.reject(e);
});
} else {
cookies.userData = userData;
_this.setAll(cookies);
defer.resolve(userData);
}
return { $promise: defer.promise };
};
/**
* @ngdoc method
* @name xos.helpers.XosUserPrefs#setSynchronizerNotificationStatus
* @methodOf xos.helpers.XosUserPrefs
* @description
* Update the notification status for a single synchronizer
* @param {string} name The synchronizer name
* @param {boolean} value The notification status (true means that it has been sent)
**/
this.setSynchronizerNotificationStatus = function () {
var name = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0];
var value = arguments[1];
if (!name) {
throw new Error('[XosUserPrefs] When updating a synchronizer is mandatory to provide a name.');
}
var cookies = _this.getAll();
if (!cookies.synchronizers) {
cookies.synchronizers = {
notification: {}
};
}
cookies.synchronizers.notification[name] = value;
_this.setAll(cookies);
};
}]);
})();
'use strict';
(function () {
'use strict';
/**
* @ngdoc service
* @name xos.helpers.ServiceGraph
* @description This factory define a set of helper function to query the service tenancy graph
**/
angular.module('xos.helpers').service('GraphService', ["$q", "Tenants", "Services", function ($q, Tenants, Services) {
var _this = this;
this.loadCoarseData = function () {
var services = void 0;
var deferred = $q.defer();
Services.query().$promise.then(function (res) {
services = res;
return Tenants.query({ kind: 'coarse' }).$promise;
}).then(function (tenants) {
deferred.resolve({
tenants: tenants,
services: services
});
});
return deferred.promise;
};
this.getCoarseGraph = function () {
_this.loadCoarseData().then(function (res) {
console.log(res);
});
return 'ciao';
};
}]);
})();
'use strict';
/* eslint-disable angular/ng_window_service*/
(function () {
'use strict';
angular.module('xos.helpers').factory('Notification', function () {
return window.Notification;
})
/**
* @ngdoc service
* @name xos.helpers.xosNotification
* @description This factory define a set of helper function to trigger desktop notification
**/
.service('xosNotification', ["$q", "$log", "Notification", function ($q, $log, Notification) {
var _this = this;
this.checkPermission = function () {
var deferred = $q.defer();
Notification.requestPermission().then(function (permission) {
if (permission === 'granted') {
deferred.resolve(permission);
} else {
deferred.reject(permission);
}
});
return deferred.promise;
};
this.sendNotification = function (title, options) {
var notification = new Notification(title, options);
notification.onerror = function (err) {
$log.error(err);
};
};
/**
* @ngdoc method
* @name xos.helpers.xosNotification#notify
* @methodOf xos.helpers.xosNotification
* @description
* This method will check for user permission and if granted will send a browser notification.
* @param {string} title The notification title
* @param {object} options The notification options: `{icon: 'url', body: 'Notification body'}`
**/
this.notify = function (title, options) {
if (!('Notification' in window)) {
$log.info('This browser does not support desktop notification');
} else if (Notification.permission !== 'granted') {
_this.checkPermission().then(function () {
return _this.sendNotification(title, options);
});
} else if (Notification.permission === 'granted') {
_this.sendNotification(title, options);
}
};
}]);
})();
'use strict';
(function () {
'use strict';
/**
* @ngdoc service
* @name xos.helpers.NoHyperlinks
* @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
**/
angular.module('xos.helpers').factory('NoHyperlinks', noHyperlinks);
function noHyperlinks() {
return {
request: function request(_request) {
if (_request.url.indexOf('.html') === -1) {
_request.url += '?no_hyperlinks=1';
}
return _request;
}
};
}
})();
'use strict';
// TODO write tests for log
/* eslint-disable angular/ng_window_service*/
angular.module('xos.helpers').config(['$provide', function ($provide) {
// Use the `decorator` solution to substitute or attach behaviors to
// original service instance; @see angular-mocks for more examples....
$provide.decorator('$log', ['$delegate', function ($delegate) {
var isLogEnabled = function isLogEnabled() {
return window.location.href.indexOf('debug=true') >= 0;
};
// Save the original $log.debug()
var logFn = $delegate.log;
var infoFn = $delegate.info;
var warnFn = $delegate.warn;
//let errorFn = $delegate.error;
var debugFn = $delegate.debug;
// create the replacement function
var replacement = function replacement(fn) {
return function () {
//console.log(`Is Log Enabled: ${isLogEnabled()}`)
if (!isLogEnabled()) {
// console.log('logging is disabled');
return;
}
var args = [].slice.call(arguments);
var now = new Date();
// Prepend timestamp
args[0] = '[' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '] ' + args[0];
// HACK awfull fix for angular mock implementation whithin jasmine test failing issue
if (angular.isFunction($delegate.reset) && !($delegate.debug.logs instanceof Array)) {
// if we are within the mock and did not reset yet, we call it to avoid issue
// console.log('mock log impl fix to avoid logs array not existing...');
$delegate.reset();
}
// Call the original with the output prepended with formatted timestamp
return fn.apply(null, args);
};
};
$delegate.info = replacement(infoFn);
$delegate.log = replacement(logFn);
$delegate.warn = replacement(warnFn);
//$delegate.error = replacement(errorFn); // note this will prevent errors to be printed
$delegate.debug = replacement(debugFn);
return $delegate;
}]);
}]);
'use strict';
(function () {
'use strict';
/**
* @ngdoc service
* @name xos.helpers.SetCSRFToken
* @description This factory is automatically loaded trough xos.helpers and will add an $http interceptor that will the CSRF-Token to your request headers
**/
setCSRFToken.$inject = ["$cookies"];
angular.module('xos.helpers').factory('SetCSRFToken', setCSRFToken);
function setCSRFToken($cookies) {
return {
request: function request(_request) {
if (_request.method !== 'GET') {
_request.headers['X-CSRFToken'] = $cookies.get('xoscsrftoken');
}
return _request;
}
};
}
})();
/**
* @ngdoc overview
* @name ngXosLib
* @id index
* @description
* # Welcome to the ngXosLib documentation! <br/>
* This is the module that group all the helpers service and UI components for XOS.
* <br/><br/>
* You can find all the documentation related to the UI Component Library here: <a href="#/module/xos.uiComponents"> xos.uiComponents</a> <br/>
* and the documentation related to all the other helpers here: <a href="#/module/xos.helpers"> xos.helpers</a> <br/>
* ## Issues
* Please report issues at https://jira.opencord.org
**/
"use strict";