// Useful for massaging the match string prior to comparison
// and display. Default version trims leading/trailing spaces.
- formatDisplayString: (ComboboxEntry) => string;
+ formatDisplayString: (e: ComboboxEntry) => string;
constructor(
private elm: ElementRef,
</eg-grid-toolbar-action>
<eg-grid-toolbar-action
- i18n-group group="Add" i18n-label label="Add Items Notes"
+ i18n-group group="Add" i18n-label label="Add Item Alerts"
(onClick)="openItemNotes($event, 'create')">
</eg-grid-toolbar-action>
+
+ <!-- row actions: Edit -->
+
+ <eg-grid-toolbar-action
+ i18n-group group="Edit" i18n-label label="Edit Item Alerts"
+ (onClick)="openItemNotes($event, 'manage')">
+ </eg-grid-toolbar-action>
<!-- row actions : Show -->
'cat.holdings_show_vols'
]);
- this.volsCheckbox.checked(settings['cat.holdings_show_vols']);
+ // Show volumes by default when no preference is set.
+ let showVols = settings['cat.holdings_show_vols'];
+ if (showVols === null) { showVols = true; }
+
+ this.volsCheckbox.checked(showVols);
this.copiesCheckbox.checked(settings['cat.holdings_show_copies']);
this.emptyVolsCheckbox.checked(settings['cat.holdings_show_empty']);
this.emptyLibsCheckbox.checked(settings['cat.holdings_show_empty_org']);
this.copyAlertsDialog.copyIds = copyIds;
this.copyAlertsDialog.mode = mode;
- this.copyAlertsDialog.open({}).then(
+ this.copyAlertsDialog.open({size: 'lg'}).then(
modified => {
if (modified) {
this.hardRefresh();
<eg-string #successMsg text="Successfully Modified Copy Alerts" i18n-text></eg-string>
<eg-string #errorMsg text="Failed To Modify Copy Alerts" i18n-text></eg-string>
+<eg-confirm-dialog #confirmDeleteDialog dialogBody="Delete Alert?"
+ i18n-dialogBody></eg-confirm-dialog>
<ng-template #dialogContent>
- <div class="modal-header bg-info">
+ <div class="modal-header">
<h4 class="modal-title">
- <span i18n>Manage Copy Alerts</span>
+ <ng-container *ngIf="mode == 'create'">
+ <span i18n>Adding alerts for {{copies.length}} item(s).</span>
+ </ng-container>
+ <ng-container *ngIf="mode == 'manage'">
+ <span i18n>Managing alerts for item {{copies[0].barcode()}}</span>
+ </ng-container>
+ <span i18n></span>
</h4>
<button type="button" class="close"
i18n-aria-label aria-label="Close" (click)="dismiss('cross_click')">
<span aria-hidden="true">×</span>
</button>
</div>
- <div class="modal-body">
- <ng-container *ngIf="mode == 'create'">
- <span i18n>Adding alerts for {{copies.length}} item(s).</span>
- </ng-container>
+ <div class="modal-body p-4">
+ <div class="row mt-2 p-2 rounded border border-success">
+ <div class="col-lg-5">
+ <div class="d-flex flex-column">
+ <eg-combobox [entries]="alertTypes"
+ i18n-placeholder placeholder="New Alert Type..."
+ (onChange)="newAlert.alert_type($event ? $event.id : null)">
+ </eg-combobox>
+ <div class="form-check pt-2">
+ <input class="form-check-input" type="checkbox"
+ [ngModel]="newAlert.temp() == 't'"
+ (ngModelChange)="newAlert.temp($event ? 't' : 'f')"
+ id="new-alert-temporary">
+ <label class="form-check-label" for="new-alert-temporary" i18n>
+ Temporary?
+ </label>
+ </div>
+ </div>
+ </div>
+ <div class="col-lg-5">
+ <textarea class="form-control" rows="2"
+ i18n-placeholder placeholder="New Alert Note..."
+ (ngModelChange)="newAlert.note($event)" [ngModel]="newAlert.note()">
+ </textarea>
+ </div>
+ <div class="col-lg-2">
+ <button class="btn btn-success" (click)="addNew()" i18n>
+ Add New
+ </button>
+ </div>
+ </div>
<ng-container *ngIf="mode == 'manage'">
- <span i18n>Managing alerts for item {{copies[0].barcode()}}</span>
+ <!-- in manage mode list all of the alerts linked to the copy -->
+ <div class="row mt-2"
+ *ngFor="let alert of copy.copy_alerts()">
+ <div class="col-lg-12 pb-2"><hr/></div>
+ <div class="col-lg-5">
+ <div class="d-flex flex-column">
+ <eg-combobox [entries]="alertTypes" [startId]="alert.alert_type()"
+ i18n-placeholder placeholder="Alert Type..."
+ (onChange)="alert.alert_type($event ? $event.id : null); alert.ischanged(true)">
+ </eg-combobox>
+ <div class="form-check pt-2">
+ <input class="form-check-input" type="checkbox"
+ [ngModel]="alert.temp() == 't'"
+ (ngModelChange)="alert.temp($event ? 't' : 'f'); alert.ischanged(true)"
+ id="alert-temporary-{{alert.id()}}">
+ <label class="form-check-label" for="alert-temporary-{{alert.id()}}" i18n>
+ Temporary?
+ </label>
+ </div>
+ </div>
+ </div>
+ <div class="col-lg-5">
+ <textarea class="form-control" rows="2"
+ i18n-placeholder placeholder="Alert Note..."
+ (ngModelChange)="alert.note($event); alert.ischanged(true)"
+ [ngModel]="alert.note()">
+ </textarea>
+ </div>
+ <div class="col-lg-2">
+ <button class="btn btn-warning" (click)="deleteAlert(alert)" i18n>
+ Delete
+ </button>
+ </div>
+ </div>
</ng-container>
</div>
<div class="modal-footer">
- <button type="button" class="btn btn-warning"
- (click)="dismiss('canceled')" i18n>Cancel</button>
- <button class="btn btn-info mr-2"
- (click)="save()" i18n>Apply Changes</button>
+ <button type="button" class="btn btn-secondary"
+ (click)="dismiss('canceled')" i18n>Close</button>
+ <ng-container *ngIf="mode == 'manage'">
+ <button class="btn btn-success mr-2"
+ (click)="applyChanges()" i18n>Apply Changes</button>
+ </ng-container>
</div>
</ng-template>
import {Component, OnInit, Input, ViewChild} from '@angular/core';
import {NetService} from '@eg/core/net.service';
-import {IdlObject} from '@eg/core/idl.service';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
import {EventService} from '@eg/core/event.service';
import {ToastService} from '@eg/share/toast/toast.service';
import {AuthService} from '@eg/core/auth.service';
import {DialogComponent} from '@eg/share/dialog/dialog.component';
import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
+import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
/**
* Dialog for managing copy alerts.
return this._copyIds;
}
- _mode: string;
+ _mode: string; // create | manage
@Input() set mode(m: string) {
this._mode = m;
}
return this._mode;
}
+ // In 'create' mode, we may be adding notes to multiple copies.
copies: IdlObject[];
- alertTypes: IdlObject[];
+ // In 'manage' mode we only handle a single copy.
+ copy: IdlObject;
+ alertTypes: ComboboxEntry[];
+ newAlert: IdlObject;
+ changesMade: boolean;
@ViewChild('successMsg') private successMsg: StringComponent;
@ViewChild('errorMsg') private errorMsg: StringComponent;
+ @ViewChild('confirmDeleteDialog')
+ private confirmDeleteDialog: ConfirmDialogComponent;
constructor(
private modal: NgbModal, // required for passing to parent
private toast: ToastService,
private net: NetService,
- private evt: EventService,
+ private idl: IdlService,
private pcrud: PcrudService,
private org: OrgService,
private auth: AuthService) {
* the mark-damanged action occured or was dismissed.
*/
async open(args: NgbModalOptions): Promise<boolean> {
+ this.copy = null;
this.copies = [];
+ this.newAlert = this.idl.create('aca');
+ this.newAlert.create_staff(this.auth.user().id());
if (this.copyIds.length === 0) {
return Promise.reject('copy ID required');
}
async getAlertTypes(): Promise<any> {
- return this.pcrud.retrieveAll('aca', {}, {atomic: true})
- .toPromise().then(alerts => this.alertTypes = alerts);
+ return this.pcrud.retrieveAll('ccat',
+ { active: true,
+ scope_org: this.org.ancestors(this.auth.user().ws_ou(), true)
+ }, {atomic: true}
+ ).toPromise().then(alerts => {
+ this.alertTypes = alerts.map(a => ({id: a.id(), label: a.name()}));
+ });
}
async getCopies(): Promise<any> {
{id: this.copyIds},
{flesh: 1, flesh_fields: {acp: ['call_number', 'copy_alerts']}},
{atomic: true}
- ).toPromise().then(copies => this.copies = copies);
+ ).toPromise().then(copies => {
+ this.copies = copies;
+ if (this.mode === 'manage') {
+ this.copy = copies[0];
+ }
+ });
+ }
+
+ // Add the in-progress new note to all copies.
+ addNew() {
+ if (!this.newAlert.alert_type()) { return; }
+
+ const alerts: IdlObject[] = [];
+ this.copies.forEach(c => {
+ const a = this.idl.clone(this.newAlert);
+ a.copy(c.id());
+ alerts.push(a);
+ });
+
+ this.pcrud.create(alerts).toPromise().then(
+ newAlert => {
+ this.successMsg.current().then(msg => this.toast.success(msg));
+ this.changesMade = true;
+ if (this.mode === 'create') {
+ // In create mode, we assume the user wants to create
+ // a single alert and be done with it.
+ this.close(this.changesMade);
+ } else {
+ // Otherwise, add the alert to the copy
+ this.copy.copy_alerts().push(newAlert);
+ }
+ },
+ err => {
+ this.errorMsg.current().then(msg => this.toast.danger(msg))
+ }
+ );
+ }
+
+ deleteAlert(copyAlert: IdlObject) {
+ this.confirmDeleteDialog.open().then(
+ ok => {
+ this.pcrud.remove(copyAlert).toPromise().then(
+ ok => {
+ this.changesMade = true;
+ this.copy.copy_alerts( // Remove the delete alert
+ this.copy.copy_alerts()
+ .filter(a => a.id() !== copyAlert.id())
+ )
+ this.successMsg.current().then(msg => this.toast.success(msg));
+ },
+ err => {
+ this.errorMsg.current().then(msg => this.toast.danger(msg))
+ }
+ );
+ },
+ dismissed => {}
+ );
}
- save() {
- this.close(false);
+ applyChanges() {
+ const alerts = this.copy.copy_alerts().filter(a => a.ischanged());
+ if (alerts.length === 0) { return ;}
+ this.pcrud.update(alerts).toPromise().then(
+ ok => this.successMsg.current().then(msg => this.toast.success(msg)),
+ err => this.errorMsg.current().then(msg => this.toast.danger(msg))
+ )
}
}