<div class="col-lg-6">
<span class="font-weight-bold" i18n>Show:</span>
<button class="btn btn-sm btn-outline-dark ml-2"
- [disabled]="context.editorFieldVisibilityLevel == 2"
+ [disabled]="visibilityLevel == 2"
(click)="changeFields(2)" i18n>Required Fields</button>
<button class="btn btn-sm btn-outline-dark ml-2"
- [disabled]="context.editorFieldVisibilityLevel == 1"
+ [disabled]="visibilityLevel == 1"
(click)="changeFields(1)" i18n>Suggested Fields</button>
<button class="btn btn-sm btn-outline-dark ml-2"
- [disabled]="context.editorFieldVisibilityLevel == 0"
+ [disabled]="visibilityLevel == 0"
(click)="changeFields(0)" i18n>All Fields</button>
</div>
<div class="col-lg-6 d-flex">
<div class="ml-auto">
- <button class="btn btn-outline-dark"
- (click)="context.printClicked.emit()" i18n>Print</button>
- <button class="btn btn-outline-dark ml-2"
- (click)="context.saveClicked.emit()" i18n>Save</button>
- <button class="btn btn-outline-dark ml-2"
- (click)="context.saveCloneClicked.emit()" i18n>Save & Clone</button>
+ <button class="btn btn-outline-dark"
+ (click)="printClicked.emit()" i18n>Print</button>
+ <button class="btn btn-outline-dark ml-2" [disabled]="disableSave"
+ (click)="saveClicked.emit()" i18n>Save</button>
+ <button class="btn btn-outline-dark ml-2" [disabled]="disableSave"
+ (click)="saveCloneClicked.emit()" i18n>Save & Clone</button>
</div>
</div>
</div>
import {OrgService} from '@eg/core/org.service';
import {NetService} from '@eg/core/net.service';
import {PatronService} from '@eg/staff/share/patron/patron.service';
-import {PatronContextService, FieldVisibilityLevel} from './patron.service';
+import {PatronContextService} from './patron.service';
+
+export enum VisibilityLevel {
+ ALL_FIELDS = 0,
+ SUGGESTED_FIELDS = 1,
+ REQUIRED_FIELDS = 2
+}
@Component({
templateUrl: 'edit-toolbar.component.html',
})
export class EditToolbarComponent implements OnInit {
+ disableSave = false;
+ visibilityLevel: VisibilityLevel = VisibilityLevel.ALL_FIELDS;
+
+ disableSaveStateChanged: EventEmitter<boolean> = new EventEmitter<boolean>();
+
+ saveClicked: EventEmitter<void> = new EventEmitter<void>();
+ saveCloneClicked: EventEmitter<void> = new EventEmitter<void>();
+ printClicked: EventEmitter<void> = new EventEmitter<void>();
+
constructor(
private org: OrgService,
private net: NetService,
) {}
ngOnInit() {
+ // Emitted by our editor component.
+ this.disableSaveStateChanged.subscribe(d => this.disableSave = d);
}
- changeFields(v: FieldVisibilityLevel) {
- this.context.editorFieldVisibilityLevel = v;
+ changeFields(v: VisibilityLevel) {
+ this.visibilityLevel = v;
}
}
<eg-patron-secondary-groups [secondaryGroups]="secondaryGroups" #secondaryGroupsDialog>
</eg-patron-secondary-groups>
+<eg-patron-barcodes #barcodesDialog [patron]="patron"></eg-patron-barcodes>
<div class="row" *ngIf="loading">
<div class="col-lg-6 offset-lg-3">
<button class="btn btn-outline-dark" (click)="replaceBarcode()" i18n>
Replace Barcode
</button>
- <button class="btn btn-outline-dark ml-2" (click)="showBarcodes()" i18n>
+ <button class="btn btn-outline-dark ml-2" (click)="barcodesDialog.open()" i18n>
See All
</button>
</div>
import {AuthService} from '@eg/core/auth.service';
import {PcrudService} from '@eg/core/pcrud.service';
import {PatronService} from '@eg/staff/share/patron/patron.service';
-import {PatronContextService, FieldVisibilityLevel} from './patron.service';
+import {PatronContextService} from './patron.service';
import {ComboboxComponent, ComboboxEntry} from '@eg/share/combobox/combobox.component';
import {DateUtil} from '@eg/share/util/date';
import {ProfileSelectComponent} from '@eg/staff/share/patron/profile-select.component';
import {PermService} from '@eg/core/perm.service';
import {SecondaryGroupsDialogComponent} from './secondary-groups.component';
import {ServerStoreService} from '@eg/core/server-store.service';
+import {EditToolbarComponent, VisibilityLevel} from './edit-toolbar.component';
const COMMON_USER_SETTING_TYPES = [
'circ.holds_behind_desk',
@Input() patronId: number;
@Input() cloneId: number;
@Input() stageUsername: string;
+ @Input() toolbar: EditToolbarComponent;
@ViewChild('profileSelect')
private profileSelect: ProfileSelectComponent;
optInSettingTypes: {[name: string]: IdlObject} = {};
secondaryGroups: IdlObject[];
expireDate: Date;
+ changesPending = false;
fieldVisibility: {[key: string]: FieldVisibility} = {};
ngOnInit() {
// Listen for edit-toolbar events
- this.context.saveClicked.subscribe(_ => this.save());
- this.context.saveCloneClicked.subscribe(_ => this.saveClone());
- this.context.printClicked.subscribe(_ => this.printPatron());
+ this.toolbar.saveClicked.subscribe(_ => this.save());
+ this.toolbar.saveCloneClicked.subscribe(_ => this.saveClone());
+ this.toolbar.printClicked.subscribe(_ => this.printPatron());
this.load();
}
.then(_ => this.loading = false);
}
+ setupToolbar() {
+ }
+
setSurveys(): Promise<any> {
return this.patronService.getSurveys()
.then(surveys => this.surveys = surveys);
return this.objectFromPath(path, index)[field]();
}
+ adjustSaveSate() {
+ // Avoid responding to any value changes while we are loading
+ if (this.loading) { return; }
- userStatCatChange(cat: IdlObject, entry: ComboboxEntry) {
- // TODO: set dirty
+ // TODO other checks
+ this.changesPending = true;
+ const canSave = document.querySelector('.ng-invalid') === null;
+ this.toolbar.disableSaveStateChanged.emit(!canSave);
+ }
+
+ userStatCatChange(cat: IdlObject, entry: ComboboxEntry) {
let map = this.patron.stat_cat_entries()
.filter(m => m.stat_cat() === cat.id())[0];
map.target_usr(this.patronId);
this.patron.stat_cat_entries().push(map);
}
+
+ this.adjustSaveSate();
}
userSettingChange(name: string, value: any) {
- // TODO: set dirty
this.userSettings[name] = value;
+ this.adjustSaveSate();
}
applySurveyResponse(question: IdlObject, answer: ComboboxEntry) {
if (!this.changeHandlerNeeded) { return; } // no changes applied
this.changeHandlerNeeded = false;
- // TODO: set dirty
-
const obj = this.objectFromPath(path, index);
const value = this.getFieldValue(path, index, field);
obj.ischanged(true); // isnew() supersedes
this.setExpireDate();
break;
}
+ this.adjustSaveSate();
}
showField(field: string): boolean {
this.fieldVisibility[field] = DEFAULT_FIELD_VISIBILITY[field] || 0;
}
- return this.fieldVisibility[field] >=
- this.context.editorFieldVisibilityLevel;
+ return this.fieldVisibility[field] >= this.toolbar.visibilityLevel;
}
fieldRequired(field: string): boolean {
- // TODO
- return false;
+
+ // Password field is not required for existing patrons.
+ if (field === 'au.passwd' && !this.patronId) {
+ return false;
+ }
+
+ return this.fieldVisibility[field] == 3;
}
showBarcodes() {
}
+
+ canSave(): boolean {
+ return document.querySelector('.ng-invalid') === null;
+ }
}
<li ngbNavItem="edit" [disabled]="!context.patron">
<a ngbNavLink i18n>Edit</a>
<ng-template ngbNavContent>
- <eg-patron-edit [patronId]="patronId"></eg-patron-edit>
+ <eg-patron-edit [patronId]="patronId" [toolbar]="editorToolbar">
+ </eg-patron-edit>
</ng-template>
</li>
<ng-container *ngIf="patronTab === 'edit'">
<!-- put the editor toolbar up here in the sticky section -->
- <eg-patron-edit-toolbar></eg-patron-edit-toolbar>
+ <eg-patron-edit-toolbar #editorToolbar></eg-patron-edit-toolbar>
</ng-container>
</div><!-- end of sticky top -->
-import {Component, OnInit, AfterViewInit} from '@angular/core';
+import {Component, ViewChild, OnInit, AfterViewInit} from '@angular/core';
import {Router, ActivatedRoute, ParamMap} from '@angular/router';
import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
import {NetService} from '@eg/core/net.service';
import {PatronContextService, BillGridEntry} from './patron.service';
import {PatronSearch, PatronSearchComponent
} from '@eg/staff/share/patron/search.component';
+import {EditToolbarComponent} from './edit-toolbar.component';
const MAIN_TABS =
['checkout', 'items_out', 'holds', 'bills', 'messages', 'edit', 'search'];
showSummary = true;
loading = true;
+ /* eg-patron-edit is unable to find #editorToolbar directly
+ * within the template. Adding a ref here allows it to
+ * successfully transfer to the editor */
+ @ViewChild('editorToolbar') editorToolbar: EditToolbarComponent;
+
constructor(
private router: Router,
private route: ActivatedRoute,
import {PatronGroupComponent} from './group.component';
import {RegisterPatronComponent} from './register.component';
import {SecondaryGroupsDialogComponent} from './secondary-groups.component';
+import {PatronBarcodesDialogComponent} from './barcodes.component';
@NgModule({
declarations: [
PatronGroupComponent,
RegisterPatronComponent,
PatronStatCatsComponent,
+ PatronBarcodesDialogComponent,
SecondaryGroupsDialogComponent
],
imports: [
import {StoreService} from '@eg/core/store.service';
import {CircService, CircDisplayInfo} from '@eg/staff/share/circ/circ.service';
-export enum FieldVisibilityLevel {
- ALL_FIELDS = 0,
- SUGGESTED_FIELDS = 1,
- REQUIRED_FIELDS = 2
-}
-
export interface BillGridEntry extends CircDisplayInfo {
xact: IdlObject; // mbt
billingLocation?: string;
settingsCache: {[key: string]: any} = {};
- // Emitted by the patron edit toolbar, which is kept as a
- // separate component so it can be positioned differently.
- // We just act as a go-between.
- saveClicked: EventEmitter<void> = new EventEmitter<void>();
- saveCloneClicked: EventEmitter<void> = new EventEmitter<void>();
- printClicked: EventEmitter<void> = new EventEmitter<void>();
-
- editorFieldVisibilityLevel: FieldVisibilityLevel =
- FieldVisibilityLevel.ALL_FIELDS;
-
constructor(
private store: StoreService,
private net: NetService,
<div class="sticky-top-with-nav bg-white">
- <eg-patron-edit-toolbar></eg-patron-edit-toolbar>
- <eg-patron-edit [stageUsername]="stageUsername" [cloneId]="cloneId">
+ <eg-patron-edit-toolbar #editorToolbar></eg-patron-edit-toolbar>
+ <eg-patron-edit [stageUsername]="stageUsername"
+ [cloneId]="cloneId" [toolbar]="editorToolbar">
</eg-patron-edit>
</div>