LP#1779158 Match set quality UI
authorBill Erickson <berickxx@gmail.com>
Wed, 25 Jul 2018 16:15:54 +0000 (12:15 -0400)
committerBill Erickson <berickxx@gmail.com>
Thu, 11 Oct 2018 18:56:30 +0000 (14:56 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/cat/vandelay/match-set-expression.component.ts
Open-ILS/src/eg2/src/app/staff/cat/vandelay/match-set-new-point.component.html
Open-ILS/src/eg2/src/app/staff/cat/vandelay/match-set-new-point.component.ts
Open-ILS/src/eg2/src/app/staff/cat/vandelay/match-set-quality.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/cat/vandelay/match-set-quality.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/cat/vandelay/match-set.component.html
Open-ILS/src/eg2/src/app/staff/cat/vandelay/vandelay.module.ts

index cba3f25..9912068 100644 (file)
@@ -51,41 +51,42 @@ export class MatchSetExpressionComponent implements OnInit {
     ngOnInit() {}
 
     refreshTree(): Promise<any> {
-        if (!this.matchSet_) { return; }
+        if (!this.matchSet_) { return Promise.resolve(); }
 
         return this.pcrud.search('vmsp',
             {match_set: this.matchSet_.id()}, {}, 
             {atomic: true, authoritative: true}
-        ).toPromise().then(points => {
-
-            // create tree nodes
-            const nodes = [];
-            const idmap: any = {};
-            points.forEach(point => {
-
-                point.negate(point.negate() === 't' ? true : false);
-                point.heading(point.heading() === 't' ? true : false);
-                point.children([]);
-
-                const node = new TreeNode({
-                    id: point.id(),
-                    expanded: true,
-                    callerData: {point: point}
-                });
-                idmap[node.id + ''] = node;
-                this.setNodeLabel(node, point).then(() => nodes.push(node));
-            });
+        ).toPromise().then(points => this.ingestMatchPoints(points));
+    }
+
+    ingestMatchPoints(points: IdlObject[]) {
+        const nodes = [];
+        const idmap: any = {};
+
+        // massage data, create tree nodes
+        points.forEach(point => {
 
-            // then apply the parent/child relationship
+            point.negate(point.negate() === 't' ? true : false);
+            point.heading(point.heading() === 't' ? true : false);
+            point.children([]);
 
-            points.forEach(point => {
-                const node = idmap[point.id() + ''];
-                if (point.parent()) {
-                    idmap[point.parent() + ''].children.push(node);
-                } else {
-                    this.tree = new Tree(node);
-                }
+            const node = new TreeNode({
+                id: point.id(),
+                expanded: true,
+                callerData: {point: point}
             });
+            idmap[node.id + ''] = node;
+            this.setNodeLabel(node, point).then(() => nodes.push(node));
+        });
+
+        // apply the tree parent/child relationships
+        points.forEach(point => {
+            const node = idmap[point.id() + ''];
+            if (point.parent()) {
+                idmap[point.parent() + ''].children.push(node);
+            } else {
+                this.tree = new Tree(node);
+            }
         });
     }
 
index 1de54c8..4ffa40c 100644 (file)
             [(ngModel)]="values.matchScore" step="0.1"/>
         </div>
       </div>
-      <div class="row mb-1">
-        <div class="col-lg-3">Negate:</div>
-        <div class="col-lg-2">
-          <input type="checkbox" 
-            class="form-check-input" [(ngModel)]="values.negate"/>
+      <ng-container *ngIf="!isForQuality">
+        <div class="row mb-1">
+          <div class="col-lg-3">Negate:</div>
+          <div class="col-lg-2">
+            <input type="checkbox" 
+              class="form-check-input" [(ngModel)]="values.negate"/>
+          </div>
         </div>
-      </div>
+      </ng-container>
     </ng-container>
     <ng-container *ngIf="values.pointType=='bool'">
       <div class="row mb-1">
         </div>
       </div>
     </ng-container>
+    <ng-container *ngIf="isForQuality">
+      <div class="row mb-1">
+        <div class="col-lg-3" i18n>Value:</div>
+        <div class="col-lg-2">
+          <input type="text" class="form-control" required 
+            [(ngModel)]="values.value"/>
+        </div>
+      </div>
+    </ng-container>
   </div>
 </div>
 
index 8e74602..6298981 100644 (file)
@@ -13,6 +13,7 @@ export class MatchSetPointValues {
     marcSf: string;
     heading: string;
     boolOp: string;
+    value: string;
 }
 
 @Component({
@@ -26,6 +27,9 @@ export class MatchSetNewPointComponent implements OnInit {
     bibAttrDefs: IdlObject[];
     bibAttrDefEntries: ComboboxEntry[];
 
+    // defining a new match_set_quality
+    @Input() isForQuality: boolean;
+
     // biblio, authority, quality
     @Input() set pointType(type_: string) { 
         this.values.pointType = type_;
@@ -35,6 +39,7 @@ export class MatchSetNewPointComponent implements OnInit {
         this.values.marcTag = '';
         this.values.marcSf = '';
         this.values.boolOp = 'AND';
+        this.values.value = '';
     }
 
     constructor(
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/vandelay/match-set-quality.component.html b/Open-ILS/src/eg2/src/app/staff/cat/vandelay/match-set-quality.component.html
new file mode 100644 (file)
index 0000000..5229ddf
--- /dev/null
@@ -0,0 +1,27 @@
+<div class="row mt-2">
+  <div class="col-lg-7">
+    <div class="row ml-2 mt-4">
+      <span class="mr-2" i18n>Add New:</span>
+      <button class="btn btn-outline-dark mr-2" *ngIf="matchSetType=='biblio'"
+        (click)="newPointType='attr'" i18n>Record Attribute</button>
+      <button class="btn btn-outline-dark mr-2" 
+        (click)="newPointType='marc'" i18n>MARC Tag and Subfield</button>
+    </div>
+    <eg-match-set-new-point #newPoint 
+      [pointType]="newPointType" [isForQuality]="true">
+    </eg-match-set-new-point>
+    <div class="row mt-2 ml-2" *ngIf="newPointType">
+      <button class="btn btn-success mr-2" 
+        (click)="addQuality()" i18n>Add</button>
+      <button class="btn btn-warning"
+        (click)="newPointType=null" i18n>Cancel</button>
+    </div>
+  </div>
+</div>
+
+<eg-grid idlClass="vmsq" [dataSource]="dataSource" #grid
+  persistKey="staff.cat.vandelay.match_set.quality">
+  <eg-grid-toolbar-action label="Delete Selected" i18n-label 
+    [action]="deleteSelected"></eg-grid-toolbar-action>
+</eg-grid>
+
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/vandelay/match-set-quality.component.ts b/Open-ILS/src/eg2/src/app/staff/cat/vandelay/match-set-quality.component.ts
new file mode 100644 (file)
index 0000000..b2409c1
--- /dev/null
@@ -0,0 +1,105 @@
+import {Component, OnInit, ViewChild, AfterViewInit, Input} from '@angular/core';
+import {Observable} from 'rxjs/Observable';
+import 'rxjs/add/observable/of';
+import {IdlObject, IdlService} from '@eg/core/idl.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {NetService} from '@eg/core/net.service';
+import {AuthService} from '@eg/core/auth.service';
+import {OrgService} from '@eg/core/org.service';
+import {GridComponent} from '@eg/share/grid/grid.component';
+import {GridDataSource} from '@eg/share/grid/grid';
+import {Pager} from '@eg/share/util/pager';
+import {MatchSetNewPointComponent} from './match-set-new-point.component';
+
+@Component({
+  selector: 'eg-match-set-quality',
+  templateUrl: 'match-set-quality.component.html'
+})
+export class MatchSetQualityComponent implements OnInit {
+
+    // Match set arrives from parent async.
+    matchSet_: IdlObject;
+    @Input() set matchSet(ms: IdlObject) {
+        this.matchSet_ = ms;
+        if (ms) { 
+            this.matchSetType = ms.mtype(); 
+            if (this.grid) {
+                this.grid.reload();
+            }
+        }
+    }
+
+    newPointType: string;
+    matchSetType: string;
+    dataSource: GridDataSource;
+    @ViewChild('newPoint') newPoint: MatchSetNewPointComponent;
+    @ViewChild('grid') grid: GridComponent;
+    deleteSelected: (rows: IdlObject[]) => void;
+
+    constructor(
+        private idl: IdlService,
+        private pcrud: PcrudService,
+        private net: NetService,
+        private auth: AuthService,
+        private org: OrgService
+    ) {
+
+        this.dataSource = new GridDataSource();
+        this.dataSource.getRows = (pager: Pager, sort: any[]) => {
+
+            if (!this.matchSet_) {
+                return Observable.of();
+            }
+
+            const orderBy: any = {};
+            if (sort.length) {
+                orderBy.vmsq = sort[0].name + ' ' + sort[0].dir;
+            }
+
+            const searchOps = {
+                offset: pager.offset,
+                limit: pager.limit,
+                order_by: orderBy
+            };
+
+            const search = {match_set: this.matchSet_.id()};
+            return this.pcrud.search('vmsq', search, searchOps);
+        }
+
+        this.deleteSelected = (rows: any[]) => {
+            this.pcrud.remove(rows).subscribe(
+                ok  => console.log('deleted ', ok),
+                err => console.error(err),
+                ()  => this.grid.reload()
+            );
+        };
+    }
+
+    ngOnInit() {}
+
+    addQuality() {
+        const quality = this.idl.create('vmsq');  
+        const values = this.newPoint.values;
+
+        quality.match_set(this.matchSet_.id());
+        quality.quality(values.matchScore);
+        quality.value(values.value);
+
+        if (values.recordAttr) {
+            quality.svf(values.recordAttr);
+        } else {
+            quality.tag(values.marcTag);
+            quality.subfield(values.marcSf);
+        }
+
+        this.pcrud.create(quality).subscribe(
+            ok  => console.debug('created ', ok),
+            err => console.error(err),
+            ()  => {
+                this.newPointType = null;
+                this.grid.reload();
+            }
+        );
+    }
+}
+
index 2c88b34..fd69cf9 100644 (file)
@@ -29,6 +29,8 @@
        </ngb-tab>
        <ngb-tab title="Match Set Quality Metrics" i18n-title id="quality">
                <ng-template ngbTabContent>
+      <eg-match-set-quality [matchSet]="matchSet">
+      </eg-match-set-quality>
                </ng-template>
        </ngb-tab>
 </ngb-tabset>
index 31dbd92..a4ce09e 100644 (file)
@@ -20,6 +20,7 @@ import {RecordItemsComponent} from './record-items.component';
 import {MatchSetListComponent} from './match-set-list.component';
 import {MatchSetComponent} from './match-set.component';
 import {MatchSetExpressionComponent} from './match-set-expression.component';
+import {MatchSetQualityComponent} from './match-set-quality.component';
 import {MatchSetNewPointComponent} from './match-set-new-point.component';
 
 @NgModule({
@@ -39,6 +40,7 @@ import {MatchSetNewPointComponent} from './match-set-new-point.component';
     MatchSetListComponent,
     MatchSetComponent,
     MatchSetExpressionComponent,
+    MatchSetQualityComponent,
     MatchSetNewPointComponent
   ],
   imports: [