diff --git a/README.md b/README.md index e093c4107..7ccb8cb41 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,11 @@ paste the import of the `settings.js` and the CSS files from ``` -In addition, you have to copy and paste the root-tags and all ` ... diff --git a/angular.json b/angular.json index d525ee8d0..102a51228 100644 --- a/angular.json +++ b/angular.json @@ -51,7 +51,7 @@ "sourceMap": true, "optimization": false, "namedChunks": true, - "allowedCommonJsDependencies": ["xss", "codelyzer"] + "allowedCommonJsDependencies": ["codelyzer"] }, "configurations": { "production": { diff --git a/package-lock.json b/package-lock.json index b228f08b9..ae3f3679b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,6 @@ "ngx-infinite-scroll": "^16.0.0", "rxjs": "~7.8.1", "tslib": "^2.6.2", - "xss": "^1.0.14", "zone.js": "~0.13.0" }, "devDependencies": { @@ -6261,11 +6260,6 @@ "node": ">=4" } }, - "node_modules/cssfilter": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", - "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==" - }, "node_modules/cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -15611,26 +15605,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "node_modules/xss": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz", - "integrity": "sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==", - "dependencies": { - "commander": "^2.20.3", - "cssfilter": "0.0.10" - }, - "bin": { - "xss": "bin/xss" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/xss/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index f653b529b..faaf1b30b 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "@angular/common": "^16.2.10", "@angular/compiler": "^16.2.10", "@angular/core": "^16.2.10", - "@angular/elements": "^16.2.10", "@angular/forms": "^16.2.10", "@angular/localize": "^16.2.10", "@angular/platform-browser": "^16.2.10", @@ -58,7 +57,6 @@ "ngx-infinite-scroll": "^16.0.0", "rxjs": "~7.8.1", "tslib": "^2.6.2", - "xss": "^1.0.14", "zone.js": "~0.13.0" }, "devDependencies": { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index da986bf0c..9e4d363b1 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,5 +1,4 @@ import { ChangeDetectionStrategy, Component, Inject } from "@angular/core"; -import { Router } from "@angular/router"; import { EMPTY } from "rxjs"; import { catchError } from "rxjs/operators"; import { SETTINGS, Settings } from "./settings"; @@ -9,6 +8,7 @@ import { NAVIGATOR } from "./shared/tokens/dom-apis"; import { decode } from "./shared/utils/decode"; @Component({ + selector: "erz-app", template: '', styleUrls: ["./app.component.scss"], @@ -16,13 +16,11 @@ import { decode } from "./shared/utils/decode"; }) export class AppComponent { constructor( - private router: Router, i18n: I18nService, private toastService: ToastService, @Inject(SETTINGS) private settings: Settings, @Inject(NAVIGATOR) private navigator: Navigator, ) { - this.router.initialNavigation(); i18n.initialize(); this.checkSettings(); } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c97a70059..4450bf66b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -2,15 +2,7 @@ import { registerLocaleData } from "@angular/common"; import { HttpClient, HttpClientModule } from "@angular/common/http"; import localeDECH from "@angular/common/locales/de-CH"; import localeFRCH from "@angular/common/locales/fr-CH"; -import { - ApplicationRef, - DoBootstrap, - ErrorHandler, - Injector, - LOCALE_ID, - NgModule, -} from "@angular/core"; -import { createCustomElement } from "@angular/elements"; +import { ErrorHandler, LOCALE_ID, NgModule } from "@angular/core"; import { FormsModule } from "@angular/forms"; import { BrowserModule } from "@angular/platform-browser"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; @@ -22,7 +14,6 @@ import { AppRoutingModule } from "./app-routing.module"; import { AppComponent } from "./app.component"; import { GlobalErrorHandler } from "./global-error-handler"; import { HomeComponent } from "./home.component"; -import { MyNotificationsShowComponent } from "./my-notifications/components/my-notifications-show/my-notifications-show.component"; import { SETTINGS, Settings } from "./settings"; import { I18nService } from "./shared/services/i18n.service"; import { SharedModule } from "./shared/shared.module"; @@ -44,12 +35,7 @@ registerLocaleData(localeDECH); registerLocaleData(localeFRCH); @NgModule({ - declarations: [ - AppComponent, - HomeComponent, - UnauthenticatedComponent, - MyNotificationsShowComponent, - ], + declarations: [AppComponent, HomeComponent, UnauthenticatedComponent], imports: [ BrowserModule, AppRoutingModule, @@ -75,22 +61,6 @@ registerLocaleData(localeFRCH); deps: [I18nService], }, ], - bootstrap: [], + bootstrap: [AppComponent], }) -export class AppModule implements DoBootstrap { - constructor(private injector: Injector) { - const notificationsElement = createCustomElement( - MyNotificationsShowComponent, - { injector: this.injector }, - ); - customElements.define("erz-notifications", notificationsElement); - - const appElement = createCustomElement(AppComponent, { - injector: this.injector, - }); - customElements.define("erz-app", appElement); - } - - // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method - ngDoBootstrap(_appRef: ApplicationRef): void {} -} +export class AppModule {} diff --git a/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.html b/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.html deleted file mode 100644 index 7293c35bb..000000000 --- a/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.html +++ /dev/null @@ -1,111 +0,0 @@ -
- -
-
-
- - {{ "my-notifications.title" | translate }} - - -
-
-
-
-
-
-
-
- -
-
-
- -
- {{ "my-notifications.none" | translate }} -
-
-
-
-
diff --git a/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.scss b/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.scss deleted file mode 100644 index 816c096b2..000000000 --- a/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.scss +++ /dev/null @@ -1,87 +0,0 @@ -/* As the styles are encapsulated in the notification component (via ViewEncapsulation.ShadowDom), - * the corresponding global styles must also be imported here. - */ -@import "../../../../bootstrap-variables"; - -:host { - --bs-border-width: #{$border-width}; - --bs-border-style: #{$border-style}; - --bs-border-color: #{$border-color}; - - position: relative; -} - -// Configuration -@import "node_modules/bootstrap/scss/maps"; -@import "node_modules/bootstrap/scss/mixins"; -@import "node_modules/bootstrap/scss/utilities"; - -// Layout & components -@import "node_modules/bootstrap/scss/root"; -@import "node_modules/bootstrap/scss/reboot"; -@import "node_modules/bootstrap/scss/type"; -@import "node_modules/bootstrap/scss/buttons"; - -// Utilities -@import "node_modules/bootstrap/scss/utilities/api"; - -.notifications-popup { - position: absolute; - margin-top: 10px; - right: 0; - z-index: 1000; - display: none; - min-width: 33vw; - background-color: white; -} - -@media (max-width: 800px) { - .notifications-popup { - position: fixed; - min-width: auto; - width: 100vw; - right: 0; - } -} - -// used to enable scrollbar for popup-data (notifications), when view port height is small -.notifications-popup-data { - max-height: calc(100vh - 145px); // 145px ≃ distance to popup-data from top - overflow: auto; -} - -.notifications-bell { - color: black; -} - -.notifications-bell-hidden { - color: #ccc; -} - -.notifications-bell-counter { - margin-left: -10px; - color: white; - font-weight: bold; - text-align: center; - line-height: 1; - padding: 1.25px 6px; - background-color: $accent; - border-radius: 50%; - box-shadow: 0 0 0 2px white; -} - -.notifications-bell-counter-hidden { - display: none; -} - -.notifications-bell-counter-visible { - display: inline; -} - -.notifications-delete-notification { - color: $primary; -} - -hr { - margin: 0; -} diff --git a/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.spec.ts b/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.spec.ts deleted file mode 100644 index 50fb0ac0d..000000000 --- a/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.spec.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { of } from "rxjs"; -import { UserSettingsService } from "src/app/shared/services/user-settings.service"; -import { buildTestModuleMetadata } from "src/spec-helpers"; -import { MyNotificationsShowComponent } from "./my-notifications-show.component"; - -describe("MyNotificationsShowComponent-WithData", () => { - let fixture: ComponentFixture; - let shadowRoot: DocumentFragment; - let userSettings: jasmine.SpyObj; - - beforeEach(waitForAsync(() => { - userSettings = jasmine.createSpyObj("UserSettingsService", [ - "refetch", - "getNotificationData", - "saveNotificationData", - ]); - userSettings.getNotificationData.and.returnValue( - of([{ id: 1, subject: "subject", body: "body" }]), - ); - userSettings.saveNotificationData.and.returnValue(of({})); - - TestBed.configureTestingModule( - buildTestModuleMetadata({ - declarations: [MyNotificationsShowComponent], - providers: [ - { - provide: UserSettingsService, - useValue: userSettings, - }, - ], - }), - ).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(MyNotificationsShowComponent); - shadowRoot = fixture.debugElement.nativeElement.shadowRoot; - fixture.detectChanges(); - }); - - it("expect delete all to be enabled", () => { - const field = shadowRoot.querySelector( - `button[id="notifications-delete-all"]`, - ) as HTMLInputElement; - expect(field).not.toBeNull(); - expect(field.disabled).toBeFalsy(); - }); - - it('expect bell not to be "hidden"', () => { - const field = shadowRoot.querySelectorAll( - ".notifications-bell-hidden", - )[0] as HTMLInputElement; - expect(field).toBeUndefined(); - }); - - it('expect counter to be "1"', () => { - const field = shadowRoot.querySelectorAll( - ".notifications-bell-counter-visible", - )[0] as HTMLInputElement; - expect(field).not.toBeNull(); - expect(field.innerHTML).toBe("1"); - }); - - it("expect one notifications to be listed", () => { - const fields = shadowRoot.querySelectorAll( - ".notifications-delete-notification", - ); - expect(fields.length).toBe(1); - }); - - it("expect user settings call when deleteAll clicked", () => { - const field = shadowRoot.querySelector( - `button[id="notifications-delete-all"]`, - ) as HTMLInputElement; - field.click(); - expect(userSettings.saveNotificationData).toHaveBeenCalled(); - expect(userSettings.refetch).toHaveBeenCalled(); - }); - - it("expect user settings call when delete clicked", () => { - const field = shadowRoot.querySelectorAll( - ".notifications-delete-notification", - )[0] as HTMLInputElement; - field.click(); - expect(userSettings.saveNotificationData).toHaveBeenCalled(); - expect(userSettings.refetch).toHaveBeenCalled(); - }); -}); - -describe("MyNotificationsShowComponent-WithoutData", () => { - let fixture: ComponentFixture; - let shadowRoot: DocumentFragment; - let userSettings: jasmine.SpyObj; - - beforeEach(waitForAsync(() => { - userSettings = jasmine.createSpyObj("MyNotificationsService", [ - "refetch", - "getNotificationData", - "saveNotificationData", - ]); - userSettings.getNotificationData.and.returnValue(of([])); - - TestBed.configureTestingModule( - buildTestModuleMetadata({ - declarations: [MyNotificationsShowComponent], - providers: [ - { - provide: UserSettingsService, - useValue: userSettings, - }, - ], - }), - ).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(MyNotificationsShowComponent); - shadowRoot = fixture.debugElement.nativeElement.shadowRoot; - fixture.detectChanges(); - }); - - it("expect delete all to be disabled", () => { - const field = shadowRoot.querySelector( - `button[id="notifications-delete-all"]`, - ) as HTMLInputElement; - expect(field).not.toBeNull(); - expect(field.disabled).toBeTruthy(); - }); - - it("expect bell to be shown", () => { - const field = shadowRoot.querySelectorAll( - ".notifications-bell-hidden", - )[0] as HTMLInputElement; - expect(field).toBeUndefined(); - }); - - it("expect counter to be zero", () => { - const field = shadowRoot.querySelectorAll( - ".notifications-bell-counter-visible", - )[0] as HTMLInputElement; - expect(field).not.toBeNull(); - expect(field.innerHTML).toBe("0"); - }); - - it("expect no notifications to be listed", () => { - const fields = shadowRoot.querySelectorAll( - ".notifications-delete-notification", - ); - expect(fields.length).toBe(0); - }); -}); - -describe("MyNotificationsShowComponent-WithoutAuthorization", () => { - let fixture: ComponentFixture; - let shadowRoot: DocumentFragment; - let userSettings: jasmine.SpyObj; - - beforeEach(waitForAsync(() => { - userSettings = jasmine.createSpyObj("MyNotificationsService", [ - "refetch", - "getNotificationData", - "saveNotificationData", - ]); - userSettings.getNotificationData.and.returnValue(of([])); - - TestBed.configureTestingModule( - buildTestModuleMetadata({ - declarations: [MyNotificationsShowComponent], - providers: [ - { - provide: UserSettingsService, - useValue: userSettings, - }, - ], - }), - ).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(MyNotificationsShowComponent); - shadowRoot = fixture.debugElement.nativeElement.shadowRoot; - fixture.detectChanges(); - }); - - it('expect bell to be "hidden"', () => { - const field = shadowRoot.querySelectorAll( - ".notifications-bell-hidden", - )[0] as HTMLInputElement; - expect(field).not.toBeNull(); - }); - - it("expect counter not to be shown", () => { - const field = shadowRoot.querySelectorAll( - ".notifications-bell-counter-hidden", - )[0] as HTMLInputElement; - expect(field).not.toBeNull(); - }); -}); diff --git a/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.ts b/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.ts deleted file mode 100644 index a34ff1b1e..000000000 --- a/src/app/my-notifications/components/my-notifications-show/my-notifications-show.component.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { HttpErrorResponse } from "@angular/common/http"; -import { - Component, - ElementRef, - Inject, - OnDestroy, - ViewChild, - ViewEncapsulation, -} from "@angular/core"; -import { - BehaviorSubject, - Observable, - Subject, - interval, - throwError, -} from "rxjs"; -import { - catchError, - shareReplay, - startWith, - switchMap, - takeUntil, - withLatestFrom, -} from "rxjs/operators"; -import { SETTINGS, Settings } from "src/app/settings"; -import { - NotificationData, - NotificationDataEntry, -} from "src/app/shared/models/user-settings.model"; -import { I18nService } from "src/app/shared/services/i18n.service"; -import { UserSettingsService } from "src/app/shared/services/user-settings.service"; - -@Component({ - templateUrl: "./my-notifications-show.component.html", - styleUrls: ["./my-notifications-show.component.scss"], - encapsulation: ViewEncapsulation.ShadowDom, -}) -export class MyNotificationsShowComponent implements OnDestroy { - @ViewChild("notificationspopup") popup: ElementRef; - - notifications$ = this.loadNotifications().pipe(shareReplay()); - isAuthenticated$ = new BehaviorSubject(false); - - private refetchTimer$ = interval( - this.settings.notificationRefreshTime * 1000, - ).pipe( - startWith(null), // Make sure we have "fresh" notifications when this component gets rendered initially - ); - private deleteAllNotifications$ = new Subject(); - private deleteNotification$ = new Subject(); - private toggleNotificationsPopup$ = new Subject>(); - private destroy$ = new Subject(); - - public xssOptions = { - whiteList: { - br: [], - div: ["style"], - span: ["style"], - a: ["href"], - ul: [], - ol: [], - li: [], - sup: [], - sub: [], - code: [], - cite: [], - }, - css: false, - }; - - constructor( - i18n: I18nService, - @Inject(SETTINGS) private settings: Settings, - public userSettings: UserSettingsService, - ) { - i18n.initialize(); - - // Check authentication - this.notifications$ - .pipe(takeUntil(this.destroy$)) - .subscribe(() => this.isAuthenticated$.next(true)); - - // Toggle notification popup - this.toggleNotificationsPopup$ - .pipe(withLatestFrom(this.isAuthenticated$), takeUntil(this.destroy$)) - .subscribe(([el, a]) => { - if (el && a === true) { - if (el.style.display === "block") { - el.style.display = "none"; - } else { - el.style.display = "block"; - } - } - }); - - // Refetch notifications periodically (polling) - this.refetchTimer$ - .pipe(takeUntil(this.destroy$)) - .subscribe(() => this.userSettings.refetch()); - - this.deleteNotification$ - .pipe( - withLatestFrom(this.notifications$), - switchMap(([id, notifications]) => - this.userSettings.saveNotificationData( - this.deleteNotificationFromArray(id, notifications), - ), - ), - takeUntil(this.destroy$), - ) - .subscribe(); - - this.deleteAllNotifications$ - .pipe( - switchMap(() => this.userSettings.saveNotificationData([])), - takeUntil(this.destroy$), - ) - .subscribe(); - } - - ngOnDestroy(): void { - this.destroy$.next(); - this.destroy$.complete(); - } - - toggleNotificationsPopup(): void { - if (this.popup.nativeElement) { - this.toggleNotificationsPopup$.next(this.popup.nativeElement); - } - } - - deleteNotification(id: number): void { - this.deleteNotification$.next(id); - } - - deleteAll(): void { - this.deleteAllNotifications$.next(); - } - - deleteNotificationFromArray( - id: number, - data: NotificationData, - ): NotificationData { - return data.filter((entry) => entry.id !== id); - } - - private loadNotifications(): Observable< - ReadonlyArray - > { - return this.userSettings.getNotificationData().pipe( - catchError((err: HttpErrorResponse) => { - if (err.status === 401) { - this.isAuthenticated$.next(false); - return []; - } - return throwError(() => err); - }), - ); - } -} diff --git a/src/app/my-notifications/my-notifications.module.ts b/src/app/my-notifications/my-notifications.module.ts deleted file mode 100644 index 452a0d06b..000000000 --- a/src/app/my-notifications/my-notifications.module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { CommonModule } from "@angular/common"; -import { NgModule } from "@angular/core"; -import { MyNotificationsShowComponent } from "./components/my-notifications-show/my-notifications-show.component"; - -@NgModule({ - declarations: [MyNotificationsShowComponent], - imports: [CommonModule], -}) -export class MyNotificationsModule {} diff --git a/src/app/settings.ts b/src/app/settings.ts index bdeb72eed..f92bdb632 100644 --- a/src/app/settings.ts +++ b/src/app/settings.ts @@ -53,7 +53,6 @@ const Settings = t.type({ testsBySubscriptionTeacherReports: t.array(Report), subscriptionDetailGroupId: t.number, headerRoleRestriction: t.record(t.string, t.string), - notificationRefreshTime: t.number, notificationTypes: NotificationTypes, notificationTypesAssignments: t.array(NotificationTypesAssignment), eventlist: t.record(t.string, t.string), diff --git a/src/app/shared/models/user-settings.model.ts b/src/app/shared/models/user-settings.model.ts index 64aba548a..fbf1d48e7 100644 --- a/src/app/shared/models/user-settings.model.ts +++ b/src/app/shared/models/user-settings.model.ts @@ -70,16 +70,6 @@ const NotificationTypesInactive = new t.Type< (output) => output.join(";"), ); -const NotificationDataEntry = t.type({ - id: t.number, - subject: t.string, - body: t.string, -}); - -const NotificationData = JsonFromUnknown.pipe( - t.readonly(t.array(NotificationDataEntry)), -); - export enum PresenceControlViewMode { Grid = "grid", List = "list", @@ -118,8 +108,6 @@ const AccessInfo = t.type({ type UserSetting = t.TypeOf; type UserSettings = t.TypeOf; type NotificationChannels = t.TypeOf; -type NotificationData = t.TypeOf; -type NotificationDataEntry = t.TypeOf; type NotificationTypesInactive = t.TypeOf; type PresenceControlViewModeObject = t.TypeOf< typeof PresenceControlViewModeObject @@ -134,8 +122,6 @@ export { UserSettings, UserSetting, NotificationChannels, - NotificationData, - NotificationDataEntry, NotificationTypesInactive, PresenceControlViewModeObject, PresenceControlGroupViewEntry, diff --git a/src/app/shared/pipes/xss.pipe.spec.ts b/src/app/shared/pipes/xss.pipe.spec.ts deleted file mode 100644 index 18b2a5b1b..000000000 --- a/src/app/shared/pipes/xss.pipe.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { XssPipe } from "./xss.pipe"; - -describe("XssPipe", () => { - it("create an instance", () => { - const pipe = new XssPipe(); - expect(pipe).toBeTruthy(); - }); -}); diff --git a/src/app/shared/pipes/xss.pipe.ts b/src/app/shared/pipes/xss.pipe.ts deleted file mode 100644 index 3a64842ca..000000000 --- a/src/app/shared/pipes/xss.pipe.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Pipe, PipeTransform } from "@angular/core"; -import xss, { IFilterXSSOptions } from "xss"; - -@Pipe({ - name: "xss", -}) -export class XssPipe implements PipeTransform { - transform(value: string, options?: IFilterXSSOptions): string { - return xss(value, options); - } -} diff --git a/src/app/shared/services/user-settings.service.ts b/src/app/shared/services/user-settings.service.ts index 7db5b03fb..9872328a5 100644 --- a/src/app/shared/services/user-settings.service.ts +++ b/src/app/shared/services/user-settings.service.ts @@ -11,7 +11,6 @@ import { } from "rxjs"; import { NotificationChannels, - NotificationData, NotificationTypesInactive, PresenceControlGroupView, PresenceControlViewMode, @@ -32,7 +31,6 @@ const PRESENCE_CONTROL_VIEW_MODE_KEY = "presenceControlViewMode"; const PRESENCE_CONTROL_GROUP_VIEW_KEY = "presenceControlGroupView"; const NOTIFICATION_CHANNELS_KEY = "notification"; const NOTIFICATION_TYPES_INACTIVE_KEY = "notificationTypesInactive"; -const NOTIFICATION_DATA_KEY = "notificationData"; @Injectable({ providedIn: "root", @@ -149,20 +147,6 @@ export class UserSettingsService { ); } - getNotificationData(): Observable { - return this.getSetting(NOTIFICATION_DATA_KEY).pipe( - defaultValue("[]"), - switchMap(decode(NotificationData)), - ); - } - - saveNotificationData(value: NotificationData): Observable { - return this.saveSetting( - NOTIFICATION_DATA_KEY, - NotificationData.encode(value), - ); - } - getRolesAndPermissions(): Observable>> { return this.accessInfo$.pipe( map(({ Roles, Permissions }) => [...Roles, ...Permissions]), diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 477618baa..ff9be65e1 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -48,7 +48,6 @@ import { PersonEmailPipe } from "./pipes/person-email.pipe"; import { SafePipe } from "./pipes/safe.pipe"; import { TestPointsPipe } from "./pipes/test-points.pipe"; import { TestsWeightPipe } from "./pipes/test-weight.pipe"; -import { XssPipe } from "./pipes/xss.pipe"; const directives = [LetDirective]; @@ -93,7 +92,6 @@ const pipes = [ SafePipe, TestPointsPipe, TestsWeightPipe, - XssPipe, ]; @NgModule({ diff --git a/src/assets/locales/de-CH.json b/src/assets/locales/de-CH.json index a119245b3..c85db5d2f 100644 --- a/src/assets/locales/de-CH.json +++ b/src/assets/locales/de-CH.json @@ -410,11 +410,6 @@ "save-success": "Einstellungen zu Benachrichtigungen erfolgreich aktualisiert" } }, - "my-notifications": { - "title": "Benachrichtigungen", - "deleteAll": "Alle löschen", - "none": "Keine Benachrichtigungen" - }, "shared": { "date-select": { "default-placeholder": "Datum wählen..." diff --git a/src/assets/locales/fr-CH.json b/src/assets/locales/fr-CH.json index a18b34ef6..67d9d951a 100644 --- a/src/assets/locales/fr-CH.json +++ b/src/assets/locales/fr-CH.json @@ -410,11 +410,6 @@ "save-success": "Les paramètres de notification ont été mis à jour avec succès" } }, - "my-notifications": { - "title": "Notifications", - "deleteAll": "Tout effacer", - "none": "Aucune notification" - }, "shared": { "date-select": { "default-placeholder": "Sélectionner la date..." diff --git a/src/index.html b/src/index.html index 878fa26c5..cb8f07ed1 100644 --- a/src/index.html +++ b/src/index.html @@ -20,7 +20,6 @@ " > Go to Home -
diff --git a/src/settings.example.js b/src/settings.example.js index ab7736e58..6c1e1e12d 100644 --- a/src/settings.example.js +++ b/src/settings.example.js @@ -112,12 +112,6 @@ window.schulverwaltung.settings = { "LessonTeacherRole;ClassTeacherRole;TeacherRole;AbsenceAdministratorRole", }, - /** - * Notifications - */ - // Refresh time for notifications - notificationRefreshTime: 30, - // Types of notifications and their language-specific texts // (the description may contain newlines '\n') notificationTypes: { diff --git a/src/spec-builders.ts b/src/spec-builders.ts index df4a78b2b..fddefd531 100644 --- a/src/spec-builders.ts +++ b/src/spec-builders.ts @@ -463,19 +463,6 @@ export function buildUserSettingsWithNotificationSetting( return { ...setting, Settings: [notification] }; } -export function buildUserSettingsWithNotificationData( - id: number, - subject: string, - body: string, -): UserSettings { - const setting = buildUserSettings(); - const notification = { - Key: "notificationData", - Value: JSON.stringify([{ id, subject, body }]), - }; - return { ...setting, Settings: [notification] }; -} - export function buildSubscriptionDetail( vssId: number, value?: string, diff --git a/src/spec-helpers.ts b/src/spec-helpers.ts index a3ff55e11..252599d67 100644 --- a/src/spec-helpers.ts +++ b/src/spec-helpers.ts @@ -50,7 +50,6 @@ export const settings: Settings = { openAbsences: "LessonTeacherRole;ClassTeacherRole", editAbsences: "LessonTeacherRole;ClassTeacherRole", }, - notificationRefreshTime: 30, notificationTypes: { BM2Student: { de: {