LPXXX Port work log to Angular user/berick/lpxxx-work-log-angular
authorBill Erickson <berickxx@gmail.com>
Wed, 16 Feb 2022 22:45:51 +0000 (17:45 -0500)
committerBill Erickson <berickxx@gmail.com>
Wed, 16 Feb 2022 22:48:43 +0000 (17:48 -0500)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html
Open-ILS/src/eg2/src/app/staff/circ/routing.module.ts
Open-ILS/src/eg2/src/app/staff/circ/worklog/routing.module.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/circ/worklog/worklog.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/circ/worklog/worklog.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/circ/worklog/worklog.module.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/nav.component.html
Open-ILS/src/eg2/src/app/staff/share/worklog/worklog.service.ts
Open-ILS/src/templates/staff/navbar.tt2

index b852b98..6c4c3a5 100644 (file)
@@ -75,6 +75,6 @@
     <eg-link-table-link i18n-label label="Transit List" 
       url="/eg/staff/circ/transits/list"></eg-link-table-link>
     <eg-link-table-link i18n-label label="Work Log" 
-      url="/eg/staff/admin/workstation/log"></eg-link-table-link>
+      routerLink="/staff/circ/worklog"></eg-link-table-link>
   </eg-link-table>
 </div>
index 9a151cf..0b11749 100644 (file)
@@ -10,6 +10,10 @@ const routes: Routes = [{
   loadChildren: () =>
     import('./item/routing.module').then(m => m.CircItemRoutingModule)
 }, {
+  path: 'worklog',
+  loadChildren: () =>
+    import('./worklog/worklog.module').then(m => m.CircWorkLogModule)
+}, {
   path: 'holds',
   loadChildren: () =>
     import('./holds/holds.module').then(m => m.HoldsUiModule)
diff --git a/Open-ILS/src/eg2/src/app/staff/circ/worklog/routing.module.ts b/Open-ILS/src/eg2/src/app/staff/circ/worklog/routing.module.ts
new file mode 100644 (file)
index 0000000..2207831
--- /dev/null
@@ -0,0 +1,14 @@
+import {NgModule} from '@angular/core';
+import {RouterModule, Routes} from '@angular/router';
+import {CircWorkLogComponent} from './worklog.component';
+
+const routes: Routes = [{
+  path: '',
+  component: CircWorkLogComponent
+}];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+export class CircWorkLogRoutingModule {}
diff --git a/Open-ILS/src/eg2/src/app/staff/circ/worklog/worklog.component.html b/Open-ILS/src/eg2/src/app/staff/circ/worklog/worklog.component.html
new file mode 100644 (file)
index 0000000..143c1e0
--- /dev/null
@@ -0,0 +1,101 @@
+<eg-staff-banner i18n-bannerText bannerText="Work Log"></eg-staff-banner>
+
+<eg-worklog-strings-components></eg-worklog-strings-components>
+
+<ng-template #barcodeTemplate let-r="row">
+  <a target="_blank" href="/eg/staff/circ/patron/{{r.usr().id()}}/edit">
+    {{r.usr().card().barcode()}}
+  </a>
+</ng-template>
+
+<ng-template #userTemplate let-row="row">
+  <a *ngIf="row.user && row.patron_id"
+    routerLink="/staff/circ/patron/{{row.patron_id}}">{{row.user}}</a>
+</ng-template>
+
+<ng-template #itemTemplate let-row="row">
+  <a *ngIf="row.item && row.item_id"
+    routerLink="/staff/cat/item/{{row.item_id}}/summary">{{row.item}}</a>
+</ng-template>
+
+
+<eg-grid #grid [dataSource]="actionDataSource" 
+       [sortable]="true" [useLocalSort]="true" [cellTextGenerator]="cellTextGenerator"
+  toolbarLabel="Most Recently Logged Staff Actions" i18n-toolbarLabel
+  persistKey="circ.worklog.actions" (onRowActivate)="showPatron($event)">
+
+  <eg-grid-toolbar-action i18n-label label="Retrieve Patron"
+    (onClick)="showPatron($event[0])"></eg-grid-toolbar-action>
+
+  <eg-grid-toolbar-action i18n-label label="Retrieve Item"
+    (onClick)="showItem($event[0])"></eg-grid-toolbar-action>
+
+  <eg-grid-column path='index' i18n-label label="Index" [index]="true" 
+    [hidden]="true"></eg-grid-column> 
+
+  <eg-grid-column path='action' i18n-label label="Code" [hidden]="true">
+  </eg-grid-column> 
+
+  <eg-grid-column path='msg' i18n-label label="Message"></eg-grid-column>        
+
+  <eg-grid-column path='amount' i18n-label label="Amount" [hidden]="true">
+  </eg-grid-column>
+
+  <eg-grid-column path='user' i18n-label label="Patron"
+    [cellTemplate]="userTemplate"></eg-grid-column>        
+
+  <eg-grid-column path='item' i18n-label label="Item"
+    [cellTemplate]="itemTemplate"></eg-grid-column>          
+
+  <eg-grid-column path='when' i18n-label label="When" datatype="timestamp" 
+    [datePlusTime]="true"></eg-grid-column>
+
+  <eg-grid-column path='actor' i18n-label label="Staff" [hidden]="true">
+  </eg-grid-column> 
+
+
+</eg-grid>
+
+<hr class="mt-2 mb-2"/>
+
+<eg-grid #grid [dataSource]="patronDataSource" 
+       [sortable]="true" [useLocalSort]="true" [cellTextGenerator]="cellTextGenerator"
+  toolbarLabel="Most Recently  Affected Patrons" i18n-toolbarLabel
+  persistKey="circ.worklog.patrons" (onRowActivate)="showPatron($event)">
+
+  <eg-grid-toolbar-action i18n-label label="Retrieve Patron"
+    (onClick)="showPatron($event[0])"></eg-grid-toolbar-action>
+
+  <eg-grid-toolbar-action i18n-label label="Retrieve Item"
+    (onClick)="showItem($event[0])"></eg-grid-toolbar-action>
+
+  <eg-grid-column path='index' i18n-label label="Index" [index]="true" 
+    [hidden]="true"></eg-grid-column> 
+
+  <eg-grid-column path='action' i18n-label label="Code" [hidden]="true">
+  </eg-grid-column> 
+
+  <eg-grid-column path='msg' i18n-label label="Message"></eg-grid-column>        
+
+  <eg-grid-column path='amount' i18n-label label="Amount" [hidden]="true">
+  </eg-grid-column>
+
+  <eg-grid-column path='user' i18n-label label="Patron"
+    [cellTemplate]="userTemplate"></eg-grid-column>        
+
+  <eg-grid-column path='item' i18n-label label="Item"
+    [cellTemplate]="itemTemplate"></eg-grid-column>          
+
+  <eg-grid-column path='when' i18n-label label="When" datatype="timestamp" 
+    [datePlusTime]="true"></eg-grid-column>
+
+  <eg-grid-column path='actor' i18n-label label="Staff" [hidden]="true">
+  </eg-grid-column> 
+
+  <!--
+  <eg-grid-column name="barcode" [cellTemplate]="barcodeTemplate">
+  </eg-grid-column>
+  -->
+
+</eg-grid>
+
diff --git a/Open-ILS/src/eg2/src/app/staff/circ/worklog/worklog.component.ts b/Open-ILS/src/eg2/src/app/staff/circ/worklog/worklog.component.ts
new file mode 100644 (file)
index 0000000..20941d0
--- /dev/null
@@ -0,0 +1,83 @@
+import {Component, OnInit, Renderer2, ViewChild} from '@angular/core';
+import {Router, ActivatedRoute} from '@angular/router';
+import {Observable, empty, of, from} from 'rxjs';
+import {concatMap} from 'rxjs/operators';
+import {IdlObject} from '@eg/core/idl.service';
+import {OrgService} from '@eg/core/org.service';
+import {AuthService} from '@eg/core/auth.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {GridDataSource, GridCellTextGenerator} from '@eg/share/grid/grid';
+import {GridComponent} from '@eg/share/grid/grid.component';
+import {Pager} from '@eg/share/util/pager';
+import {Location} from '@angular/common';
+import {WorkLogEntry, WorkLogService} from '@eg/staff/share/worklog/worklog.service';
+
+@Component({
+    templateUrl: 'worklog.component.html'
+})
+
+export class CircWorkLogComponent implements OnInit {
+
+    autoIndex = 1;
+    cellTextGenerator: GridCellTextGenerator;
+    actionDataSource: GridDataSource = new GridDataSource();
+    patronDataSource: GridDataSource = new GridDataSource();
+
+    @ViewChild('actionGrid') actionGrid: GridComponent;
+    @ViewChild('patronGrid') patronGrid: GridComponent;
+
+    constructor(
+        private router: Router,
+        private ngLocation: Location,
+        private org: OrgService,
+        private auth: AuthService,
+        private pcrud: PcrudService,
+        private workLog: WorkLogService,
+    ) { }
+
+    ngOnInit() {
+
+        this.workLog.loadSettings();
+
+        this.actionDataSource.getRows =
+            (pager: Pager, sort: any[]): Observable<any> => {
+
+            const actions = this.workLog.getActions()
+            actions.forEach(p => p.index = this.autoIndex++);
+
+            return from(actions);
+        };
+
+        this.patronDataSource.getRows =
+            (pager: Pager, sort: any[]): Observable<any> => {
+
+            const patrons = this.workLog.getPatrons();
+            patrons.forEach(p => p.index = this.autoIndex++);
+
+            return from(patrons);
+        };
+
+        this.cellTextGenerator = {
+            user: row => row.user,
+            item: row => row.item
+        };
+    }
+
+    showPatron(row: IdlObject) {
+        if (row.patron_id) {
+            const url = this.ngLocation.prepareExternalUrl(
+                `/staff/circ/patron/${row.patron_id}/checkout`);
+            window.open(url);
+        }
+    }
+
+    showItem(row: IdlObject) {
+        if (row.item_id) {
+            const url = this.ngLocation.prepareExternalUrl(
+                `/staff/cat/item/${row.item_id}/summary`);
+            window.open(url);
+        }
+    }
+
+}
+
diff --git a/Open-ILS/src/eg2/src/app/staff/circ/worklog/worklog.module.ts b/Open-ILS/src/eg2/src/app/staff/circ/worklog/worklog.module.ts
new file mode 100644 (file)
index 0000000..4becf7d
--- /dev/null
@@ -0,0 +1,21 @@
+import {NgModule} from '@angular/core';
+import {StaffCommonModule} from '@eg/staff/common.module';
+import {CircWorkLogRoutingModule} from './routing.module';
+import {CircWorkLogComponent} from './worklog.component';
+import {WorkLogModule} from '@eg/staff/share/worklog/worklog.module';
+
+@NgModule({
+  declarations: [
+    CircWorkLogComponent
+  ],
+  imports: [
+    StaffCommonModule,
+    CircWorkLogRoutingModule,
+    WorkLogModule
+  ],
+  providers: [
+  ]
+})
+
+export class CircWorkLogModule {}
+
index a2c43ff..11c3e5c 100644 (file)
             <span class="material-icons" aria-hidden="true">grid_on</span>
             <span i18n>Scan Item as Missing Pieces</span>
           </a>
+          <a class="dropdown-item" routerLink="/staff/circ/worklog">
+            <span class="material-icons">history</span>
+            <span i18n>Work Log</span>
+          </a>
           <div class="dropdown-divider"></div>
           <a class="dropdown-item" (click)="reprintLast()"
             egAccessKey keyCtx="navbar" i18n-keySpec i18n-keyDesc
index 8fe3cc1..d83e870 100644 (file)
@@ -16,6 +16,7 @@ export interface WorkLogEntry {
     patron_id?: number;
     hold_id?: number;
     amount?: number; // paid amount
+    index?: number; // for grid display
 }
 
 
@@ -42,6 +43,14 @@ export class WorkLogService {
         });
     }
 
+    getPatrons(): WorkLogEntry[] {
+        return this.store.getLocalItem('eg.patron_log') || [];
+    }
+
+    getActions(): WorkLogEntry[] {
+        return this.store.getLocalItem('eg.work_log') || [];
+    }
+
     record(entry: WorkLogEntry) {
 
         if (this.maxEntries === null) {
index 87914a8..1091713 100644 (file)
               <span>[% l('Scan Item as Missing Pieces') %]</span>
             </a>
           </li>
+          <li>
+            <a href="/eg2/staff/circ/worklog">
+              <span class="glyphicon glyphicon-th" aria-hidden="true"></span>
+              <span>[% l('Work Log') %]</span>
+            </a>
+          </li>
           <li class="divider"></li>
           <li>
             <a href="" ng-click="reprintLast($event)"