]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/admin/local/course-reserves/course-list.component.ts
lp1849212: Course Admin Page and OPAC improvements
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / admin / local / course-reserves / course-list.component.ts
1 import {Component, Input, ViewChild, OnInit} from '@angular/core';
2 import { Router, ActivatedRoute }    from '@angular/router';
3 import {IdlObject} from '@eg/core/idl.service';
4 import {PcrudService} from '@eg/core/pcrud.service';
5 import {AuthService} from '@eg/core/auth.service';
6 import {CourseService} from '@eg/staff/share/course.service';
7 import {NetService} from '@eg/core/net.service';
8 import {OrgService} from '@eg/core/org.service';
9 import {GridComponent} from '@eg/share/grid/grid.component';
10 import {Pager} from '@eg/share/util/pager';
11 import {GridDataSource, GridColumn} from '@eg/share/grid/grid';
12 import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
13 import {StringComponent} from '@eg/share/string/string.component';
14 import {ToastService} from '@eg/share/toast/toast.service';
15
16 import {CourseAssociateMaterialComponent
17     } from './course-associate-material.component';
18
19 @Component({
20     templateUrl: './course-list.component.html'
21 })
22
23 export class CourseListComponent implements OnInit { 
24  
25     @ViewChild('editDialog', { static: true }) editDialog: FmRecordEditorComponent;
26     @ViewChild('grid', { static: true }) grid: GridComponent;
27     @ViewChild('successString', { static: true }) successString: StringComponent;
28     @ViewChild('createString', { static: false }) createString: StringComponent;
29     @ViewChild('createErrString', { static: false }) createErrString: StringComponent;
30     @ViewChild('updateFailedString', { static: false }) updateFailedString: StringComponent;
31     @ViewChild('deleteFailedString', { static: true }) deleteFailedString: StringComponent;
32     @ViewChild('deleteSuccessString', { static: true }) deleteSuccessString: StringComponent;
33     @ViewChild('archiveFailedString', { static: true }) archiveFailedString: StringComponent;
34     @ViewChild('archiveSuccessString', { static: true }) archiveSuccessString: StringComponent;
35     @ViewChild('courseMaterialDialog', {static: true})
36         private courseMaterialDialog: CourseAssociateMaterialComponent;
37     @Input() sort_field: string;
38     @Input() idl_class = "acmc";
39     @Input() dialog_size: 'sm' | 'lg' = 'lg';
40     @Input() table_name = "Course";
41     grid_source: GridDataSource = new GridDataSource();
42     currentMaterials: any[] = [];
43     search_value = '';
44
45     constructor(
46         private auth: AuthService,
47         private courseSvc: CourseService,
48         private net: NetService,
49         private org: OrgService,
50         private pcrud: PcrudService,
51         private route: ActivatedRoute,
52         private router: Router,
53         private toast: ToastService
54     ){}
55
56     ngOnInit() {
57         this.getSource();
58         this.grid.onRowActivate.subscribe((course:IdlObject) => {
59             let idToEdit = course.id();
60             this.navigateToCoursePage(idToEdit);
61         })
62     }
63
64     /**
65      * Gets the data, specified by the class, that is available.
66      */
67     getSource() {
68         this.grid_source.getRows = (pager: Pager, sort: any[]) => {
69             const orderBy: any = {};
70             if (sort.length) {
71                 // Sort specified from grid
72                 orderBy[this.idl_class] = sort[0].name + ' ' + sort[0].dir;
73             } else if (this.sort_field) {
74                 // Default sort field
75                 orderBy[this.idl_class] = this.sort_field;
76             }
77             const searchOps = {
78                 offset: pager.offset,
79                 limit: pager.limit,
80                 order_by: orderBy
81             };
82             return this.pcrud.retrieveAll(this.idl_class, searchOps, {fleshSelectors: true});
83         };
84     }
85
86     navigateToCoursePage(id: any) {
87         this.router.navigate(["/staff/admin/local/asset/course_list/" + id]);
88     }
89
90     showEditDialog(standingPenalty: IdlObject): Promise<any> {
91         this.editDialog.mode = 'update';
92         this.editDialog.recordId = standingPenalty['id']();
93         return new Promise((resolve, reject) => {
94             this.editDialog.open({size: this.dialog_size}).subscribe(
95                 result => {
96                     this.successString.current()
97                         .then(str => this.toast.success(str));
98                     this.grid.reload();
99                     resolve(result);
100                 },
101                 error => {
102                     this.updateFailedString.current()
103                         .then(str => this.toast.danger(str));
104                     reject(error);
105                 }
106             );
107         });
108     }
109
110     createNew() {
111         this.editDialog.mode = 'create';
112         this.editDialog.recordId = null;
113         this.editDialog.record = null;
114         this.editDialog.open({size: this.dialog_size}).subscribe(
115             ok => {
116                 this.createString.current()
117                     .then(str => this.toast.success(str));
118                 this.grid.reload();
119             },
120             rejection => {
121                 if (!rejection.dismissed) {
122                     this.createErrString.current()
123                         .then(str => this.toast.danger(str));
124                 }
125             }
126         );
127     }
128
129     editSelected(fields: IdlObject[]) {
130         // Edit each IDL thing one at a time
131         const editOneThing = (field_object: IdlObject) => {
132             if (!field_object) { return; }
133             this.showEditDialog(field_object).then(
134                 () => editOneThing(fields.shift()));
135         };
136         editOneThing(fields.shift());
137     }
138
139     archiveSelected(course: IdlObject[]) {
140         this.courseSvc.disassociateMaterials(course).then(res => {
141             course.forEach(course => {
142                 console.log(course);
143                 course.is_archived(true);
144             });
145             this.pcrud.update(course).subscribe(
146                 val => {
147                     console.debug('archived: ' + val);
148                     this.archiveSuccessString.current()
149                         .then(str => this.toast.success(str));
150                 }, err => {
151                     this.archiveFailedString.current()
152                         .then(str => this.toast.danger(str));
153                 }, () => {
154                     this.grid.reload();
155                 }
156             );
157         });
158     }
159
160     deleteSelected(idl_object: IdlObject[]) {
161         this.courseSvc.disassociateMaterials(idl_object).then(res => {
162             idl_object.forEach(idl_object => {
163                 idl_object.isdeleted(true)
164             });
165             this.pcrud.autoApply(idl_object).subscribe(
166                 val => {
167                     console.debug('deleted: ' + val);
168                     this.deleteSuccessString.current()
169                         .then(str => this.toast.success(str));
170                 },
171                 err => {
172                     this.deleteFailedString.current()
173                         .then(str => this.toast.danger(str));
174                 },
175                 () => this.grid.reload()
176             );
177         });
178     };
179
180     fetchCourseMaterials(course, currentMaterials): Promise<any> {
181         return new Promise((resolve, reject) => {
182             this.pcrud.search('acmcm', {course: course}).subscribe(res => {
183                 if (res) this.fleshItemDetails(res.item(), res.relationship());
184             }, err => {
185                 reject(err);
186             }, () => resolve(this.courseMaterialDialog.gridDataSource.data));
187         });
188     }
189
190     fleshItemDetails(itemId, relationship): Promise<any> {
191         return new Promise((resolve, reject) => {
192             this.net.request(
193                 'open-ils.circ',
194                 'open-ils.circ.copy_details.retrieve',
195                 this.auth.token(), itemId
196             ).subscribe(res => {
197                 if (res) {
198                     let item = res.copy;
199                     item.call_number(res.volume);
200                     item._title = res.mvr.title();
201                     item.circ_lib(this.org.get(item.circ_lib()));
202                     item._relationship = relationship;
203                     this.courseMaterialDialog.gridDataSource.data.push(item);
204                 }
205             }, err => {
206                 reject(err);
207             }, () => resolve(this.courseMaterialDialog.gridDataSource.data));
208         });
209     }
210
211     openMaterialsDialog(course) {
212         let currentMaterials = []
213         this.courseMaterialDialog.gridDataSource.data = [];
214         this.fetchCourseMaterials(course[0].id(), currentMaterials).then(res => {
215             this.courseMaterialDialog.currentCourse = course[0];
216             this.courseMaterialDialog.materials = currentMaterials;
217             this.courseMaterialDialog.open({size: 'lg'}).subscribe(res => {
218                 console.log(res);
219             });
220         });
221     }
222 }
223