LP1849212: Angular Course Page improvements, OPAC course search
[evergreen-equinox.git] / Open-ILS / src / eg2 / src / app / staff / admin / local / course-reserves / course-associate-users.component.ts
1 import {Component, Input, ViewChild, OnInit, TemplateRef} from '@angular/core';
2 import {Router, ActivatedRoute} from '@angular/router';
3 import {Observable, Observer, of} from 'rxjs';
4 import {DialogComponent} from '@eg/share/dialog/dialog.component';
5 import {AuthService} from '@eg/core/auth.service';
6 import {NetService} from '@eg/core/net.service';
7 import {EventService} from '@eg/core/event.service';
8 import {OrgService} from '@eg/core/org.service';
9 import {PcrudService} from '@eg/core/pcrud.service';
10 import {Pager} from '@eg/share/util/pager';
11 import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
12 import {GridDataSource} from '@eg/share/grid/grid';
13 import {GridComponent} from '@eg/share/grid/grid.component';
14 import {IdlObject, IdlService} from '@eg/core/idl.service';
15 import {StringComponent} from '@eg/share/string/string.component';
16 import {StaffBannerComponent} from '@eg/staff/share/staff-banner.component';
17 import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
18 import {ToastService} from '@eg/share/toast/toast.service';
19 import {CourseService} from '@eg/staff/share/course.service';
20
21 @Component({
22     selector: 'eg-course-associate-users-dialog',
23     templateUrl: './course-associate-users.component.html'
24 })
25
26 export class CourseAssociateUsersComponent extends DialogComponent implements OnInit {
27     @Input() currentCourse: IdlObject;
28     @Input() courseId: any;
29     @Input() displayMode: String;
30     users: any[] = [];
31     @ViewChild('editDialog', { static: true }) editDialog: FmRecordEditorComponent;
32     @ViewChild('usersGrid', {static: true}) usersGrid: GridComponent;
33     @ViewChild('userDeleteFailedString', { static: true })
34         userDeleteFailedString: StringComponent;
35     @ViewChild('userDeleteSuccessString', { static: true })
36         userDeleteSuccessString: StringComponent;
37     @ViewChild('userAddSuccessString', { static: true })
38         userAddSuccessString: StringComponent;
39     @ViewChild('userAddFailedString', { static: true })
40         userAddFailedString: StringComponent;
41     @ViewChild('userEditSuccessString', { static: true })
42         userEditSuccessString: StringComponent;
43     @ViewChild('userEditFailedString', { static: true })
44         userEditFailedString: StringComponent;
45     usersDataSource: GridDataSource;
46     @Input() userBarcode: String;
47     @Input() userRoleInput: String;
48     @Input() isPublicRole: Boolean;
49
50     constructor(
51         private auth: AuthService,
52         private course: CourseService,
53         private event: EventService,
54         private idl: IdlService,
55         private net: NetService,
56         private org: OrgService,
57         private pcrud: PcrudService,
58         private route: ActivatedRoute,
59         private toast: ToastService,
60         private modal: NgbModal
61     ) {
62         super(modal);
63         this.usersDataSource = new GridDataSource();
64     }
65
66     ngOnInit() {
67         this.usersDataSource.getRows = (pager: Pager, sort: any[]) => {
68             return this.loadUsersGrid(pager);
69         }
70     }
71
72     isDialog(): boolean {
73         return this.displayMode === 'dialog';
74     }
75
76     loadUsersGrid(pager: Pager): Observable<any> {
77         return new Observable<any>(observer => {
78             this.course.getUsers(this.courseId).then(users => {
79                 users.forEach(user => {
80                     this.course.fleshUser(user).then(fleshed_user => {
81                         this.usersDataSource.data.push(fleshed_user);
82                     });
83                     observer.complete();
84                 });
85             });
86         });
87     }
88
89     associateUser(barcode) {
90         if (barcode) {
91             let args = {
92                 currentCourse: this.currentCourse,
93                 barcode: barcode,
94                 role: this.userRoleInput,
95                 is_public: this.isPublicRole
96             }
97
98             this.userBarcode = null;
99
100             this.net.request(
101                 'open-ils.actor',
102                 'open-ils.actor.user.retrieve_id_by_barcode_or_username',
103                 this.auth.token(), barcode
104             ).subscribe(patron => {
105                 let associatedUser = this.course.associateUsers(patron, args).then(res => {
106                     this.course.fleshUser(res).then(fleshed_user => {
107                         this.usersDataSource.data.push(fleshed_user);
108                         this.userAddSuccessString.current().then(str => this.toast.success(str));
109                     });
110                 }, err => {
111                     this.userAddFailedString.current().then(str => this.toast.danger(str));
112                 });
113             });
114         }
115     }
116
117     editSelectedUsers(userFields: IdlObject[]) {
118         // Edit each IDL thing one at a time
119         const editOneThing = (user: IdlObject) => {
120             if (!user) { return; }
121
122             this.showEditDialog(user).then(
123                 () => editOneThing(userFields.shift()));
124         };
125
126         editOneThing(userFields.shift());
127     }
128
129     showEditDialog(user: IdlObject): Promise<any> {
130         this.editDialog.mode = 'update';
131         this.editDialog.recordId = user._id;
132         return new Promise((resolve, reject) => {
133             this.editDialog.open({size: 'lg'}).subscribe(
134                 result => {
135                     this.userEditSuccessString.current()
136                         .then(str => this.toast.success(str));
137                     this.pcrud.retrieve('acmcu', result).subscribe(u => {
138                         if (u.course() != this.courseId) {
139                             this.usersDataSource.data.splice(this.usersDataSource.data.indexOf(user, 0), 1);
140                         } else {
141                             user._is_public = u.is_public();
142                             user._role = u.usr_role();
143                         }
144                     });
145                     resolve(result);
146                 },
147                 error => {
148                     this.userEditFailedString.current()
149                         .then(str => this.toast.danger(str));
150                     reject(error);
151                 }
152             );
153         });
154     }
155
156     deleteSelectedUsers(users) {
157         let user_ids = [];
158         users.forEach(user => {
159             this.usersDataSource.data.splice(this.usersDataSource.data.indexOf(user, 0), 1);
160             user_ids.push(user.id())
161         });
162         this.pcrud.search('acmcu', {course: this.courseId, usr: user_ids}).subscribe(user => {
163             user.isdeleted(true);
164             this.pcrud.autoApply(user).subscribe(
165                 val => {
166                     console.debug('deleted: ' + val);
167                     this.userDeleteSuccessString.current().then(str => this.toast.success(str));
168                 },
169                 err => {
170                     this.userDeleteFailedString.current()
171                         .then(str => this.toast.danger(str));
172                 }
173             );
174         });
175     }
176
177 }