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';
16 import {CourseAssociateMaterialComponent
17 } from './course-associate-material.component';
19 import {CourseAssociateUsersComponent
20 } from './course-associate-users.component';
23 templateUrl: './course-list.component.html'
26 export class CourseListComponent implements OnInit {
28 @ViewChild('editDialog', { static: true }) editDialog: FmRecordEditorComponent;
29 @ViewChild('grid', { static: true }) grid: GridComponent;
30 @ViewChild('successString', { static: true }) successString: StringComponent;
31 @ViewChild('createString', { static: false }) createString: StringComponent;
32 @ViewChild('createErrString', { static: false }) createErrString: StringComponent;
33 @ViewChild('updateFailedString', { static: false }) updateFailedString: StringComponent;
34 @ViewChild('deleteFailedString', { static: true }) deleteFailedString: StringComponent;
35 @ViewChild('deleteSuccessString', { static: true }) deleteSuccessString: StringComponent;
36 @ViewChild('archiveFailedString', { static: true }) archiveFailedString: StringComponent;
37 @ViewChild('archiveSuccessString', { static: true }) archiveSuccessString: StringComponent;
38 @ViewChild('courseMaterialDialog', {static: true})
39 private courseMaterialDialog: CourseAssociateMaterialComponent;
40 @ViewChild('courseUserDialog', {static: true})
41 private courseUserDialog: CourseAssociateUsersComponent;
43 @Input() sort_field: string;
44 @Input() idl_class = "acmc";
45 @Input() dialog_size: 'sm' | 'lg' = 'lg';
46 @Input() table_name = "Course";
47 grid_source: GridDataSource = new GridDataSource();
48 currentMaterials: any[] = [];
52 private auth: AuthService,
53 private courseSvc: CourseService,
54 private net: NetService,
55 private org: OrgService,
56 private pcrud: PcrudService,
57 private route: ActivatedRoute,
58 private router: Router,
59 private toast: ToastService
64 this.grid.onRowActivate.subscribe((course:IdlObject) => {
65 let idToEdit = course.id();
66 this.navigateToCoursePage(idToEdit);
71 * Gets the data, specified by the class, that is available.
74 this.grid_source.getRows = (pager: Pager, sort: any[]) => {
75 const orderBy: any = {};
77 // Sort specified from grid
78 orderBy[this.idl_class] = sort[0].name + ' ' + sort[0].dir;
79 } else if (this.sort_field) {
81 orderBy[this.idl_class] = this.sort_field;
88 return this.pcrud.retrieveAll(this.idl_class, searchOps, {fleshSelectors: true})
92 navigateToCoursePage(id: any) {
93 this.router.navigate(["/staff/admin/local/asset/course_list/" + id]);
96 showEditDialog(standingPenalty: IdlObject): Promise<any> {
97 this.editDialog.mode = 'update';
98 this.editDialog.recordId = standingPenalty['id']();
99 return new Promise((resolve, reject) => {
100 this.editDialog.open({size: this.dialog_size}).subscribe(
102 this.successString.current()
103 .then(str => this.toast.success(str));
108 this.updateFailedString.current()
109 .then(str => this.toast.danger(str));
117 this.editDialog.mode = 'create';
118 this.editDialog.recordId = null;
119 this.editDialog.record = null;
120 this.editDialog.open({size: this.dialog_size}).subscribe(
122 this.createString.current()
123 .then(str => this.toast.success(str));
127 if (!rejection.dismissed) {
128 this.createErrString.current()
129 .then(str => this.toast.danger(str));
135 editSelected(fields: IdlObject[]) {
136 // Edit each IDL thing one at a time
137 const editOneThing = (field_object: IdlObject) => {
138 if (!field_object) { return; }
139 this.showEditDialog(field_object).then(
140 () => editOneThing(fields.shift()));
142 editOneThing(fields.shift());
145 archiveSelected(course: IdlObject[]) {
146 this.courseSvc.disassociateMaterials(course).then(res => {
147 course.forEach(course => {
149 course.is_archived(true);
151 this.pcrud.update(course).subscribe(
153 console.debug('archived: ' + val);
154 this.archiveSuccessString.current()
155 .then(str => this.toast.success(str));
157 this.archiveFailedString.current()
158 .then(str => this.toast.danger(str));
166 deleteSelected(idl_object: IdlObject[]) {
167 this.courseSvc.disassociateMaterials(idl_object).then(res => {
168 idl_object.forEach(idl_object => {
169 idl_object.isdeleted(true)
171 this.pcrud.autoApply(idl_object).subscribe(
173 console.debug('deleted: ' + val);
174 this.deleteSuccessString.current()
175 .then(str => this.toast.success(str));
178 this.deleteFailedString.current()
179 .then(str => this.toast.danger(str));
181 () => this.grid.reload()
186 fetchCourseMaterials(course, currentMaterials): Promise<any> {
187 return new Promise((resolve, reject) => {
188 this.pcrud.search('acmcm', {course: course}).subscribe(res => {
189 if (res) this.fleshItemDetails(res.item(), res.relationship());
192 }, () => resolve(this.courseMaterialDialog.gridDataSource.data));
197 * Uses the course id to fetch the different users associated with that course.
198 * @param course The course id
199 * @param currentMaterials
201 fetchCourseUsers(course, currentMaterials): Promise<any> {
202 return new Promise((resolve, reject) => {
203 this.pcrud.search('acmcu', {course: course}).subscribe(res => {
204 if(res) this.fleshUserDetails(res.usr(), res.usr_role());
207 }, () => resolve(this.courseUserDialog.gridDataSource.data));
212 * Takes the user id from the course table, and cross references that with the user table,
213 * to find the right data.
214 * @param userId The user id that is to be cross referenced.
215 * @param usr_role The user role that is to be added to the grid.
217 fleshUserDetails(userId, usr_role) {
218 return new Promise((resolve, reject) => {
219 this.pcrud.search("au", {id:userId}).subscribe(res => {
222 user._usr_role = usr_role;
223 this.courseUserDialog.gridDataSource.data.push(user);
227 }, () => resolve(this.courseMaterialDialog.gridDataSource.data));
231 fleshItemDetails(itemId, relationship): Promise<any> {
232 return new Promise((resolve, reject) => {
235 'open-ils.circ.copy_details.retrieve',
236 this.auth.token(), itemId
240 item.call_number(res.volume);
241 item._title = res.mvr.title();
242 item.circ_lib(this.org.get(item.circ_lib()));
243 item._relationship = relationship;
244 this.courseMaterialDialog.gridDataSource.data.push(item);
248 }, () => resolve(this.courseMaterialDialog.gridDataSource.data));
252 openMaterialsDialog(course) {
253 let currentMaterials = []
254 this.courseMaterialDialog.gridDataSource.data = [];
255 this.fetchCourseMaterials(course[0].id(), currentMaterials).then(res => {
256 this.courseMaterialDialog.currentCourse = course[0];
257 this.courseMaterialDialog.materials = currentMaterials;
258 this.courseMaterialDialog.open({size: 'lg'}).subscribe(res => {
265 * Opens the user dialog component using the course id
268 openUsersDialog(course) {
269 let currentUsers = []
270 this.courseUserDialog.gridDataSource.data = [];
271 this.fetchCourseUsers(course[0].id(), currentUsers).then(res => {
272 this.courseUserDialog.currentCourse = course[0];
273 this.courseUserDialog.users = currentUsers;
274 this.courseUserDialog.open({size: 'lg'}).subscribe(res => {