Created first CRUD view
Change-Id: I3e7f3f36896921cce671c6a53e0155de9165eeb3
diff --git a/src/app/config/app.config.ts b/src/app/config/app.config.ts
index 7b6fa12..2357f77 100644
--- a/src/app/config/app.config.ts
+++ b/src/app/config/app.config.ts
@@ -6,6 +6,6 @@
}
export const AppConfig: IAppConfig = {
- apiEndpoint: 'http://xos.dev:3000/api',
- websocketClient: 'http://xos.dev:3000'
+ apiEndpoint: 'http://xos-rest-gw:3000/api',
+ websocketClient: 'http://xos-rest-gw:3000'
};
diff --git a/src/app/core/index.ts b/src/app/core/index.ts
index d0875b6..ee73f99 100644
--- a/src/app/core/index.ts
+++ b/src/app/core/index.ts
@@ -3,6 +3,7 @@
import {xosNav} from './nav/nav';
import routesConfig from './routes';
import {xosLogin} from './login/login';
+import {xosTable} from './table/table';
export const xosCore = 'xosCore';
@@ -12,4 +13,5 @@
.component('xosHeader', xosHeader)
.component('xosFooter', xosFooter)
.component('xosNav', xosNav)
- .component('xosLogin', xosLogin);
+ .component('xosLogin', xosLogin)
+ .component('xosTable', xosTable);
diff --git a/src/app/core/login/login.ts b/src/app/core/login/login.ts
index af46619..51dc7c9 100644
--- a/src/app/core/login/login.ts
+++ b/src/app/core/login/login.ts
@@ -16,8 +16,7 @@
password: password
})
.then(res => {
- console.log(res);
- this.$state.go('app');
+ this.$state.go('xos.dashboard');
})
.catch(e => console.error);
}
diff --git a/src/app/core/nav/nav.ts b/src/app/core/nav/nav.ts
index d90df10..82d9d64 100644
--- a/src/app/core/nav/nav.ts
+++ b/src/app/core/nav/nav.ts
@@ -1,6 +1,6 @@
import './nav.scss';
-interface INavItem {
+export interface INavItem {
label: string;
state: string;
}
diff --git a/src/app/core/table/table.html b/src/app/core/table/table.html
new file mode 100644
index 0000000..58a46e0
--- /dev/null
+++ b/src/app/core/table/table.html
@@ -0,0 +1,101 @@
+<!--<div ng-show="vm.data.length > 0 && vm.loader == false">-->
+ <div class="row" ng-if="vm.config.filter == 'fulltext'">
+ <div class="col-xs-12">
+ <input
+ class="form-control"
+ placeholder="Type to search.."
+ type="text"
+ ng-model="vm.query"/>
+ </div>
+ </div>
+ <table ng-class="vm.classes">
+ <thead>
+ <tr>
+ <th ng-repeat="col in vm.columns">
+ {{col.label}}
+ <span ng-if="vm.config.order">
+ <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = false">
+ <i class="glyphicon glyphicon-chevron-up"></i>
+ </a>
+ <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = true">
+ <i class="glyphicon glyphicon-chevron-down"></i>
+ </a>
+ </span>
+ </th>
+ <th ng-if="vm.config.actions">Actions:</th>
+ </tr>
+ </thead>
+ <tbody ng-if="vm.config.filter == 'field'">
+ <tr>
+ <td ng-repeat="col in vm.columns">
+ <input
+ ng-if="col.type !== 'boolean' && col.type !== 'array' && col.type !== 'object' && col.type !== 'custom'"
+ class="form-control"
+ placeholder="Type to search by {{col.label}}"
+ type="text"
+ ng-model="vm.query[col.prop]"/>
+ <select
+ ng-if="col.type === 'boolean'"
+ class="form-control"
+ ng-model="vm.query[col.prop]">
+ <option value="">-</option>
+ <option value="true">True</option>
+ <option value="false">False</option>
+ </select>
+ </td>
+ <td ng-if="vm.config.actions"></td>
+ </tr>
+ </tbody>
+ <tbody>
+ <tr ng-repeat="item in vm.data | filter:vm.query | orderBy:vm.orderBy:vm.reverse track by $index">
+ <td ng-repeat="col in vm.columns">
+ <span ng-if="!col.type || col.type === 'text'">{{item[col.prop]}}</span>
+ <span ng-if="col.type === 'boolean'">
+ <i class="glyphicon"
+ ng-class="{'glyphicon-ok': item[col.prop], 'glyphicon-remove': !item[col.prop]}">
+ </i>
+ </span>
+ <span ng-if="col.type === 'date'">
+ {{item[col.prop] | date:'H:mm MMM d, yyyy'}}
+ </span>
+ <span ng-if="col.type === 'array'">
+ {{item[col.prop] | arrayToList}}
+ </span>
+ <span ng-if="col.type === 'object'">
+ <dl class="dl-horizontal">
+ <span ng-repeat="(k,v) in item[col.prop]">
+ <dt>{{k}}</dt>
+ <dd>{{v}}</dd>
+ </span>
+ </dl>
+ </span>
+ <span ng-if="col.type === 'custom'">
+ {{col.formatter(item)}}
+ </span>
+ <span ng-if="col.type === 'icon'">
+ <i class="glyphicon glyphicon-{{col.formatter(item)}}">
+ </i>
+ </span>
+ </td>
+ <td ng-if="vm.config.actions">
+ <a href=""
+ ng-repeat="action in vm.config.actions"
+ ng-click="action.cb(item)"
+ title="{{action.label}}">
+ <i
+ class="glyphicon glyphicon-{{action.icon}}"
+ style="color: {{action.color}};"></i>
+ </a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+<!--</div>-->
+<!--<div ng-show="(vm.data.length == 0 || !vm.data) && vm.loader == false">-->
+ <!--<xos-alert config="{type: 'info'}">-->
+ <!--No data to show.-->
+ <!--</xos-alert>-->
+<!--</div>-->
+<!--<div ng-show="vm.loader == true">-->
+ <!--<div class="loader"></div>-->
+<!--</div>-->
\ No newline at end of file
diff --git a/src/app/core/table/table.ts b/src/app/core/table/table.ts
new file mode 100644
index 0000000..43360c6
--- /dev/null
+++ b/src/app/core/table/table.ts
@@ -0,0 +1,88 @@
+// TODO fininsh to import all methods from https://github.com/opencord/ng-xos-lib/blob/master/src/ui_components/dumbComponents/table/table.component.js
+// TODO import tests
+
+import * as _ from 'lodash';
+
+interface IXosTableCgfOrder {
+ reverse: boolean;
+ field: string;
+}
+
+export interface IXosTableCfg {
+ columns: any[];
+ order: IXosTableCgfOrder; // | boolean;
+}
+
+class TableCtrl {
+ $inject = ['$onInit'];
+
+ public columns: any[];
+ public orderBy: string;
+ public reverse: boolean;
+
+ private data: any[];
+ private config: IXosTableCfg;
+
+
+ $onInit() {
+ 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
+ let customCols = _.filter(this.config.columns, {type: 'custom'});
+ if (angular.isArray(customCols) && customCols.length > 0) {
+ _.forEach(customCols, (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
+ let iconCols = _.filter(this.config.columns, {type: 'icon'});
+ if (angular.isArray(iconCols) && iconCols.length > 0) {
+ _.forEach(iconCols, (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
+ let linkedColumns = _.filter(this.config.columns, col => angular.isDefined(col.link));
+ if (angular.isArray(linkedColumns) && linkedColumns.length > 0) {
+ _.forEach(linkedColumns, (col) => {
+ if (!angular.isFunction(col.link)) {
+ throw new Error('[xosTable] The link property should be a function.');
+ }
+ });
+ }
+
+ this.columns = this.config.columns;
+
+ }
+}
+
+export const xosTable: angular.IComponentOptions = {
+ template: require('./table.html'),
+ controllerAs: 'vm',
+ controller: TableCtrl,
+ bindings: {
+ data: '=',
+ config: '='
+ }
+};
diff --git a/src/app/views/crud/crud.html b/src/app/views/crud/crud.html
new file mode 100644
index 0000000..fbbec88
--- /dev/null
+++ b/src/app/views/crud/crud.html
@@ -0,0 +1,2 @@
+<h1>{{vm.title}}</h1>
+<xos-table config="vm.tableCfg" data="vm.tableData"></xos-table>
\ No newline at end of file
diff --git a/src/app/views/crud/crud.ts b/src/app/views/crud/crud.ts
new file mode 100644
index 0000000..b35c104
--- /dev/null
+++ b/src/app/views/crud/crud.ts
@@ -0,0 +1,42 @@
+import {IXosResourceService} from '../../rest/slices.rest';
+import {IXosTableCfg} from '../../core/table/table';
+export interface IXosCrudData {
+ title: string;
+ resource: string;
+ xosTableCfg: IXosTableCfg;
+}
+
+class CrudController {
+ static $inject = ['$state', '$injector'];
+
+ public data: IXosCrudData;
+ public tableCfg: IXosTableCfg;
+ public title: string;
+ public resourceName: string;
+ public resource: ng.resource.IResourceClass<ng.resource.IResource<any>>;
+ public tableData: any[];
+
+ constructor(
+ private $state: angular.ui.IStateService,
+ private $injector: angular.Injectable<any>
+ ) {
+ this.data = this.$state.current.data;
+ console.log('xosCrud', this.data);
+ this.tableCfg = this.data.xosTableCfg;
+ this.title = this.data.title;
+ this.resourceName = this.data.resource;
+ this.resource = this.$injector.get(this.resourceName).getResource();
+
+ this.resource
+ .query().$promise
+ .then(res => {
+ this.tableData = res;
+ });
+ }
+}
+
+export const xosCrud: angular.IComponentOptions = {
+ template: require('./crud.html'),
+ controllerAs: 'vm',
+ controller: CrudController
+};
diff --git a/src/app/views/index.ts b/src/app/views/index.ts
new file mode 100644
index 0000000..495e2a4
--- /dev/null
+++ b/src/app/views/index.ts
@@ -0,0 +1,8 @@
+import {xosCore} from '../core/index';
+import {xosCrud} from './crud/crud';
+
+export const xosViews = 'xosViews';
+
+angular
+ .module('xosViews', [xosCore])
+ .component('xosCrud', xosCrud);
diff --git a/src/interceptors.ts b/src/interceptors.ts
index bd4cba3..0a1cd08 100644
--- a/src/interceptors.ts
+++ b/src/interceptors.ts
@@ -1,5 +1,7 @@
/// <reference path="../typings/index.d.ts" />
+// TODO handle backend failure
+
export function interceptorConfig($httpProvider: angular.IHttpProvider, $resourceProvider: angular.resource.IResourceServiceProvider) {
$httpProvider.interceptors.push('UserStatusInterceptor');
$httpProvider.interceptors.push('CredentialsInterceptor');
diff --git a/src/routes.ts b/src/routes.ts
index 3c8ae3d..8290e9a 100644
--- a/src/routes.ts
+++ b/src/routes.ts
@@ -31,7 +31,16 @@
title: 'Slices',
resource: 'SlicesRest',
xosTableCfg: {
- columns: ['name', 'default_isolation']
+ columns: [
+ {
+ label: 'Name',
+ prop: 'name'
+ },
+ {
+ label: 'Default Isolation',
+ prop: 'default_isolation'
+ }
+ ]
}
}
})