LP#1779158 Initial support for displaying active imports
authorBill Erickson <berickxx@gmail.com>
Thu, 20 Sep 2018 21:50:07 +0000 (17:50 -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/active-imports.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/cat/vandelay/active-imports.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/cat/vandelay/routing.module.ts
Open-ILS/src/eg2/src/app/staff/cat/vandelay/vandelay.component.html
Open-ILS/src/eg2/src/app/staff/cat/vandelay/vandelay.module.ts

diff --git a/Open-ILS/src/eg2/src/app/staff/cat/vandelay/active-imports.component.html b/Open-ILS/src/eg2/src/app/staff/cat/vandelay/active-imports.component.html
new file mode 100644 (file)
index 0000000..153fc4f
--- /dev/null
@@ -0,0 +1,46 @@
+
+
+
+  <div class="row" *ngFor="let tracker of trackers">
+    <div class="col-lg-6">
+      <div class="card">
+        <div class="card-header">
+          <div class="panel-title text-center">
+            <span i18n>Import Tracker {{tracker.name()}}</span>
+          </div>
+        </div>
+        <div class="card-body">
+          <div class="list-group">
+            <div class="list-group-item border-0 p-2">
+              <!-- .id (not .id()) check to see if it's fleshed yet -->
+              <span i18n *ngIf="tracker.queue().id">
+                Created for Queue 
+                <a routerLink="/staff/cat/vandelay/queue/{{tracker.record_type()}}/{{tracker.queue().id()}}">
+                  {{tracker.queue().name()}}
+                </a>
+                on {{tracker.create_time() | date}}
+              </span>
+            </div>
+            <div class="list-group-item border-0 p-2">
+                <span i18n>State: 
+                    <span *ngIf="tracker.state() == 'active'" i18n>Active</span>
+                    <span *ngIf="tracker.state() == 'complete'" i18n>Complete</span>
+                    <span *ngIf="tracker.state() == 'error'" i18n>Error</span>
+                </span>
+                <span class='pl-3' *ngIf="tracker.state() == 'complete'">
+                    <span class="material-icons text-success">thumb_up</span>
+                </span>
+            </div>
+            <div class="list-group-item border-0 p-2">
+                <!-- ensure the progress shows 100% when complete -->
+                <eg-progress-inline 
+                    [max]="tracker.state() == 'complete' ? tracker.actions_performed() : tracker.total_actions() || null"
+                    [value]="tracker.actions_performed()">
+                </eg-progress-inline>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/vandelay/active-imports.component.ts b/Open-ILS/src/eg2/src/app/staff/cat/vandelay/active-imports.component.ts
new file mode 100644 (file)
index 0000000..7fc353a
--- /dev/null
@@ -0,0 +1,92 @@
+import {Component, OnInit} from '@angular/core';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
+import {AuthService} from '@eg/core/auth.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {VandelayService} from './vandelay.service';
+
+@Component({
+    templateUrl: 'active-imports.component.html'
+})
+
+export class ActiveImportsComponent implements OnInit {
+
+    trackers: IdlObject[];
+    refreshInterval = 2000; // ms
+
+    constructor(
+        private idl: IdlService,
+        private auth: AuthService,
+        private pcrud: PcrudService,
+        private vandelay: VandelayService
+    ) {
+        this.trackers = [];
+    }
+
+    ngOnInit() {
+        this.pollTrackers();
+    }
+
+    pollTrackers() {
+
+        const prevTrackers = this.trackers;
+
+        // Report on active trackers for this workstation and for the
+        // logged in user, plus any that were already reported in the
+        // current instance of the UI.
+        const query: any = {
+            '-and' : [
+                {
+                    '-or': [
+                        {workstation: this.auth.user().wsid()},
+                        {usr: this.auth.user().id()}
+                    ]
+                }
+            ]
+        };
+
+        if (this.trackers.length) {
+            query['-and'].push({
+                '-or': [
+                    {state: 'active'},
+                    {id: prevTrackers.map(t => t.id())}
+                ]
+            });
+        } else {
+            query['-and'].push({state: 'active'});
+        }
+
+        this.pcrud.search('vst', query, {order_by: {vst: 'create_time'}})
+        .subscribe(
+            tracker => {
+                // The screen flickers less if the tracker array is 
+                // updated inline instead of rebuilt every time.
+
+                const existing = 
+                    this.trackers.filter(t => t.id() === tracker.id())[0];
+
+                if (existing) {
+                    existing.update_time(tracker.update_time());
+                    existing.state(tracker.state());
+                    existing.total_actions(tracker.total_actions());
+                    existing.actions_performed(tracker.actions_performed());
+                } else {
+                    this.trackers.push(tracker);
+
+                    // TODO: flesh the queue / check record_type
+                }
+            },
+            err => {},
+            ()  => {
+                const active = 
+                    this.trackers.filter(t => t.state() === 'active');
+
+                // Continue updating the display with updated tracker
+                // data as long as we have any active trackers.
+                if (active.length > 0) {
+                    setTimeout(
+                        () => this.pollTrackers(), this.refreshInterval);
+                }
+            }
+        );
+    }
+}
index a7776d5..aee0720 100644 (file)
@@ -12,6 +12,7 @@ import {HoldingsProfilesComponent} from './holdings-profiles.component';
 import {QueueItemsComponent} from './queue-items.component';
 import {MatchSetListComponent} from './match-set-list.component';
 import {MatchSetComponent} from './match-set.component';
+import {ActiveImportsComponent} from './active-imports.component';
 
 const routes: Routes = [{
   path: '',
@@ -59,6 +60,9 @@ const routes: Routes = [{
   }, {
     path: 'match_sets/:id/:matchSetTab',
     component: MatchSetComponent
+  }, {
+    path: 'active_imports',
+    component: ActiveImportsComponent
   }]
 }];
 
index 1fc1a52..24471ed 100644 (file)
       routerLink="/staff/cat/vandelay/holdings_profiles" 
       i18n>Holdings Import Profiles</a>
   </li>
+  <li class="nav-item">
+    <a class="nav-link" [ngClass]="{active: tab=='active_imports'}" 
+      routerLink="/staff/cat/vandelay/active_imports" 
+      i18n>Active Imports</a>
+  </li>
 </ul>
 
 <!-- load nav-specific page -->
index a4ce09e..1a1d9b1 100644 (file)
@@ -22,6 +22,7 @@ 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';
+import {ActiveImportsComponent} from './active-imports.component';
 
 @NgModule({
   declarations: [
@@ -41,7 +42,8 @@ import {MatchSetNewPointComponent} from './match-set-new-point.component';
     MatchSetComponent,
     MatchSetExpressionComponent,
     MatchSetQualityComponent,
-    MatchSetNewPointComponent
+    MatchSetNewPointComponent,
+    ActiveImportsComponent
   ],
   imports: [
     TreeModule,