]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/admin/local/course-reserves/course-list.component.ts
LP2045292 Color contrast for AngularJS patron bills
[Evergreen.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     styleUrls: ['./course-page.component.css']
26 })
27
28 export class CourseListComponent implements OnInit, AfterViewInit {
29
30     @ViewChild('editDialog', { static: true }) editDialog: FmRecordEditorComponent;
31     @ViewChild('grid') grid: GridComponent;
32     @ViewChild('successString', { static: true }) successString: StringComponent;
33     @ViewChild('createString') createString: StringComponent;
34     @ViewChild('createErrString') createErrString: StringComponent;
35     @ViewChild('updateFailedString') updateFailedString: StringComponent;
36     @ViewChild('deleteFailedString', { static: true }) deleteFailedString: StringComponent;
37     @ViewChild('deleteSuccessString', { static: true }) deleteSuccessString: StringComponent;
38     @ViewChild('archiveFailedString', { static: true }) archiveFailedString: StringComponent;
39     @ViewChild('archiveSuccessString', { static: true }) archiveSuccessString: StringComponent;
40     @ViewChild('unarchiveFailedString', { static: true }) unarchiveFailedString: StringComponent;
41     @ViewChild('unarchiveSuccessString', { static: true }) unarchiveSuccessString: StringComponent;
42     @ViewChild('duplicateFailedString', { static: true }) duplicateFailedString: StringComponent;
43     @ViewChild('duplicateSuccessString', { static: true }) duplicateSuccessString: StringComponent;
44     @ViewChild('courseMaterialDialog', {static: true})
45     private courseMaterialDialog: CourseAssociateMaterialComponent;
46     @ViewChild('courseUserDialog', {static: true})
47     private courseUserDialog: CourseAssociateUsersComponent;
48
49     @Input() sortField: string;
50     @Input() idlClass = 'acmc';
51     @Input() dialog_size: 'sm' | 'lg' = 'lg';
52     @Input() tableName = 'Course';
53     grid_source: GridDataSource = new GridDataSource();
54     currentMaterials: any[] = [];
55     search_value = '';
56     defaultOuId: number;
57     searchOrgs: OrgFamily;
58     defaultTerm: IdlObject;
59
60
61     constructor(
62         private courseSvc: CourseService,
63         private locale: LocaleService,
64         private auth: AuthService,
65         private idl: IdlService,
66         private org: OrgService,
67         private pcrud: PcrudService,
68         private router: Router,
69         private toast: ToastService
70     ) {}
71
72     ngOnInit() {
73         this.getSource();
74         this.defaultTerm = this.idl.create('acmt');
75         this.defaultOuId = this.auth.user().ws_ou() || this.org.root().id();
76         this.defaultTerm.owning_lib(this.defaultOuId);
77         this.searchOrgs = {primaryOrgId: this.defaultOuId};
78     }
79
80     ngAfterViewInit() {
81         this.grid.onRowActivate.subscribe((course: IdlObject) => {
82             const idToEdit = course.id();
83             this.navigateToCoursePage(idToEdit);
84         });
85
86     }
87
88     acmtcmQueryParams (row: any): {gridFilters: string} {
89         return {gridFilters: '{"course":' + row.id() + '}'};
90     }
91
92
93     /**
94      * Gets the data, specified by the class, that is available.
95      */
96     getSource() {
97         this.grid_source.getRows = (pager: Pager, sort: any[]) => {
98             const orderBy: any = {};
99             if (sort.length) {
100                 // Sort specified from grid
101                 orderBy[this.idlClass] = sort[0].name + ' ' + sort[0].dir;
102             } else if (this.sortField) {
103                 // Default sort field
104                 orderBy[this.idlClass] = this.sortField;
105             }
106             const search: any = new Array();
107             const orgFilter: any = {};
108             orgFilter['owning_lib'] =
109                 this.searchOrgs.orgIds || [this.defaultOuId];
110             search.push(orgFilter);
111             const searchOps = {
112                 offset: pager.offset,
113                 limit: pager.limit,
114                 order_by: orderBy
115             };
116             return this.pcrud.search(this.idlClass, search, searchOps, {fleshSelectors: true});
117         };
118     }
119
120     navigateToCoursePage(id_arr: IdlObject[]) {
121         if (typeof id_arr === 'number') { id_arr = [id_arr]; }
122         const urls = [];
123         id_arr.forEach(id => {
124             console.log(this.router.url);
125             urls.push([this.locale.currentLocaleCode() + this.router.url + '/' +  id]);
126         });
127         if (id_arr.length === 1) {
128             this.router.navigate([this.router.url + '/' + id_arr[0]]);
129         } else {
130             urls.forEach(url => {
131                 window.open(url);
132             });
133         }
134     }
135
136     createNew() {
137         this.editDialog.mode = 'create';
138         const course_module_course = this.idl.create('acmc');
139         course_module_course.owning_lib(this.auth.user().ws_ou());
140         this.editDialog.recordId = null;
141         this.editDialog.record = course_module_course;
142         this.editDialog.open({size: this.dialog_size}).subscribe(
143             ok => {
144                 this.createString.current()
145                     .then(str => this.toast.success(str));
146                 this.grid.reload();
147             },
148             // eslint-disable-next-line rxjs/no-implicit-any-catch
149             (rejection: any) => {
150                 if (!rejection.dismissed) {
151                     this.createErrString.current()
152                         .then(str => this.toast.danger(str));
153                 }
154             }
155         );
156     }
157
158     editSelected(fields: IdlObject[]) {
159         // Edit each IDL thing one at a time
160         const course_ids = [];
161         fields.forEach(field => {
162             if (typeof field['id'] === 'function') {
163                 course_ids.push(field.id());
164             } else {
165                 course_ids.push(field['id']);
166             }
167         });
168         this.navigateToCoursePage(course_ids);
169     }
170
171     archiveSelected(course: IdlObject[]) {
172         this.courseSvc.disassociateMaterials(course).then(res => {
173             course.forEach(courseToArchive => {
174                 courseToArchive.is_archived(true);
175             });
176             this.pcrud.update(course).subscribe(
177                 val => {
178                     console.debug('archived: ' + val);
179                     this.archiveSuccessString.current()
180                         .then(str => this.toast.success(str));
181                 }, (err: unknown) => {
182                     this.archiveFailedString.current()
183                         .then(str => this.toast.danger(str));
184                 }, () => {
185                     this.grid.reload();
186                 }
187             );
188         });
189     }
190
191     courseArchiveableOrNot(course: IdlObject[], archiveBool) {
192         course.forEach(courseToMod => {
193             // eslint-disable-next-line eqeqeq
194             if (archiveBool == false) {return courseToMod.is_archived() == 't';}
195             // eslint-disable-next-line eqeqeq
196             return courseToMod.is_archived() == 'f';
197         });
198     }
199
200     unarchiveSelected(course: IdlObject[]) {
201         course.forEach(courseToUnarchive => {
202             courseToUnarchive.is_archived(false);
203         });
204         this.pcrud.update(course).subscribe(
205             val => {
206                 course.forEach(courseEntry => {
207                     this.courseSvc.removeNonPublicUsers(courseEntry.id());
208                 });
209                 console.debug('archived: ' + val);
210                 this.unarchiveSuccessString.current()
211                     .then(str => this.toast.success(str));
212             }, (err: unknown) => {
213                 this.unarchiveFailedString.current()
214                     .then(str => this.toast.danger(str));
215             }, () => {
216                 this.grid.reload();
217             }
218         );
219     }
220
221     duplicateSelected(course: IdlObject[]) {
222         course.forEach(courseToCopy => {
223             const new_course = this.idl.create('acmc');
224             new_course.name(courseToCopy.name() + $localize`:duplicate of an existing course: (Copy)`);
225             new_course.course_number(courseToCopy.course_number());
226             new_course.section_number(courseToCopy.section_number());
227             new_course.owning_lib(courseToCopy.owning_lib());
228             new_course.is_archived(courseToCopy.is_archived());
229             this.pcrud.create(new_course).subscribe({next: (val) => {
230                 console.debug('duplicated: ' + val);
231                 this.duplicateSuccessString.current()
232                     .then(str => this.toast.success(str));
233             }, error: (err: unknown) => {
234                 this.duplicateFailedString.current()
235                     .then(str => this.toast.danger(str));
236             }, complete: () => this.grid.reload()
237             });
238         });
239     }
240
241     deleteSelected(idlObject: IdlObject[]) {
242         this.courseSvc.disassociateMaterials(idlObject).then(res => {
243             idlObject.forEach(object => {
244                 object.isdeleted(true);
245             });
246             this.pcrud.autoApply(idlObject).subscribe(
247                 val => {
248                     console.debug('deleted: ' + val);
249                     this.deleteSuccessString.current()
250                         .then(str => this.toast.success(str));
251                 },
252                 (err: unknown) => {
253                     this.deleteFailedString.current()
254                         .then(str => this.toast.danger(str));
255                 },
256                 () => this.grid.reload()
257             );
258         });
259     }
260 }
261