// opChangeUser refers to the user that has been superseded during
// an op-change event. opChangeUser resumes its status as the
// activeUser once the op-change cycle has completed.
- private opChangeUser: EgAuthUser;
+ private opChangeUser: EgAuthUser = null;
workstationState: EgAuthWsState = EgAuthWsState.PENDING;
new BroadcastChannel('eg.auth') : {};
}
+ // Returns true if we are currently in op-change mode.
+ opChangeIsActive(): boolean {
+ return this.opChangeUser !== null;
+ }
// - Accessor functions always refer to the active user.
Shared Angular services, components, directives, and associated classes.
-These items are NOT automatically imported to the base module. Import
-as needed.
+These items are NOT automatically imported to the base module, though some
+may already be imported by intermediate modules (e.g. EgStaffCommonModule).
+Import as needed.
-import {Component, Input, ViewChild, TemplateRef} from '@angular/core';
+import {Component, Input, OnInit, ViewChild, TemplateRef, EventEmitter} from '@angular/core';
import {NgbModal, NgbModalRef, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
/**
selector: 'eg-dialog',
template: '<ng-template></ng-template>'
})
-export class EgDialogComponent {
+export class EgDialogComponent implements OnInit {
// Assume all dialogs support a title attribute.
@Input() public dialogTitle: string;
@ViewChild('dialogContent')
private dialogContent: TemplateRef<any>;
+ // Emitted after open() is called on the ngbModal.
+ // Note when overriding open(), this will not fire unless also
+ // called in the overridding method.
+ onOpen$ = new EventEmitter<any>();
+
// The modalRef allows direct control of the modal instance.
private modalRef: NgbModalRef = null;
constructor(private modalService: NgbModal) {}
+ ngOnInit() {
+ this.onOpen$ = new EventEmitter<any>();
+ }
+
open(options?: NgbModalOptions): Promise<any> {
if (this.modalRef !== null) {
}
this.modalRef = this.modalService.open(this.dialogContent, options);
+
+ if (this.onOpen$) {
+ // Let the digest cycle complete
+ setTimeout(() => this.onOpen$.emit(true));
+ }
+
return new Promise( (resolve, reject) => {
this.modalRef.result.then(
import {ResultsComponent} from './result/results.component';
import {RecordComponent} from './record/record.component';
import {CopiesComponent} from './record/copies.component';
-import {EgBibSummaryComponent} from '../share/bib-summary.component';
+import {EgBibSummaryComponent} from '@eg/staff/share/bib-summary/bib-summary.component';
import {ResultPaginationComponent} from './result/pagination.component';
import {ResultFacetsComponent} from './result/facets.component';
import {ResultRecordComponent} from './result/record.component';
from '@eg/share/catalog/search-context';
import {EgCatalogService} from '@eg/share/catalog/catalog.service';
import {StaffCatalogService} from '../catalog.service';
-import {EgBibSummaryComponent} from '../../share/bib-summary.component';
+import {EgBibSummaryComponent} from '@eg/staff/share/bib-summary/bib-summary.component';
@Component({
selector: 'eg-catalog-record',
import {EgAccessKeyDirective} from '@eg/share/accesskey/accesskey.directive';
import {EgAccessKeyService} from '@eg/share/accesskey/accesskey.service';
import {EgAccessKeyInfoComponent} from '@eg/share/accesskey/accesskey-info.component';
+import {EgOpChangeComponent} from '@eg/staff/share/op-change/op-change.component';
+import {EgToastService} from '@eg/share/toast/toast.service';
+import {EgToastComponent} from '@eg/share/toast/toast.component';
/**
* Imports the EG common modules and adds modules common to all staff UI's.
EgPromptDialogComponent,
EgProgressDialogComponent,
EgAccessKeyDirective,
- EgAccessKeyInfoComponent
+ EgAccessKeyInfoComponent,
+ EgToastComponent,
+ EgOpChangeComponent
],
imports: [
EgCommonModule
EgPromptDialogComponent,
EgProgressDialogComponent,
EgAccessKeyDirective,
- EgAccessKeyInfoComponent
+ EgAccessKeyInfoComponent,
+ EgToastComponent,
+ EgOpChangeComponent
]
})
static forRoot(): ModuleWithProviders {
return {
ngModule: EgStaffCommonModule,
- providers: [
- EgAccessKeyService
- /* placeholder for exporting staff-wide services */
+ providers: [ // Export staff-wide services
+ EgAccessKeyService,
+ EgToastService
]
};
}
-
}
+
<i class="material-icons">list</i>
</a>
<div class="dropdown-menu" ngbDropdownMenu>
+ <eg-op-change #navOpChange></eg-op-change>
+ <a class="dropdown-item" *ngIf="!opChangeActive()"
+ (click)="navOpChange.open()">
+ <span class="material-icons">transform</span>
+ <span i18n>Change Operator</span>
+ </a>
+ <a *ngIf="opChangeActive()" class="dropdown-item"
+ (click)="restoreOperator()">
+ <span class="material-icons">transform</span>
+ <span i18n>Restore Operator</span>
+ </a>
<a class="dropdown-item" (click)="logout()">
<span class="material-icons">lock_outline</span>
<span i18n>Logout</span>
}
}
+ opChangeActive(): boolean {
+ return this.auth.opChangeIsActive();
+ }
+
+ restoreOperator() {
+ this.auth.undoOpChange().then(
+ ok => {
+ console.log('OP change undo succeeded');
+ },
+
+ err => {
+ console.warn('OP change undo auth expired');
+ this.router.navigate(['/staff/login']);
+ }
+ );
+ }
+
// Broadcast to all tabs that we're logging out.
// Redirect to the login page, which performs the remaining
// logout duties.
</div>
<!-- /Progress Dialog Experiments ----------------------------- -->
+<!-- eg toast -->
+<button class="btn btn-info" (click)="testToast()">Test Toast Message</button>
+
import {Component, OnInit, ViewChild} from '@angular/core';
import {EgProgressDialogComponent} from '@eg/share/dialog/progress.component';
+import {EgToastService} from '@eg/share/toast/toast.service';
@Component({
templateUrl: 'sandbox.component.html'
@ViewChild('progressDialog')
private progressDialog: EgProgressDialogComponent;
- constructor() {}
+ constructor(
+ private toast: EgToastService
+ ) {}
ngOnInit() {
}
setTimeout(() => this.progressDialog.update({value: 95}), 4000);
setTimeout(() => this.progressDialog.close(), 5000);
}
+
+ testToast() {
+ this.toast.success('HELLO TOAST TEST');
+ }
}
+++ /dev/null
-
-<div class='eg-bib-summary card tight-card w-100' *ngIf="summary">
- <div class="card-header d-flex">
- <div class="font-weight-bold">
- Record Summary
- </div>
- <div class="flex-1"></div>
- <div>
- <a class="with-material-icon no-href text-primary"
- title="Show More" i18n-title
- *ngIf="!expandDisplay" (click)="expandDisplay=true">
- <span class="material-icons">expand_more</span>
- </a>
- <a class="with-material-icon no-href text-primary"
- title="Show Less" i18n-title
- *ngIf="expandDisplay" (click)="expandDisplay=false">
- <span class="material-icons">expand_less</span>
- </a>
- </div>
- </div>
- <div class="card-body">
- <ul class="list-group list-group-flush">
- <li class="list-group-item">
- <div class="d-flex">
- <div class="flex-1 font-weight-bold" i18n>Title:</div>
- <div class="flex-3">{{summary.title}}</div>
- <div class="flex-1 font-weight-bold pl-1" i18n>Edition:</div>
- <div class="flex-1">{{summary.edition}}</div>
- <div class="flex-1 font-weight-bold" i18n>TCN:</div>
- <div class="flex-1">{{summary.tcn_value}}</div>
- <div class="flex-1 font-weight-bold pl-1" i18n>Created By:</div>
- <div class="flex-1" *ngIf="summary.creator.usrname">
- {{summary.creator.usrname()}}
- </div>
- </div>
- </li>
- <li class="list-group-item" *ngIf="expandDisplay">
- <div class="d-flex">
- <div class="flex-1 font-weight-bold" i18n>Author:</div>
- <div class="flex-3">{{summary.author}}</div>
- <div class="flex-1 font-weight-bold pl-1" i18n>Pubdate:</div>
- <div class="flex-1">{{summary.pubdate}}</div>
- <div class="flex-1 font-weight-bold" i18n>Database ID:</div>
- <div class="flex-1">{{summary.id}}</div>
- <div class="flex-1 font-weight-bold pl-1" i18n>Last Edited By:</div>
- <div class="flex-1" *ngIf="summary.editor.usrname">
- {{summary.editor.usrname()}}
- </div>
- </div>
- </li>
- <li class="list-group-item" *ngIf="expandDisplay">
- <div class="d-flex">
- <div class="flex-1 font-weight-bold" i18n>Bib Call #:</div>
- <div class="flex-3">{{summary.callNumber}}</div>
- <div class="flex-1 font-weight-bold" i18n>Record Owner:</div>
- <div class="flex-1">TODO</div>
- <div class="flex-1 font-weight-bold pl-1" i18n>Created On:</div>
- <div class="flex-1">{{summary.create_date | date:'shortDate'}}</div>
- <div class="flex-1 font-weight-bold pl-1" i18n>Last Edited On:</div>
- <div class="flex-1">{{summary.edit_date | date:'shortDate'}}</div>
- </div>
- </li>
- </ul>
- </div>
-</div>
-
+++ /dev/null
-import {Component, OnInit, Input} from '@angular/core';
-import {EgNetService} from '@eg/core/net.service';
-import {EgPcrudService} from '@eg/core/pcrud.service';
-import {EgCatalogService} from '@eg/share/catalog/catalog.service';
-
-@Component({
- selector: 'eg-bib-summary',
- templateUrl: 'bib-summary.component.html'
-})
-export class EgBibSummaryComponent implements OnInit {
-
- initDone: boolean = false;
-
- // If provided, the record will be fetched by the component.
- @Input() recordId: number;
-
- // Otherwise, we'll use the provided bib summary object.
- summary: any;
- @Input() set bibSummary(s: any) {
- this.summary = s;
- if (this.initDone) this.fetchBibCallNumber();
- }
-
- expandDisplay: boolean = true;
-
- constructor(
- private cat: EgCatalogService,
- private net: EgNetService,
- private pcrud: EgPcrudService
- ) {}
-
- ngOnInit() {
- this.initDone = true;
- if (this.summary) {
- this.fetchBibCallNumber();
- } else {
- if (this.recordId) this.loadSummary();
- }
- }
-
- loadSummary(): void {
- this.cat.getBibSummary(this.recordId).then(summary => {
- this.summary = summary;
- this.fetchBibCallNumber();
-
- // Flesh the user data
- this.pcrud.search('au', {id: [summary.creator, summary.editor]})
- .subscribe(user => {
- if (user.id() == summary.creator)
- summary.creator = user;
- if (user.id() == summary.editor)
- summary.editor = user;
- })
- });
- }
-
- fetchBibCallNumber(): void {
- if (!this.summary || this.summary.callNumber) return;
-
- // TODO labelClass = cat.default_classification_scheme YAOUS
- let labelClass = 1;
-
- this.net.request(
- 'open-ils.cat',
- 'open-ils.cat.biblio.record.marc_cn.retrieve',
- this.summary.id, labelClass
- ).subscribe(cnArray => {
- if (cnArray && cnArray.length > 0) {
- let key1 = Object.keys(cnArray[0])[0];
- this.summary.callNumber = cnArray[0][key1];
- }
- });
- }
-}
-
-
--- /dev/null
+
+<div class='eg-bib-summary card tight-card w-100' *ngIf="summary">
+ <div class="card-header d-flex">
+ <div class="font-weight-bold">
+ Record Summary
+ </div>
+ <div class="flex-1"></div>
+ <div>
+ <a class="with-material-icon no-href text-primary"
+ title="Show More" i18n-title
+ *ngIf="!expandDisplay" (click)="expandDisplay=true">
+ <span class="material-icons">expand_more</span>
+ </a>
+ <a class="with-material-icon no-href text-primary"
+ title="Show Less" i18n-title
+ *ngIf="expandDisplay" (click)="expandDisplay=false">
+ <span class="material-icons">expand_less</span>
+ </a>
+ </div>
+ </div>
+ <div class="card-body">
+ <ul class="list-group list-group-flush">
+ <li class="list-group-item">
+ <div class="d-flex">
+ <div class="flex-1 font-weight-bold" i18n>Title:</div>
+ <div class="flex-3">{{summary.title}}</div>
+ <div class="flex-1 font-weight-bold pl-1" i18n>Edition:</div>
+ <div class="flex-1">{{summary.edition}}</div>
+ <div class="flex-1 font-weight-bold" i18n>TCN:</div>
+ <div class="flex-1">{{summary.tcn_value}}</div>
+ <div class="flex-1 font-weight-bold pl-1" i18n>Created By:</div>
+ <div class="flex-1" *ngIf="summary.creator.usrname">
+ {{summary.creator.usrname()}}
+ </div>
+ </div>
+ </li>
+ <li class="list-group-item" *ngIf="expandDisplay">
+ <div class="d-flex">
+ <div class="flex-1 font-weight-bold" i18n>Author:</div>
+ <div class="flex-3">{{summary.author}}</div>
+ <div class="flex-1 font-weight-bold pl-1" i18n>Pubdate:</div>
+ <div class="flex-1">{{summary.pubdate}}</div>
+ <div class="flex-1 font-weight-bold" i18n>Database ID:</div>
+ <div class="flex-1">{{summary.id}}</div>
+ <div class="flex-1 font-weight-bold pl-1" i18n>Last Edited By:</div>
+ <div class="flex-1" *ngIf="summary.editor.usrname">
+ {{summary.editor.usrname()}}
+ </div>
+ </div>
+ </li>
+ <li class="list-group-item" *ngIf="expandDisplay">
+ <div class="d-flex">
+ <div class="flex-1 font-weight-bold" i18n>Bib Call #:</div>
+ <div class="flex-3">{{summary.callNumber}}</div>
+ <div class="flex-1 font-weight-bold" i18n>Record Owner:</div>
+ <div class="flex-1">TODO</div>
+ <div class="flex-1 font-weight-bold pl-1" i18n>Created On:</div>
+ <div class="flex-1">{{summary.create_date | date:'shortDate'}}</div>
+ <div class="flex-1 font-weight-bold pl-1" i18n>Last Edited On:</div>
+ <div class="flex-1">{{summary.edit_date | date:'shortDate'}}</div>
+ </div>
+ </li>
+ </ul>
+ </div>
+</div>
+
--- /dev/null
+import {Component, OnInit, Input} from '@angular/core';
+import {EgNetService} from '@eg/core/net.service';
+import {EgPcrudService} from '@eg/core/pcrud.service';
+import {EgCatalogService} from '@eg/share/catalog/catalog.service';
+
+@Component({
+ selector: 'eg-bib-summary',
+ templateUrl: 'bib-summary.component.html'
+})
+export class EgBibSummaryComponent implements OnInit {
+
+ initDone: boolean = false;
+
+ // If provided, the record will be fetched by the component.
+ @Input() recordId: number;
+
+ // Otherwise, we'll use the provided bib summary object.
+ summary: any;
+ @Input() set bibSummary(s: any) {
+ this.summary = s;
+ if (this.initDone) this.fetchBibCallNumber();
+ }
+
+ expandDisplay: boolean = true;
+
+ constructor(
+ private cat: EgCatalogService,
+ private net: EgNetService,
+ private pcrud: EgPcrudService
+ ) {}
+
+ ngOnInit() {
+ this.initDone = true;
+ if (this.summary) {
+ this.fetchBibCallNumber();
+ } else {
+ if (this.recordId) this.loadSummary();
+ }
+ }
+
+ loadSummary(): void {
+ this.cat.getBibSummary(this.recordId).then(summary => {
+ this.summary = summary;
+ this.fetchBibCallNumber();
+
+ // Flesh the user data
+ this.pcrud.search('au', {id: [summary.creator, summary.editor]})
+ .subscribe(user => {
+ if (user.id() == summary.creator)
+ summary.creator = user;
+ if (user.id() == summary.editor)
+ summary.editor = user;
+ })
+ });
+ }
+
+ fetchBibCallNumber(): void {
+ if (!this.summary || this.summary.callNumber) return;
+
+ // TODO labelClass = cat.default_classification_scheme YAOUS
+ let labelClass = 1;
+
+ this.net.request(
+ 'open-ils.cat',
+ 'open-ils.cat.biblio.record.marc_cn.retrieve',
+ this.summary.id, labelClass
+ ).subscribe(cnArray => {
+ if (cnArray && cnArray.length > 0) {
+ let key1 = Object.keys(cnArray[0])[0];
+ this.summary.callNumber = cnArray[0][key1];
+ }
+ });
+ }
+}
+
+
(click)="egAccessKeyInfo.open()">
</a>
+<!-- global toast alerts -->
+<eg-toast></eg-toast>