cc1f75b51e8fa0d780d717349540f489e9c77e4e
[evergreen-equinox.git] / Open-ILS / src / eg2 / src / app / staff / admin / local / course-reserves / course-list.component.ts
1 import {Component, Input, ViewChild, OnInit, AfterViewInit} from '@angular/core';
2 import {Router} from '@angular/router';
3 import {IdlObject, IdlService} from '@eg/core/idl.service';
4 import {PcrudService} from '@eg/core/pcrud.service';
5 import {CourseService} from '@eg/staff/share/course.service';
6 import {GridComponent} from '@eg/share/grid/grid.component';
7 import {Pager} from '@eg/share/util/pager';
8 import {GridDataSource, GridColumn} from '@eg/share/grid/grid';
9 import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
10 import {StringComponent} from '@eg/share/string/string.component';
11 import {ToastService} from '@eg/share/toast/toast.service';
12 import {LocaleService} from '@eg/core/locale.service';
13 import {AuthService} from '@eg/core/auth.service';
14 import {OrgService} from '@eg/core/org.service';
15 import {OrgFamily} from '@eg/share/org-family-select/org-family-select.component';
16
17 import {CourseAssociateMaterialComponent
18     } from './course-associate-material.component';
19
20 import {CourseAssociateUsersComponent
21     } from './course-associate-users.component';
22
23 @Component({
24     templateUrl: './course-list.component.html'
25 })
26
27 export class CourseListComponent implements OnInit, AfterViewInit {
28
29     @ViewChild('editDialog', { static: true }) editDialog: FmRecordEditorComponent;
30     @ViewChild('grid') grid: GridComponent;
31     @ViewChild('successString', { static: true }) successString: StringComponent;
32     @ViewChild('createString') createString: StringComponent;
33     @ViewChild('createErrString') createErrString: StringComponent;
34     @ViewChild('updateFailedString') updateFailedString: StringComponent;
35     @ViewChild('deleteFailedString', { static: true }) deleteFailedString: StringComponent;
36     @ViewChild('deleteSuccessString', { static: true }) deleteSuccessString: StringComponent;
37     @ViewChild('archiveFailedString', { static: true }) archiveFailedString: StringComponent;
38     @ViewChild('archiveSuccessString', { static: true }) archiveSuccessString: StringComponent;
39     @ViewChild('unarchiveFailedString', { static: true }) unarchiveFailedString: StringComponent;
40     @ViewChild('unarchiveSuccessString', { static: true }) unarchiveSuccessString: StringComponent;
41     @ViewChild('courseMaterialDialog', {static: true})
42         private courseMaterialDialog: CourseAssociateMaterialComponent;
43     @ViewChild('courseUserDialog', {static: true})
44         private courseUserDialog: CourseAssociateUsersComponent;
45
46     @Input() sortField: string;
47     @Input() idlClass = 'acmc';
48     @Input() dialog_size: 'sm' | 'lg' = 'lg';
49     @Input() tableName = 'Course';
50     grid_source: GridDataSource = new GridDataSource();
51     currentMaterials: any[] = [];
52     search_value = '';
53     defaultOuId: number;
54     searchOrgs: OrgFamily;
55     defaultTerm: IdlObject;
56
57
58     constructor(
59         private courseSvc: CourseService,
60         private locale: LocaleService,
61         private auth: AuthService,
62         private idl: IdlService,
63         private org: OrgService,
64         private pcrud: PcrudService,
65         private router: Router,
66         private toast: ToastService
67     ) {}
68
69     ngOnInit() {
70         this.getSource();
71         this.defaultTerm = this.idl.create('acmt');
72         this.defaultOuId = this.auth.user().ws_ou() || this.org.root().id();
73         this.defaultTerm.owning_lib(this.defaultOuId);
74         this.searchOrgs = {primaryOrgId: this.defaultOuId};
75     }
76
77     ngAfterViewInit() {
78         this.grid.onRowActivate.subscribe((course: IdlObject) => {
79             const idToEdit = course.id();
80             this.navigateToCoursePage(idToEdit);
81         });
82
83     }
84
85     acmtcmQueryParams (row: any): {gridFilters: string} {
86         return {gridFilters: '{"course":' + row.id() + '}'};
87     }
88
89
90     /**
91      * Gets the data, specified by the class, that is available.
92      */
93     getSource() {
94         this.grid_source.getRows = (pager: Pager, sort: any[]) => {
95             const orderBy: any = {};
96             if (sort.length) {
97                 // Sort specified from grid
98                 orderBy[this.idlClass] = sort[0].name + ' ' + sort[0].dir;
99             } else if (this.sortField) {
100                 // Default sort field
101                 orderBy[this.idlClass] = this.sortField;
102             }
103             const search: any = new Array();
104             const orgFilter: any = {};
105             orgFilter['owning_lib'] =
106                 this.searchOrgs.orgIds || [this.defaultOuId];
107             search.push(orgFilter);
108             const searchOps = {
109                 offset: pager.offset,
110                 limit: pager.limit,
111                 order_by: orderBy
112             };
113             return this.pcrud.search(this.idlClass, search, searchOps, {fleshSelectors: true});
114         };
115     }
116
117     navigateToCoursePage(id_arr: IdlObject[]) {
118         if (typeof id_arr === 'number') { id_arr = [id_arr]; }
119         const urls = [];
120         id_arr.forEach(id => {console.log(this.router.url);
121             urls.push([this.locale.currentLocaleCode() + this.router.url + '/' +  id]);
122         });
123         if (id_arr.length === 1) {
124         this.router.navigate([this.router.url + '/' + id_arr[0]]);
125         } else {
126             urls.forEach(url => {
127                 window.open(url);
128             });
129         }
130     }
131
132     createNew() {
133         this.editDialog.mode = 'create';
134         const course_module_course = this.idl.create('acmc');
135         course_module_course.owning_lib(this.auth.user().ws_ou());
136         this.editDialog.recordId = null;
137         this.editDialog.record = course_module_course;
138         this.editDialog.open({size: this.dialog_size}).subscribe(
139             ok => {
140                 this.createString.current()
141                     .then(str => this.toast.success(str));
142                 this.grid.reload();
143             },
144             rejection => {
145                 if (!rejection.dismissed) {
146                     this.createErrString.current()
147                         .then(str => this.toast.danger(str));
148                 }
149             }
150         );
151     }
152
153     editSelected(fields: IdlObject[]) {
154         // Edit each IDL thing one at a time
155         const course_ids = [];
156         fields.forEach(field => {
157             if (typeof field['id'] === 'function') {
158                 course_ids.push(field.id());
159             } else {
160                 course_ids.push(field['id']);
161             }
162         });
163         this.navigateToCoursePage(course_ids);
164     }
165
166     archiveSelected(course: IdlObject[]) {
167         this.courseSvc.disassociateMaterials(course).then(res => {
168             course.forEach(courseToArchive => {
169                 courseToArchive.is_archived(true);
170             });
171             this.pcrud.update(course).subscribe(
172                 val => {
173                     console.debug('archived: ' + val);
174                     this.archiveSuccessString.current()
175                         .then(str => this.toast.success(str));
176                 }, err => {
177                     this.archiveFailedString.current()
178                         .then(str => this.toast.danger(str));
179                 }, () => {
180                     this.grid.reload();
181                 }
182             );
183         });
184     }
185     
186     courseArchiveableOrNot(course: IdlObject[], archiveBool) {
187         course.forEach(courseToMod => {
188             if (archiveBool == false) return courseToMod.is_archived() == 't';
189             return courseToMod.is_archived() == 'f';
190         });
191     }
192
193     unarchiveSelected(course: IdlObject[]) {
194         course.forEach(courseToUnarchive => {
195             courseToUnarchive.is_archived(false);
196         });
197         this.pcrud.update(course).subscribe(
198             val => {
199                 course.forEach(courseEntry => {
200                     this.courseSvc.removeNonPublicUsers(courseEntry.id());
201                 });
202                 console.debug('archived: ' + val);
203                 this.unarchiveSuccessString.current()
204                     .then(str => this.toast.success(str));
205             }, err => {
206                 this.unarchiveFailedString.current()
207                     .then(str => this.toast.danger(str));
208             }, () => {
209                 this.grid.reload();
210             }
211         );
212     }
213
214     deleteSelected(idlObject: IdlObject[]) {
215         this.courseSvc.disassociateMaterials(idlObject).then(res => {
216             idlObject.forEach(object => {
217                 object.isdeleted(true);
218             });
219             this.pcrud.autoApply(idlObject).subscribe(
220                 val => {
221                     console.debug('deleted: ' + val);
222                     this.deleteSuccessString.current()
223                         .then(str => this.toast.success(str));
224                 },
225                 err => {
226                     this.deleteFailedString.current()
227                         .then(str => this.toast.danger(str));
228                 },
229                 () => this.grid.reload()
230             );
231         });
232     }
233 }
234