Splitted form component
diff --git a/.gitignore b/.gitignore
index 3c86d00..bf493e8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,4 @@
!xos/core/static/xos.css
.DS_Store
xos/configurations/setup/
+migrations/
diff --git a/views/ngXosLib/gulp/ngXosHelpers.js b/views/ngXosLib/gulp/ngXosHelpers.js
index f29a646..638e665 100644
--- a/views/ngXosLib/gulp/ngXosHelpers.js
+++ b/views/ngXosLib/gulp/ngXosHelpers.js
@@ -85,6 +85,7 @@
module: {
glob: [
options.xosHelperSource + '*.js',
+ options.xosHelperSource + 'services/helpers/**/*.js',
options.xosHelperSource + 'services/*.js',
options.xosHelperSource + 'ui_components/**/*.js'
],
@@ -115,9 +116,7 @@
gulp.task('docs', ['makeDocs', 'serveDocs'], function(){
var files = [
- options.xosHelperSource + '*.js',
- options.xosHelperSource + 'services/*.js',
- options.xosHelperSource + 'ui_components/**/*.js'
+ options.xosHelperSource + '**/*.js'
];
gulp.watch(files, ['makeDocs']);
diff --git a/views/ngXosLib/karma.conf.js b/views/ngXosLib/karma.conf.js
index 9d880a0..18c6f6f 100644
--- a/views/ngXosLib/karma.conf.js
+++ b/views/ngXosLib/karma.conf.js
@@ -94,7 +94,7 @@
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: [
'PhantomJS',
- // 'Chrome'
+ 'Chrome'
],
diff --git a/views/ngXosLib/xosHelpers/spec/ui/field.test.js b/views/ngXosLib/xosHelpers/spec/ui/field.test.js
new file mode 100644
index 0000000..9e7a7f2
--- /dev/null
+++ b/views/ngXosLib/xosHelpers/spec/ui/field.test.js
@@ -0,0 +1,80 @@
+/**
+ * © OpenCORD
+ *
+ * Created by teone on 5/25/16.
+ */
+
+(function () {
+ 'use strict';
+
+ let element, scope, isolatedScope, rootScope, compile;
+ const compileElement = () => {
+
+ if(!scope){
+ scope = rootScope.$new();
+ }
+
+ element = angular.element('<xos-field name="name" field="field" ng-model="ngModel"></xos-field>');
+ compile(element)(scope);
+ scope.$digest();
+ isolatedScope = element.isolateScope().vm;
+ }
+
+ describe('The xos.helper module', function(){
+
+ describe('The xosField component', () => {
+
+ beforeEach(module('xos.helpers'));
+
+ beforeEach(inject(function ($compile, $rootScope) {
+ compile = $compile;
+ rootScope = $rootScope;
+ }));
+
+ it('should throw an error if no name is passed', inject(($compile, $rootScope) => {
+ function errorFunctionWrapper(){
+ // setup the parent scope
+ scope = $rootScope.$new();
+ scope.field = {
+ label: 'Label',
+ type: 'number',
+ validators: {}
+ };
+ scope.ngModel = {
+ label: 1
+ };
+ compileElement();
+ }
+ expect(errorFunctionWrapper).toThrow(new Error('[xosField] Please provide a field name'));
+ }));
+
+ it('should throw an error if no field definition is passed', inject(($compile, $rootScope) => {
+ function errorFunctionWrapper(){
+ // setup the parent scope
+ scope = $rootScope.$new();
+ scope.name = 'label';
+ scope.ngModel = {
+ label: 1
+ };
+ compileElement();
+ }
+ expect(errorFunctionWrapper).toThrow(new Error('[xosField] Please provide a field definition'));
+ }));
+
+ it('should throw an error if no field model is passed', inject(($compile, $rootScope) => {
+ function errorFunctionWrapper(){
+ // setup the parent scope
+ scope = $rootScope.$new();
+ scope.name = 'label';
+ scope.field = {
+ label: 'Label',
+ type: 'number',
+ validators: {}
+ };
+ compileElement();
+ }
+ expect(errorFunctionWrapper).toThrow(new Error('[xosField] Please provide an ng-model'));
+ }));
+ });
+ });
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/spec/ui/form.test.js b/views/ngXosLib/xosHelpers/spec/ui/form.test.js
index 226a62a..7673fc8 100644
--- a/views/ngXosLib/xosHelpers/spec/ui/form.test.js
+++ b/views/ngXosLib/xosHelpers/spec/ui/form.test.js
@@ -9,6 +9,7 @@
describe('The xos.helper module', function(){
+ // TODO move in separate file
describe('The XosFormHelper service', () => {
let service;
@@ -122,6 +123,16 @@
expect(service._getFieldFormat(new Date())).toEqual('date');
expect(service._getFieldFormat('2016-04-19T23:09:10.208092Z')).toEqual('date');
});
+
+ it('should return array', () => {
+ expect(service._getFieldFormat([])).toEqual('array');
+ expect(service._getFieldFormat(['a', 'b'])).toEqual('array');
+ });
+
+ it('should return object', () => {
+ expect(service._getFieldFormat({})).toEqual('object');
+ expect(service._getFieldFormat({foo: 'bar'})).toEqual('object');
+ });
});
it('should convert the fields array in an empty form object', () => {
@@ -274,10 +285,11 @@
enabled: true,
role: 'user', //select
a_permissions: [
-
],
- o_permissions: {
-
+ object_field: {
+ string: 'bar',
+ number: 1,
+ email: 'teo@onlab.us'
}
};
@@ -292,14 +304,15 @@
expect(isolatedScope.excludedField).toEqual(expected);
});
- it('should render 8 input field', () => {
+ xit('should render 8 input field', () => {
// boolean are in the form model, but are not input
expect(Object.keys(isolatedScope.formField).length).toEqual(9);
var field = element[0].getElementsByTagName('input');
- expect(field.length).toEqual(8);
+ expect(field.length).toEqual(10);
});
it('should render 1 boolean field', () => {
+ // console.log($(element).find('.boolean-field'));
expect($(element).find('.boolean-field > button').length).toEqual(2)
});
@@ -336,7 +349,7 @@
expect(isolatedScope.ngModel.enabled).toEqual(false);
});
- it('should change value to false', () => {
+ it('should change value to true', () => {
isolatedScope.ngModel.enabled = false;
scope.$apply();
expect(isolatedScope.ngModel.enabled).toEqual(false);
@@ -397,6 +410,10 @@
expect(isolatedScope.testForm.age.$error.min).toBeTruthy();
});
});
+
+ describe('the object field', () => {
+
+ });
});
});
});
diff --git a/views/ngXosLib/xosHelpers/src/services/helpers/ui/form.helpers.js b/views/ngXosLib/xosHelpers/src/services/helpers/ui/form.helpers.js
new file mode 100644
index 0000000..ce52272
--- /dev/null
+++ b/views/ngXosLib/xosHelpers/src/services/helpers/ui/form.helpers.js
@@ -0,0 +1,149 @@
+(function () {
+
+ angular.module('xos.uiComponents')
+
+ /**
+ * @ngdoc service
+ * @name xos.uiComponents.XosFormHelpers
+ * @requires xos.uiComponents.LabelFormatter
+ * @requires xos.helpers._
+ **/
+
+ .service('XosFormHelpers', function(_, LabelFormatter){
+
+ /**
+ * @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 = (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 = (value) => {
+
+ if(angular.isArray(value)){
+ return 'array';
+ }
+
+ // check if is date
+ if (_.isDate(value) || (!Number.isNaN(Date.parse(value)) && new Date(value).getTime() > 631180800000)){
+ 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 a number
+ if(!isNaN(value) && value !== null){
+ return 'number';
+ }
+
+ // check if a string is an email
+ if(this._isEmail(value)){
+ return 'email';
+ }
+
+ // if null return string
+ if(value === null){
+ return 'string';
+ }
+
+ return 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
+ * }
+ * }
+ * ```
+ **/
+
+ this.buildFormStructure = (modelField, customField, model) => {
+
+ modelField = Object.keys(modelField).length > 0 ? modelField : customField; //if no model field are provided, check custom
+ customField = customField || {};
+
+ return _.reduce(Object.keys(modelField), (form, f) => {
+
+ form[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 : {}
+ };
+
+ if(form[f].type === 'date'){
+ model[f] = new Date(model[f]);
+ }
+
+ if(form[f].type === 'number'){
+ model[f] = parseInt(model[f], 10);
+ }
+
+ return form;
+ }, {});
+ };
+
+ /**
+ * @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 = (fields) => {
+ return _.reduce(fields, (form, f) => {
+ form[f] = {};
+ return form;
+ }, {});
+ }
+
+ });
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/label_formatter.service.js b/views/ngXosLib/xosHelpers/src/services/helpers/ui/label_formatter.service.js
similarity index 95%
rename from views/ngXosLib/xosHelpers/src/services/label_formatter.service.js
rename to views/ngXosLib/xosHelpers/src/services/helpers/ui/label_formatter.service.js
index 3b63ecd..bb1d279 100644
--- a/views/ngXosLib/xosHelpers/src/services/label_formatter.service.js
+++ b/views/ngXosLib/xosHelpers/src/services/helpers/ui/label_formatter.service.js
@@ -3,7 +3,7 @@
/**
* @ngdoc service
- * @name xos.helpers.LabelFormatter
+ * @name xos.uiComponents.LabelFormatter
* @description This factory define a set of helper function to format label started from an object property
**/
diff --git a/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/field/field.component.js b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/field/field.component.js
new file mode 100644
index 0000000..923def6
--- /dev/null
+++ b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/field/field.component.js
@@ -0,0 +1,89 @@
+/**
+ * © 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
+ */
+ .directive('xosField', function(){
+ return {
+ restrict: 'E',
+ scope: {
+ name: '=',
+ field: '=',
+ ngModel: '='
+ },
+ template: `
+ <label>{{vm.field.label}}</label>
+ <input
+ ng-if="vm.field.type !== 'boolean' && vm.field.type !== 'object'"
+ type="{{vm.field.type}}"
+ name="{{vm.name}}"
+ class="form-control"
+ ng-model="vm.ngModel"
+ ng-minlength="vm.field.validators.minlength || 0"
+ ng-maxlength="vm.field.validators.maxlength || 2000"
+ ng-required="vm.field.validators.required || false" />
+ <span class="boolean-field" ng-if="vm.field.type === 'boolean'">
+ <button
+ class="btn btn-success"
+ ng-show="vm.ngModel"
+ ng-click="vm.ngModel = false">
+ <i class="glyphicon glyphicon-ok"></i>
+ </button>
+ <button
+ class="btn btn-danger"
+ ng-show="!vm.ngModel"
+ ng-click="vm.ngModel = true">
+ <i class="glyphicon glyphicon-remove"></i>
+ </button>
+ </span>
+ <div
+ class="panel panel-default object-field"
+ ng-if="vm.field.type == 'object' "
+ >
+ <div class="panel-heading">Panel heading without title</div>
+ <div class="panel-body">
+ Panel content
+ </div>
+ </div>
+ `,
+ bindToController: true,
+ controllerAs: 'vm',
+ controller: function(){
+ // console.log('Field: ', this.name, this.field.type, this.ngModel);
+ 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.ngModel){
+ throw new Error('[xosField] Please provide an ng-model');
+ }
+ }
+ }
+ });
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/form/form.component.js b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/form/form.component.js
index 5294229..db4a2fd 100644
--- a/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/form/form.component.js
+++ b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/form/form.component.js
@@ -48,6 +48,9 @@
* ```
* @element ANY
* @scope
+ * @requires xos.uiComponents.directive:xosField
+ * @requires xos.uiComponents.XosFormHelpers
+ * @requires xos.helpers._
* @example
Autogenerated form
@@ -159,31 +162,7 @@
template: `
<ng-form name="vm.{{vm.config.formName || 'form'}}">
<div class="form-group" ng-repeat="(name, field) in vm.formField">
- <label>{{field.label}}</label>
- <input
- ng-if="field.type !== 'boolean'"
- type="{{field.type}}"
- name="{{name}}"
- class="form-control"
- ng-model="vm.ngModel[name]"
- ng-minlength="field.validators.minlength || 0"
- ng-maxlength="field.validators.maxlength || 2000"
- ng-required="field.validators.required || false" />
- <span class="boolean-field" ng-if="field.type === 'boolean'">
- <button
- class="btn btn-success"
- ng-show="vm.ngModel[name]"
- ng-click="vm.ngModel[name] = false">
- <i class="glyphicon glyphicon-ok"></i>
- </button>
- <button
- class="btn btn-danger"
- ng-show="!vm.ngModel[name]"
- ng-click="vm.ngModel[name] = true">
- <i class="glyphicon glyphicon-remove"></i>
- </button>
- </span>
- <!-- <pre>{{vm[vm.config.formName][name].$error | json}}</pre> -->
+ <xos-field name="name" field="field" ng-model="vm.ngModel[name]"></xos-field>
<xos-validation errors="vm[vm.config.formName || 'form'][name].$error"></xos-validation>
</div>
<div class="form-group" ng-if="vm.config.actions">
@@ -233,76 +212,5 @@
}
}
- })
- .service('XosFormHelpers', function(_, LabelFormatter){
-
- this._isEmail = (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);
- };
-
- this._getFieldFormat = (value) => {
-
- // check if is date
- if (_.isDate(value) || (!Number.isNaN(Date.parse(value)) && new Date(value).getTime() > 631180800000)){
- 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 a number
- if(!isNaN(value) && value !== null){
- return 'number';
- }
-
- // check if a string is an email
- if(this._isEmail(value)){
- return 'email';
- }
-
- // if null return string
- if(value === null){
- return 'string';
- }
-
- return typeof value;
- };
-
- this.buildFormStructure = (modelField, customField, model) => {
-
- modelField = Object.keys(modelField).length > 0 ? modelField : customField; //if no model field are provided, check custom
- customField = customField || {};
-
- return _.reduce(Object.keys(modelField), (form, f) => {
-
- form[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 : {}
- };
-
- if(form[f].type === 'date'){
- model[f] = new Date(model[f]);
- }
-
- if(form[f].type === 'number'){
- model[f] = parseInt(model[f], 10);
- }
-
- return form;
- }, {});
- };
-
- this.parseModelField = (fields) => {
- return _.reduce(fields, (form, f) => {
- form[f] = {};
- return form;
- }, {});
- }
-
- })
+ });
})();
diff --git a/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js b/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js
index 059f461..b3a2eec 100644
--- a/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js
+++ b/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js
@@ -249,6 +249,7 @@
});
// build form structure
+ // TODO move in a pure function for testing purposes
props.forEach((p, i) => {
this.formConfig.fields[p] = {
label: LabelFormatter.format(labels[i]).replace(':', ''),
diff --git a/views/ngXosLib/xosHelpers/src/xosHelpers.module.js b/views/ngXosLib/xosHelpers/src/xosHelpers.module.js
index b74ddf9..4af3680 100644
--- a/views/ngXosLib/xosHelpers/src/xosHelpers.module.js
+++ b/views/ngXosLib/xosHelpers/src/xosHelpers.module.js
@@ -27,6 +27,13 @@
'xos.uiComponents',
])
.config(config)
+
+ /**
+ * @ngdoc service
+ * @name xos.helpers._
+ * @description Wrap [lodash](https://lodash.com/docs) in an Angular Service
+ **/
+
.factory('_', $window => $window._ );
function config($httpProvider, $interpolateProvider, $resourceProvider) {
diff --git a/views/ngXosViews/subscribers/src/js/main.js b/views/ngXosViews/subscribers/src/js/main.js
index 6665b6d..957f807 100644
--- a/views/ngXosViews/subscribers/src/js/main.js
+++ b/views/ngXosViews/subscribers/src/js/main.js
@@ -25,38 +25,29 @@
templateUrl: 'templates/subscribers-list.tpl.html',
controller: function(Subscribers){
- this.tableConfig = {
- filter: 'field',
- order: true,
- pagination: {
- pageSize: 10
- },
- columns: [
- {
- label: 'Name',
- prop: 'humanReadableName'
- },
- {
- label: 'Identity',
- prop: 'identity',
- type: 'object'
- },
- {
- label: 'Related Info',
- prop: 'related',
- type: 'object'
- }
- ]
- };
-
this.smartTableConfig = {
resource: 'Subscribers'
};
+
+ this.formConfig = {
+ 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'
+ }
+ ]
+ };
// retrieving user list
Subscribers.query().$promise
.then((users) => {
- this.users = users;
+ this.users = users[0];
})
.catch((e) => {
throw new Error(e);
diff --git a/views/ngXosViews/subscribers/src/templates/subscribers-list.tpl.html b/views/ngXosViews/subscribers/src/templates/subscribers-list.tpl.html
index bd14fd5..afd7178 100644
--- a/views/ngXosViews/subscribers/src/templates/subscribers-list.tpl.html
+++ b/views/ngXosViews/subscribers/src/templates/subscribers-list.tpl.html
@@ -1,3 +1,4 @@
-<!-- <xos-table config="vm.tableConfig" data="vm.users"></xos-table> -->
+
+<xos-form ng-model="vm.users" config="vm.formConfig"></xos-form>
<xos-smart-table config="vm.smartTableConfig"></xos-smart-table>
\ No newline at end of file
diff --git a/xos/configurations/frontend/docker-compose.yml b/xos/configurations/frontend/docker-compose.yml
index 39b8faa..835eb83 100644
--- a/xos/configurations/frontend/docker-compose.yml
+++ b/xos/configurations/frontend/docker-compose.yml
@@ -20,9 +20,8 @@
- xos_db
volumes:
- ../common/xos_common_config:/opt/xos/xos_configuration/xos_common_config
- - ../vtn/files/xos_vtn_config:/opt/xos/xos_configuration/xos_vtn_config:ro
- - ../../core/xoslib:/opt/xos/core/xoslib
- ../../tosca:/opt/xos/tosca
+ - ../../core/xoslib:/opt/xos/core/xoslib
- ../../core/static:/opt/xos/core/static
- ../../core/dashboard:/opt/xos/core/dashboard
- ../../core/templatetags:/opt/xos/core/templatetags
@@ -31,6 +30,5 @@
- ../../configurations:/opt/xos/configurations
- ../../xos:/opt/xos/xos
- ../../api:/opt/xos/api
- - ../../core/views:/opt/xos/core/views
- ../../services:/opt/xos/services
diff --git a/xos/core/xoslib/static/js/vendor/ngXosHelpers.js b/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
index 85670c2..47b9c11 100644
--- a/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
+++ b/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
@@ -241,6 +241,7 @@
});
// build form structure
+ // TODO move in a pure function for testing purposes
props.forEach(function (p, i) {
_this.formConfig.fields[p] = {
label: LabelFormatter.format(labels[i]).replace(':', ''),
@@ -1033,6 +1034,65 @@
*
* 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
+ */
+ .directive('xosField', function () {
+ return {
+ restrict: 'E',
+ scope: {
+ name: '=',
+ field: '=',
+ ngModel: '='
+ },
+ template: '\n <label>{{vm.field.label}}</label>\n <input\n ng-if="vm.field.type !== \'boolean\' && vm.field.type !== \'object\'"\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 <span class="boolean-field" ng-if="vm.field.type === \'boolean\'">\n <button\n class="btn btn-success"\n ng-show="vm.ngModel"\n ng-click="vm.ngModel = false">\n <i class="glyphicon glyphicon-ok"></i>\n </button>\n <button\n class="btn btn-danger"\n ng-show="!vm.ngModel"\n ng-click="vm.ngModel = true">\n <i class="glyphicon glyphicon-remove"></i>\n </button>\n </span>\n <div\n class="panel panel-default object-field"\n ng-if="vm.field.type == \'object\' "\n >\n <div class="panel-heading">Panel heading without title</div>\n <div class="panel-body">\n Panel content\n </div>\n </div>\n ',
+ bindToController: true,
+ controllerAs: 'vm',
+ controller: function controller() {
+ // console.log('Field: ', this.name, this.field.type, this.ngModel);
+ 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.ngModel) {
+ throw new Error('[xosField] Please provide an ng-model');
+ }
+ }
+ };
+ });
+})();
+//# sourceMappingURL=../../../maps/ui_components/dumbComponents/field/field.component.js.map
+
+'use strict';
+
+/**
+ * © OpenCORD
+ *
+ * Visit http://guide.xosproject.org/devguide/addview/ for more information
+ *
* Created by teone on 4/15/16.
*/
@@ -1132,8 +1192,6 @@
'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; };
-
/**
* © OpenCORD
*
@@ -1184,6 +1242,9 @@
* ```
* @element ANY
* @scope
+ * @requires xos.uiComponents.directive:xosField
+ * @requires xos.uiComponents.XosFormHelpers
+ * @requires xos.helpers._
* @example
Autogenerated form
@@ -1287,7 +1348,7 @@
config: '=',
ngModel: '='
},
- template: '\n <ng-form name="vm.{{vm.config.formName || \'form\'}}">\n <div class="form-group" ng-repeat="(name, field) in vm.formField">\n <label>{{field.label}}</label>\n <input\n ng-if="field.type !== \'boolean\'"\n type="{{field.type}}"\n name="{{name}}"\n class="form-control"\n ng-model="vm.ngModel[name]"\n ng-minlength="field.validators.minlength || 0"\n ng-maxlength="field.validators.maxlength || 2000"\n ng-required="field.validators.required || false" />\n <span class="boolean-field" ng-if="field.type === \'boolean\'">\n <button\n class="btn btn-success"\n ng-show="vm.ngModel[name]"\n ng-click="vm.ngModel[name] = false">\n <i class="glyphicon glyphicon-ok"></i>\n </button>\n <button\n class="btn btn-danger"\n ng-show="!vm.ngModel[name]"\n ng-click="vm.ngModel[name] = true">\n <i class="glyphicon glyphicon-remove"></i>\n </button>\n </span>\n <!-- <pre>{{vm[vm.config.formName][name].$error | json}}</pre> -->\n <xos-validation errors="vm[vm.config.formName || \'form\'][name].$error"></xos-validation>\n </div>\n <div class="form-group" ng-if="vm.config.actions">\n <button role="button" href=""\n ng-repeat="action in vm.config.actions"\n ng-click="action.cb(vm.ngModel)"\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 </ng-form>\n ',
+ template: '\n <ng-form name="vm.{{vm.config.formName || \'form\'}}">\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 errors="vm[vm.config.formName || \'form\'][name].$error"></xos-validation>\n </div>\n <div class="form-group" ng-if="vm.config.actions">\n <button role="button" href=""\n ng-repeat="action in vm.config.actions"\n ng-click="action.cb(vm.ngModel)"\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 </ng-form>\n ',
bindToController: true,
controllerAs: 'vm',
controller: ["$scope", "$log", "_", "XosFormHelpers", function controller($scope, $log, _, XosFormHelpers) {
@@ -1324,77 +1385,7 @@
});
}]
};
- }).service('XosFormHelpers', ["_", "LabelFormatter", function (_, LabelFormatter) {
- var _this2 = this;
-
- 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);
- };
-
- this._getFieldFormat = function (value) {
-
- // check if is date
- if (_.isDate(value) || !Number.isNaN(Date.parse(value)) && new Date(value).getTime() > 631180800000) {
- 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 a number
- if (!isNaN(value) && value !== null) {
- return 'number';
- }
-
- // check if a string is an email
- if (_this2._isEmail(value)) {
- return 'email';
- }
-
- // if null return string
- if (value === null) {
- return 'string';
- }
-
- return typeof value === 'undefined' ? 'undefined' : _typeof(value);
- };
-
- this.buildFormStructure = function (modelField, customField, model) {
-
- modelField = Object.keys(modelField).length > 0 ? modelField : customField; //if no model field are provided, check custom
- customField = customField || {};
-
- return _.reduce(Object.keys(modelField), function (form, f) {
-
- form[f] = {
- label: customField[f] && customField[f].label ? customField[f].label + ':' : LabelFormatter.format(f),
- type: customField[f] && customField[f].type ? customField[f].type : _this2._getFieldFormat(model[f]),
- validators: customField[f] && customField[f].validators ? customField[f].validators : {}
- };
-
- if (form[f].type === 'date') {
- model[f] = new Date(model[f]);
- }
-
- if (form[f].type === 'number') {
- model[f] = parseInt(model[f], 10);
- }
-
- return form;
- }, {});
- };
-
- this.parseModelField = function (fields) {
- return _.reduce(fields, function (form, f) {
- form[f] = {};
- return form;
- }, {});
- };
- }]);
+ });
})();
//# sourceMappingURL=../../../maps/ui_components/dumbComponents/form/form.component.js.map
@@ -1542,6 +1533,210 @@
(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() {
+
+ var _formatByUnderscore = function _formatByUnderscore(string) {
+ return string.split('_').join(' ').trim();
+ };
+
+ var _formatByUppercase = function _formatByUppercase(string) {
+ return string.split(/(?=[A-Z])/).map(function (w) {
+ return w.toLowerCase();
+ }).join(' ');
+ };
+
+ var _capitalize = function _capitalize(string) {
+ return string.slice(0, 1).toUpperCase() + string.slice(1);
+ };
+
+ 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
+ };
+ }
+})();
+//# sourceMappingURL=../../../maps/services/helpers/ui/label_formatter.service.js.map
+
+'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 (_.isDate(value) || !Number.isNaN(Date.parse(value)) && new Date(value).getTime() > 631180800000) {
+ 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 a number
+ if (!isNaN(value) && value !== null) {
+ return 'number';
+ }
+
+ // check if a string is an email
+ if (_this._isEmail(value)) {
+ return 'email';
+ }
+
+ // if null return string
+ if (value === null) {
+ return 'string';
+ }
+
+ 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
+ * }
+ * }
+ * ```
+ **/
+
+ this.buildFormStructure = function (modelField, customField, model) {
+
+ modelField = Object.keys(modelField).length > 0 ? modelField : customField; //if no model field are provided, check custom
+ customField = customField || {};
+
+ return _.reduce(Object.keys(modelField), function (form, f) {
+
+ form[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 : {}
+ };
+
+ if (form[f].type === 'date') {
+ model[f] = new Date(model[f]);
+ }
+
+ if (form[f].type === 'number') {
+ model[f] = parseInt(model[f], 10);
+ }
+
+ return form;
+ }, {});
+ };
+
+ /**
+ * @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;
+ }, {});
+ };
+ }]);
+})();
+//# sourceMappingURL=../../../maps/services/helpers/ui/form.helpers.js.map
+
+'use strict';
+
+(function () {
+ 'use strict';
+
config.$inject = ["$httpProvider", "$interpolateProvider", "$resourceProvider"];
angular.module('bugSnag', []).factory('$exceptionHandler', function () {
return function (exception, cause) {
@@ -1559,7 +1754,15 @@
* @description this is the module that group all the helpers service and components for XOS
**/
- angular.module('xos.helpers', ['ngCookies', 'ngResource', 'ngAnimate', 'bugSnag', 'xos.uiComponents']).config(config).factory('_', ["$window", function ($window) {
+ angular.module('xos.helpers', ['ngCookies', 'ngResource', 'ngAnimate', 'bugSnag', '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._;
}]);
@@ -2208,7 +2411,7 @@
/**
* @ngdoc service
- * @name xos.helpers.LabelFormatter
+ * @name xos.uiComponents.LabelFormatter
* @description This factory define a set of helper function to format label started from an object property
**/