Preparation to bower release
diff --git a/src/ui_components/smartComponents/smartTable/smartTable.component.js b/src/ui_components/smartComponents/smartTable/smartTable.component.js
new file mode 100644
index 0000000..622952f
--- /dev/null
+++ b/src/ui_components/smartComponents/smartTable/smartTable.component.js
@@ -0,0 +1,269 @@
+/**
+ * © 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>
+    */
+   
+  .directive('xosSmartTable', function(){
+    return {
+      restrict: 'E',
+      scope: {
+        config: '='
+      },
+      template: `
+        <div class="row" ng-show="vm.data.length > 0">
+          <div class="col-xs-12 text-right">
+            <a href="" class="btn btn-success" ng-click="vm.createItem()">
+              Add
+            </a>
+          </div>
+        </div>
+        <div class="row">
+          <div class="col-xs-12 table-responsive">
+            <xos-table config="vm.tableConfig" data="vm.data"></xos-table>
+          </div>
+        </div>
+        <div class="panel panel-default" ng-show="vm.detailedItem">
+          <div class="panel-heading">
+            <div class="row">
+              <div class="col-xs-11">
+                <h3 class="panel-title" ng-show="vm.detailedItem.id">Update {{vm.config.resource}} {{vm.detailedItem.id}}</h3>
+                <h3 class="panel-title" ng-show="!vm.detailedItem.id">Create {{vm.config.resource}} item</h3>
+              </div>
+              <div class="col-xs-1">
+                <a href="" ng-click="vm.cleanForm()">
+                  <i class="glyphicon glyphicon-remove pull-right"></i>
+                </a>
+              </div>
+            </div>
+          </div>
+          <div class="panel-body">
+            <xos-form config="vm.formConfig" ng-model="vm.detailedItem"></xos-form>
+          </div>
+        </div>
+        <xos-alert config="{type: 'success', closeBtn: true}" show="vm.responseMsg">{{vm.responseMsg}}</xos-alert>
+        <xos-alert config="{type: 'danger', closeBtn: true}" show="vm.responseErr">{{vm.responseErr}}</xos-alert>
+      `,
+      bindToController: true,
+      controllerAs: 'vm',
+      controller: function($injector, LabelFormatter, _, XosFormHelpers){
+        
+        // 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: (item) => {
+                this.Resource.delete({id: item.id}).$promise
+                .then(() => {
+                  _.remove(this.data, (d) => d.id === item.id);
+                  this.responseMsg = `${this.config.resource} with id ${item.id} successfully deleted`;
+                })
+                .catch(err => {
+                  this.responseErr = err.data.detail || `Error while deleting ${this.config.resource} with id ${item.id}`;
+                });
+              },
+              color: 'red'
+            },
+            {
+              label: 'details',
+              icon: 'search',
+              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: (item) => {
+                let p;
+                let isNew = true;
+
+                if(item.id){
+                  p = item.$update();
+                  isNew = false;
+                }
+                else {
+                  p = item.$save();
+                }
+
+                p.then((res) => {
+                  if(isNew){
+                    this.data.push(angular.copy(res));
+                  }
+                  delete this.detailedItem;
+                  this.responseMsg = `${this.config.resource} with id ${item.id} successfully saved`;
+                })
+                .catch((err) => {
+                  this.responseErr = err.data.detail || `Error while saving ${this.config.resource} with id ${item.id}`;
+                })
+              },
+              class: 'success'
+            }
+          ]
+        };
+
+        this.cleanForm = () => {
+          delete this.detailedItem;
+        };
+
+        this.createItem = () => {
+          this.detailedItem = new this.Resource();
+        };
+
+        this.Resource = $injector.get(this.config.resource);
+
+        const getData = () => {
+          this.Resource.query().$promise
+          .then((res) => {
+
+            if(!res[0]){
+              this.data = res;
+              return;
+            }
+
+            let item = res[0];
+            let props = Object.keys(item);
+
+            _.remove(props, 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)
+            }
+
+            let labels = props.map(p => LabelFormatter.format(p));
+
+            props.forEach((p, i) => {
+              let fieldConfig = {
+                label: labels[i],
+                prop: p
+              };
+
+              if(angular.isString(item[p]) && typeof item[p] !== 'undefined'){
+                fieldConfig.type = typeof item[p];
+              }
+
+              this.tableConfig.columns.push(fieldConfig);
+            });
+
+            // 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(':', ''),
+                type: XosFormHelpers._getFieldFormat(item[p])
+              };
+            });
+
+            this.data = res;
+          });
+        }
+
+        getData();
+      }
+    };
+  });
+})();
\ No newline at end of file