LP 1907921: Add a patron search button to course admin screen
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / admin / local / course-reserves / course-associate-users.component.ts
1 import {Component, Input, ViewChild, OnInit} from '@angular/core';
2 import {DialogComponent} from '@eg/share/dialog/dialog.component';
3 import {AuthService} from '@eg/core/auth.service';
4 import {NetService} from '@eg/core/net.service';
5 import {PcrudService} from '@eg/core/pcrud.service';
6 import {Pager} from '@eg/share/util/pager';
7 import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
8 import {GridDataSource} from '@eg/share/grid/grid';
9 import {GridComponent} from '@eg/share/grid/grid.component';
10 import {IdlObject} from '@eg/core/idl.service';
11 import {StringComponent} from '@eg/share/string/string.component';
12 import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
13 import {PatronSearchDialogComponent} from '@eg/staff/share/patron/search-dialog.component';
14 import {ToastService} from '@eg/share/toast/toast.service';
15 import {CourseService} from '@eg/staff/share/course.service';
16 import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
17
18 @Component({
19     selector: 'eg-course-associate-users-dialog',
20     templateUrl: './course-associate-users.component.html'
21 })
22
23 export class CourseAssociateUsersComponent extends DialogComponent implements OnInit {
24     @Input() currentCourse: IdlObject;
25     @Input() courseId: number;
26     @Input() displayMode: String;
27     users: any[] = [];
28     @ViewChild('editDialog', { static: true }) editDialog: FmRecordEditorComponent;
29     @ViewChild('patronSearch') patronSearch: PatronSearchDialogComponent;
30     @ViewChild('usersGrid') usersGrid: GridComponent;
31     @ViewChild('userDeleteFailedString', { static: true })
32         userDeleteFailedString: StringComponent;
33     @ViewChild('userDeleteSuccessString', { static: true })
34         userDeleteSuccessString: StringComponent;
35     @ViewChild('userAddSuccessString', { static: true })
36         userAddSuccessString: StringComponent;
37     @ViewChild('userAddFailedString', { static: true })
38         userAddFailedString: StringComponent;
39     @ViewChild('userEditSuccessString', { static: true })
40         userEditSuccessString: StringComponent;
41     @ViewChild('userEditFailedString', { static: true })
42         userEditFailedString: StringComponent;
43     usersDataSource: GridDataSource;
44     userBarcode: String;
45     userRoleInput: ComboboxEntry;
46
47     constructor(
48         private auth: AuthService,
49         private course: CourseService,
50         private net: NetService,
51         private pcrud: PcrudService,
52         private toast: ToastService,
53         private modal: NgbModal
54     ) {
55         super(modal);
56         this.usersDataSource = new GridDataSource();
57     }
58
59     ngOnInit() {
60         this.usersDataSource.getRows = (pager: Pager, sort: any[]) => {
61             return this.course.getUsers([this.courseId]);
62         };
63     }
64
65     isDialog(): boolean {
66         return this.displayMode === 'dialog';
67     }
68
69     associateUser(barcode) {
70         if (barcode) {
71             const args = {
72                 currentCourse: this.currentCourse,
73                 barcode: barcode.trim(),
74             };
75
76             if (this.userRoleInput) {
77                 args['role'] = this.userRoleInput.id;
78             }
79
80             this.userBarcode = null;
81
82             this.net.request(
83                 'open-ils.actor',
84                 'open-ils.actor.user.retrieve_id_by_barcode_or_username',
85                 this.auth.token(), barcode.trim()
86             ).subscribe(patron => {
87                     this.course.associateUsers(patron, args)
88                     .then(() => this.usersGrid.reload());
89                 }, err => {
90                     this.userAddFailedString.current().then(str => this.toast.danger(str));
91                 }
92             );
93         }
94     }
95
96     editSelectedUsers(userFields: IdlObject[]) {
97         // Edit each IDL thing one at a time
98         const editOneThing = (user: IdlObject) => {
99             if (!user) { return; }
100
101             this.showEditDialog(user).then(
102                 () => editOneThing(userFields.shift()));
103         };
104
105         editOneThing(userFields.shift());
106     }
107
108     searchPatrons() {
109         this.patronSearch.open({size: 'xl'}).toPromise().then(
110             patrons => {
111                 if (!patrons || patrons.length === 0) { return; }
112                 const user = patrons[0];
113                 this.userBarcode = user.card().barcode();
114             }
115         );
116     }
117
118     showEditDialog(user: IdlObject): Promise<any> {
119         this.editDialog.mode = 'update';
120         this.editDialog.recordId = user.id();
121         return new Promise((resolve, reject) => {
122             this.editDialog.open({size: 'lg'}).subscribe(
123                 result => {
124                     this.userEditSuccessString.current()
125                         .then(str => this.toast.success(str));
126                     this.usersGrid.reload();
127                     resolve(result);
128                 },
129                 error => {
130                     this.userEditFailedString.current()
131                         .then(str => this.toast.danger(str));
132                     reject(error);
133                 }
134             );
135         });
136     }
137
138     deleteSelectedUsers(users) {
139         const acmcu_ids = users.map(u => u.id());
140         this.pcrud.search('acmcu', {course: this.courseId, id: acmcu_ids}).subscribe(user => {
141             user.isdeleted(true);
142             this.pcrud.autoApply(user).subscribe(
143                 val => {
144                     console.debug('deleted: ' + val);
145                     this.userDeleteSuccessString.current().then(str => this.toast.success(str));
146                     this.usersGrid.reload();
147                 },
148                 err => {
149                     this.userDeleteFailedString.current()
150                         .then(str => this.toast.danger(str));
151                 }
152             );
153         }).add(() => this.usersGrid.reload());
154     }
155
156 }