LP#1626157 grid experiment
authorBill Erickson <berickxx@gmail.com>
Sun, 29 Apr 2018 21:55:35 +0000 (17:55 -0400)
committerBill Erickson <berickxx@gmail.com>
Sun, 29 Apr 2018 21:55:35 +0000 (17:55 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
14 files changed:
Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html
Open-ILS/src/eg2/src/app/share/grid/grid-body.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid-column.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid-column.ts
Open-ILS/src/eg2/src/app/share/grid/grid-data-source.ts
Open-ILS/src/eg2/src/app/share/grid/grid-header.component.html
Open-ILS/src/eg2/src/app/share/grid/grid-header.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid.component.css
Open-ILS/src/eg2/src/app/share/grid/grid.component.html
Open-ILS/src/eg2/src/app/share/grid/grid.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid.module.ts
Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts
Open-ILS/src/eg2/src/index.html

index 139597f..e738721 100644 (file)
@@ -1,2 +1,15 @@
 
+<div class="eg-grid-row eg-grid-body-row"
+  [ngClass]="{'eg-grid-row-selected': selector[idx]}"
+  *ngFor="let row of currentPage(); let idx = index">
+
+  <div class="eg-grid-cell eg-grid-checkbox-cell">
+    <input type='checkbox' [(ngModel)]="selector[idx]">
+  </div>
+  <div class="eg-grid-cell eg-grid-body-cell" [ngStyle]="{flex:col.flex}"
+    *ngFor="let col of columnSet.displayColumns()">
+    {{col.displayValue(row)}}
+  </div>
+
+<div>
 
index 4c45119..a85f9e0 100644 (file)
@@ -1,6 +1,7 @@
 import {Component, Input, OnInit, Host, TemplateRef} from '@angular/core';
-import {EgGridColumn} from './grid-column';
+import {EgGridColumn, EgGridColumnSet} from './grid-column';
 import {EgGridDataSource} from './grid-data-source';
+import {Pager} from '@eg/share/util/pager';
 
 @Component({
   selector: 'eg-grid-body',
@@ -10,9 +11,16 @@ import {EgGridDataSource} from './grid-data-source';
 export class EgGridBodyComponent implements OnInit {
 
     @Input() dataSource: EgGridDataSource;
-    @Input() columns: EgGridColumn[];
+    @Input() columnSet: EgGridColumnSet;
+    @Input() pager: Pager;
+    @Input() selector: {[idx:number] : boolean};
 
     ngOnInit() {
     }
+
+    currentPage(): any[] {
+        if (!this.dataSource.data) return [];
+        return this.dataSource.data.slice(this.pager.offset, this.pager.limit);
+    }
 }
 
index b895b3e..c1e1f93 100644 (file)
@@ -13,10 +13,12 @@ export class EgGridColumnComponent implements OnInit {
     @Input() name: string;
     @Input() path: string;
     @Input() label: string;
-    @Input() flex: number = 1;
-    @Input() visible: boolean = false;
+    @Input() flex: number;
+    @Input() hidden: boolean = false;
     @Input() cellTemplate: TemplateRef<any>;
-    @Input() grid: EgGridComponent;
+
+    // get a reference to our container grid.
+    constructor(@Host() private grid: EgGridComponent) {}
 
     ngOnInit() {
 
@@ -28,11 +30,11 @@ export class EgGridColumnComponent implements OnInit {
         let col = new EgGridColumn();
         col.name = this.name;
         col.path = this.path;
-        col.label = this.label;
-        col.flex = this.flex;
-        col.visible = this.visible;
+        col.label = this.label || this.name;
+        col.flex = this.flex || 2;
+        col.hidden = this.hidden;
         col.cellTemplate = this.cellTemplate;
-        this.grid.columns.push(col);
+        this.grid.columnSet.add(col);
     }
 }
 
index 07dcac9..fc2256b 100644 (file)
@@ -1,11 +1,12 @@
 import {TemplateRef} from '@angular/core';
+import {EgIdlService} from '@eg/core/idl.service';
 
 export class EgGridColumn {
     name: string;
     path: string;
     label: string;
-    flex: number = 1;
-    visible: boolean = false;
+    flex: number;
+    hidden: boolean;
     cellTemplate: TemplateRef<any>;
 
     displayValue(row: any): string {
@@ -15,10 +16,53 @@ export class EgGridColumn {
         if (row[this.name] === undefined || row[this.name] === null) 
             return '';
 
-        if (typeof row[this.name] == 'function')
-            return row[this.name]()+'';
+        if (typeof row[this.name] == 'function') {
+            let val = row[this.name]();
+            if (val === undefined || val === null) return '';
+            return val+'';
+        }
 
         return row[this.name]+'';
     }
+}
+
+export class EgGridColumnSet {
+  
+    columns: EgGridColumn[];
+
+    constructor() {
+        this.columns = [];
+    }
 
+    add(col: EgGridColumn) {
+        this.columns.push(col);
+    }
+
+    displayColumns(): EgGridColumn[] {
+        return this.columns.filter(c => !c.hidden);
+    }
 }
+
+export class EgGridIdlColumnSet extends EgGridColumnSet {
+    idl: EgIdlService;
+    idlClass: string;
+
+    constructor(idl: EgIdlService, idlClass: string) { 
+        super();
+        this.idl = idl;
+        this.idlClass = idlClass;
+        this.generateColumns();
+    }
+
+    generateColumns() {
+        this.idl.classes[this.idlClass].fields.forEach(field => {
+            if (field.virtual) return;
+            let col = new EgGridColumn();
+            col.name = field.name;
+            col.label = field.label || field.name;
+            this.add(col);
+        });
+    }
+}
+
+
index 8ef090f..5120678 100644 (file)
@@ -1,11 +1,15 @@
-
+//import {Observable} from 'rxjs/Rx';
 
 export class EgGridDataSource {
     data: any[] = []; 
 
+    sortSpec: any[] = [];
+
     // Do we know how many items we have in total?
     indeterminate: boolean
 
+    applySort() {
+    }
 }
 
 
index 07e0e1e..1a03da8 100644 (file)
@@ -1,5 +1,12 @@
 
 <div class="eg-grid-row eg-grid-header-row">
-    <div *ngFor="let col of columns">{{col.label}}</div>
+  <div class="eg-grid-cell eg-grid-header-cell eg-grid-checkbox-cell">
+    <input type='checkbox'> <!-- add click handlers ; shared selector mod -->
+  </div>
+
+    <div *ngFor="let col of columnSet.displayColumns()" 
+      class="eg-grid-cell eg-grid-header-cell" [ngStyle]="{flex:col.flex}">
+      {{col.label}}
+    </div>
 </div>
 
index 75bf2fc..1a19e8e 100644 (file)
@@ -1,5 +1,5 @@
 import {Component, Input, OnInit} from '@angular/core';
-import {EgGridColumn} from './grid-column';
+import {EgGridColumn, EgGridColumnSet} from './grid-column';
 
 @Component({
   selector: 'eg-grid-header',
@@ -8,7 +8,8 @@ import {EgGridColumn} from './grid-column';
 
 export class EgGridHeaderComponent implements OnInit {
 
-    @Input() columns: EgGridColumn[];
+    @Input() columnSet: EgGridColumnSet;
+    @Input() selected: {[idx:number] : boolean};
 
     constructor() {}
 
index 6ad85eb..0d9a331 100644 (file)
@@ -1,15 +1,32 @@
 
+.eg-grid {
+    width: 100%;
+    color: rgba(0,0,0,.87); 
+}
+    
 .eg-grid-row {
     display: flex;
+    border-bottom: 1px solid rgba(0,0,0,.12);
+    padding-left: 10px;
+    padding-right: 10px;
 }
 
 .eg-grid-header-row {
 }
 
+.eg-grid-body-row {
+}
+
 .eg-grid-header-cell {
     font-weight: bold;
 }
 
 .eg-grid-cell {
+    flex: 1; /* applied per column */
+    padding: 6px;
 }
 
+.eg-grid-body-cell {
+}
+
+
index b22a064..0b4a533 100644 (file)
@@ -1,11 +1,14 @@
 
 <div class="eg-grid">
   <!--
-  <eg-grid-toolbar [columns]="columns"></eg-grid-toolbar>
-  -->
-  <eg-grid-header [columns]="columns"></eg-grid-header>
-  <!--
-  <eg-grid-body [columns]="columns" [dataSource]="dataSource"></eg-grid-body>
+  <eg-grid-toolbar [columnSet]="columnSet"></eg-grid-toolbar>
   -->
+  <eg-grid-header [columnSet]="columnSet"></eg-grid-header>
+  <eg-grid-body 
+    [columnSet]="columnSet" 
+    [dataSource]="dataSource"
+    [pager]="pager"
+    [selector]="selector">
+  </eg-grid-body>
 </div>
 
index 80f8833..af94b40 100644 (file)
@@ -1,23 +1,38 @@
-import {Component, Input, OnInit} from '@angular/core';
+import {Component, Input, OnInit, ViewEncapsulation} from '@angular/core';
 import {EgGridDataSource} from './grid-data-source';
-import {EgGridColumn} from './grid-column';
+import {EgGridColumn, EgGridColumnSet, EgGridIdlColumnSet} from './grid-column';
+import {EgIdlService} from '@eg/core/idl.service';
+import {Pager} from '@eg/share/util/pager';
 
 @Component({
   selector: 'eg-grid',
   templateUrl: './grid.component.html',
-  styleUrls: ['./grid.component.css']
+  styleUrls: ['grid.component.css'],
+  // share grid css globally once imported.
+  encapsulation: ViewEncapsulation.None
 })
 
 export class EgGridComponent implements OnInit {
 
     @Input() dataSource: EgGridDataSource;
-    columns: EgGridColumn[];
+    @Input() idlClass: string;
+
+    pager: Pager;
+    columnSet: EgGridColumnSet;
+    selector: {[idx:number] : boolean};
     
-    constructor() {
-        this.columns = [];
+    constructor(private idl: EgIdlService) {
+        this.pager = new Pager();
+        this.pager.limit = 10; // TODO
+        this.selector = {};
     }
 
     ngOnInit() {
+        if (this.idlClass) {
+            this.columnSet = new EgGridIdlColumnSet(this.idl, this.idlClass);
+        } else {
+            this.columnSet = new EgGridColumnSet();
+        }
     }
 
 }
index 0d3e31c..455e286 100644 (file)
@@ -1,5 +1,6 @@
 import {NgModule} from '@angular/core';
 import {CommonModule} from '@angular/common';
+import {FormsModule} from '@angular/forms';
 import {EgGridComponent} from './grid.component';
 import {EgGridColumnComponent} from './grid-column.component';
 import {EgGridHeaderComponent} from './grid-header.component';
@@ -14,7 +15,8 @@ import {EgGridBodyComponent} from './grid-body.component';
         EgGridBodyComponent
     ],
     imports: [
-        CommonModule
+        CommonModule,
+        FormsModule
     ],
     exports: [
         // public components
index 900201e..87b075c 100644 (file)
 
 <!-- grid stuff -->
 
-<eg-grid #testGrid [dataSource]="gridDataSource"></eg-grid>
-<eg-grid-column [grid]="testGrid" name="name" label="Name" i18n-label></eg-grid-column>
+
+<eg-grid #cbtGrid idlClass="cbt" [dataSource]="billingTypes">
+</eg-grid>
+
+<!--
+<eg-grid #testGrid [dataSource]="gridDataSource">
+  <eg-grid-column  name="name" label="Name" i18n-label></eg-grid-column>
+  <eg-grid-column  name="state" label="State" i18n-label></eg-grid-column>
+</eg-grid>
+-->
+
+
+
+
+
 
index 8a719f9..965a0f6 100644 (file)
@@ -4,6 +4,7 @@ import {EgToastService} from '@eg/share/toast/toast.service';
 import {EgStringService} from '@eg/share/string/string.service';
 import {Observable} from 'rxjs/Rx';
 import {EgGridDataSource} from '@eg/share/grid/grid-data-source';
+import {EgIdlService, EgIdlObject} from '@eg/core/idl.service';
 
 @Component({
   templateUrl: 'sandbox.component.html'
@@ -17,6 +18,8 @@ export class EgSandboxComponent implements OnInit {
 
     gridDataSource: EgGridDataSource = new EgGridDataSource();
 
+    billingTypes: EgGridDataSource = new EgGridDataSource();
+
 
     testStr: string;
     @Input() set testString(str: string) {
@@ -26,6 +29,7 @@ export class EgSandboxComponent implements OnInit {
     name: string = 'Jane';
 
     constructor(
+        private idl: EgIdlService,
         private strings: EgStringService,
         private toast: EgToastService
     ) {}
@@ -33,10 +37,18 @@ export class EgSandboxComponent implements OnInit {
     ngOnInit() {
 
         this.gridDataSource.data = [
-            {name: 'Jane'},
-            {name: 'Al'},
-            {name: 'The Tick'}
+            {name: 'Jane', state: 'AZ'},
+            {name: 'Al', state: 'CA'},
+            {name: 'The Tick', state: 'TX'}
         ];
+
+        let bt1 = this.idl.create('cbt');
+        let bt2 = this.idl.create('cbt');
+        bt1.id = 12;
+        bt1.name = 'BT1';
+        bt2.id = 47;
+        bt1.name = 'BT2';
+        this.billingTypes.data = [bt1, bt2];
     }
 
     showProgress() {
index b169c21..d84bab7 100644 (file)
   <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
   <!-- link to bootstrap manually for the time being.  With 
         ng-bootstrap, we only need the CSS, not the JS -->
+  <!--
   <link rel="stylesheet" crossorigin="anonymous"
     href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" 
     integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm">
+    -->
+  <!-- lnk to local copy for dev on the go -->
+  <link rel="stylesheet" crossorigin="anonymous"
+    href="/css/bootstrap.min.css" 
 </head>
 <body>
   <eg-root></eg-root>