|
1 | 1 | import {Component, OnInit} from '@angular/core';
|
2 | 2 | import {UserService} from '../../shared/services/user.service';
|
3 | 3 | import {CourseService, NotificationSettingsService} from '../../shared/services/data.service';
|
4 |
| -import {ICourse} from '../../../../../../shared/models/ICourse'; |
5 |
| -import {MatSnackBar, MatTableDataSource} from '@angular/material'; |
| 4 | +import {MatTableDataSource} from '@angular/material'; |
| 5 | +import {SnackBarService} from '../../shared/services/snack-bar.service'; |
6 | 6 | import {SelectionModel} from '@angular/cdk/collections';
|
7 | 7 | import {
|
8 |
| - INotificationSettings, NOTIFICATION_TYPE_ALL_CHANGES, |
| 8 | + INotificationSettings, |
| 9 | + NOTIFICATION_TYPE_ALL_CHANGES, |
9 | 10 | NOTIFICATION_TYPE_NONE
|
10 | 11 | } from '../../../../../../shared/models/INotificationSettings';
|
11 | 12 | import {NotificationSettings} from '../../models/NotificationSettings';
|
12 |
| -import {isNullOrUndefined} from 'util'; |
13 |
| -import {AfterContentInit} from '@angular/core/src/metadata/lifecycle_hooks'; |
| 13 | +import {ICourseDashboard} from '../../../../../../shared/models/ICourseDashboard'; |
14 | 14 |
|
15 | 15 | @Component({
|
16 | 16 | selector: 'app-user-settings',
|
17 | 17 | templateUrl: './user-settings.component.html',
|
18 | 18 | styleUrls: ['./user-settings.component.scss']
|
19 | 19 | })
|
20 |
| -export class UserSettingsComponent implements OnInit, AfterContentInit { |
| 20 | +export class UserSettingsComponent implements OnInit { |
21 | 21 |
|
22 |
| - myCourses: ICourse[]; |
| 22 | + myCourses: ICourseDashboard[]; |
23 | 23 | displayedColumns = ['name', 'Notifications', 'email'];
|
24 |
| - dataSource: MatTableDataSource<ICourse>; |
25 |
| - notificationSelection = new SelectionModel<ICourse>(true, []); |
26 |
| - emailSelection = new SelectionModel<ICourse>(true, []); |
| 24 | + dataSource: MatTableDataSource<ICourseDashboard>; |
| 25 | + notificationSelection = new SelectionModel<ICourseDashboard>(true, []); |
| 26 | + emailSelection = new SelectionModel<ICourseDashboard>(true, []); |
27 | 27 | notificationSettings: INotificationSettings[];
|
28 | 28 |
|
29 |
| - constructor(public userService: UserService, |
30 |
| - public courseService: CourseService, |
31 |
| - public notificationSettingsService: NotificationSettingsService, |
32 |
| - public snackBar: MatSnackBar) { |
| 29 | + constructor(private userService: UserService, |
| 30 | + private courseService: CourseService, |
| 31 | + private notificationSettingsService: NotificationSettingsService, |
| 32 | + private snackBar: SnackBarService) { |
33 | 33 | }
|
34 | 34 |
|
35 |
| - ngOnInit() { |
36 |
| - this.getCourses(); |
37 |
| - this.getNotificationSettings().then(() => { |
38 |
| - this.setSelection(); |
39 |
| - }); |
40 |
| - } |
41 |
| - async ngAfterContentInit() { |
| 35 | + async ngOnInit() { |
| 36 | + await this.getCourses(); |
42 | 37 | await this.getNotificationSettings();
|
43 |
| - this.setSelection(); |
| 38 | + this.setSelection(); |
44 | 39 | }
|
45 | 40 |
|
46 |
| - getCourses() { |
| 41 | + async getCourses() { |
47 | 42 | this.myCourses = [];
|
48 |
| - this.courseService.readItems().then(courses => { |
49 |
| - courses.forEach((course: ICourse) => { |
50 |
| - if (this.userService.isMemberOfCourse(course)) { |
51 |
| - this.myCourses.push(course); |
52 |
| - } |
53 |
| - }); |
54 |
| - this.dataSource = new MatTableDataSource<ICourse>(this.myCourses); |
55 |
| - }); |
| 43 | + try { |
| 44 | + this.myCourses = (await this.courseService.readItems<ICourseDashboard>()) |
| 45 | + .filter((course: ICourseDashboard) => course.userIsCourseMember); |
| 46 | + this.dataSource = new MatTableDataSource<ICourseDashboard>(this.myCourses); |
| 47 | + } catch (err) { |
| 48 | + this.snackBar.open('Could not fetch courses'); |
| 49 | + } |
56 | 50 | }
|
57 | 51 |
|
58 | 52 | async getNotificationSettings() {
|
59 |
| - const settings = await this.notificationSettingsService.getNotificationSettingsPerUser(this.userService.user); |
60 |
| - if (settings.length <= 0) { |
61 |
| - await Promise.all(this.myCourses.map(async (course) => { |
62 |
| - const newSetting = await this.notificationSettingsService.createItem({user: this.userService.user, course: course}); |
63 |
| - settings.push(newSetting); |
64 |
| - })); |
65 |
| - } |
66 |
| - this.notificationSettings = settings; |
| 53 | + this.notificationSettings = await this.notificationSettingsService.getNotificationSettingsPerUser(this.userService.user); |
67 | 54 | }
|
68 | 55 |
|
69 | 56 | setSelection() {
|
70 |
| - if (this.notificationSettings) { |
71 |
| - this.notificationSettings.forEach((setting: INotificationSettings) => { |
72 |
| - const courseWithNotificationSettings = this.myCourses.find(x => x._id === setting.course._id); |
73 |
| - if (courseWithNotificationSettings) { |
74 |
| - if (setting.notificationType === NOTIFICATION_TYPE_ALL_CHANGES) { |
75 |
| - this.notificationSelection.select(courseWithNotificationSettings); |
76 |
| - } |
77 |
| - if (setting.emailNotification) { |
78 |
| - this.emailSelection.select(courseWithNotificationSettings); |
79 |
| - } |
80 |
| - } |
81 |
| - }); |
| 57 | + if (!this.notificationSettings) { |
| 58 | + return; |
82 | 59 | }
|
| 60 | + |
| 61 | + this.notificationSettings.forEach((setting: INotificationSettings) => { |
| 62 | + const course = this.myCourses.find(tmp => tmp._id === setting.course._id); |
| 63 | + |
| 64 | + if (course === undefined) { |
| 65 | + return; |
| 66 | + } |
| 67 | + |
| 68 | + if (setting.notificationType === NOTIFICATION_TYPE_ALL_CHANGES) { |
| 69 | + this.notificationSelection.select(course); |
| 70 | + } |
| 71 | + |
| 72 | + if (setting.emailNotification) { |
| 73 | + this.emailSelection.select(course); |
| 74 | + } |
| 75 | + }); |
83 | 76 | }
|
84 | 77 |
|
85 |
| - saveNotificationSettings() { |
86 |
| - try { |
87 |
| - this.myCourses.forEach(async course => { |
88 |
| - let settings: INotificationSettings; |
89 |
| - this.notificationSettings.forEach((x) => { |
90 |
| - if (x.course._id === course._id) { |
91 |
| - settings = x; |
92 |
| - } |
93 |
| - }); |
94 |
| - if (settings === null || settings === undefined) { |
| 78 | + async saveNotificationSettings() { |
| 79 | + const errors = []; |
| 80 | + |
| 81 | + for (const course of this.myCourses) { |
| 82 | + try { |
| 83 | + let settings = this.notificationSettings.find(tmp => tmp.course._id === course._id); |
| 84 | + |
| 85 | + if (settings === undefined) { |
95 | 86 | settings = await this.notificationSettingsService.createItem(new NotificationSettings(this.userService.user, course));
|
96 | 87 | this.notificationSettings.push(settings);
|
97 | 88 | }
|
| 89 | + |
98 | 90 | if (this.notificationSelection.isSelected(course)) {
|
99 | 91 | settings.notificationType = NOTIFICATION_TYPE_ALL_CHANGES;
|
100 | 92 | } else {
|
101 | 93 | settings.notificationType = NOTIFICATION_TYPE_NONE;
|
102 | 94 | }
|
| 95 | + |
103 | 96 | if (this.emailSelection.isSelected(course)) {
|
104 | 97 | settings.emailNotification = true;
|
105 | 98 | } else {
|
106 | 99 | settings.emailNotification = false;
|
107 | 100 | }
|
| 101 | + |
108 | 102 | await this.notificationSettingsService.updateItem(settings);
|
109 |
| - }); |
110 |
| - this.snackBar.open('Notification settings updated successfully.', '', {duration: 3000}); |
111 |
| - } catch (error) { |
112 |
| - this.snackBar.open(error.message, 'Dismiss'); |
| 103 | + } catch (err) { |
| 104 | + if (errors.indexOf(err.error.message) === -1) { |
| 105 | + errors.push(err.error.message); |
| 106 | + } |
| 107 | + } |
113 | 108 | }
|
114 |
| - } |
115 | 109 |
|
116 |
| - isAllSelected(selectionModel: SelectionModel<ICourse>) { |
117 |
| - const numSelected = selectionModel.selected.length; |
118 |
| - const numRows = this.dataSource.data.length; |
119 |
| - return numSelected === numRows; |
| 110 | + if (errors.length === 0) { |
| 111 | + this.snackBar.open('Notification settings updated successfully.'); |
| 112 | + } else { |
| 113 | + this.snackBar.openLong('Failed to save notification settings: ' + errors.join(', ')); |
| 114 | + } |
120 | 115 | }
|
121 | 116 |
|
122 |
| - masterToggle(selectionModel: SelectionModel<ICourse>) { |
123 |
| - this.isAllSelected(selectionModel) ? |
124 |
| - selectionModel.clear() : |
125 |
| - this.dataSource.data.forEach(row => selectionModel.select(row)); |
| 117 | + isAllSelected(selectionModel: SelectionModel<ICourseDashboard>) { |
| 118 | + return selectionModel.selected.length === this.dataSource.data.length; |
126 | 119 | }
|
127 | 120 |
|
128 |
| - |
| 121 | + masterToggle(selectionModel: SelectionModel<ICourseDashboard>) { |
| 122 | + this.isAllSelected(selectionModel) |
| 123 | + ? selectionModel.clear() |
| 124 | + : this.dataSource.data.forEach(row => selectionModel.select(row)); |
| 125 | + } |
129 | 126 | }
|
0 commit comments