]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/admin/local/course-reserves/course-associate-material.component.ts
LP1849212: Angular Course Page improvements, OPAC course search
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / admin / local / course-reserves / course-associate-material.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-material-dialog',
23     templateUrl: './course-associate-material.component.html'
24 })
25
26 export class CourseAssociateMaterialComponent extends DialogComponent {
27     @Input() currentCourse: IdlObject;
28     @Input() courseId: any;
29     @Input() displayMode: String;
30     materials: any[] = [];
31     @ViewChild('editDialog', { static: true }) editDialog: FmRecordEditorComponent;
32     @ViewChild('materialsGrid', {static: true}) materialsGrid: GridComponent;
33     @ViewChild('materialDeleteFailedString', { static: true })
34         materialDeleteFailedString: StringComponent;
35     @ViewChild('materialDeleteSuccessString', { static: true })
36         materialDeleteSuccessString: StringComponent;
37     @ViewChild('materialAddSuccessString', { static: true })
38         materialAddSuccessString: StringComponent;
39     @ViewChild('materialAddFailedString', { static: true })
40         materialAddFailedString: StringComponent;
41     @ViewChild('materialEditSuccessString', { static: true })
42         materialEditSuccessString: StringComponent;
43     @ViewChild('materialEditFailedString', { static: true })
44         materialEditFailedString: StringComponent;
45     @ViewChild('materialAddDifferentLibraryString', { static: true })
46         materialAddDifferentLibraryString: StringComponent;
47     materialsDataSource: GridDataSource;
48     @Input() barcodeInput: String;
49     @Input() relationshipInput: String;
50     @Input() tempCallNumber: String;
51     @Input() tempStatus: Number;
52     @Input() tempLocation: Number;
53     @Input() tempCircMod: String;
54     @Input() isModifyingStatus: Boolean;
55     @Input() isModifyingCircMod: Boolean;
56     @Input() isModifyingCallNumber: Boolean;
57     @Input() isModifyingLocation: Boolean;
58
59     constructor(
60         private auth: AuthService,
61         private course: CourseService,
62         private event: EventService,
63         private idl: IdlService,
64         private net: NetService,
65         private org: OrgService,
66         private pcrud: PcrudService,
67         private route: ActivatedRoute,
68         private toast: ToastService,
69         private modal: NgbModal
70     ) {
71         super(modal);
72         this.materialsDataSource = new GridDataSource();
73     }
74
75     ngOnInit() {
76         this.materialsDataSource.getRows = (pager: Pager, sort: any[]) => {
77             return this.loadMaterialsGrid(pager);
78         }
79     }
80
81     isDialog(): boolean {
82         return this.displayMode === 'dialog';
83     }
84
85     loadMaterialsGrid(pager: Pager): Observable<any> {
86         return new Observable<any>(observer => {
87             this.course.getMaterials(this.courseId).then(materials => {
88                 materials.forEach(material => {
89                     this.course.fleshMaterial(material).then(fleshed_material => {
90                         this.materialsDataSource.data.push(fleshed_material);
91                     });
92                 });
93             });
94             observer.complete();
95         });
96     }
97
98     editSelectedMaterials(itemFields: IdlObject[]) {
99         // Edit each IDL thing one at a time
100         const editOneThing = (item: IdlObject) => {
101             if (!item) { return; }
102
103             this.showEditDialog(item).then(
104                 () => editOneThing(itemFields.shift()));
105         };
106
107         editOneThing(itemFields.shift());
108     }
109
110     showEditDialog(course_material: IdlObject): Promise<any> {
111         this.editDialog.mode = 'update';
112         this.editDialog.recordId = course_material._id;
113         return new Promise((resolve, reject) => {
114             this.editDialog.open({size: 'lg'}).subscribe(
115                 result => {
116                     this.materialEditSuccessString.current()
117                         .then(str => this.toast.success(str));
118                     this.pcrud.retrieve('acmcm', result).subscribe(material => {
119                         if (material.course() != this.courseId) {
120                             this.materialsDataSource.data.splice(
121                                 this.materialsDataSource.data.indexOf(course_material, 0), 1
122                             );
123                         } else {
124                             course_material._relationship = material.relationship();
125                         }
126                     });
127                     resolve(result);
128                 },
129                 error => {
130                     this.materialEditFailedString.current()
131                         .then(str => this.toast.danger(str));
132                     reject(error);
133                 }
134             );
135         });
136     }
137     
138     associateItem(barcode, relationship) {
139         if (barcode) {
140             let args = {
141                 barcode: barcode,
142                 relationship: relationship,
143                 isModifyingCallNumber: this.isModifyingCallNumber,
144                 isModifyingCircMod: this.isModifyingCircMod,
145                 isModifyingLocation: this.isModifyingLocation,
146                 isModifyingStatus: this.isModifyingStatus,
147                 tempCircMod: this.tempCircMod,
148                 tempLocation: this.tempLocation,
149                 tempStatus: this.tempStatus,
150                 currentCourse: this.currentCourse
151             }
152             this.barcodeInput = null;
153
154             this.pcrud.search('acp', {barcode: args.barcode}, {
155                 flesh: 3, flesh_fields: {acp: ['call_number']}
156             }).subscribe(item => {
157                 let associatedMaterial = this.course.associateMaterials(item, args);
158                 associatedMaterial.material.then(res => {
159                     item = associatedMaterial.item;
160                     let new_cn = item.call_number().label();
161                     if (this.tempCallNumber) new_cn = this.tempCallNumber;
162                     this.course.updateItem(item, this.currentCourse.owning_lib(),
163                         new_cn, args.isModifyingCallNumber
164                     ).then(resp => {
165                         this.course.fleshMaterial(res).then(fleshed_material => {
166                             this.materialsDataSource.data.push(fleshed_material);
167                         });
168                         if (item.circ_lib() != this.currentCourse.owning_lib()) {
169                             this.materialAddDifferentLibraryString.current()
170                             .then(str => this.toast.warning(str));
171                         } else {
172                             this.materialAddSuccessString.current()
173                             .then(str => this.toast.success(str));
174                         }
175                     });
176                 }, err => {
177                     this.materialAddFailedString.current()
178                     .then(str => this.toast.danger(str));
179                 });
180             });
181         }
182     }
183
184     deleteSelectedMaterials(items) {
185         let item_ids = [];
186         items.forEach(item => {
187             this.materialsDataSource.data.splice(this.materialsDataSource.data.indexOf(item, 0), 1);
188             item_ids.push(item.id())
189         });
190         this.pcrud.search('acmcm', {course: this.courseId, item: item_ids}).subscribe(material => {
191             material.isdeleted(true);
192             this.pcrud.autoApply(material).subscribe(
193                 val => {
194                     this.course.resetItemFields(material, this.currentCourse.owning_lib());
195                     console.debug('deleted: ' + val);
196                     this.materialDeleteSuccessString.current().then(str => this.toast.success(str));
197                 },
198                 err => {
199                     this.materialDeleteFailedString.current()
200                         .then(str => this.toast.danger(str));
201                 }
202             );
203         });
204     }
205 }