From 0d2d81146610a323c9d84adda081244ed2b48a28 Mon Sep 17 00:00:00 2001 From: Mathis Hofer Date: Tue, 24 Oct 2023 15:44:13 +0200 Subject: [PATCH] Whip ESLint config into shape & cleanup unused things with Knip #561 --- .eslintrc.json | 35 +- .htmlvalidate.json | 12 - .knip.json | 38 ++ doc/prettier.md | 10 +- doc/setup-dev-environment.md | 6 + package-lock.json | 584 +----------------- package.json | 24 +- src/app/app.module.ts | 8 +- src/app/auth.guard.spec.ts | 12 +- .../edit-absences-edit.component.spec.ts | 36 +- .../edit-absences-header.component.ts | 23 +- .../evaluate-absences-header.component.ts | 3 +- .../evaluate-absences-list.component.spec.ts | 12 +- .../components/grade/grade.component.spec.ts | 18 +- .../tests-add/tests-add.component.spec.ts | 6 +- .../tests-add/tests-add.component.ts | 15 +- .../tests-delete/tests-delete.component.ts | 4 +- .../tests-edit/tests-edit.component.spec.ts | 8 +- .../tests-edit/tests-edit.component.ts | 21 +- .../tests-list/tests-list.component.spec.ts | 8 +- .../services/events-state.service.spec.ts | 18 +- src/app/events/utils/events.spec.ts | 36 +- src/app/events/utils/events.ts | 11 +- src/app/global-error-handler.ts | 9 +- .../my-absences-report-header.component.ts | 1 - .../my-absences-report-link.component.ts | 1 - .../my-absences-report-list.component.ts | 32 +- .../my-absences-report.component.ts | 2 +- .../my-absences-show.component.spec.ts | 12 +- .../my-absences-show.component.ts | 36 +- .../my-absences/my-absences.component.ts | 2 +- .../my-absences-report-state.service.spec.ts | 12 +- .../services/my-absences.service.spec.ts | 4 +- .../services/my-absences.service.ts | 48 +- .../my-notifications-show.component.spec.ts | 78 +-- .../my-notifications-show.component.ts | 20 +- .../my-profile-address.component.ts | 7 +- .../my-profile-edit.component.spec.ts | 14 +- .../my-profile-entry.component.ts | 7 +- .../my-profile-header.component.ts | 5 +- .../my-profile-show.component.ts | 2 +- .../my-profile/my-profile.component.ts | 2 +- ...ngs-notifications-toggle.component.spec.ts | 6 +- ...y-settings-notifications.component.spec.ts | 36 +- .../my-settings-notifications.component.ts | 52 +- .../my-settings-show.component.spec.ts | 4 +- .../open-absences-detail.component.spec.ts | 14 +- .../open-absences-list.component.spec.ts | 18 +- .../open-absences.component.spec.ts | 3 +- .../open-absences/open-absences.component.ts | 2 +- .../services/open-absences.service.spec.ts | 38 +- .../services/open-absences.service.ts | 38 +- .../utils/open-absences-entries.ts | 63 +- .../person-search-header.component.spec.ts | 7 +- .../presence-control-header.component.ts | 5 +- ...nce-control-preceding-absence.component.ts | 2 +- .../models/lesson-entry.model.spec.ts | 19 +- ...sence-control-block-lesson.service.spec.ts | 27 +- .../presence-control-group.service.spec.ts | 19 +- .../presence-control-group.service.ts | 58 +- .../presence-control-state.service.spec.ts | 47 +- .../utils/lesson-presences.ts | 9 +- .../presence-control/utils/presence-types.ts | 19 +- .../utils/subscriptions-details.ts | 20 +- src/app/rest-auth-interceptor.spec.ts | 8 +- src/app/rest-auth-interceptor.ts | 10 +- src/app/rest-error-interceptor.ts | 33 +- src/app/rest-role-interceptor.ts | 4 +- .../components/avatar/avatar.component.ts | 5 +- .../confirm-absences.component.spec.ts | 8 +- .../date-select/date-select.component.ts | 2 +- .../multiselect/multiselect.component.spec.ts | 6 +- .../resettable-input.component.ts | 2 +- .../select/select.component.spec.ts | 6 +- .../components/select/select.component.ts | 5 +- .../components/spinner/spinner.component.ts | 2 +- .../dossier-course-tests.component.spec.ts | 3 +- .../dossier-grades.component.spec.ts | 8 +- .../dossier-single-test.component.ts | 20 +- .../student-backlink.component.ts | 4 +- .../student-dossier-absences.component.ts | 18 +- ...ossier-apprenticeship-company.component.ts | 7 +- .../switch/switch.component.spec.ts | 6 +- .../components/toast/toast.component.spec.ts | 6 +- src/app/shared/directives/let.directive.ts | 8 +- .../models/apprenticeship-contract.model.ts | 2 +- src/app/shared/models/job-trainer.model.ts | 2 +- src/app/shared/models/student-grades.spec.ts | 54 +- src/app/shared/models/student-grades.ts | 26 +- src/app/shared/models/user-settings.model.ts | 12 +- src/app/shared/pipes/add-space.pipe.spec.ts | 3 + src/app/shared/pipes/safe.pipe.spec.ts | 6 +- src/app/shared/pipes/safe.pipe.ts | 3 +- ...renticeship-contracts-rest.service.spec.ts | 15 - .../apprenticeship-contracts-rest.service.ts | 16 - ...confirm-absences-selection.service.spec.ts | 4 +- .../services/courses-rest.service.spec.ts | 36 +- .../services/dossier-grades.service.spec.ts | 20 +- .../shared/services/dossier-grades.service.ts | 84 +-- .../services/events-rest.service.spec.ts | 5 +- ...legal-representatives-rest.service.spec.ts | 15 - .../legal-representatives-rest.service.ts | 17 - .../lesson-absences-rest.service.spec.ts | 15 - .../services/lesson-absences-rest.service.ts | 17 - .../lesson-dispensations-rest.service.spec.ts | 15 - .../lesson-dispensations-rest.service.ts | 17 - .../lesson-incidents-rest.service.spec.ts | 15 - .../services/lesson-incidents-rest.service.ts | 17 - .../lesson-presences-rest.service.spec.ts | 38 +- ...sson-presences-update-rest.service.spec.ts | 6 +- .../lesson-presences-update-rest.service.ts | 14 +- .../lesson-presences-update.service.spec.ts | 36 +- .../lesson-presences-update.service.ts | 51 +- .../services/presence-types.service.spec.ts | 3 +- .../shared/services/presence-types.service.ts | 30 +- src/app/shared/services/rest.service.ts | 5 +- .../services/scroll-position.service.ts | 20 +- src/app/shared/services/sort.service.spec.ts | 1 + .../shared/services/storage.service.spec.ts | 11 +- src/app/shared/services/storage.service.ts | 9 +- .../shared/services/typeahead-rest.service.ts | 24 +- .../services/user-settings-rest.service.ts | 4 +- .../shared/services/user-settings.service.ts | 42 +- .../shared/tokens/confirm-absences-service.ts | 4 +- src/app/shared/utils/absences-filter.ts | 10 +- src/app/shared/utils/array.spec.ts | 6 +- src/app/shared/utils/array.ts | 14 +- src/app/shared/utils/filter.ts | 11 +- src/app/shared/utils/form.ts | 30 +- src/app/shared/utils/function.ts | 4 +- src/app/shared/utils/observable.ts | 28 +- src/app/shared/utils/persons.spec.ts | 6 - src/app/shared/utils/presence-types.ts | 10 +- src/app/shared/utils/url.ts | 2 +- src/app/unauthenticated.component.ts | 2 +- src/spec-builders.ts | 63 +- src/spec-helpers.ts | 18 +- src/typings.d.ts | 3 +- 138 files changed, 1072 insertions(+), 1768 deletions(-) delete mode 100644 .htmlvalidate.json create mode 100644 .knip.json delete mode 100644 src/app/shared/services/apprenticeship-contracts-rest.service.spec.ts delete mode 100644 src/app/shared/services/apprenticeship-contracts-rest.service.ts delete mode 100644 src/app/shared/services/legal-representatives-rest.service.spec.ts delete mode 100644 src/app/shared/services/legal-representatives-rest.service.ts delete mode 100644 src/app/shared/services/lesson-absences-rest.service.spec.ts delete mode 100644 src/app/shared/services/lesson-absences-rest.service.ts delete mode 100644 src/app/shared/services/lesson-dispensations-rest.service.spec.ts delete mode 100644 src/app/shared/services/lesson-dispensations-rest.service.ts delete mode 100644 src/app/shared/services/lesson-incidents-rest.service.spec.ts delete mode 100644 src/app/shared/services/lesson-incidents-rest.service.ts diff --git a/.eslintrc.json b/.eslintrc.json index b8e287852..c056b989e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,8 +9,11 @@ "createDefaultProgram": true }, "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", "plugin:@angular-eslint/recommended", - "plugin:@angular-eslint/template/process-inline-templates" + "plugin:@angular-eslint/template/process-inline-templates", + "prettier" ], "plugins": ["deprecation"], "rules": { @@ -25,9 +28,17 @@ "@angular-eslint/directive-selector": [ "error", { + "type": "attribute", "prefix": "erz", - "style": "camelCase", - "type": "attribute" + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "erz", + "style": "kebab-case" } ], "no-restricted-globals": [ @@ -43,21 +54,19 @@ "patterns": ["fp-ts/lib/*"] } ], - "deprecation/deprecation": "warn" + "deprecation/deprecation": "warn", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "argsIgnorePattern": "_.*" + } + ] } }, { "files": ["*.html"], - "extends": ["plugin:@angular-eslint/template/recommended"], + "extends": ["plugin:@angular-eslint/template/recommended", "prettier"], "rules": {} - }, - { - "files": ["*.html"], - "excludedFiles": ["*inline-template-*.component.html"], - "extends": ["plugin:prettier/recommended"], - "rules": { - "prettier/prettier": ["error", { "parser": "angular" }] - } } ] } diff --git a/.htmlvalidate.json b/.htmlvalidate.json deleted file mode 100644 index 00b887d91..000000000 --- a/.htmlvalidate.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "rules": { - "element-required-attributes": "error" - }, - "elements": [ - { - "button": { - "requiredAttributes": ["type"] - } - } - ] -} diff --git a/.knip.json b/.knip.json new file mode 100644 index 000000000..0b8dac0a8 --- /dev/null +++ b/.knip.json @@ -0,0 +1,38 @@ +{ + "entry": [ + "src/main.ts", + "src/spec-builders.ts", + "src/spec-helpers.ts", + "src/specs/expectations.ts", + "src/specs/utils.ts", + "src/polyfills.ts" + ], + "project": ["src/**/*.{ts,js}"], + "ignore": [ + "src/**/*.spec.ts", + "src/environments/environment.prod.ts", + "src/karma.conf.js", + "src/settings.example.js" + ], + "ignoreDependencies": [ + "@angular-eslint/schematics", + "@angular-eslint/template-parser", + "@angular/language-service", + "@typescript-eslint/parser", + "bootstrap", + "jasmine-core", + "karma-brief-reporter", + "karma-chrome-launcher", + "karma-coverage-istanbul-reporter", + "karma-jasmine", + "karma-jasmine-html-reporter", + "karma-spec-reporter" + ], + "ignoreBinaries": ["knip", "webpack-bundle-analyzer"], + "rules": { + "exports": "warn", + "types": "warn", + "classMembers": "off", + "enumMembers": "off" + } +} diff --git a/doc/prettier.md b/doc/prettier.md index 35971942f..08573da98 100644 --- a/doc/prettier.md +++ b/doc/prettier.md @@ -4,23 +4,23 @@ We use Prettier to automatically format the source code. -The module is integrated threefold: +The module is integrated as follows: - Format on save in the editor, see https://prettier.io/docs/en/editors.html - Pre-commit hook in Git -- Linting step in the CI pipeline: The build fails when a (TypeScript) file is not properly formatted (part of `npm run lint`) ## Update Prettier version Automatic Prettier updates are disabled, because the formatting rules can change in newer versions. Therefore an exact version of the Prettier module is installed. -You can update it manually: +You can update it manually (will also reformat source with new Prettier version): ``` -npm install --save-exact prettier@latest +format:upgrade +git commit -a -m "Reformat sources after Prettier update" ``` -To reformat the code base afterwards: +Or to just reformat the code: ``` npm run format diff --git a/doc/setup-dev-environment.md b/doc/setup-dev-environment.md index 65c1687c2..7531c8b76 100644 --- a/doc/setup-dev-environment.md +++ b/doc/setup-dev-environment.md @@ -28,6 +28,12 @@ Run `npm run build` to build the project. The build artifacts will be stored in Run `npm test` to execute the unit tests via [Karma](https://karma-runner.github.io). +## Linting & checks + +Run `npm lint` to check source files with [ESLint](https://eslint.org/). For the configuration, see [.eslintrc.json](./.eslintrc.json). + +Run `npm unused` to print a report of unused dependencies, files & exports using [Knip](https://github.com/webpro/knip). For the configuration, see [.knip.json](./.knip.json). + ## Further help To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). diff --git a/package-lock.json b/package-lock.json index 0e0589319..38db6956e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,6 @@ "name": "webapp-schulverwaltung", "version": "0.0.0", "dependencies": { - "-": "0.0.1", "@angular/animations": "^16.2.10", "@angular/common": "^16.2.10", "@angular/compiler": "^16.2.10", @@ -25,9 +24,7 @@ "@ngx-translate/http-loader": "^8.0.0", "@popperjs/core": "^2.11.8", "bootstrap": "^5.3.2", - "core-js": "~3.33.1", "date-fns": "^2.30.0", - "document-register-element": "^1.14.10", "fp-ts": "^2.16.1", "io-ts": "^2.2.20", "io-ts-types": "^0.5.19", @@ -37,7 +34,6 @@ "ngx-infinite-scroll": "^16.0.0", "rxjs": "~7.8.1", "tslib": "^2.6.2", - "watchpack": "^2.4.0", "xss": "^1.0.14", "zone.js": "~0.13.0" }, @@ -52,7 +48,6 @@ "@angular/compiler-cli": "^16.2.10", "@angular/language-service": "^16.2.10", "@types/jasmine": "~5.1.1", - "@types/jasminewd2": "~2.0.12", "@types/lodash-es": "^4.17.10", "@types/node": "^18.11.0", "@typescript-eslint/eslint-plugin": "^6.9.0", @@ -60,12 +55,9 @@ "eslint": "^8.52.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-deprecation": "^2.0.0", - "eslint-plugin-prettier": "^5.0.1", - "fibers": "^5.0.3", "html-validate": "^8.7.0", "husky": "^8.0.3", "jasmine-core": "~5.1.1", - "jasmine-spec-reporter": "~7.0.0", "karma": "~6.4.2", "karma-brief-reporter": "^0.2.2", "karma-chrome-launcher": "~3.2.0", @@ -75,15 +67,9 @@ "karma-spec-reporter": "^0.0.36", "lint-staged": "~15.0.2", "prettier": "3.0.3", - "ts-node": "~10.9.1", "typescript": "~5.1.0" } }, - "node_modules/-": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/-/-/--0.0.1.tgz", - "integrity": "sha512-3HfneK3DGAm05fpyj20sT3apkNcvPpCuccOThOPdzz8sY7GgQGe0l93XH9bt+YzibcTIgUAIMoyVJI740RtgyQ==" - }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -2616,28 +2602,6 @@ "node": ">=0.1.90" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -3836,56 +3800,6 @@ "node": ">=14" } }, - "node_modules/@pkgr/utils": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", - "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "fast-glob": "^3.3.0", - "is-glob": "^4.0.3", - "open": "^9.1.0", - "picocolors": "^1.0.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/@pkgr/utils/node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@pkgr/utils/node_modules/open": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", - "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", - "dev": true, - "dependencies": { - "default-browser": "^4.0.0", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -4060,30 +3974,6 @@ "node": ">= 6" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, "node_modules/@tufjs/canonical-json": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz", @@ -4254,15 +4144,6 @@ "integrity": "sha512-qL4GoZHHJl1JQ0vK31OtXMfkfGxYJnysmYz9kk0E8j5W96ThKykBF90uD3PcVmQUAzulbsaus2eFiBhCH5itfw==", "dev": true }, - "node_modules/@types/jasminewd2": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.12.tgz", - "integrity": "sha512-C4rXKMnGqLqTw4mgfiT0fL91g5oFAUhreR8jeeYk4xYcgh1/CImqgn5pWcErnpJJS43XFUfHGit0sSPQ39G1Pg==", - "dev": true, - "dependencies": { - "@types/jasmine": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.14", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", @@ -5172,15 +5053,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/adjust-sourcemap-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", @@ -5376,12 +5248,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -5622,15 +5488,6 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, - "node_modules/big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -5734,18 +5591,6 @@ "@popperjs/core": "^2.11.8" } }, - "node_modules/bplist-parser": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", - "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", - "dev": true, - "dependencies": { - "big-integer": "^1.6.44" - }, - "engines": { - "node": ">= 5.10.0" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -5843,21 +5688,6 @@ "semver": "^7.0.0" } }, - "node_modules/bundle-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", - "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", - "dev": true, - "dependencies": { - "run-applescript": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -6466,16 +6296,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/core-js": { - "version": "3.33.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.1.tgz", - "integrity": "sha512-qVSq3s+d4+GsqN0teRCJtM6tdEEXyWxjzbhVrCHmBS5ZTM0FS2MOS0D13dUXAWDUN6a+lHI/N1hF9Ytz6iLl9Q==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-js-compat": { "version": "3.33.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.1.tgz", @@ -6552,12 +6372,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/critters": { "version": "0.0.20", "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.20.tgz", @@ -6843,78 +6657,6 @@ "node": ">=0.10.0" } }, - "node_modules/default-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", - "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", - "dev": true, - "dependencies": { - "bundle-name": "^3.0.0", - "default-browser-id": "^3.0.0", - "execa": "^7.1.1", - "titleize": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", - "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", - "dev": true, - "dependencies": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/default-browser/node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/default-browser/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/default-gateway": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", @@ -7105,6 +6847,8 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, + "optional": true, + "peer": true, "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -7124,15 +6868,6 @@ "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", "dev": true }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -7175,12 +6910,6 @@ "node": ">=6.0.0" } }, - "node_modules/document-register-element": { - "version": "1.14.10", - "resolved": "https://registry.npmjs.org/document-register-element/-/document-register-element-1.14.10.tgz", - "integrity": "sha512-w5UA37hEIrs+9pruo2yR5UD13c4UHDlkqqjt4qurnp7QsBI9b1IOi8WXUim+aCqKBsENX3Z/cso7XMOuwJH1Yw==", - "deprecated": "V0 is gone and the best V1 polyfill is now @ungap/custom-elements" - }, "node_modules/dom-serialize": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", @@ -7839,35 +7568,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/eslint-plugin-prettier": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", - "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.5" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -8462,12 +8162,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -8522,6 +8216,8 @@ "integrity": "sha512-/qYTSoZydQkM21qZpGLDLuCq8c+B8KhuCQ1kLPvnRNhxhVbvrpmH9l2+Lblf5neDuEsY4bfT7LeO553TXQDvJw==", "dev": true, "hasInstallScript": true, + "optional": true, + "peer": true, "dependencies": { "detect-libc": "^1.0.3" }, @@ -8965,7 +8661,8 @@ "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true }, "node_modules/glob/node_modules/brace-expansion": { "version": "2.0.1", @@ -9034,7 +8731,8 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true }, "node_modules/graphemer": { "version": "1.4.0", @@ -9822,39 +9520,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-inside-container/node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -10280,15 +9945,6 @@ "integrity": "sha512-UrzO3fL7nnxlQXlvTynNAenL+21oUQRlzqQFsA2U11ryb4+NLOCOePZ70PTojEaUKhiFugh7dG0Q+I58xlPdWg==", "dev": true }, - "node_modules/jasmine-spec-reporter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz", - "integrity": "sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==", - "dev": true, - "dependencies": { - "colors": "1.4.0" - } - }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -11385,12 +11041,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "node_modules/make-fetch-happen": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", @@ -13357,18 +13007,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -13927,116 +13565,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/run-applescript": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", - "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", - "dev": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-applescript/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/run-applescript/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/run-applescript/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-applescript/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/run-applescript/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/run-applescript/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-applescript/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/run-applescript/node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -15042,22 +14570,6 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/synckit": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", - "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", - "dev": true, - "dependencies": { - "@pkgr/utils": "^2.3.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -15320,18 +14832,6 @@ "next-tick": "1" } }, - "node_modules/titleize": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", - "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -15429,49 +14929,6 @@ "typescript": ">=4.2.0" } }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", @@ -15692,15 +15149,6 @@ "node": ">= 0.8" } }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -15779,12 +15227,6 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -15906,6 +15348,7 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -16531,15 +15974,6 @@ "node": ">=12" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index c6ed9f292..082614cbd 100644 --- a/package.json +++ b/package.json @@ -17,12 +17,12 @@ "format:upgrade": "npm install --save-exact prettier@latest && npm run format", "preanalyze": "ng build --stats-json", "analyze": "npx webpack-bundle-analyzer dist/$(ng config defaultProject)/stats.json", + "unused": "npx knip", "postanalyze": "rm dist/$(ng config defaultProject)/stats.json", "prepare": "husky install" }, "private": true, "dependencies": { - "-": "0.0.1", "@angular/animations": "^16.2.10", "@angular/common": "^16.2.10", "@angular/compiler": "^16.2.10", @@ -39,9 +39,7 @@ "@ngx-translate/http-loader": "^8.0.0", "@popperjs/core": "^2.11.8", "bootstrap": "^5.3.2", - "core-js": "~3.33.1", "date-fns": "^2.30.0", - "document-register-element": "^1.14.10", "fp-ts": "^2.16.1", "io-ts": "^2.2.20", "io-ts-types": "^0.5.19", @@ -51,7 +49,6 @@ "ngx-infinite-scroll": "^16.0.0", "rxjs": "~7.8.1", "tslib": "^2.6.2", - "watchpack": "^2.4.0", "xss": "^1.0.14", "zone.js": "~0.13.0" }, @@ -66,7 +63,6 @@ "@angular/compiler-cli": "^16.2.10", "@angular/language-service": "^16.2.10", "@types/jasmine": "~5.1.1", - "@types/jasminewd2": "~2.0.12", "@types/lodash-es": "^4.17.10", "@types/node": "^18.11.0", "@typescript-eslint/eslint-plugin": "^6.9.0", @@ -74,12 +70,9 @@ "eslint": "^8.52.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-deprecation": "^2.0.0", - "eslint-plugin-prettier": "^5.0.1", - "fibers": "^5.0.3", "html-validate": "^8.7.0", "husky": "^8.0.3", "jasmine-core": "~5.1.1", - "jasmine-spec-reporter": "~7.0.0", "karma": "~6.4.2", "karma-brief-reporter": "^0.2.2", "karma-chrome-launcher": "~3.2.0", @@ -89,21 +82,10 @@ "karma-spec-reporter": "^0.0.36", "lint-staged": "~15.0.2", "prettier": "3.0.3", - "ts-node": "~10.9.1", "typescript": "~5.1.0" }, "lint-staged": { - "./src/app/**/*.{ts,html}": [ - "eslint" - ], - "./src/app/**/*.ts": [ - "prettier --write" - ], - "./**/*.{js,json,css,scss,html,md,yaml}": [ - "prettier --write" - ], - "./src/app/**/*.html": [ - "html-validate" - ] + "./src/app/**/*.{ts,html}": "eslint", + "**/*": "prettier --write --ignore-unknown" } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 0eff98305..63f26c844 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -31,12 +31,12 @@ import { FormsModule } from '@angular/forms'; // AoT requires an exported function for factories export function HttpLoaderFactory( http: HttpClient, - settings: Settings + settings: Settings, ): TranslateHttpLoader { return new TranslateHttpLoader( http, `${settings.scriptsAndAssetsPath}/assets/locales/`, - '.json' + '.json', ); } @@ -81,7 +81,7 @@ export class AppModule implements DoBootstrap { constructor(private injector: Injector) { const notificationsElement = createCustomElement( MyNotificationsShowComponent, - { injector: this.injector } + { injector: this.injector }, ); customElements.define('erz-notifications', notificationsElement); @@ -92,5 +92,5 @@ export class AppModule implements DoBootstrap { } // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method - ngDoBootstrap(appRef: ApplicationRef): void {} + ngDoBootstrap(_appRef: ApplicationRef): void {} } diff --git a/src/app/auth.guard.spec.ts b/src/app/auth.guard.spec.ts index 5791cd660..faed4e355 100644 --- a/src/app/auth.guard.spec.ts +++ b/src/app/auth.guard.spec.ts @@ -11,6 +11,8 @@ import { authGuard } from './auth.guard'; import { AuthService } from './shared/services/auth.service'; import { buildTestModuleMetadata } from 'src/spec-helpers'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('authGuard', () => { let router: Router; let authServiceMock: AuthService; @@ -40,25 +42,25 @@ describe('authGuard', () => { }, ], declarations: [DummyComponent], - }) + }), ); router = TestBed.inject(Router); authServiceMock = TestBed.inject(AuthService); activatedRouteSnapshotMock = jasmine.createSpyObj( 'ActivatedRouteSnapshot', - ['toString'] + ['toString'], ); routerStateSnapshotMock = jasmine.createSpyObj( 'RouterStateSnapshot', - ['toString'] + ['toString'], ); }); describe('authenticated', () => { it('allows to activate', fakeAsync(() => { const result = TestBed.runInInjectionContext(() => - authGuard()(activatedRouteSnapshotMock, routerStateSnapshotMock) + authGuard()(activatedRouteSnapshotMock, routerStateSnapshotMock), ); expect(result).toBe(true); tick(); @@ -74,7 +76,7 @@ describe('authGuard', () => { it('does not allow to activate and redirects to /unauthenticated', fakeAsync(() => { const result = TestBed.runInInjectionContext(() => - authGuard()(activatedRouteSnapshotMock, routerStateSnapshotMock) + authGuard()(activatedRouteSnapshotMock, routerStateSnapshotMock), ); expect(result).toBe(false); tick(); diff --git a/src/app/edit-absences/components/edit-absences-edit/edit-absences-edit.component.spec.ts b/src/app/edit-absences/components/edit-absences-edit/edit-absences-edit.component.spec.ts index 986ed4afa..777966d50 100644 --- a/src/app/edit-absences/components/edit-absences-edit/edit-absences-edit.component.spec.ts +++ b/src/app/edit-absences/components/edit-absences-edit/edit-absences-edit.component.spec.ts @@ -12,6 +12,8 @@ import { DropDownItemsRestService } from 'src/app/shared/services/drop-down-item import { PresenceType } from 'src/app/shared/models/presence-type.model'; import { DropDownItem } from 'src/app/shared/models/drop-down-item.model'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('EditAbsencesEditComponent', () => { let component: EditAbsencesEditComponent; let fixture: ComponentFixture; @@ -43,7 +45,7 @@ describe('EditAbsencesEditComponent', () => { dispensation = buildPresenceType( settings.dispensationPresenceTypeId, false, - false + false, ); dispensation.IsDispensation = true; @@ -106,7 +108,7 @@ describe('EditAbsencesEditComponent', () => { }, }, ], - }) + }), ).compileComponents(); httpTestingController = TestBed.inject(HttpTestingController); @@ -136,7 +138,7 @@ describe('EditAbsencesEditComponent', () => { 'Math', undefined, undefined, - ill.Id + ill.Id, ), buildLessonPresence( 2, @@ -145,7 +147,7 @@ describe('EditAbsencesEditComponent', () => { 'Deutsch', undefined, undefined, - ill.Id + ill.Id, ), ]; fixture.detectChanges(); @@ -161,7 +163,7 @@ describe('EditAbsencesEditComponent', () => { 'Math', undefined, undefined, - doctor.Id + doctor.Id, ), buildLessonPresence( 2, @@ -170,7 +172,7 @@ describe('EditAbsencesEditComponent', () => { 'Deutsch', undefined, undefined, - ill.Id + ill.Id, ), ]; fixture.detectChanges(); @@ -191,7 +193,7 @@ describe('EditAbsencesEditComponent', () => { undefined, undefined, undefined, - 100 + 100, ), buildLessonPresence( 2, @@ -202,7 +204,7 @@ describe('EditAbsencesEditComponent', () => { undefined, absence.Id, undefined, - 100 + 100, ), buildLessonPresence( 3, @@ -213,7 +215,7 @@ describe('EditAbsencesEditComponent', () => { undefined, doctor.Id, undefined, - 100 + 100, ), buildLessonPresence( 4, @@ -224,7 +226,7 @@ describe('EditAbsencesEditComponent', () => { undefined, ill.Id, undefined, - 100 + 100, ), buildLessonPresence( 5, @@ -235,7 +237,7 @@ describe('EditAbsencesEditComponent', () => { undefined, late.Id, undefined, - 100 + 100, ), buildLessonPresence( 6, @@ -246,7 +248,7 @@ describe('EditAbsencesEditComponent', () => { undefined, dispensation.Id, undefined, - 100 + 100, ), buildLessonPresence( 7, @@ -257,7 +259,7 @@ describe('EditAbsencesEditComponent', () => { undefined, halfDay.Id, undefined, - 100 + 100, ), ]; fixture.detectChanges(); @@ -385,7 +387,7 @@ describe('EditAbsencesEditComponent', () => { function getSelect(controlName: string): HTMLSelectElement { const select = element.querySelector( - `select[formControlName="${controlName}"]` + `select[formControlName="${controlName}"]`, ) as HTMLSelectElement | undefined; expect(select).toBeDefined(); return select as HTMLSelectElement; @@ -402,7 +404,7 @@ describe('EditAbsencesEditComponent', () => { function clickRadio(labelText: string): void { const labels = Array.prototype.slice.call( - element.querySelectorAll('label') + element.querySelectorAll('label'), ); const label = labels.find((l) => l.textContent.includes(labelText)) as | HTMLElement @@ -423,7 +425,7 @@ describe('EditAbsencesEditComponent', () => { httpTestingController .expectOne( (req) => req.urlWithParams === url && isEqual(req.body, body), - url + url, ) .flush(''); } @@ -434,7 +436,7 @@ describe('EditAbsencesEditComponent', () => { httpTestingController .expectOne( (req) => req.urlWithParams === url && isEqual(req.body, body), - url + url, ) .flush(''); } diff --git a/src/app/edit-absences/components/edit-absences-header/edit-absences-header.component.ts b/src/app/edit-absences/components/edit-absences-header/edit-absences-header.component.ts index 70f5c790d..1415e4dfa 100644 --- a/src/app/edit-absences/components/edit-absences-header/edit-absences-header.component.ts +++ b/src/app/edit-absences/components/edit-absences-header/edit-absences-header.component.ts @@ -2,7 +2,6 @@ import { ChangeDetectionStrategy, Component, EventEmitter, - OnInit, Output, Input, } from '@angular/core'; @@ -66,23 +65,23 @@ export class EditAbsencesHeaderComponent { map((i) => addGroupToDropdownItem( i, - this.translate.instant('shared.multiselect.all-option') - ) - ) + this.translate.instant('shared.multiselect.all-option'), + ), + ), ); presenceTypesGrouped$ = this.state.presenceTypes$.pipe( map((presenceTypes) => - presenceTypes.filter(not(isComment)).filter(not(isIncident)) + presenceTypes.filter(not(isComment)).filter(not(isIncident)), ), map(sortPresenceTypes), map(createPresenceTypesDropdownItems), map((i) => addGroupToDropdownItem( i, - this.translate.instant('shared.multiselect.all-option') - ) - ) + this.translate.instant('shared.multiselect.all-option'), + ), + ), ); incidentTypesGrouped$ = this.state.presenceTypes$.pipe( @@ -92,9 +91,9 @@ export class EditAbsencesHeaderComponent { map((i) => addGroupToDropdownItem( i, - this.translate.instant('shared.multiselect.all-option') - ) - ) + this.translate.instant('shared.multiselect.all-option'), + ), + ), ); constructor( @@ -103,7 +102,7 @@ export class EditAbsencesHeaderComponent { public studyClassService: StudyClassesRestService, public teacherResourcesService: TeacherResourcesRestService, private state: EditAbsencesStateService, - private translate: TranslateService + private translate: TranslateService, ) {} classesHttpFilter = { diff --git a/src/app/evaluate-absences/components/evaluate-absences-header/evaluate-absences-header.component.ts b/src/app/evaluate-absences/components/evaluate-absences-header/evaluate-absences-header.component.ts index 7e58a2677..2c0c462e4 100644 --- a/src/app/evaluate-absences/components/evaluate-absences-header/evaluate-absences-header.component.ts +++ b/src/app/evaluate-absences/components/evaluate-absences-header/evaluate-absences-header.component.ts @@ -1,6 +1,5 @@ import { Component, - OnInit, ChangeDetectionStrategy, Output, EventEmitter, @@ -31,7 +30,7 @@ export class EvaluateAbsencesHeaderComponent { constructor( public studentsService: StudentsRestService, public educationalEventsService: EducationalEventsRestService, - public studyClassesService: StudyClassesRestService + public studyClassesService: StudyClassesRestService, ) {} classesHttpFilter = { diff --git a/src/app/evaluate-absences/components/evaluate-absences-list/evaluate-absences-list.component.spec.ts b/src/app/evaluate-absences/components/evaluate-absences-list/evaluate-absences-list.component.spec.ts index bb9aaca05..038cc476e 100644 --- a/src/app/evaluate-absences/components/evaluate-absences-list/evaluate-absences-list.component.spec.ts +++ b/src/app/evaluate-absences/components/evaluate-absences-list/evaluate-absences-list.component.spec.ts @@ -12,7 +12,7 @@ import { PresenceTypesService } from 'src/app/shared/services/presence-types.ser describe('EvaluateAbsencesListComponent', () => { let fixture: ComponentFixture; - let component: EvaluateAbsencesListComponent; + // let component: EvaluateAbsencesListComponent; let element: HTMLElement; let stateServiceMock: EvaluateAbsencesStateService; let presenceTypesServiceMock: PresenceTypesService; @@ -62,13 +62,13 @@ describe('EvaluateAbsencesListComponent', () => { }, }, ], - }) + }), ).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(EvaluateAbsencesListComponent); - component = fixture.componentInstance; + // component = fixture.componentInstance; element = fixture.debugElement.nativeElement; }); @@ -84,7 +84,7 @@ describe('EvaluateAbsencesListComponent', () => { const headerCells = table!.querySelectorAll('th'); expect(Array.from(headerCells)).toHaveSize(7); expect(headerCells[6].textContent).toContain( - 'evaluate-absences.list.header.incident' + 'evaluate-absences.list.header.incident', ); const rows = table!.querySelectorAll('tbody tr'); @@ -110,10 +110,10 @@ describe('EvaluateAbsencesListComponent', () => { const headerCells = table!.querySelectorAll('th'); expect(Array.from(headerCells)).toHaveSize(8); expect(headerCells[6].textContent).toContain( - 'evaluate-absences.list.header.incident' + 'evaluate-absences.list.header.incident', ); expect(headerCells[7].textContent).toContain( - 'evaluate-absences.list.header.halfday' + 'evaluate-absences.list.header.halfday', ); const rows = table!.querySelectorAll('tbody tr'); diff --git a/src/app/events/components/grade/grade.component.spec.ts b/src/app/events/components/grade/grade.component.spec.ts index be774d93f..09f324806 100644 --- a/src/app/events/components/grade/grade.component.spec.ts +++ b/src/app/events/components/grade/grade.component.spec.ts @@ -24,7 +24,7 @@ describe('GradeComponent', () => { TestBed.configureTestingModule( buildTestModuleMetadata({ declarations: [GradeComponent], - }) + }), ).compileComponents(); fixture = TestBed.createComponent(GradeComponent); @@ -191,7 +191,7 @@ describe('GradeComponent', () => { fixture.detectChanges(); component.gradingScaleDisabled$.subscribe((result) => - expect(result).toBe(true) + expect(result).toBe(true), ); }); @@ -205,7 +205,7 @@ describe('GradeComponent', () => { fixture.detectChanges(); component.gradingScaleDisabled$.subscribe((result) => - expect(result).toBe(false) + expect(result).toBe(false), ); }); @@ -222,7 +222,7 @@ describe('GradeComponent', () => { // then component.gradingScaleDisabled$.subscribe((result) => - expect(result).toBe(false) + expect(result).toBe(false), ); }); @@ -238,7 +238,7 @@ describe('GradeComponent', () => { // then component.gradingScaleDisabled$.subscribe((result) => - expect(result).toBe(false) + expect(result).toBe(false), ); }); }); @@ -248,11 +248,3 @@ function expectPointsInputValue(debugElement: DebugElement, expected: string) { const input = debugElement.query(byTestId('point-input')).nativeElement; expect(input.value).toBe(expected); } - -function expectValidationErrorMessage(debugElement: DebugElement) { - const error = debugElement.query( - byTestId('validation-error-message') - ).nativeElement; - - expect(error.textContent).toContain('global.validation-errors.invalidPoints'); -} diff --git a/src/app/events/components/tests-add/tests-add.component.spec.ts b/src/app/events/components/tests-add/tests-add.component.spec.ts index 95a4eb270..4b5b1bf6a 100644 --- a/src/app/events/components/tests-add/tests-add.component.spec.ts +++ b/src/app/events/components/tests-add/tests-add.component.spec.ts @@ -15,7 +15,7 @@ describe('TestsAddComponent', () => { let courseService: jasmine.SpyObj; beforeEach(async () => { - let course = buildCourse(1); + const course = buildCourse(1); activatedRouteMock = new ActivatedRouteMock({ id: course.Id, @@ -32,7 +32,7 @@ describe('TestsAddComponent', () => { { provide: ActivatedRoute, useValue: activatedRouteMock }, { provide: CoursesRestService, useValue: courseService }, ], - }) + }), ).compileComponents(); }); @@ -65,7 +65,7 @@ describe('TestsAddComponent', () => { formGroupValue.weight, formGroupValue.isPointGrading, formGroupValue.maxPoints, - formGroupValue.maxPointsAdjusted + formGroupValue.maxPointsAdjusted, ); }); }); diff --git a/src/app/events/components/tests-add/tests-add.component.ts b/src/app/events/components/tests-add/tests-add.component.ts index fa08a0b35..0fa41a05a 100644 --- a/src/app/events/components/tests-add/tests-add.component.ts +++ b/src/app/events/components/tests-add/tests-add.component.ts @@ -21,7 +21,7 @@ export class TestsAddComponent { courseId$ = this.route.paramMap.pipe( map((params) => Number(params.get('id'))), - distinctUntilChanged() + distinctUntilChanged(), ); constructor( @@ -29,9 +29,10 @@ export class TestsAddComponent { private courseService: CoursesRestService, private toastService: ToastService, private translate: TranslateService, - private router: Router + private router: Router, ) {} + // eslint-disable-next-line @typescript-eslint/no-explicit-any save(formGroupValue: any): void { this.saving$.next(true); const { @@ -52,24 +53,24 @@ export class TestsAddComponent { weight, isPointGrading, maxPoints, - maxPointsAdjusted - ) + maxPointsAdjusted, + ), ), - finalize(() => this.saving$.next(false)) + finalize(() => this.saving$.next(false)), ) .subscribe(this.onSaveSuccess.bind(this)); } private onSaveSuccess(): void { this.toastService.success( - this.translate.instant('tests.form.save-success') + this.translate.instant('tests.form.save-success'), ); this.navigateBack(); } private navigateBack(): void { this.courseId$.subscribe((id) => - this.router.navigate(['events', id, 'tests']) + this.router.navigate(['events', id, 'tests']), ); } } diff --git a/src/app/events/components/tests-edit/tests-delete/tests-delete.component.ts b/src/app/events/components/tests-edit/tests-delete/tests-delete.component.ts index 24eb0bd29..8a7cd66d5 100644 --- a/src/app/events/components/tests-edit/tests-delete/tests-delete.component.ts +++ b/src/app/events/components/tests-edit/tests-delete/tests-delete.component.ts @@ -13,12 +13,12 @@ export class TestsDeleteComponent { constructor(public activeModal: NgbActiveModal) {} get canDeleteTest(): boolean { - let testsExists = + const testsExists = this.test?.Results?.filter( (test) => test.GradeId !== null || test.GradeValue !== null || - test.Points !== null + test.Points !== null, ) || []; return testsExists.length === 0 ? true : false; } diff --git a/src/app/events/components/tests-edit/tests-edit.component.spec.ts b/src/app/events/components/tests-edit/tests-edit.component.spec.ts index cbf5863d1..a577f2847 100644 --- a/src/app/events/components/tests-edit/tests-edit.component.spec.ts +++ b/src/app/events/components/tests-edit/tests-edit.component.spec.ts @@ -17,8 +17,8 @@ describe('TestsEditComponent', () => { let courseRestServiceMock: jasmine.SpyObj; beforeEach(async () => { - let course = buildCourse(1234); - let test = buildTest(1234, 1, []); + const course = buildCourse(1234); + const test = buildTest(1234, 1, []); course.Tests = [test]; activatedRouteMock = new ActivatedRouteMock({ @@ -47,7 +47,7 @@ describe('TestsEditComponent', () => { { provide: ActivatedRoute, useValue: activatedRouteMock }, { provide: CoursesRestService, useValue: courseRestServiceMock }, ], - }) + }), ).compileComponents(); }); @@ -81,7 +81,7 @@ describe('TestsEditComponent', () => { formGroupValue.weight, formGroupValue.isPointGrading, formGroupValue.maxPoints, - formGroupValue.maxPointsAdjusted + formGroupValue.maxPointsAdjusted, ); }); }); diff --git a/src/app/events/components/tests-edit/tests-edit.component.ts b/src/app/events/components/tests-edit/tests-edit.component.ts index 82d591201..a642a9683 100644 --- a/src/app/events/components/tests-edit/tests-edit.component.ts +++ b/src/app/events/components/tests-edit/tests-edit.component.ts @@ -27,11 +27,11 @@ export class TestsEditComponent { private testId$ = this.route.paramMap.pipe( map((params) => Number(params.get('testId'))), - distinctUntilChanged() + distinctUntilChanged(), ); test$ = combineLatest([this.state.tests$, this.testId$]).pipe( - map(([tests, id]) => tests.find((t) => t.Id === id)) + map(([tests, id]) => tests.find((t) => t.Id === id)), ); constructor( @@ -41,7 +41,7 @@ export class TestsEditComponent { private toastService: ToastService, private translate: TranslateService, private router: Router, - private modalService: NgbModal + private modalService: NgbModal, ) {} openDeleteModal(test: Test) { @@ -55,11 +55,12 @@ export class TestsEditComponent { .subscribe(this.onDeleteSuccess.bind(this)); } }, - () => {} + () => {}, ); } - save(formGroupValue: any): void { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + save(formGroupValue: Dict): void { this.saving$.next(true); const { designation, @@ -81,24 +82,24 @@ export class TestsEditComponent { weight, isPointGrading, maxPoints, - maxPointsAdjusted - ) + maxPointsAdjusted, + ), ), - finalize(() => this.saving$.next(false)) + finalize(() => this.saving$.next(false)), ) .subscribe(this.onSaveSuccess.bind(this)); } private onSaveSuccess(): void { this.toastService.success( - this.translate.instant('tests.form.save-success') + this.translate.instant('tests.form.save-success'), ); this.navigateBack(); } private onDeleteSuccess(deletedTestId: number): void { this.toastService.success( - this.translate.instant('tests.form.delete-success') + this.translate.instant('tests.form.delete-success'), ); this.state.deleteTest(deletedTestId); this.navigateBack(); diff --git a/src/app/events/components/tests-list/tests-list.component.spec.ts b/src/app/events/components/tests-list/tests-list.component.spec.ts index 5aa04ea62..d9d24f4f3 100644 --- a/src/app/events/components/tests-list/tests-list.component.spec.ts +++ b/src/app/events/components/tests-list/tests-list.component.spec.ts @@ -17,8 +17,8 @@ describe('TestsListComponent', () => { let component: TestsListComponent; let fixture: ComponentFixture; let testStateServiceMock: TestStateService; - let result = buildResult(12, 1); - let test = buildTest(1234, 12, [result]); + const result = buildResult(12, 1); + const test = buildTest(1234, 12, [result]); const course = buildCourse(1234); @@ -58,7 +58,7 @@ describe('TestsListComponent', () => { useValue: reportServiceMock as ReportsService, }, ], - }) + }), ).compileComponents(); })); @@ -80,7 +80,7 @@ describe('TestsListComponent', () => { expect(link).not.toBeNull(); expect(link.href).toBe( - `http://localhost:9876/link-to-evaluation-module.aspx?IDAnlass=${course.Id}` + `http://localhost:9876/link-to-evaluation-module.aspx?IDAnlass=${course.Id}`, ); expectElementPresent(fixture.debugElement, 'link-to-rating-overview'); diff --git a/src/app/events/services/events-state.service.spec.ts b/src/app/events/services/events-state.service.spec.ts index 182b9febf..5fec1ae37 100644 --- a/src/app/events/services/events-state.service.spec.ts +++ b/src/app/events/services/events-state.service.spec.ts @@ -15,9 +15,9 @@ import { Event, EventsStateService, EventState } from './events-state.service'; describe('EventsStateService', () => { let service: EventsStateService; let httpTestingController: HttpTestingController; - let storageServiceMock: StorageService = jasmine.createSpyObj( + const storageServiceMock: StorageService = jasmine.createSpyObj( 'StorageService', - ['getPayload'] + ['getPayload'], ); let courseEvents: Event[]; @@ -41,7 +41,7 @@ describe('EventsStateService', () => { useValue: storageServiceMock, }, ], - }) + }), ); httpTestingController = TestBed.inject(HttpTestingController); @@ -96,11 +96,11 @@ describe('EventsStateService', () => { ...evaluationStatus, HasReviewOfEvaluationStarted: true, }, - studyClasses + studyClasses, ), { FinalGrades: [buildFinalGrading(45)], - } + }, ); courses = [ @@ -114,7 +114,7 @@ describe('EventsStateService', () => { HasEvaluationStarted: true, EvaluationUntil: new Date(2022, 5, 3), }, - [studyClasses[0]] + [studyClasses[0]], ), buildCourse( 3, @@ -125,7 +125,7 @@ describe('EventsStateService', () => { HasEvaluationStarted: true, }, [studyClasses[1]], - 10300 + 10300, ), buildCourse( 4, @@ -135,7 +135,7 @@ describe('EventsStateService', () => { ...evaluationStatus, HasTestGrading: true, }, - studyClasses + studyClasses, ), ratedCourse, ]; @@ -200,7 +200,7 @@ describe('EventsStateService', () => { ...studyClassEvents, ...assessmentEvents, ...courseEvents, - ]) + ]), ); expectCoursesRequest(); diff --git a/src/app/events/utils/events.spec.ts b/src/app/events/utils/events.spec.ts index ad75e38a4..4d01e9189 100644 --- a/src/app/events/utils/events.spec.ts +++ b/src/app/events/utils/events.spec.ts @@ -28,7 +28,7 @@ describe('Course utils', () => { 1234, 'Course in no state', undefined, - evaluationStatusRef + evaluationStatusRef, ); // then @@ -49,7 +49,7 @@ describe('Course utils', () => { 1234, 'Course in state add-tests', undefined, - evaluationStatusRef + evaluationStatusRef, ); // then @@ -71,7 +71,7 @@ describe('Course utils', () => { 1234, 'Course in state rating-until', undefined, - evaluationStatusRef + evaluationStatusRef, ); // then @@ -95,7 +95,7 @@ describe('Course utils', () => { undefined, evaluationStatusRef, undefined, - 10300 + 10300, ); // then @@ -120,7 +120,7 @@ describe('Course utils', () => { 1234, 'Course in no state', undefined, - evaluationStatusRef + evaluationStatusRef, ); // then @@ -141,7 +141,7 @@ describe('Course utils', () => { 1234, 'Course in no state', undefined, - evaluationStatusRef + evaluationStatusRef, ); // then @@ -162,7 +162,7 @@ describe('Course utils', () => { 1234, 'Course in no state', undefined, - evaluationStatusRef + evaluationStatusRef, ); // then @@ -183,7 +183,7 @@ describe('Course utils', () => { 1234, 'Course in no state', undefined, - evaluationStatusRef + evaluationStatusRef, ); // then @@ -209,7 +209,7 @@ describe('Course utils', () => { 1234, 'Course in no state', undefined, - evaluationStatusRef + evaluationStatusRef, ); // then @@ -235,7 +235,7 @@ describe('Course utils', () => { 1234, 'Course in no state', undefined, - evaluationStatusRef + evaluationStatusRef, ); // then @@ -251,11 +251,11 @@ describe('Course utils', () => { const evaluationStatusRef = { HasReviewOfEvaluationStarted: true, } as unknown as EvaluationStatusRef; - let course = buildCourse( + const course = buildCourse( 1, 'rated course', undefined, - evaluationStatusRef + evaluationStatusRef, ); course.FinalGrades = [buildFinalGrading(3)]; @@ -268,11 +268,11 @@ describe('Course utils', () => { const evaluationStatusRef = { HasReviewOfEvaluationStarted: true, } as unknown as EvaluationStatusRef; - let course = buildCourse( + const course = buildCourse( 1, 'rated course', undefined, - evaluationStatusRef + evaluationStatusRef, ); course.FinalGrades = null; @@ -285,11 +285,11 @@ describe('Course utils', () => { const evaluationStatusRef = { HasReviewOfEvaluationStarted: true, } as unknown as EvaluationStatusRef; - let course = buildCourse( + const course = buildCourse( 1, 'rated course', undefined, - evaluationStatusRef + evaluationStatusRef, ); course.FinalGrades = []; @@ -302,11 +302,11 @@ describe('Course utils', () => { const evaluationStatusRef = { HasReviewOfEvaluationStarted: false, } as unknown as EvaluationStatusRef; - let course = buildCourse( + const course = buildCourse( 1, 'rated course', undefined, - evaluationStatusRef + evaluationStatusRef, ); course.FinalGrades = null; diff --git a/src/app/events/utils/events.ts b/src/app/events/utils/events.ts index 3e5d43137..df102076f 100644 --- a/src/app/events/utils/events.ts +++ b/src/app/events/utils/events.ts @@ -17,12 +17,8 @@ const COURSE_ACTIVE_STATUS_ID = 10350; * course's evaluation and test status. See #427 */ export function getEventState(course: Course): Option { - const { - HasEvaluationStarted, - HasReviewOfEvaluationStarted, - EvaluationUntil, - HasTestGrading, - } = course.EvaluationStatusRef; + const { HasEvaluationStarted, EvaluationUntil, HasTestGrading } = + course.EvaluationStatusRef; if ( HasEvaluationStarted === true && @@ -52,7 +48,8 @@ export function getEventState(course: Course): Option { if ( HasEvaluationStarted === false && HasTestGrading === true && - (course.StatusId !== DEFINITIVELY_EVALUATED_STATUS_ID && course.StatusId !== REVIEW_EVALUATED_STATUS_ID) + course.StatusId !== DEFINITIVELY_EVALUATED_STATUS_ID && + course.StatusId !== REVIEW_EVALUATED_STATUS_ID ) { // Tests erfassen return { diff --git a/src/app/global-error-handler.ts b/src/app/global-error-handler.ts index 2f553e502..4125a4152 100644 --- a/src/app/global-error-handler.ts +++ b/src/app/global-error-handler.ts @@ -1,4 +1,4 @@ -import { Injectable, ErrorHandler, Injector, NgZone } from '@angular/core'; +import { Injectable, ErrorHandler, NgZone } from '@angular/core'; import { HttpErrorResponse } from '@angular/common/http'; import { TranslateService } from '@ngx-translate/core'; import { ToastService } from './shared/services/toast.service'; @@ -7,12 +7,11 @@ import { ToastService } from './shared/services/toast.service'; export class GlobalErrorHandler implements ErrorHandler { constructor( private ngZone: NgZone, - private injector: Injector, private translate: TranslateService, - private toastService: ToastService + private toastService: ToastService, ) {} - handleError(error: any): void { + handleError(error: unknown): void { console.error(String(error)); if (!(error instanceof HttpErrorResponse)) { @@ -24,7 +23,7 @@ export class GlobalErrorHandler implements ErrorHandler { this.ngZone.run(() => { this.toastService.error( this.translate.instant('global.app-errors.exception-message'), - this.translate.instant('global.app-errors.exception-title') + this.translate.instant('global.app-errors.exception-title'), ); }); } diff --git a/src/app/my-absences/components/my-absences-report-header/my-absences-report-header.component.ts b/src/app/my-absences/components/my-absences-report-header/my-absences-report-header.component.ts index 914a6740b..28cb504ac 100644 --- a/src/app/my-absences/components/my-absences-report-header/my-absences-report-header.component.ts +++ b/src/app/my-absences/components/my-absences-report-header/my-absences-report-header.component.ts @@ -1,6 +1,5 @@ import { Component, - OnInit, Input, Output, EventEmitter, diff --git a/src/app/my-absences/components/my-absences-report-link/my-absences-report-link.component.ts b/src/app/my-absences/components/my-absences-report-link/my-absences-report-link.component.ts index 8d4cdc701..733e54f81 100644 --- a/src/app/my-absences/components/my-absences-report-link/my-absences-report-link.component.ts +++ b/src/app/my-absences/components/my-absences-report-link/my-absences-report-link.component.ts @@ -1,6 +1,5 @@ import { Component, - OnInit, ChangeDetectionStrategy, HostListener, ViewChild, diff --git a/src/app/my-absences/components/my-absences-report-list/my-absences-report-list.component.ts b/src/app/my-absences/components/my-absences-report-list/my-absences-report-list.component.ts index 58206f249..1544c8e9f 100644 --- a/src/app/my-absences/components/my-absences-report-list/my-absences-report-list.component.ts +++ b/src/app/my-absences/components/my-absences-report-list/my-absences-report-list.component.ts @@ -43,15 +43,15 @@ export class MyAbsencesReportListComponent this.selectionService.selection$, this.state.entries$.pipe( switchMap((entries) => - combineLatest(entries.map((e) => this.getPresenceType(e))) - ) + combineLatest(entries.map((e) => this.getPresenceType(e))), + ), ), ]).pipe( map( ([selection, presenceTypes]) => selection.length > 0 && - selection.length === presenceTypes.filter(not(isAbsent)).length - ) + selection.length === presenceTypes.filter(not(isAbsent)).length, + ), ); private destroy$ = new Subject(); @@ -62,7 +62,7 @@ export class MyAbsencesReportListComponent private route: ActivatedRoute, private scrollPosition: ScrollPositionService, private presenceTypesService: PresenceTypesService, - @Inject(SETTINGS) private settings: Settings + @Inject(SETTINGS) private settings: Settings, ) {} ngOnInit(): void { @@ -86,7 +86,7 @@ export class MyAbsencesReportListComponent } getPresenceCategory( - lessonPresence: LessonPresence + lessonPresence: LessonPresence, ): Observable> { return this.getPresenceType(lessonPresence).pipe( map((type) => { @@ -106,12 +106,12 @@ export class MyAbsencesReportListComponent }; } return null; - }) + }), ); } getPresenceTypeDesignation( - lessonPresence: LessonPresence + lessonPresence: LessonPresence, ): Observable> { return this.presenceTypesService.displayedTypes$.pipe( map( @@ -119,8 +119,8 @@ export class MyAbsencesReportListComponent (lessonPresence.TypeRef.Id && types.find((t) => t.Id === lessonPresence.TypeRef.Id) ?.Designation) || - null - ) + null, + ), ); } @@ -136,9 +136,9 @@ export class MyAbsencesReportListComponent checked ? entries.filter( (e) => - e.TypeRef.Id == null || !absentTypeIds.includes(e.TypeRef.Id) + e.TypeRef.Id == null || !absentTypeIds.includes(e.TypeRef.Id), ) - : null + : null, ); }); } @@ -148,22 +148,22 @@ export class MyAbsencesReportListComponent if ( checkbox && event.target !== checkbox && - !Boolean((event.target as HTMLElement).closest('.buttons')) + !(event.target as HTMLElement).closest('.buttons') ) { (checkbox as HTMLInputElement).click(); } } private getPresenceType( - lessonPresence: LessonPresence + lessonPresence: LessonPresence, ): Observable> { return this.presenceTypesService.presenceTypes$.pipe( map( (types) => (lessonPresence.TypeRef.Id && types.find((t) => t.Id === lessonPresence.TypeRef.Id)) || - null - ) + null, + ), ); } } diff --git a/src/app/my-absences/components/my-absences-report/my-absences-report.component.ts b/src/app/my-absences/components/my-absences-report/my-absences-report.component.ts index 47b2c0bfa..63401bed2 100644 --- a/src/app/my-absences/components/my-absences-report/my-absences-report.component.ts +++ b/src/app/my-absences/components/my-absences-report/my-absences-report.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { MyAbsencesReportStateService } from '../../services/my-absences-report-state.service'; import { MyAbsencesReportSelectionService } from '../../services/my-absences-report-selection.service'; diff --git a/src/app/my-absences/components/my-absences-show/my-absences-show.component.spec.ts b/src/app/my-absences/components/my-absences-show/my-absences-show.component.spec.ts index 85ff398a3..1b3f46a00 100644 --- a/src/app/my-absences/components/my-absences-show/my-absences-show.component.spec.ts +++ b/src/app/my-absences/components/my-absences-show/my-absences-show.component.spec.ts @@ -9,8 +9,10 @@ import { StorageService } from 'src/app/shared/services/storage.service'; import { buildLessonAbsence } from '../../../../spec-builders'; import { ConfirmAbsencesSelectionService } from 'src/app/shared/services/confirm-absences-selection.service'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('MyAbsencesShowComponent', () => { - let component: MyAbsencesShowComponent; + // let component: MyAbsencesShowComponent; let fixture: ComponentFixture; let element: HTMLElement; let openLessonAbsences$: BehaviorSubject; @@ -46,13 +48,13 @@ describe('MyAbsencesShowComponent', () => { }, }, ], - }) + }), ).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(MyAbsencesShowComponent); - component = fixture.componentInstance; + // component = fixture.componentInstance; element = fixture.debugElement.nativeElement; }); @@ -63,7 +65,7 @@ describe('MyAbsencesShowComponent', () => { it('should have all absences report disabled', () => { const reportLink = element.getElementsByClassName( - 'report' + 'report', )[0] as HTMLElement; expect(reportLink?.className.includes('disabled')).toBeTrue(); }); @@ -72,7 +74,7 @@ describe('MyAbsencesShowComponent', () => { openLessonAbsences$.next([buildLessonAbsence('12')]); fixture.detectChanges(); const reportLink = element.getElementsByClassName( - 'report' + 'report', )[0] as HTMLElement; expect(reportLink?.className.includes('disabled')).toBeFalse(); }); diff --git a/src/app/my-absences/components/my-absences-show/my-absences-show.component.ts b/src/app/my-absences/components/my-absences-show/my-absences-show.component.ts index 0891c4f2c..f3f32f0de 100644 --- a/src/app/my-absences/components/my-absences-show/my-absences-show.component.ts +++ b/src/app/my-absences/components/my-absences-show/my-absences-show.component.ts @@ -28,7 +28,7 @@ export class MyAbsencesShowComponent implements OnInit, OnDestroy { openAbsencesReportAvailable$ = this.reportsService.studentConfirmationAvailability$; allAbsencesReportUrlAvailable$ = this.allAbsencesReportUrl$.pipe( - map((url) => (url ? url.length > 0 : false)) + map((url) => (url ? url.length > 0 : false)), ); private destroy$ = new Subject(); @@ -36,7 +36,7 @@ export class MyAbsencesShowComponent implements OnInit, OnDestroy { constructor( private reportsService: ReportsService, public myAbsencesService: MyAbsencesService, - public absencesSelectionService: ConfirmAbsencesSelectionService + public absencesSelectionService: ConfirmAbsencesSelectionService, ) {} ngOnInit(): void { @@ -46,8 +46,8 @@ export class MyAbsencesShowComponent implements OnInit, OnDestroy { .pipe(take(1), filter(not(isEmptyArray))) .subscribe((absences: ReadonlyArray) => this.reportsService.setStudentConfirmationAvailabilityRecordIds( - absences.map((a) => `${a.LessonRef.Id}_${a.RegistrationId}`) - ) + absences.map((a) => `${a.LessonRef.Id}_${a.RegistrationId}`), + ), ); } @@ -63,15 +63,15 @@ export class MyAbsencesShowComponent implements OnInit, OnDestroy { switchMap(([selectedWithout, selectedIds]) => selectedWithout.length === 0 && selectedIds.length > 0 ? this.getOpenAbsencesReportRecordIds( - uniq(flatten(selectedIds.map((s) => s.lessonIds))) + uniq(flatten(selectedIds.map((s) => s.lessonIds))), ) - : of(null) + : of(null), ), map((recordIds) => recordIds ? this.reportsService.getStudentConfirmationUrl(recordIds) - : null - ) + : null, + ), ); } @@ -85,36 +85,38 @@ export class MyAbsencesShowComponent implements OnInit, OnDestroy { ]).pipe( map( ( - absences: ReadonlyArray> - ) => this.buildUrl(flatten(absences)) + absences: ReadonlyArray< + ReadonlyArray + >, + ) => this.buildUrl(flatten(absences)), ), - shareReplay(1) + shareReplay(1), ); } - private buildUrl(absences: any[]) { + private buildUrl(absences: ReadonlyArray) { return absences.length > 0 ? this.reportsService.getEvaluateAbsencesUrl( - this.getAllReportRecordIds(absences) + this.getAllReportRecordIds(absences), ) : null; } private getAllReportRecordIds( - presences: ReadonlyArray + presences: ReadonlyArray, ): ReadonlyArray { return presences.map((p) => `${p.LessonRef.Id}_${p.RegistrationId}`); } private getOpenAbsencesReportRecordIds( - lessonIds: ReadonlyArray + lessonIds: ReadonlyArray, ): Observable> { return this.myAbsencesService.openLessonAbsences$.pipe( map((absences) => absences .filter((a) => lessonIds.includes(a.LessonRef.Id)) - .map((a) => `${a.LessonRef.Id}_${a.RegistrationId}`) - ) + .map((a) => `${a.LessonRef.Id}_${a.RegistrationId}`), + ), ); } } diff --git a/src/app/my-absences/components/my-absences/my-absences.component.ts b/src/app/my-absences/components/my-absences/my-absences.component.ts index 5af339128..a2e42618f 100644 --- a/src/app/my-absences/components/my-absences/my-absences.component.ts +++ b/src/app/my-absences/components/my-absences/my-absences.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { MyAbsencesService } from '../../services/my-absences.service'; @Component({ diff --git a/src/app/my-absences/services/my-absences-report-state.service.spec.ts b/src/app/my-absences/services/my-absences-report-state.service.spec.ts index fb864f27f..3fc45f660 100644 --- a/src/app/my-absences/services/my-absences-report-state.service.spec.ts +++ b/src/app/my-absences/services/my-absences-report-state.service.spec.ts @@ -18,9 +18,9 @@ import { addHours, subHours } from 'date-fns'; describe('MyAbsencesReportStateService', () => { let service: MyAbsencesReportStateService; let entriesCallback: jasmine.Spy; - let storageMock: jasmine.SpyObj = jasmine.createSpyObj( + const storageMock: jasmine.SpyObj = jasmine.createSpyObj( 'StorageService', - ['getPayload'] + ['getPayload'], ); let beforeLessonStart: TimetableEntry; @@ -31,17 +31,17 @@ describe('MyAbsencesReportStateService', () => { beforeLessonStart = buildTimetableEntry( 1, subHours(new Date(), 2), - subHours(new Date(), 1) + subHours(new Date(), 1), ); onLessonStart = buildTimetableEntry( 2, subHours(new Date(), 1), - addHours(new Date(), 1) + addHours(new Date(), 1), ); afterLessonStart = buildTimetableEntry( 3, addHours(new Date(), 1), - addHours(new Date(), 2) + addHours(new Date(), 2), ); TestBed.configureTestingModule( @@ -67,7 +67,7 @@ describe('MyAbsencesReportStateService', () => { }, }, ], - }) + }), ); }); diff --git a/src/app/my-absences/services/my-absences.service.spec.ts b/src/app/my-absences/services/my-absences.service.spec.ts index 1a6ea8692..cf51b490b 100644 --- a/src/app/my-absences/services/my-absences.service.spec.ts +++ b/src/app/my-absences/services/my-absences.service.spec.ts @@ -15,13 +15,13 @@ describe('MyAbsencesService', () => { { provide: StorageService, useValue: { - getPayload(): any { + getPayload(): Dict { return { id_person: '123' }; }, }, }, ], - }) + }), ); service = TestBed.inject(MyAbsencesService); }); diff --git a/src/app/my-absences/services/my-absences.service.ts b/src/app/my-absences/services/my-absences.service.ts index 382a01ed7..0550d044d 100644 --- a/src/app/my-absences/services/my-absences.service.ts +++ b/src/app/my-absences/services/my-absences.service.ts @@ -30,11 +30,11 @@ export class MyAbsencesService { // entry (i.e. for which no lesson presence entry will be built) this.studentId$.pipe( switchMap(this.loadLessonAbsences.bind(this)), - shareReplay(1) + shareReplay(1), ); private lessonIncidents$ = this.studentId$.pipe( switchMap(this.loadLessonIncidents.bind(this)), - shareReplay(1) + shareReplay(1), ); private lessonPresences$ = this.getLessonPresences(); @@ -81,7 +81,7 @@ export class MyAbsencesService { constructor( @Inject(SETTINGS) private settings: Settings, private storageService: StorageService, - private studentsService: StudentsRestService + private studentsService: StudentsRestService, ) { const studentId = this.storageService.getPayload()?.id_person; if (studentId) { @@ -107,33 +107,33 @@ export class MyAbsencesService { switchMap(([studentId, absences, incidents]) => this.loadTimetableEntries(studentId, absences, incidents).pipe( map((timetableEntries) => - this.buildLessonPresences(absences, incidents, timetableEntries) - ) - ) + this.buildLessonPresences(absences, incidents, timetableEntries), + ), + ), ), - map(sortLessonPresencesByDate) - ) + map(sortLessonPresencesByDate), + ), ); } private getAbsences( - confirmationStateId: Option + confirmationStateId: Option, ): Observable>> { return this.getCached( this.lessonPresences$.pipe( map( (presences) => presences?.filter( - (p) => p.ConfirmationStateId === confirmationStateId - ) || null - ) - ) + (p) => p.ConfirmationStateId === confirmationStateId, + ) || null, + ), + ), ); } private getLessonAbsences( absences: ReadonlyArray, - lessonAbsences: ReadonlyArray + lessonAbsences: ReadonlyArray, ): ReadonlyArray { const lessonIds = absences.map((a) => a.LessonRef.Id); return lessonAbsences.filter((a) => lessonIds.includes(a.LessonRef.Id)); @@ -141,7 +141,7 @@ export class MyAbsencesService { private getLessonIncidents( absences: ReadonlyArray, - lessonIncidents: ReadonlyArray + lessonIncidents: ReadonlyArray, ): ReadonlyArray { const incidentIds = absences.map((a) => a.LessonRef.Id); return lessonIncidents.filter((i) => incidentIds.includes(i.LessonRef.Id)); @@ -169,8 +169,8 @@ export class MyAbsencesService { unexcusedAbsences, incidents, halfDays: null, - }) - ) + }), + ), ); } @@ -178,24 +178,24 @@ export class MyAbsencesService { return source$.pipe( startWith(null), // Clear the cache if all subscribers disconnect (don't replay the previous value) - share({ connector: () => new ReplaySubject>(1) }) + share({ connector: () => new ReplaySubject>(1) }), ); } private getCount( - source$: Observable>> + source$: Observable>>, ): Observable> { return source$.pipe(map((absences) => absences?.length ?? null)); } private loadLessonAbsences( - studentId: number + studentId: number, ): Observable> { return this.studentsService.getLessonAbsences(studentId); } private loadLessonIncidents( - studentId: number + studentId: number, ): Observable> { return this.studentsService.getLessonIncidents(studentId); } @@ -203,7 +203,7 @@ export class MyAbsencesService { private loadTimetableEntries( studentId: number, absences: ReadonlyArray, - incidents: ReadonlyArray + incidents: ReadonlyArray, ): Observable> { return this.studentsService.getTimetableEntries(studentId, { 'filter.Id': `;${[...absences, ...incidents] @@ -216,7 +216,7 @@ export class MyAbsencesService { private buildLessonPresences( absences: ReadonlyArray, incidents: ReadonlyArray, - timetableEntries: ReadonlyArray + timetableEntries: ReadonlyArray, ): ReadonlyArray { return [...absences, ...incidents] .map((absence) => this.buildLessonPresence(absence, timetableEntries)) @@ -229,7 +229,7 @@ export class MyAbsencesService { */ private buildLessonPresence( absence: LessonAbsence | LessonIncident, - timetableEntries: ReadonlyArray + timetableEntries: ReadonlyArray, ): Option { const entry = timetableEntries.find((e) => e.Id === absence.LessonRef.Id); if (!entry) { 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 index beb5baae2..af76c3fea 100644 --- 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 @@ -10,17 +10,17 @@ describe('MyNotificationsShowComponent-WithData', () => { let element: HTMLElement; let userSettings: jasmine.SpyObj; - userSettings = jasmine.createSpyObj('UserSettingsService', [ - 'refetch', - 'getNotificationData', - 'saveNotificationData', - ]); - userSettings.getNotificationData.and.returnValue( - of([{ id: 1, subject: 'subject', body: 'body' }]) - ); - userSettings.saveNotificationData.and.returnValue(of({})); - 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], @@ -30,7 +30,7 @@ describe('MyNotificationsShowComponent-WithData', () => { useValue: userSettings, }, ], - }) + }), ).compileComponents(); })); @@ -42,7 +42,7 @@ describe('MyNotificationsShowComponent-WithData', () => { it('expect delete all to be enabled', () => { const field = element.querySelector( - `button[id="notifications-delete-all"]` + `button[id="notifications-delete-all"]`, ) as HTMLInputElement; expect(field).not.toBeNull(); expect(field.disabled).toBeFalsy(); @@ -50,14 +50,14 @@ describe('MyNotificationsShowComponent-WithData', () => { it('expect bell no to be "hidden"', () => { const field = element.getElementsByClassName( - 'notifications-bell-hidden' + 'notifications-bell-hidden', )[0] as HTMLInputElement; expect(field).toBeUndefined(); }); it('expect counter to be "1"', () => { const field = element.getElementsByClassName( - 'notifications-bell-counter-visible' + 'notifications-bell-counter-visible', )[0] as HTMLInputElement; expect(field).not.toBeNull(); expect(field.innerHTML).toBe('1'); @@ -65,14 +65,14 @@ describe('MyNotificationsShowComponent-WithData', () => { it('expect one notifications to be listed', () => { const fields = element.getElementsByClassName( - 'notifications-delete-notification' + 'notifications-delete-notification', ); expect(fields.length).toBe(1); }); it('expect user settings call when deleteAll clicked', () => { const field = element.querySelector( - `button[id="notifications-delete-all"]` + `button[id="notifications-delete-all"]`, ) as HTMLInputElement; field.click(); expect(userSettings.saveNotificationData).toHaveBeenCalled(); @@ -81,7 +81,7 @@ describe('MyNotificationsShowComponent-WithData', () => { it('expect user settings call when delete clicked', () => { const field = element.getElementsByClassName( - 'notifications-delete-notification' + 'notifications-delete-notification', )[0] as HTMLInputElement; field.click(); expect(userSettings.saveNotificationData).toHaveBeenCalled(); @@ -94,14 +94,14 @@ describe('MyNotificationsShowComponent-WithoutData', () => { let element: HTMLElement; let userSettings: jasmine.SpyObj; - userSettings = jasmine.createSpyObj('MyNotificationsService', [ - 'refetch', - 'getNotificationData', - 'saveNotificationData', - ]); - userSettings.getNotificationData.and.returnValue(of([])); - beforeEach(waitForAsync(() => { + userSettings = jasmine.createSpyObj('MyNotificationsService', [ + 'refetch', + 'getNotificationData', + 'saveNotificationData', + ]); + userSettings.getNotificationData.and.returnValue(of([])); + TestBed.configureTestingModule( buildTestModuleMetadata({ declarations: [MyNotificationsShowComponent], @@ -111,7 +111,7 @@ describe('MyNotificationsShowComponent-WithoutData', () => { useValue: userSettings, }, ], - }) + }), ).compileComponents(); })); @@ -123,7 +123,7 @@ describe('MyNotificationsShowComponent-WithoutData', () => { it('expect delete all to be disabled', () => { const field = element.querySelector( - `button[id="notifications-delete-all"]` + `button[id="notifications-delete-all"]`, ) as HTMLInputElement; expect(field).not.toBeNull(); expect(field.disabled).toBeTruthy(); @@ -131,14 +131,14 @@ describe('MyNotificationsShowComponent-WithoutData', () => { it('expect bell to be shown', () => { const field = element.getElementsByClassName( - 'notifications-bell-hidden' + 'notifications-bell-hidden', )[0] as HTMLInputElement; expect(field).toBeUndefined(); }); it('expect counter to be zero', () => { const field = element.getElementsByClassName( - 'notifications-bell-counter-visible' + 'notifications-bell-counter-visible', )[0] as HTMLInputElement; expect(field).not.toBeNull(); expect(field.innerHTML).toBe('0'); @@ -146,7 +146,7 @@ describe('MyNotificationsShowComponent-WithoutData', () => { it('expect no notifications to be listed', () => { const fields = element.getElementsByClassName( - 'notifications-delete-notification' + 'notifications-delete-notification', ); expect(fields.length).toBe(0); }); @@ -157,14 +157,14 @@ describe('MyNotificationsShowComponent-WithoutAuthorization', () => { let element: HTMLElement; let userSettings: jasmine.SpyObj; - userSettings = jasmine.createSpyObj('MyNotificationsService', [ - 'refetch', - 'getNotificationData', - 'saveNotificationData', - ]); - userSettings.getNotificationData.and.returnValue(of([])); - beforeEach(waitForAsync(() => { + userSettings = jasmine.createSpyObj('MyNotificationsService', [ + 'refetch', + 'getNotificationData', + 'saveNotificationData', + ]); + userSettings.getNotificationData.and.returnValue(of([])); + TestBed.configureTestingModule( buildTestModuleMetadata({ declarations: [MyNotificationsShowComponent], @@ -174,7 +174,7 @@ describe('MyNotificationsShowComponent-WithoutAuthorization', () => { useValue: userSettings, }, ], - }) + }), ).compileComponents(); })); @@ -186,14 +186,14 @@ describe('MyNotificationsShowComponent-WithoutAuthorization', () => { it('expect bell to be "hidden"', () => { const field = element.getElementsByClassName( - 'notifications-bell-hidden' + 'notifications-bell-hidden', )[0] as HTMLInputElement; expect(field).not.toBeNull(); }); it('expect counter not to be shown', () => { const field = element.getElementsByClassName( - 'notifications-bell-counter-hidden' + '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 index 0294e15d6..53fb06f00 100644 --- 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 @@ -32,13 +32,13 @@ export class MyNotificationsShowComponent implements OnDestroy { isAuthenticated$ = new BehaviorSubject(false); private refetchTimer$ = interval( - this.settings.notificationRefreshTime * 1000 + this.settings.notificationRefreshTime * 1000, ).pipe( - startWith(null) // Make sure we have "fresh" notifications when this component gets rendered initially + 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 toggleNotificationsPopup$ = new Subject>(); private destroy$ = new Subject(); public xssOptions = { @@ -61,7 +61,7 @@ export class MyNotificationsShowComponent implements OnDestroy { constructor( i18n: I18nService, @Inject(SETTINGS) private settings: Settings, - public userSettings: UserSettingsService + public userSettings: UserSettingsService, ) { i18n.initialize(); @@ -93,17 +93,17 @@ export class MyNotificationsShowComponent implements OnDestroy { withLatestFrom(this.notifications$), switchMap(([id, notifications]) => this.userSettings.saveNotificationData( - this.deleteNotificationFromArray(id, notifications) - ) + this.deleteNotificationFromArray(id, notifications), + ), ), - takeUntil(this.destroy$) + takeUntil(this.destroy$), ) .subscribe(); this.deleteAllNotifications$ .pipe( switchMap(() => this.userSettings.saveNotificationData([])), - takeUntil(this.destroy$) + takeUntil(this.destroy$), ) .subscribe(); } @@ -128,7 +128,7 @@ export class MyNotificationsShowComponent implements OnDestroy { deleteNotificationFromArray( id: number, - data: NotificationData + data: NotificationData, ): NotificationData { return data.filter((entry) => entry.id !== id); } @@ -143,7 +143,7 @@ export class MyNotificationsShowComponent implements OnDestroy { return []; } return throwError(() => err); - }) + }), ); } } diff --git a/src/app/my-profile/components/my-profile-address/my-profile-address.component.ts b/src/app/my-profile/components/my-profile-address/my-profile-address.component.ts index 1a9f9c1df..1885c568e 100644 --- a/src/app/my-profile/components/my-profile-address/my-profile-address.component.ts +++ b/src/app/my-profile/components/my-profile-address/my-profile-address.component.ts @@ -1,9 +1,4 @@ -import { - Component, - Input, - OnInit, - ChangeDetectionStrategy, -} from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'erz-my-profile-address', diff --git a/src/app/my-profile/components/my-profile-edit/my-profile-edit.component.spec.ts b/src/app/my-profile/components/my-profile-edit/my-profile-edit.component.spec.ts index 89d120e40..dc35b4fc1 100644 --- a/src/app/my-profile/components/my-profile-edit/my-profile-edit.component.spec.ts +++ b/src/app/my-profile/components/my-profile-edit/my-profile-edit.component.spec.ts @@ -8,7 +8,7 @@ import { MyProfileService } from '../../services/my-profile.service'; import { PersonsRestService } from 'src/app/shared/services/persons-rest.service'; describe('MyProfileEditComponent', () => { - let component: MyProfileEditComponent; + // let component: MyProfileEditComponent; let fixture: ComponentFixture; let element: HTMLElement; let profileService: MyProfileService; @@ -44,20 +44,20 @@ describe('MyProfileEditComponent', () => { { provide: MyProfileService, useValue: profileService }, { provide: PersonsRestService, useValue: personsService }, ], - }) + }), ).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(MyProfileEditComponent); - component = fixture.componentInstance; + // component = fixture.componentInstance; element = fixture.debugElement.nativeElement; fixture.detectChanges(); }); it('renders address', () => { expect(element.querySelector('address')?.textContent).toBe( - 'Postfach Industriegasse 123 3000 Bern' + 'Postfach Industriegasse 123 3000 Bern', ); }); @@ -99,7 +99,7 @@ describe('MyProfileEditComponent', () => { 123, '+41 31 987 65 54', '+41 79 987 65 54', - 'jane@example.com' + 'jane@example.com', ); }); @@ -119,7 +119,7 @@ describe('MyProfileEditComponent', () => { return field as HTMLInputElement; } - function changeValue(name: string, value: any): void { + function changeValue(name: string, value: string): void { const input = getInput(name); input.value = value; input.dispatchEvent(new Event('input')); @@ -128,7 +128,7 @@ describe('MyProfileEditComponent', () => { function clickSubmitButton(): void { const button = element.querySelector( - '.btn-primary' + '.btn-primary', ) as Option; if (button) { button.click(); diff --git a/src/app/my-profile/components/my-profile-entry/my-profile-entry.component.ts b/src/app/my-profile/components/my-profile-entry/my-profile-entry.component.ts index c561e6b9a..e4236122e 100644 --- a/src/app/my-profile/components/my-profile-entry/my-profile-entry.component.ts +++ b/src/app/my-profile/components/my-profile-entry/my-profile-entry.component.ts @@ -1,9 +1,4 @@ -import { - Component, - OnInit, - Input, - ChangeDetectionStrategy, -} from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'erz-my-profile-entry', diff --git a/src/app/my-profile/components/my-profile-header/my-profile-header.component.ts b/src/app/my-profile/components/my-profile-header/my-profile-header.component.ts index 67edf79d6..648e504f3 100644 --- a/src/app/my-profile/components/my-profile-header/my-profile-header.component.ts +++ b/src/app/my-profile/components/my-profile-header/my-profile-header.component.ts @@ -1,7 +1,6 @@ import { Component, Input, - OnInit, SimpleChanges, OnChanges, ChangeDetectionStrategy, @@ -30,8 +29,8 @@ export class MyProfileHeaderComponent implements OnChanges { map(([available, studentId]) => available && studentId ? this.reportsService.getPersonMasterDataUrl(studentId) - : null - ) + : null, + ), ); constructor(private reportsService: ReportsService) {} diff --git a/src/app/my-profile/components/my-profile-show/my-profile-show.component.ts b/src/app/my-profile/components/my-profile-show/my-profile-show.component.ts index 452ff95c3..90b383ca4 100644 --- a/src/app/my-profile/components/my-profile-show/my-profile-show.component.ts +++ b/src/app/my-profile/components/my-profile-show/my-profile-show.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { MyProfileService } from '../../services/my-profile.service'; @Component({ diff --git a/src/app/my-profile/components/my-profile/my-profile.component.ts b/src/app/my-profile/components/my-profile/my-profile.component.ts index 0d7b59155..6a524abd5 100644 --- a/src/app/my-profile/components/my-profile/my-profile.component.ts +++ b/src/app/my-profile/components/my-profile/my-profile.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { MyProfileService } from '../../services/my-profile.service'; @Component({ diff --git a/src/app/my-settings/components/my-settings-notifications-toggle/my-settings-notifications-toggle.component.spec.ts b/src/app/my-settings/components/my-settings-notifications-toggle/my-settings-notifications-toggle.component.spec.ts index 963b1c9b1..eeab8a3c1 100644 --- a/src/app/my-settings/components/my-settings-notifications-toggle/my-settings-notifications-toggle.component.spec.ts +++ b/src/app/my-settings/components/my-settings-notifications-toggle/my-settings-notifications-toggle.component.spec.ts @@ -13,7 +13,7 @@ describe('MySettingsNotificationsToggleComponent', () => { await TestBed.configureTestingModule( buildTestModuleMetadata({ declarations: [MySettingsNotificationsToggleComponent, SwitchComponent], - }) + }), ).compileComponents(); fixture = TestBed.createComponent(MySettingsNotificationsToggleComponent); @@ -25,7 +25,7 @@ describe('MySettingsNotificationsToggleComponent', () => { component.label = 'This is a label'; await waitForRender(); expect(element.querySelector('label')?.textContent).toContain( - 'This is a label' + 'This is a label', ); }); @@ -79,7 +79,7 @@ describe('MySettingsNotificationsToggleComponent', () => { return input!; } - function waitForRender(): Promise { + function waitForRender() { fixture.detectChanges(); return fixture.whenStable(); } diff --git a/src/app/my-settings/components/my-settings-notifications/my-settings-notifications.component.spec.ts b/src/app/my-settings/components/my-settings-notifications/my-settings-notifications.component.spec.ts index cbe58dff2..41ad97531 100644 --- a/src/app/my-settings/components/my-settings-notifications/my-settings-notifications.component.spec.ts +++ b/src/app/my-settings/components/my-settings-notifications/my-settings-notifications.component.spec.ts @@ -11,21 +11,23 @@ describe('MySettingsNotificationsComponent', () => { let fixture: ComponentFixture; let userSettings: jasmine.SpyObj; - userSettings = jasmine.createSpyObj('UserSettingsService', [ - 'getNotificationChannels', - 'saveNotificationChannels', - 'getNotificationTypesInactive', - 'saveNotificationTypesInactive', - 'refetch', - ]); - userSettings.getNotificationChannels.and.returnValue( - of({ mail: true, gui: true, phoneMobile: false }) - ); - userSettings.saveNotificationChannels.and.returnValue(of({})); - userSettings.getNotificationTypesInactive.and.returnValue(of(['BM2Student'])); - userSettings.saveNotificationTypesInactive.and.returnValue(of({})); - beforeEach(waitForAsync(() => { + userSettings = jasmine.createSpyObj('UserSettingsService', [ + 'getNotificationChannels', + 'saveNotificationChannels', + 'getNotificationTypesInactive', + 'saveNotificationTypesInactive', + 'refetch', + ]); + userSettings.getNotificationChannels.and.returnValue( + of({ mail: true, gui: true, phoneMobile: false }), + ); + userSettings.saveNotificationChannels.and.returnValue(of({})); + userSettings.getNotificationTypesInactive.and.returnValue( + of(['BM2Student']), + ); + userSettings.saveNotificationTypesInactive.and.returnValue(of({})); + TestBed.configureTestingModule( buildTestModuleMetadata({ declarations: [ @@ -47,7 +49,7 @@ describe('MySettingsNotificationsComponent', () => { useValue: userSettings, }, ], - }) + }), ).compileComponents(); })); @@ -128,7 +130,7 @@ describe('MySettingsNotificationsComponent', () => { it('updates settings and reloads on BM2Student types form field change', async () => { toggleInput('notification-types-BM2Student'); expect(userSettings.saveNotificationTypesInactive).toHaveBeenCalledWith( - [] + [], ); }); @@ -153,7 +155,7 @@ describe('MySettingsNotificationsComponent', () => { fixture.detectChanges(); } - function waitForRender(): Promise { + function waitForRender() { fixture.detectChanges(); return fixture.whenStable(); } diff --git a/src/app/my-settings/components/my-settings-notifications/my-settings-notifications.component.ts b/src/app/my-settings/components/my-settings-notifications/my-settings-notifications.component.ts index a75277494..7487de436 100644 --- a/src/app/my-settings/components/my-settings-notifications/my-settings-notifications.component.ts +++ b/src/app/my-settings/components/my-settings-notifications/my-settings-notifications.component.ts @@ -5,14 +5,7 @@ import { OnDestroy, } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; -import { - BehaviorSubject, - combineLatest, - merge, - Observable, - of, - Subject, -} from 'rxjs'; +import { BehaviorSubject, merge, Observable, of, Subject } from 'rxjs'; import { TranslateService } from '@ngx-translate/core'; import { shareReplay, @@ -80,24 +73,29 @@ export class MySettingsNotificationsComponent implements OnInit, OnDestroy { channelsFormGroup$ = this.channelsValue$.pipe( map((value) => this.createFormGroup(this.channelsSettings, value)), - shareReplay(1) + shareReplay(1), ); allChannelsInactive$ = merge( this.channelsValue$, this.channelsFormGroup$.pipe( - switchMap((formGroup) => formGroup.valueChanges) - ) + switchMap((formGroup) => formGroup.valueChanges), + ), ).pipe( map((channels) => Object.values(channels).every((enabled) => !enabled)), - distinctUntilChanged() + distinctUntilChanged(), ); typesFormGroup$ = this.typesValue$.pipe( withLatestFrom(this.allChannelsInactive$), map(([value, allChannelsInactive]) => - this.createFormGroup(this.typesSettings, value, true, allChannelsInactive) + this.createFormGroup( + this.typesSettings, + value, + true, + allChannelsInactive, + ), ), - shareReplay(1) + shareReplay(1), ); private saving$ = new BehaviorSubject(false); @@ -108,7 +106,7 @@ export class MySettingsNotificationsComponent implements OnInit, OnDestroy { private formBuilder: UntypedFormBuilder, private toastService: ToastService, private translate: TranslateService, - private notificationTypes: NotificationTypesService + private notificationTypes: NotificationTypesService, ) {} ngOnInit(): void { @@ -120,11 +118,11 @@ export class MySettingsNotificationsComponent implements OnInit, OnDestroy { .pipe( skip(1), withLatestFrom(this.typesFormGroup$), - takeUntil(this.destroy$) + takeUntil(this.destroy$), ) .subscribe(([allChannelsInactive, formGroup]) => { Object.values(formGroup.controls).forEach((control) => - allChannelsInactive ? control.disable() : control.enable() + allChannelsInactive ? control.disable() : control.enable(), ); }); @@ -132,7 +130,7 @@ export class MySettingsNotificationsComponent implements OnInit, OnDestroy { this.channelsFormGroup$ .pipe( takeUntil(this.destroy$), - switchMap((formGroup) => formGroup.valueChanges) + switchMap((formGroup) => formGroup.valueChanges), ) .subscribe(this.saveChannels.bind(this)); @@ -140,7 +138,7 @@ export class MySettingsNotificationsComponent implements OnInit, OnDestroy { this.typesFormGroup$ .pipe( takeUntil(this.destroy$), - switchMap((formGroup) => formGroup.valueChanges) + switchMap((formGroup) => formGroup.valueChanges), ) .subscribe(this.saveTypes.bind(this)); } @@ -153,7 +151,7 @@ export class MySettingsNotificationsComponent implements OnInit, OnDestroy { settings: ReadonlyArray, record: Record, defaultValue = false, - disabled = false + disabled = false, ): UntypedFormGroup { return this.formBuilder.group( settings.reduce( @@ -161,8 +159,8 @@ export class MySettingsNotificationsComponent implements OnInit, OnDestroy { ...acc, [key]: [{ value: record[key] ?? defaultValue, disabled }], }), - {} - ) + {}, + ), ); } @@ -184,26 +182,26 @@ export class MySettingsNotificationsComponent implements OnInit, OnDestroy { private onSaveSuccess(): void { this.toastService.success( - this.translate.instant('my-settings.notifications.save-success') + this.translate.instant('my-settings.notifications.save-success'), ); } private typesArrayToRecord( - inactiveTypes: NotificationTypesInactive + inactiveTypes: NotificationTypesInactive, ): Record { const result = this.typesSettings.reduce( (acc, { key }) => ({ ...acc, [key]: !inactiveTypes.includes(key) }), - {} + {}, ); return result; } private typesRecordToArray( - record: Record + record: Record, ): NotificationTypesInactive { const result = Object.keys(record).reduce( (acc, key) => (!record[key] ? [...acc, key] : acc), - [] as NotificationTypesInactive + [] as NotificationTypesInactive, ); return result; } diff --git a/src/app/my-settings/components/my-settings-show/my-settings-show.component.spec.ts b/src/app/my-settings/components/my-settings-show/my-settings-show.component.spec.ts index ffce56348..04fd57114 100644 --- a/src/app/my-settings/components/my-settings-show/my-settings-show.component.spec.ts +++ b/src/app/my-settings/components/my-settings-show/my-settings-show.component.spec.ts @@ -20,13 +20,13 @@ describe('MySettingsShowComponent', () => { { provide: StorageService, useValue: { - getPayload(): any { + getPayload(): Dict { return { id_person: '123' }; }, }, }, ], - }) + }), ).compileComponents(); })); diff --git a/src/app/open-absences/components/open-absences-detail/open-absences-detail.component.spec.ts b/src/app/open-absences/components/open-absences-detail/open-absences-detail.component.spec.ts index 7e52cab59..cf3ed45d7 100644 --- a/src/app/open-absences/components/open-absences-detail/open-absences-detail.component.spec.ts +++ b/src/app/open-absences/components/open-absences-detail/open-absences-detail.component.spec.ts @@ -10,6 +10,8 @@ import { LessonPresence } from 'src/app/shared/models/lesson-presence.model'; import { take } from 'rxjs/operators'; import { ConfirmAbsencesSelectionService } from 'src/app/shared/services/confirm-absences-selection.service'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('OpenAbsencesDetailComponent', () => { let component: OpenAbsencesDetailComponent; let fixture: ComponentFixture; @@ -33,22 +35,22 @@ describe('OpenAbsencesDetailComponent', () => { 10, 21, 11, - new Date(2000, 0, 23, 12) + new Date(2000, 0, 23, 12), ); presenceB = buildLessonPresenceWithIds( 11, 21, 11, - new Date(2000, 0, 23, 13) + new Date(2000, 0, 23, 13), ); presenceC = buildLessonPresenceWithIds( 11, 21, 11, - new Date(2000, 0, 24, 13) + new Date(2000, 0, 24, 13), ); [presenceA, presenceB, presenceC].forEach( - (p) => (p.StudentFullName = 'Einstein Albert') + (p) => (p.StudentFullName = 'Einstein Albert'), ); TestBed.configureTestingModule( @@ -69,7 +71,7 @@ describe('OpenAbsencesDetailComponent', () => { }, }, ], - }) + }), ).compileComponents(); openAbsencesService = TestBed.inject(OpenAbsencesService); @@ -90,7 +92,7 @@ describe('OpenAbsencesDetailComponent', () => { expect(element.querySelectorAll('div.absence-entry').length).toBe(2); expect(element.querySelectorAll('div.absence-all').length).toBe(1); expect(element.querySelectorAll('div.all')[0].textContent).toBe( - 'open-absences.detail.all' + 'open-absences.detail.all', ); }); diff --git a/src/app/open-absences/components/open-absences-list/open-absences-list.component.spec.ts b/src/app/open-absences/components/open-absences-list/open-absences-list.component.spec.ts index 4b00f785a..e3bb62798 100644 --- a/src/app/open-absences/components/open-absences-list/open-absences-list.component.spec.ts +++ b/src/app/open-absences/components/open-absences-list/open-absences-list.component.spec.ts @@ -9,16 +9,17 @@ import { OpenAbsencesService } from '../../services/open-absences.service'; import { OpenAbsencesEntry } from '../../models/open-absences-entry.model'; import { ConfirmAbsencesSelectionService } from 'src/app/shared/services/confirm-absences-selection.service'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('OpenAbsencesListComponent', () => { - let component: OpenAbsencesListComponent; + // let component: OpenAbsencesListComponent; let fixture: ComponentFixture; let element: HTMLElement; - let openAbsencesService: OpenAbsencesService; let selectionService: ConfirmAbsencesSelectionService; let entryA: OpenAbsencesEntry; let entryB: OpenAbsencesEntry; - let storeMock: any; + let storeMock: Dict>; beforeEach(waitForAsync(() => { entryA = new OpenAbsencesEntry([ @@ -32,10 +33,10 @@ describe('OpenAbsencesListComponent', () => { storeMock = {}; spyOn(localStorage, 'getItem').and.callFake( - (key: string) => storeMock[key] || null + (key: string) => storeMock[key] || null, ); spyOn(localStorage, 'setItem').and.callFake( - (key: string) => storeMock[key] || null + (key: string) => storeMock[key] || null, ); storeMock['CLX.LoginToken'] = @@ -57,16 +58,15 @@ describe('OpenAbsencesListComponent', () => { }, }, ], - }) + }), ).compileComponents(); - openAbsencesService = TestBed.inject(OpenAbsencesService); selectionService = TestBed.inject(ConfirmAbsencesSelectionService); })); beforeEach(() => { fixture = TestBed.createComponent(OpenAbsencesListComponent); - component = fixture.componentInstance; + // component = fixture.componentInstance; element = fixture.debugElement.nativeElement; fixture.detectChanges(); }); @@ -115,7 +115,7 @@ describe('OpenAbsencesListComponent', () => { function toggleHeaderCheckbox(): void { ( element.querySelector( - '.absence-header input[type="checkbox"]' + '.absence-header input[type="checkbox"]', ) as HTMLInputElement ).click(); fixture.detectChanges(); diff --git a/src/app/open-absences/components/open-absences/open-absences.component.spec.ts b/src/app/open-absences/components/open-absences/open-absences.component.spec.ts index e4553bb7a..bb15207cd 100644 --- a/src/app/open-absences/components/open-absences/open-absences.component.spec.ts +++ b/src/app/open-absences/components/open-absences/open-absences.component.spec.ts @@ -2,7 +2,6 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { OpenAbsencesComponent } from './open-absences.component'; import { buildTestModuleMetadata } from 'src/spec-helpers'; -import { TestStateService } from '../../../events/services/test-state.service'; describe('OpenAbsencesComponent', () => { let component: OpenAbsencesComponent; @@ -12,7 +11,7 @@ describe('OpenAbsencesComponent', () => { TestBed.configureTestingModule( buildTestModuleMetadata({ declarations: [OpenAbsencesComponent], - }) + }), ).compileComponents(); })); diff --git a/src/app/open-absences/components/open-absences/open-absences.component.ts b/src/app/open-absences/components/open-absences/open-absences.component.ts index ad0836af3..06a33fbe3 100644 --- a/src/app/open-absences/components/open-absences/open-absences.component.ts +++ b/src/app/open-absences/components/open-absences/open-absences.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { OpenAbsencesService } from '../../services/open-absences.service'; import { CONFIRM_ABSENCES_SERVICE } from 'src/app/shared/tokens/confirm-absences-service'; diff --git a/src/app/open-absences/services/open-absences.service.spec.ts b/src/app/open-absences/services/open-absences.service.spec.ts index e4e6fcf50..0ec6dbd4f 100644 --- a/src/app/open-absences/services/open-absences.service.spec.ts +++ b/src/app/open-absences/services/open-absences.service.spec.ts @@ -11,6 +11,8 @@ import { import { LessonPresence } from '../../shared/models/lesson-presence.model'; import { ConfirmAbsencesSelectionService } from 'src/app/shared/services/confirm-absences-selection.service'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('OpenAbsencesService', () => { let service: OpenAbsencesService; @@ -29,7 +31,7 @@ describe('OpenAbsencesService', () => { }, }, ], - }) + }), ); service = TestBed.inject(OpenAbsencesService); }); @@ -39,17 +41,17 @@ describe('OpenAbsencesService', () => { }); describe('buildMailToString', () => { - const translation = { - 'open-absences': { - detail: { - mail: { - subject: 'Erinnerung offene Absenzen', - body: 'Bitte entschuldigen Sie folgende offenen Absenzen:', - bodyToLargeForEmailTo: 'Text zu lang fĂĽr ĂĽbergabe an Mailprogramm.', - }, - }, - }, - }; + // const translation = { + // 'open-absences': { + // detail: { + // mail: { + // subject: 'Erinnerung offene Absenzen', + // body: 'Bitte entschuldigen Sie folgende offenen Absenzen:', + // bodyToLargeForEmailTo: 'Text zu lang fĂĽr ĂĽbergabe an Mailprogramm.', + // }, + // }, + // }, + // }; it('returns an mailto string observable for the given person and absences', () => { const person = buildPersonWithEmails(3, '', 'foo@bar.ch'); @@ -58,37 +60,37 @@ describe('OpenAbsencesService', () => { 1, new Date(2021, 3, 22, 9, 0), new Date(2021, 3, 22, 9, 45), - 'Deutsch-S1' + 'Deutsch-S1', ); const absence2 = buildLessonPresence( 1, new Date(2021, 3, 29, 9, 0), new Date(2021, 3, 29, 9, 45), - 'Deutsch-S1' + 'Deutsch-S1', ); const absence3 = buildLessonPresence( 1, new Date(2021, 4, 3, 10, 5), new Date(2021, 4, 3, 10, 50), - 'Englisch-S3' + 'Englisch-S3', ); const absences: LessonPresence[] = [absence1, absence2, absence3]; expect(service.buildMailToString(person, absences)).toEqual( - `foo@bar.ch?subject=open-absences.detail.mail.subject&body=open-absences.detail.mail.body%0D%0ADeutsch-S1, 22.04.2021, 09:00-09:45%0D%0ADeutsch-S1, 29.04.2021, 09:00-09:45%0D%0AEnglisch-S3, 03.05.2021, 10:05-10:50` + `foo@bar.ch?subject=open-absences.detail.mail.subject&body=open-absences.detail.mail.body%0D%0ADeutsch-S1, 22.04.2021, 09:00-09:45%0D%0ADeutsch-S1, 29.04.2021, 09:00-09:45%0D%0AEnglisch-S3, 03.05.2021, 10:05-10:50`, ); const absence4 = buildLessonPresence( 1, new Date(2021, 4, 3, 10, 5), new Date(2021, 4, 3, 10, 50), - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD', ); const absencesToMuchChar: LessonPresence[] = [absence4]; expect( - service.buildMailToString(person, absencesToMuchChar).length + service.buildMailToString(person, absencesToMuchChar).length, ).toBeLessThanOrEqual(1650); }); }); diff --git a/src/app/open-absences/services/open-absences.service.ts b/src/app/open-absences/services/open-absences.service.ts index 44c2def9d..0e31e6578 100644 --- a/src/app/open-absences/services/open-absences.service.ts +++ b/src/app/open-absences/services/open-absences.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { BehaviorSubject, @@ -36,11 +37,11 @@ export class OpenAbsencesService implements IConfirmAbsencesService { >(); private unconfirmedAbsences$ = merge( this.loadUnconfirmedAbsences(), - this.updateUnconfirmedAbsences$ + this.updateUnconfirmedAbsences$, ).pipe(shareReplay(1)); private entries$ = this.unconfirmedAbsences$.pipe( map(buildOpenAbsencesEntries), - shareReplay(1) + shareReplay(1), ); private sortCriteriaSubject$ = new BehaviorSubject< @@ -52,12 +53,12 @@ export class OpenAbsencesService implements IConfirmAbsencesService { sortCriteria$ = this.sortCriteriaSubject$.asObservable(); sortedEntries$ = combineLatest([this.entries$, this.sortCriteria$]).pipe( - map(spread(sortOpenAbsencesEntries)) + map(spread(sortOpenAbsencesEntries)), ); filteredEntries$ = combineLatest([this.sortedEntries$, this.search$]).pipe( map(spread(searchEntries)), - shareReplay(1) + shareReplay(1), ); currentDetail: Option<{ date: string; personId: number }> = null; @@ -66,32 +67,32 @@ export class OpenAbsencesService implements IConfirmAbsencesService { private lessonPresencesService: LessonPresencesRestService, private selectionService: ConfirmAbsencesSelectionService, private loadingService: LoadingService, - private translate: TranslateService + private translate: TranslateService, ) {} getUnconfirmedAbsences( dateString: string, - studentId: number + studentId: number, ): Observable> { return this.entries$.pipe( map((entries) => { const entry = entries.find( - (e) => e.dateString === dateString && e.studentId === studentId + (e) => e.dateString === dateString && e.studentId === studentId, ); return entry ? entry.absences : []; - }) + }), ); } getAllUnconfirmedAbsencesForStudent( - studentId: number + studentId: number, ): Observable> { return this.entries$.pipe( map((entries) => { return entries .filter((e) => e.studentId === studentId) .reduce((a: LessonPresence[], e) => a.concat(e.absences), []); - }) + }), ); } @@ -117,7 +118,7 @@ export class OpenAbsencesService implements IConfirmAbsencesService { }); } - get confirmBackLink(): any[] { + get confirmBackLink(): Parameters[0] { if (this.currentDetail) { return [ '/open-absences/detail', @@ -152,7 +153,7 @@ export class OpenAbsencesService implements IConfirmAbsencesService { */ buildMailToString( person: Person, - absences: ReadonlyArray + absences: ReadonlyArray, ): string { const address = person.Email; const subject = this.translate.instant('open-absences.detail.mail.subject'); @@ -161,20 +162,21 @@ export class OpenAbsencesService implements IConfirmAbsencesService { .join('%0D%0A'); let body = `${this.translate.instant( - 'open-absences.detail.mail.body' + 'open-absences.detail.mail.body', )}%0D%0A${formattedAbsences}`; - if (body.length >= 1600) { - body = `${body.substring(0,1500)}%0D%0A${this.translate.instant('open-absences.detail.mail.bodyToLargeForEmailTo')}` ; - } - + body = `${body.substring(0, 1500)}%0D%0A${this.translate.instant( + 'open-absences.detail.mail.bodyToLargeForEmailTo', + )}`; + } + return `${address}?subject=${subject}&body=${body}`; } private loadUnconfirmedAbsences(): Observable> { return this.loadingService.load( - this.lessonPresencesService.getListOfUnconfirmed() + this.lessonPresencesService.getListOfUnconfirmed(), ); } } diff --git a/src/app/open-absences/utils/open-absences-entries.ts b/src/app/open-absences/utils/open-absences-entries.ts index 3060fd915..f707cbe65 100644 --- a/src/app/open-absences/utils/open-absences-entries.ts +++ b/src/app/open-absences/utils/open-absences-entries.ts @@ -8,7 +8,7 @@ import { SortCriteria } from 'src/app/shared/utils/sort'; import { PrimarySortKey } from '../services/open-absences.service'; export function buildOpenAbsencesEntries( - absences: ReadonlyArray + absences: ReadonlyArray, ): ReadonlyArray { const groupedAbsences = groupAbsences(absences); return Object.keys(groupedAbsences).reduce((acc, day) => { @@ -16,7 +16,7 @@ export function buildOpenAbsencesEntries( acc = [ ...acc, new OpenAbsencesEntry( - groupedAbsences[day][studentId].sort(lessonsComparator) + groupedAbsences[day][studentId].sort(lessonsComparator), ), ]; }); @@ -26,13 +26,13 @@ export function buildOpenAbsencesEntries( export function sortOpenAbsencesEntries( entries: ReadonlyArray, - sortCriteria: SortCriteria + sortCriteria: SortCriteria, ): ReadonlyArray { return [...entries].sort(getOpenAbsencesComparator(sortCriteria)); } export function flattenOpenAbsencesEntries( - entries: ReadonlyArray + entries: ReadonlyArray, ): ReadonlyArray { return entries.reduce((acc, e) => { return acc.concat(e.absences); @@ -44,30 +44,30 @@ export function removeOpenAbsences( affectedIds: ReadonlyArray<{ lessonIds: ReadonlyArray; personId: number; - }> + }>, ): ReadonlyArray { return entries.filter( (e) => !affectedIds.some( ({ lessonIds, personId }) => - lessonIds.includes(e.LessonRef.Id) && personId === e.StudentRef.Id - ) + lessonIds.includes(e.LessonRef.Id) && personId === e.StudentRef.Id, + ), ); } export function mergeUniqueLessonPresences( a: ReadonlyArray, - b: ReadonlyArray + b: ReadonlyArray, ): ReadonlyArray { return uniqBy([...a, ...b], 'Id'); } function getOpenAbsencesComparator( - sortCriteria: SortCriteria + sortCriteria: SortCriteria, ): (a: OpenAbsencesEntry, b: OpenAbsencesEntry) => number { return (a, b) => { switch (sortCriteria.primarySortKey) { - case 'date': + case 'date': { // First sort by time (ascending/descending), then by name (always ascending) const timeA = a.date.getTime(); const timeB = b.date.getTime(); @@ -75,8 +75,9 @@ function getOpenAbsencesComparator( return a.studentFullName.localeCompare(b.studentFullName); } return sortCriteria.ascending ? timeA - timeB : timeB - timeA; + } - case 'name': + case 'name': { // First sort by name (ascending/descending), then by date (always descending) const nameDiff = sortCriteria.ascending ? a.studentFullName.localeCompare(b.studentFullName) @@ -85,11 +86,14 @@ function getOpenAbsencesComparator( return b.date.getTime() - a.date.getTime(); } return nameDiff; + } + + default: + throw new UnreachableError( + sortCriteria.primarySortKey, + 'Unhandled sort criteria', + ); } - throw new UnreachableError( - sortCriteria.primarySortKey, - 'Unhandled sort criteria' - ); }; } @@ -97,18 +101,21 @@ function getOpenAbsencesComparator( * Groups lesson presences by day, then student id. */ function groupAbsences( - absences: ReadonlyArray + absences: ReadonlyArray, ): Dict> { - return absences.reduce((acc, absence) => { - const day = format(absence.LessonDateTimeFrom, 'yyyy-MM-dd'); - const studentId = absence.StudentRef.Id; - if (!acc[day]) { - acc[day] = {}; - } - if (!acc[day][studentId]) { - acc[day][studentId] = []; - } - acc[day][studentId].push(absence); - return acc; - }, {} as Dict>); + return absences.reduce( + (acc, absence) => { + const day = format(absence.LessonDateTimeFrom, 'yyyy-MM-dd'); + const studentId = absence.StudentRef.Id; + if (!acc[day]) { + acc[day] = {}; + } + if (!acc[day][studentId]) { + acc[day][studentId] = []; + } + acc[day][studentId].push(absence); + return acc; + }, + {} as Dict>, + ); } diff --git a/src/app/person-search/components/person-search-header/person-search-header.component.spec.ts b/src/app/person-search/components/person-search-header/person-search-header.component.spec.ts index fd7107e6a..b56ddc69d 100644 --- a/src/app/person-search/components/person-search-header/person-search-header.component.spec.ts +++ b/src/app/person-search/components/person-search-header/person-search-header.component.spec.ts @@ -7,18 +7,17 @@ import { Router } from '@angular/router'; describe('PersonSearchHeaderComponent.navigateToDossier', () => { let component: PersonSearchHeaderComponent; let fixture: ComponentFixture; - - let element: HTMLElement; + // let element: HTMLElement; let router: Router; beforeEach(() => { TestBed.configureTestingModule( - buildTestModuleMetadata({ declarations: [PersonSearchHeaderComponent] }) + buildTestModuleMetadata({ declarations: [PersonSearchHeaderComponent] }), ).compileComponents(); fixture = TestBed.createComponent(PersonSearchHeaderComponent); component = fixture.componentInstance; - element = fixture.debugElement.nativeElement; + // element = fixture.debugElement.nativeElement; fixture.detectChanges(); router = TestBed.inject(Router); diff --git a/src/app/presence-control/components/presence-control-header/presence-control-header.component.ts b/src/app/presence-control/components/presence-control-header/presence-control-header.component.ts index fd38ef30e..fa423be19 100644 --- a/src/app/presence-control/components/presence-control-header/presence-control-header.component.ts +++ b/src/app/presence-control/components/presence-control-header/presence-control-header.component.ts @@ -1,6 +1,5 @@ import { Component, - OnInit, Input, Output, EventEmitter, @@ -23,6 +22,7 @@ import { PresenceControlViewMode } from 'src/app/shared/models/user-settings.mod * avoid the dropdown to be placed off-screen. To avoid side-effects * in other contexts, we only do this for the lesson dropdown. */ +/* eslint-disable @typescript-eslint/no-explicit-any */ const positionMenuOriginal = (NgbDropdown.prototype as any)._positionMenu; (NgbDropdown.prototype as any)._positionMenu = function _positionMenuPatched( ...args: any[] @@ -34,7 +34,7 @@ const positionMenuOriginal = (NgbDropdown.prototype as any)._positionMenu; if (this._anchor.nativeElement.id === 'lesson-dropdown') { const container = this._bodyContainer || this._menu.nativeElement; const matches = container.style.transform?.match( - /translate\(([0-9-\.]+)px, ([0-9-\.]+)px\)/ + /translate\(([0-9-.]+)px, ([0-9-.]+)px\)/, ); if (matches && parseFloat(matches[1]) < 0) { container.style.transform = `translate(0px, ${matches[2]}px)`; @@ -44,6 +44,7 @@ const positionMenuOriginal = (NgbDropdown.prototype as any)._positionMenu; // Return original return value return result; }; +/* eslint-enable @typescript-eslint/no-explicit-any */ interface ViewModeOption { viewMode: PresenceControlViewMode; diff --git a/src/app/presence-control/components/presence-control-preceding-absence/presence-control-preceding-absence.component.ts b/src/app/presence-control/components/presence-control-preceding-absence/presence-control-preceding-absence.component.ts index 8e62bf2a5..979d0a2f8 100644 --- a/src/app/presence-control/components/presence-control-preceding-absence/presence-control-preceding-absence.component.ts +++ b/src/app/presence-control/components/presence-control-preceding-absence/presence-control-preceding-absence.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { LessonAbsence } from '../../../shared/models/lesson-absence.model'; diff --git a/src/app/presence-control/models/lesson-entry.model.spec.ts b/src/app/presence-control/models/lesson-entry.model.spec.ts index eefafb1ee..ccf6fd656 100644 --- a/src/app/presence-control/models/lesson-entry.model.spec.ts +++ b/src/app/presence-control/models/lesson-entry.model.spec.ts @@ -10,8 +10,8 @@ describe('lessons entry', () => { new Date(2000, 0, 23, 9), new Date(2000, 0, 23, 10), 'Math I', - 'Monika Muster' - ) + 'Monika Muster', + ), ); const math2 = fromLesson( @@ -20,8 +20,8 @@ describe('lessons entry', () => { new Date(2000, 0, 23, 9), new Date(2000, 0, 23, 10), 'Math II', - 'Monika Muster' - ) + 'Monika Muster', + ), ); expect(lessonsEntryEqual(math1, math2)).toBeTruthy(); @@ -37,7 +37,7 @@ describe('lessons entry', () => { 'Deutsch', 'Dora Durrer', 'D4b', - 333 + 333, ); const lessonEntry = fromLesson(lesson); @@ -59,7 +59,7 @@ describe('lessons entry', () => { 'Deutsch I', 'Dora Durrer', '9a', - 333 + 333, ); const deutsch2 = buildLesson( @@ -69,7 +69,7 @@ describe('lessons entry', () => { 'Deutsch II', 'Dora Durrer', '9B', - 333 + 333, ); const lessonEntry = fromLesson(deutsch1); @@ -77,13 +77,14 @@ describe('lessons entry', () => { expect(lessonEntry.TeacherInformation).toBe('Dora Durrer'); expect(lessonEntry.LessonDateTimeFrom).toEqual( - deutsch1.LessonDateTimeFrom + deutsch1.LessonDateTimeFrom, ); expect(lessonEntry.LessonDateTimeTo).toEqual(deutsch1.LessonDateTimeTo); expect(lessonEntry.id).toEqual('1-2'); expect(lessonEntry.eventDesignations).toBe('Deutsch I, Deutsch II'); expect(lessonEntry.studyClassNumbers).toBe('9a, 9B'); - expect(lessonEntry.lessons).toContain(deutsch1, deutsch2); + expect(lessonEntry.lessons).toContain(deutsch1); + expect(lessonEntry.lessons).toContain(deutsch2); }); }); }); diff --git a/src/app/presence-control/services/presence-control-block-lesson.service.spec.ts b/src/app/presence-control/services/presence-control-block-lesson.service.spec.ts index cb15a4397..d0d74d77b 100644 --- a/src/app/presence-control/services/presence-control-block-lesson.service.spec.ts +++ b/src/app/presence-control/services/presence-control-block-lesson.service.spec.ts @@ -36,7 +36,7 @@ describe('PresenceControlBlockLessonService', () => { 'Martina Moser', undefined, undefined, - 42 + 42, ); mathEinstein2 = buildLessonPresence( 2, @@ -47,7 +47,7 @@ describe('PresenceControlBlockLessonService', () => { 'Martina Moser', undefined, undefined, - 42 + 42, ); mathEinstein3 = buildLessonPresence( 3, @@ -58,7 +58,7 @@ describe('PresenceControlBlockLessonService', () => { 'Martina Moser', undefined, undefined, - 42 + 42, ); mathEinstein4 = buildLessonPresence( 4, @@ -69,7 +69,7 @@ describe('PresenceControlBlockLessonService', () => { 'Martina Moser', undefined, undefined, - 42 + 42, ); lessonPresences = [ mathEinstein1, @@ -92,7 +92,7 @@ describe('PresenceControlBlockLessonService', () => { PresenceControlBlockLessonService, { provide: PresenceControlStateService, useValue: stateMock }, ], - }) + }), ); service = TestBed.inject(PresenceControlBlockLessonService); httpTestingController = TestBed.inject(HttpTestingController); @@ -106,7 +106,7 @@ describe('PresenceControlBlockLessonService', () => { it('returns all block lessons related to the given entry', (done) => { service .getBlockLessonPresenceControlEntries( - buildPresenceControlEntry(mathEinstein1) + buildPresenceControlEntry(mathEinstein1), ) .subscribe((result) => { expect(result).toEqual([ @@ -120,14 +120,14 @@ describe('PresenceControlBlockLessonService', () => { expectLessonPresencesRequest( lessonPresences[0].LessonDateTimeFrom, lessonPresences[0].StudentRef.Id, - lessonPresences[0].StudyClassRef.Id ?? undefined + lessonPresences[0].StudyClassRef.Id ?? undefined, ); }); it('returns a single lesson if the given entry is not part of a block lesson', (done) => { service .getBlockLessonPresenceControlEntries( - buildPresenceControlEntry(mathEinstein4) + buildPresenceControlEntry(mathEinstein4), ) .subscribe((result) => { expect(result).toEqual([buildPresenceControlEntry(mathEinstein4)]); @@ -137,7 +137,7 @@ describe('PresenceControlBlockLessonService', () => { expectLessonPresencesRequest( lessonPresences[0].LessonDateTimeFrom, lessonPresences[0].StudentRef.Id, - lessonPresences[0].StudyClassRef.Id ?? undefined + lessonPresences[0].StudyClassRef.Id ?? undefined, ); }); }); @@ -146,11 +146,11 @@ describe('PresenceControlBlockLessonService', () => { date: Date, studentId: number, studyClassId?: number, - response = lessonPresences + response = lessonPresences, ): void { const url = `https://eventotest.api/LessonPresences/?filter.LessonDateTimeFrom==${format( date, - 'yyyy-MM-dd' + 'yyyy-MM-dd', )}&filter.StudentRef==${studentId}&filter.StudyClassRef==${studyClassId}`; httpTestingController @@ -161,9 +161,10 @@ describe('PresenceControlBlockLessonService', () => { function lessonsFromPresences(presences: LessonPresence[]): Lesson[] { return presences.map((p) => Object.keys(Lesson.props).reduce( + // eslint-disable-next-line @typescript-eslint/no-explicit-any (obj, key) => ({ ...obj, [key]: (p as any)[key] }), - {} as Lesson - ) + {} as Lesson, + ), ); } }); diff --git a/src/app/presence-control/services/presence-control-group.service.spec.ts b/src/app/presence-control/services/presence-control-group.service.spec.ts index 6e5b592e2..77b0b9146 100644 --- a/src/app/presence-control/services/presence-control-group.service.spec.ts +++ b/src/app/presence-control/services/presence-control-group.service.spec.ts @@ -1,7 +1,6 @@ import { HttpTestingController } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import * as t from 'io-ts/lib/index'; -import { Subject } from 'rxjs'; import { buildLesson, buildSubscriptionDetail } from '../../../spec-builders'; import { buildTestModuleMetadata } from '../../../spec-helpers'; import { SubscriptionDetail } from '../../shared/models/subscription-detail.model'; @@ -14,11 +13,9 @@ describe('PresenceControlGroupService', () => { let selectedLesson: Option; - let selectedLesson$: Subject>; - beforeEach(() => { TestBed.configureTestingModule( - buildTestModuleMetadata({ providers: [PresenceControlGroupService] }) + buildTestModuleMetadata({ providers: [PresenceControlGroupService] }), ); httpTestingController = TestBed.inject(HttpTestingController); service = TestBed.inject(PresenceControlGroupService); @@ -30,8 +27,6 @@ describe('PresenceControlGroupService', () => { describe('groupsAvailability$', () => { beforeEach(() => { - selectedLesson$ = new Subject(); - selectedLesson = fromLesson( buildLesson( 2, @@ -40,14 +35,14 @@ describe('PresenceControlGroupService', () => { 'Deutsch', 'Dora Durrer', undefined, - 333 - ) + 333, + ), ); }); it('returns true if the selected lesson has groups available', () => { service.groupsAvailability$.subscribe((result) => - expect(result).toBeTruthy() + expect(result).toBeTruthy(), ); service.setSelectedLesson(selectedLesson); @@ -59,7 +54,7 @@ describe('PresenceControlGroupService', () => { it('returns false if the selected lesson does not have groups available', () => { service.groupsAvailability$.subscribe((result) => - expect(result).toBeFalsy() + expect(result).toBeFalsy(), ); service.setSelectedLesson(selectedLesson); @@ -72,13 +67,13 @@ describe('PresenceControlGroupService', () => { function expectSubscriptionDetailsDefinitionsRequest( eventId: number, - subscriptionDetailsDefinitions: SubscriptionDetail[] + subscriptionDetailsDefinitions: SubscriptionDetail[], ): void { const url = `https://eventotest.api/Events/${eventId}/SubscriptionDetails`; httpTestingController .expectOne(url) .flush( - t.array(SubscriptionDetail).encode(subscriptionDetailsDefinitions) + t.array(SubscriptionDetail).encode(subscriptionDetailsDefinitions), ); } }); diff --git a/src/app/presence-control/services/presence-control-group.service.ts b/src/app/presence-control/services/presence-control-group.service.ts index 782491dce..9df696916 100644 --- a/src/app/presence-control/services/presence-control-group.service.ts +++ b/src/app/presence-control/services/presence-control-group.service.ts @@ -1,14 +1,8 @@ import { Inject, Injectable } from '@angular/core'; import { combineLatest, Observable, of, ReplaySubject } from 'rxjs'; import { forkJoin, merge, Subject } from 'rxjs'; -import { - map, - switchMap, - shareReplay, - startWith, - distinctUntilChanged, -} from 'rxjs/operators'; -import { flatten, isEqual, uniq } from 'lodash-es'; +import { map, switchMap, shareReplay, startWith } from 'rxjs/operators'; +import { flatten, uniq } from 'lodash-es'; import { SETTINGS, Settings } from '../../settings'; import { LessonPresence } from '../../shared/models/lesson-presence.model'; import { SubscriptionDetail } from '../../shared/models/subscription-detail.model'; @@ -45,13 +39,13 @@ export class PresenceControlGroupService { switchMap((lesson) => this.userSettings .getPresenceControlGroupView() - .pipe(map((views) => this.findGroupByLesson(views, lesson))) - ) + .pipe(map((views) => this.findGroupByLesson(views, lesson))), + ), ); group$ = merge(this.selectGroup$, this.savedGroup$).pipe( startWith(this.defaultGroup), - shareReplay(1) + shareReplay(1), ); loading$ = this.loadingService.loading(GROUP_LOADING_CONTEXT); @@ -60,10 +54,12 @@ export class PresenceControlGroupService { map((lesson) => lesson?.getEventIds() || []), switchMap((ids) => forkJoin( - ids.map((id) => this.eventService.getSubscriptionDetailsDefinitions(id)) - ) + ids.map((id) => + this.eventService.getSubscriptionDetailsDefinitions(id), + ), + ), ), - shareReplay(1) + shareReplay(1), ); /** @@ -74,10 +70,10 @@ export class PresenceControlGroupService { groupsAvailability$ = this.subscriptionDetailsDefinitions$.pipe( map((detailsByEvent) => detailsByEvent.every((details) => - findSubscriptionDetailByGroupId(details, this.settings) - ) + findSubscriptionDetailByGroupId(details, this.settings), + ), ), - shareReplay(1) + shareReplay(1), ); private subscriptionDetails$ = combineLatest([ @@ -85,18 +81,18 @@ export class PresenceControlGroupService { this.groupsAvailability$, this.reloadSubscriptionDetails$.pipe( map(() => false), - startWith(true) + startWith(true), ), ]).pipe( switchMap(([lesson, groupsAvailability, initial]) => lesson && groupsAvailability ? this.loadSubscriptionDetailsForLesson(lesson, initial) - : of([]) + : of([]), ), map((details) => - filterSubscriptionDetailsByGroupId(details, this.settings) + filterSubscriptionDetailsByGroupId(details, this.settings), ), - shareReplay(1) + shareReplay(1), ); subscriptionDetailPersonIds$ = combineLatest([ @@ -104,9 +100,9 @@ export class PresenceControlGroupService { this.subscriptionDetails$, ]).pipe( map(([group, details]) => - details.filter((d) => d.Value === group).map((d) => d.IdPerson) + details.filter((d) => d.Value === group).map((d) => d.IdPerson), ), - startWith([]) + startWith([]), ); constructor( @@ -115,7 +111,7 @@ export class PresenceControlGroupService { private subscriptionService: SubscriptionsRestService, private subscriptionDetailsService: SubscriptionDetailsRestService, private loadingService: LoadingService, - @Inject(SETTINGS) private settings: Settings + @Inject(SETTINGS) private settings: Settings, ) {} selectGroup(groupId: GroupOptions['id']): void { @@ -133,7 +129,7 @@ export class PresenceControlGroupService { getSubscriptionDetailsDefinitions(): Observable> { return this.subscriptionDetailsDefinitions$.pipe( map(flatten), - map((details) => findSubscriptionDetailByGroupId(details, this.settings)) + map((details) => findSubscriptionDetailByGroupId(details, this.settings)), ); } @@ -157,26 +153,26 @@ export class PresenceControlGroupService { private loadSubscriptionDetailsForLesson( lesson: LessonEntry, - initial = true + initial = true, ): Observable> { return this.loadingService .load( forkJoin( uniq(lesson.getEventIds()).map((eventId) => - this.subscriptionDetailsService.getListForEvent(eventId) - ) + this.subscriptionDetailsService.getListForEvent(eventId), + ), ), - !initial ? GROUP_LOADING_CONTEXT : undefined + !initial ? GROUP_LOADING_CONTEXT : undefined, ) .pipe(map(flatten)); } private findGroupByLesson( groupViews: ReadonlyArray, - lesson: Option + lesson: Option, ): GroupOptions['id'] { const groupView = groupViews.find( - (gv) => gv.eventId === lesson?.getEventIds()[0] // All event ids of a lesson share the same group + (gv) => gv.eventId === lesson?.getEventIds()[0], // All event ids of a lesson share the same group ); return groupView?.group || this.defaultGroup; diff --git a/src/app/presence-control/services/presence-control-state.service.spec.ts b/src/app/presence-control/services/presence-control-state.service.spec.ts index 83884f3cb..c0cdc6a88 100644 --- a/src/app/presence-control/services/presence-control-state.service.spec.ts +++ b/src/app/presence-control/services/presence-control-state.service.spec.ts @@ -75,7 +75,7 @@ describe('PresenceControlStateService', () => { }, }, ], - }) + }), ); httpTestingController = TestBed.inject(HttpTestingController); service = TestBed.inject(PresenceControlStateService); @@ -84,7 +84,7 @@ describe('PresenceControlStateService', () => { service.selectedLesson$.subscribe(selectedLessonCb); presenceControlEntriesCb = jasmine.createSpy( - 'presenceControlEntries$ callback' + 'presenceControlEntries$ callback', ); service.presenceControlEntries$.subscribe(presenceControlEntriesCb); @@ -104,7 +104,7 @@ describe('PresenceControlStateService', () => { new Date(2000, 0, 23, 8, 0), 'Turnen', 'Frisch Max', - 'Tina Tran' + 'Tina Tran', ); deutschEinsteinAbwesend = buildLessonPresence( 2, @@ -114,7 +114,7 @@ describe('PresenceControlStateService', () => { 'Einstein Albert', 'Dora Durrer', absent.Id, - 333 + 333, ); deutschFrisch = buildLessonPresence( 2, @@ -124,7 +124,7 @@ describe('PresenceControlStateService', () => { 'Frisch Max', 'Dora Durrer', undefined, - 333 + 333, ); mathEinstein1 = buildLessonPresence( 3, @@ -135,7 +135,7 @@ describe('PresenceControlStateService', () => { 'Martina Moser', undefined, 33, - 66 + 66, ); mathEinstein2 = buildLessonPresence( 4, @@ -146,7 +146,7 @@ describe('PresenceControlStateService', () => { 'Martina Moser', undefined, 33, - 66 + 66, ); mathEinstein3 = buildLessonPresence( 5, @@ -157,7 +157,7 @@ describe('PresenceControlStateService', () => { 'Martina Moser', undefined, 34, - 66 + 66, ); mathEinstein4 = buildLessonPresence( 6, @@ -168,7 +168,7 @@ describe('PresenceControlStateService', () => { 'Martina Moser', undefined, 35, - 66 + 66, ); lessonPresences = [ turnenFrisch, @@ -204,9 +204,9 @@ describe('PresenceControlStateService', () => { 'Deutsch', 'Dora Durrer', undefined, - 333 - ) - ) + 333, + ), + ), ); expect(presenceControlEntriesCb).toHaveBeenCalledWith([ buildPresenceControlEntry(deutschEinsteinAbwesend, absent), @@ -229,7 +229,7 @@ describe('PresenceControlStateService', () => { new Date(2000, 0, 10, 16, 0), new Date(2000, 0, 10, 17, 0), 'Werken', - 'Frisch Max' + 'Frisch Max', ); expectLessonsRequest(lessonsFromPresences([werkenFrisch]), '2000-01-10'); expectLessonPresencesRequest([werkenFrisch], [99]); @@ -242,9 +242,9 @@ describe('PresenceControlStateService', () => { new Date(2000, 0, 10, 16, 0), new Date(2000, 0, 10, 17, 0), 'Werken', - '' - ) - ) + '', + ), + ), ); expect(presenceControlEntriesCb).toHaveBeenCalledWith([ buildPresenceControlEntry(werkenFrisch), @@ -257,7 +257,7 @@ describe('PresenceControlStateService', () => { expectLessonsRequest(); expectLessonPresencesRequest( lessonPresences.filter((p) => p.LessonRef.Id === 3), - [3] + [3], ); expectPresenceTypesRequest(); expectAbsenceConfirmationStatesRequest(); @@ -296,10 +296,10 @@ describe('PresenceControlStateService', () => { function expectLessonPresencesRequest( response = lessonPresences, - lessionIds = [2] + lessionIds = [2], ): void { const url = `https://eventotest.api/LessonPresences/?filter.LessonRef=;${lessionIds.join( - ';' + ';', )}`; httpTestingController @@ -315,7 +315,7 @@ describe('PresenceControlStateService', () => { } function expectAbsenceConfirmationStatesRequest( - response = confirmationStates + response = confirmationStates, ): void { const url = 'https://eventotest.api/DropDownItems/AbsenceConfirmationStates'; @@ -327,7 +327,7 @@ describe('PresenceControlStateService', () => { function expectLoadOtherTeachersAbsencesRequest( response = otherAbsences, personId: number, - students?: number[] + students?: number[], ): void { let url = `https://eventotest.api/LessonTeachers/except/${personId}/LessonAbsences?expand=LessonRef`; if (students && students.length > 0) { @@ -341,9 +341,10 @@ describe('PresenceControlStateService', () => { function lessonsFromPresences(presences: LessonPresence[]): Lesson[] { return presences.map((p) => Object.keys(Lesson.props).reduce( + // eslint-disable-next-line @typescript-eslint/no-explicit-any (obj, key) => ({ ...obj, [key]: (p as any)[key] }), - {} as Lesson - ) + {} as Lesson, + ), ); } }); diff --git a/src/app/presence-control/utils/lesson-presences.ts b/src/app/presence-control/utils/lesson-presences.ts index e42e23601..434c615a0 100644 --- a/src/app/presence-control/utils/lesson-presences.ts +++ b/src/app/presence-control/utils/lesson-presences.ts @@ -1,4 +1,3 @@ -import { uniq } from 'lodash-es'; import { Settings } from 'src/app/settings'; import { OptionalReference } from 'src/app/shared/models/common-types'; import { LessonPresence } from 'src/app/shared/models/lesson-presence.model'; @@ -10,11 +9,11 @@ export function updatePresenceTypeForPresences( allLessonPresences: ReadonlyArray, updates: ReadonlyArray, presenceTypes: ReadonlyArray, - settings: Settings + settings: Settings, ): ReadonlyArray { return allLessonPresences.map((lessonPresence) => { const update = updates.find((u) => - lessonPresenceEquals(u.presence, lessonPresence) + lessonPresenceEquals(u.presence, lessonPresence), ); if (update) { let newPresenceType: Option; @@ -33,7 +32,7 @@ export function updatePresenceTypeForPresences( Type: newPresenceType ? newPresenceType.Designation : null, ConfirmationStateId: getNewConfirmationStateId( newPresenceType, - settings + settings, ), }; } @@ -48,7 +47,7 @@ function lessonPresenceEquals(a: LessonPresence, b: LessonPresence): boolean { } function buildPresenceTypeRef( - presenceType: Option + presenceType: Option, ): OptionalReference { return { Id: presenceType ? presenceType.Id : null, diff --git a/src/app/presence-control/utils/presence-types.ts b/src/app/presence-control/utils/presence-types.ts index 4b08ba696..44b702193 100644 --- a/src/app/presence-control/utils/presence-types.ts +++ b/src/app/presence-control/utils/presence-types.ts @@ -1,7 +1,6 @@ import { PresenceType } from 'src/app/shared/models/presence-type.model'; import { Settings } from 'src/app/settings'; import { LessonPresence } from 'src/app/shared/models/lesson-presence.model'; -import { DropDownItem } from '../../shared/models/drop-down-item.model'; export function isPresent(presenceType: Option): boolean { return Boolean(!presenceType); @@ -20,45 +19,45 @@ export function isAbsent(presenceType: Option): boolean { presenceType && (presenceType.IsAbsence || presenceType.IsDispensation || - presenceType.IsHalfDay) + presenceType.IsHalfDay), ); } export function isDefaultAbsence( presenceType: Option, - settings: Settings + settings: Settings, ): boolean { return Boolean( presenceType && settings && - presenceType.Id === settings.absencePresenceTypeId + presenceType.Id === settings.absencePresenceTypeId, ); } export function isUnapprovedAbsence( settings: Settings, - confirmationStateId: Maybe + confirmationStateId: Maybe, ): boolean { return Boolean( settings && confirmationStateId && - confirmationStateId === settings.checkableAbsenceStateId + confirmationStateId === settings.checkableAbsenceStateId, ); } export function isLate( presenceType: Option, - settings: Settings + settings: Settings, ): boolean { return Boolean( - presenceType && settings && presenceType.Id === settings.latePresenceTypeId + presenceType && settings && presenceType.Id === settings.latePresenceTypeId, ); } export function canChangePresenceType( lessonPresence: LessonPresence, presenceType: Option, - settings: Settings + settings: Settings, ): boolean { if ( (isPresent(presenceType) && lessonPresence.ConfirmationStateId === null) || @@ -81,7 +80,7 @@ export function canChangePresenceType( export function getNewConfirmationStateId( presenceType: Option, - settings: Settings + settings: Settings, ): Option { return presenceType?.IsAbsence ? settings.unconfirmedAbsenceStateId : null; } diff --git a/src/app/presence-control/utils/subscriptions-details.ts b/src/app/presence-control/utils/subscriptions-details.ts index 83fa710e2..1adbc3963 100644 --- a/src/app/presence-control/utils/subscriptions-details.ts +++ b/src/app/presence-control/utils/subscriptions-details.ts @@ -12,38 +12,40 @@ export interface SubscriptionDetailWithName { export function sortSubscriptionDetails( details: ReadonlyArray, - sortCriteria: SortCriteria + sortCriteria: SortCriteria, ): ReadonlyArray { return [...details].sort(getSubscriptionDetailComparator(sortCriteria)); } function getSubscriptionDetailComparator( - sortCriteria: SortCriteria + sortCriteria: SortCriteria, ): (a: SubscriptionDetailWithName, b: SubscriptionDetailWithName) => number { return (a, b) => { switch (sortCriteria.primarySortKey) { - case 'name': + case 'name': { const nameComparator = a.name.localeCompare(b.name); return sortCriteria.ascending ? nameComparator * -1 : nameComparator; - case 'group': + } + case 'group': { const groupComparator = (a.detail.Value || '').localeCompare( - b.detail.Value || '' + b.detail.Value || '', ); return sortCriteria.ascending ? groupComparator * -1 : groupComparator; + } } }; } export function getSubscriptionDetailsWithName( details: ReadonlyArray, - presences: ReadonlyArray + presences: ReadonlyArray, ): ReadonlyArray { return details.map((d) => mapToSubscriptionDetailWithName(d, presences)); } function mapToSubscriptionDetailWithName( detail: SubscriptionDetail, - presences: ReadonlyArray + presences: ReadonlyArray, ): SubscriptionDetailWithName { return { id: detail.IdPerson, @@ -57,14 +59,14 @@ function mapToSubscriptionDetailWithName( export function filterSubscriptionDetailsByGroupId( details: ReadonlyArray, - settings: Settings + settings: Settings, ): ReadonlyArray { return details.filter((d) => d.VssId === settings.subscriptionDetailGroupId); } export function findSubscriptionDetailByGroupId( details: ReadonlyArray, - settings: Settings + settings: Settings, ): Maybe { return details.find((d) => d.VssId === settings.subscriptionDetailGroupId); } diff --git a/src/app/rest-auth-interceptor.spec.ts b/src/app/rest-auth-interceptor.spec.ts index ea09d3e16..fcd955120 100644 --- a/src/app/rest-auth-interceptor.spec.ts +++ b/src/app/rest-auth-interceptor.spec.ts @@ -5,6 +5,8 @@ import { HttpTestingController } from '@angular/common/http/testing'; import { buildTestModuleMetadata } from 'src/spec-helpers'; import { AuthService } from './shared/services/auth.service'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('RestAuthInterceptor', () => { let http: HttpClient; let httpTestingController: HttpTestingController; @@ -37,7 +39,7 @@ describe('RestAuthInterceptor', () => { (req) => req.url === 'https://eventotest.api/foo' && req.headers.get('CLX-Authorization') === - 'token_type=urn:ietf:params:oauth:token-type:jwt-bearer, access_token=abcdefghijklmnopqrstuvwxyz' + 'token_type=urn:ietf:params:oauth:token-type:jwt-bearer, access_token=abcdefghijklmnopqrstuvwxyz', ) .flush('hello', { status: 200, statusText: 'Success' }); @@ -53,7 +55,7 @@ describe('RestAuthInterceptor', () => { .expectOne( (req) => req.url === 'http://example.com' && - !req.headers.has('CLX-Authorization') + !req.headers.has('CLX-Authorization'), ) .flush('hello', { status: 200, statusText: 'Success' }); @@ -82,7 +84,7 @@ describe('RestAuthInterceptor', () => { .expectOne( (req) => req.url === 'https://eventotest.api/foo' && - !req.headers.has('CLX-Authorization') + !req.headers.has('CLX-Authorization'), ) .flush('hello', { status: 200, statusText: 'Success' }); diff --git a/src/app/rest-auth-interceptor.ts b/src/app/rest-auth-interceptor.ts index 72c082bf8..e414d1ab6 100644 --- a/src/app/rest-auth-interceptor.ts +++ b/src/app/rest-auth-interceptor.ts @@ -14,20 +14,20 @@ import { SETTINGS, Settings } from './settings'; export class RestAuthInterceptor implements HttpInterceptor { constructor( private auth: AuthService, - @Inject(SETTINGS) private settings: Settings + @Inject(SETTINGS) private settings: Settings, ) {} /** * Adds the CLX-Authorization HTTP header to API requests. */ intercept( - req: HttpRequest, - next: HttpHandler - ): Observable> { + req: HttpRequest, + next: HttpHandler, + ): Observable> { if (req.url.startsWith(this.settings.apiUrl) && this.auth.accessToken) { const headers = req.headers.set( 'CLX-Authorization', - `token_type=urn:ietf:params:oauth:token-type:jwt-bearer, access_token=${this.auth.accessToken}` + `token_type=urn:ietf:params:oauth:token-type:jwt-bearer, access_token=${this.auth.accessToken}`, ); return next.handle(req.clone({ headers })); } diff --git a/src/app/rest-error-interceptor.ts b/src/app/rest-error-interceptor.ts index 68e323deb..2f5c719ac 100644 --- a/src/app/rest-error-interceptor.ts +++ b/src/app/rest-error-interceptor.ts @@ -27,7 +27,7 @@ export function withConfig( | HttpParams | { [param: string]: string | string[]; - } = {} + } = {}, ): HttpParams { let httpParams: HttpParams; if (params instanceof HttpParams) { @@ -53,7 +53,7 @@ export class RestErrorInterceptor implements HttpInterceptor { constructor( private router: Router, private toastService: ToastService, - private translate: TranslateService + private translate: TranslateService, ) {} /** @@ -79,9 +79,9 @@ export class RestErrorInterceptor implements HttpInterceptor { * this.http.get('/', { params }).pipe(catchError( handle 403/404 here... )) */ intercept( - req: HttpRequest, - next: HttpHandler - ): Observable> { + req: HttpRequest, + next: HttpHandler, + ): Observable> { // TODO: there might be better ways of passing options to the // interceptor in the future, see: // https://github.com/angular/angular/issues/18155 @@ -92,16 +92,12 @@ export class RestErrorInterceptor implements HttpInterceptor { } private getErrorHandler( - config: RestConfig + config: RestConfig, ): ( - error: any, - caught: Observable> - ) => Observable> { - // eslint-disable-next-line - return ( - error: any, - caught: Observable> - ): Observable> => { + error: unknown, + caught: Observable>, + ) => Observable> { + return (error: unknown): Observable> => { if ( error instanceof HttpErrorResponse && !config.disableErrorHandling && @@ -140,7 +136,7 @@ export class RestErrorInterceptor implements HttpInterceptor { private notifyError(messageKey: string): void { this.toastService.error( this.translate.instant(`global.rest-errors.${messageKey}-message`), - this.translate.instant(`global.rest-errors.${messageKey}-title`) + this.translate.instant(`global.rest-errors.${messageKey}-title`), ); } @@ -168,19 +164,20 @@ export class RestErrorInterceptor implements HttpInterceptor { */ private notifyConflictError(error: HttpErrorResponse): void { const defaultMessage = this.translate.instant( - `global.rest-errors.conflict-message` + `global.rest-errors.conflict-message`, ); const issues = this.parseConflictIssues(error); this.toastService.error( issues.length > 0 ? issues.join('\n') : defaultMessage, - this.translate.instant(`global.rest-errors.conflict-title`) + this.translate.instant(`global.rest-errors.conflict-title`), ); } private parseConflictIssues(error: HttpErrorResponse): ReadonlyArray { if (Array.isArray(error.error?.Issues)) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any return error.error.Issues.map((issue: any) => issue?.Message).filter( - nonEmptyString + nonEmptyString, ); } return []; diff --git a/src/app/rest-role-interceptor.ts b/src/app/rest-role-interceptor.ts index 8889eb62b..2746a84d4 100644 --- a/src/app/rest-role-interceptor.ts +++ b/src/app/rest-role-interceptor.ts @@ -22,9 +22,9 @@ export class RestRoleInterceptor implements HttpInterceptor { * Adds the X-Role-Restriction custom HTTP header for the given module to API requests. */ intercept( - req: HttpRequest, + req: HttpRequest, next: HttpHandler, - ): Observable> { + ): Observable> { if ( !req.headers.has('X-Role-Restriction') && this.settings.headerRoleRestriction diff --git a/src/app/shared/components/avatar/avatar.component.ts b/src/app/shared/components/avatar/avatar.component.ts index 0b6c78211..19a31d0d3 100644 --- a/src/app/shared/components/avatar/avatar.component.ts +++ b/src/app/shared/components/avatar/avatar.component.ts @@ -2,7 +2,6 @@ import { Component, Inject, Input, - OnInit, SimpleChanges, OnChanges, } from '@angular/core'; @@ -25,7 +24,7 @@ export class AvatarComponent implements OnChanges { constructor( @Inject(SETTINGS) private settings: Settings, - private storageService: StorageService + private storageService: StorageService, ) {} ngOnChanges(changes: SimpleChanges): void { @@ -47,7 +46,7 @@ export class AvatarComponent implements OnChanges { private buildAvatarUrl(studentId: number): string { const accessToken = this.storageService.getAccessToken() || ''; - return `${this.settings.apiUrl}/Files\/personPictures/${studentId}?token=${accessToken}`; + return `${this.settings.apiUrl}/Files/personPictures/${studentId}?token=${accessToken}`; } private get fallbackAvatarUrl(): string { diff --git a/src/app/shared/components/confirm-absences/confirm-absences.component.spec.ts b/src/app/shared/components/confirm-absences/confirm-absences.component.spec.ts index 121acb61b..6c872c021 100644 --- a/src/app/shared/components/confirm-absences/confirm-absences.component.spec.ts +++ b/src/app/shared/components/confirm-absences/confirm-absences.component.spec.ts @@ -6,6 +6,8 @@ import { ConfirmAbsencesComponent } from './confirm-absences.component'; import { OpenAbsencesService } from 'src/app/open-absences/services/open-absences.service'; import { ConfirmAbsencesSelectionService } from '../../services/confirm-absences-selection.service'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('ConfirmAbsencesComponent', () => { let component: ConfirmAbsencesComponent; let fixture: ComponentFixture; @@ -14,10 +16,10 @@ describe('ConfirmAbsencesComponent', () => { beforeEach(waitForAsync(() => { storeMock = {}; spyOn(localStorage, 'getItem').and.callFake( - (key: string) => storeMock[key] || null + (key: string) => storeMock[key] || null, ); spyOn(localStorage, 'setItem').and.callFake( - (key: string) => storeMock[key] || null + (key: string) => storeMock[key] || null, ); storeMock['CLX.LoginToken'] = @@ -42,7 +44,7 @@ describe('ConfirmAbsencesComponent', () => { }, }, ], - }) + }), ).compileComponents(); })); diff --git a/src/app/shared/components/date-select/date-select.component.ts b/src/app/shared/components/date-select/date-select.component.ts index dedb48c18..576557eed 100644 --- a/src/app/shared/components/date-select/date-select.component.ts +++ b/src/app/shared/components/date-select/date-select.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { Component, Input, Output, EventEmitter } from '@angular/core'; import { uniqueId } from 'lodash-es'; @Component({ diff --git a/src/app/shared/components/multiselect/multiselect.component.spec.ts b/src/app/shared/components/multiselect/multiselect.component.spec.ts index ce8f1b8fb..0e3e5e36c 100644 --- a/src/app/shared/components/multiselect/multiselect.component.spec.ts +++ b/src/app/shared/components/multiselect/multiselect.component.spec.ts @@ -6,17 +6,17 @@ import { MultiselectComponent } from './multiselect.component'; describe('MultiselectComponent', () => { let component: MultiselectComponent; let fixture: ComponentFixture; - let element: HTMLElement; + // let element: HTMLElement; beforeEach(waitForAsync(() => { TestBed.configureTestingModule( - buildTestModuleMetadata({}) + buildTestModuleMetadata({}), ).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(MultiselectComponent); - element = fixture.debugElement.nativeElement; + // element = fixture.debugElement.nativeElement; component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/src/app/shared/components/resettable-input/resettable-input.component.ts b/src/app/shared/components/resettable-input/resettable-input.component.ts index 8ba2ff694..8789d0478 100644 --- a/src/app/shared/components/resettable-input/resettable-input.component.ts +++ b/src/app/shared/components/resettable-input/resettable-input.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector: 'erz-resettable-input', diff --git a/src/app/shared/components/select/select.component.spec.ts b/src/app/shared/components/select/select.component.spec.ts index ab4eec275..7a6c12f9f 100644 --- a/src/app/shared/components/select/select.component.spec.ts +++ b/src/app/shared/components/select/select.component.spec.ts @@ -6,17 +6,17 @@ import { SelectComponent } from './select.component'; describe('SelectComponent', () => { let component: SelectComponent; let fixture: ComponentFixture; - let element: HTMLElement; + // let element: HTMLElement; beforeEach(waitForAsync(() => { TestBed.configureTestingModule( - buildTestModuleMetadata({}) + buildTestModuleMetadata({}), ).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(SelectComponent); - element = fixture.debugElement.nativeElement; + // element = fixture.debugElement.nativeElement; component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/src/app/shared/components/select/select.component.ts b/src/app/shared/components/select/select.component.ts index 855619b3e..c42112961 100644 --- a/src/app/shared/components/select/select.component.ts +++ b/src/app/shared/components/select/select.component.ts @@ -10,7 +10,6 @@ import { import { DropDownItem } from '../../models/drop-down-item.model'; import { BehaviorSubject, combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; -import { number } from 'fp-ts'; @Component({ selector: 'erz-select', @@ -32,8 +31,8 @@ export class SelectComponent implements OnChanges { value$ = combineLatest([this.rawValue$, this.options$]).pipe( map( ([rawValue, options]) => - (options && options.find((o) => o.Key === rawValue)) || null - ) + (options && options.find((o) => o.Key === rawValue)) || null, + ), ); constructor() {} diff --git a/src/app/shared/components/spinner/spinner.component.ts b/src/app/shared/components/spinner/spinner.component.ts index 17c7449c0..ae19568c6 100644 --- a/src/app/shared/components/spinner/spinner.component.ts +++ b/src/app/shared/components/spinner/spinner.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; @Component({ selector: 'erz-spinner', diff --git a/src/app/shared/components/student-dossier/dossier-course-tests/dossier-course-tests.component.spec.ts b/src/app/shared/components/student-dossier/dossier-course-tests/dossier-course-tests.component.spec.ts index 2728b9c74..b89f88b1c 100644 --- a/src/app/shared/components/student-dossier/dossier-course-tests/dossier-course-tests.component.spec.ts +++ b/src/app/shared/components/student-dossier/dossier-course-tests/dossier-course-tests.component.spec.ts @@ -1,6 +1,5 @@ import { DebugElement } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { Course } from 'src/app/shared/models/course.model'; import { GradingScale } from 'src/app/shared/models/grading-scale.model'; import { buildTestModuleMetadata } from 'src/spec-helpers'; import { expectText } from 'src/specs/expectations'; @@ -31,7 +30,7 @@ describe('DossierCourseTestsComponent', () => { }, }, ], - }) + }), ).compileComponents(); }); diff --git a/src/app/shared/components/student-dossier/dossier-grades/dossier-grades.component.spec.ts b/src/app/shared/components/student-dossier/dossier-grades/dossier-grades.component.spec.ts index 63aaa343f..41c17eb77 100644 --- a/src/app/shared/components/student-dossier/dossier-grades/dossier-grades.component.spec.ts +++ b/src/app/shared/components/student-dossier/dossier-grades/dossier-grades.component.spec.ts @@ -13,6 +13,8 @@ import { Course } from '../../../models/course.model'; import { buildCourse, buildGradingScale } from '../../../../../spec-builders'; import { GradingScale } from '../../../models/grading-scale.model'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('DossierGradesComponent', () => { let component: DossierGradesComponent; let fixture: ComponentFixture; @@ -25,7 +27,7 @@ describe('DossierGradesComponent', () => { let studentCourses$: BehaviorSubject; let gradingScales$: BehaviorSubject; - let courses = [buildCourse(1234)]; + const courses = [buildCourse(1234)]; const gradingScales = [buildGradingScale(1)]; beforeEach(async () => { @@ -39,7 +41,7 @@ describe('DossierGradesComponent', () => { loading$ = new BehaviorSubject(false); studentCourses$ = new BehaviorSubject(courses); gradingScales$ = new BehaviorSubject( - gradingScales + gradingScales, ); dossierGradesServiceMock = { @@ -65,7 +67,7 @@ describe('DossierGradesComponent', () => { useValue: jasmine.createSpyObj('StorageService', ['getPayload']), }, ], - }) + }), ).compileComponents(); }); diff --git a/src/app/shared/components/student-dossier/dossier-single-test/dossier-single-test.component.ts b/src/app/shared/components/student-dossier/dossier-single-test/dossier-single-test.component.ts index d14662bce..523aa0e32 100644 --- a/src/app/shared/components/student-dossier/dossier-single-test/dossier-single-test.component.ts +++ b/src/app/shared/components/student-dossier/dossier-single-test/dossier-single-test.component.ts @@ -1,12 +1,4 @@ -import { - Component, - Input, - OnInit, - Output, - EventEmitter, - SimpleChanges, - OnChanges, -} from '@angular/core'; +import { Component, Input, SimpleChanges, OnChanges } from '@angular/core'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { map, ReplaySubject } from 'rxjs'; import { @@ -46,7 +38,7 @@ import { DossierGradesService } from '../../../services/dossier-grades.service'; {{ test | erzTestWeight }}
- {{ test | erzTestPoints: studentId:'dossier.points' }} + {{ test | erzTestPoints: studentId : 'dossier.points' }}
{{ test.Owner }} @@ -71,7 +63,7 @@ export class DossierSingleTestComponent implements OnChanges { constructor( private gradeService: DossierGradesService, - private modalService: NgbModal + private modalService: NgbModal, ) {} ngOnChanges(changes: SimpleChanges): void { @@ -95,7 +87,7 @@ export class DossierSingleTestComponent implements OnChanges { (updatedTestResult) => { if (updatedTestResult) this.updateStudentGrade(updatedTestResult, test); }, - () => {} + () => {}, ); } @@ -107,7 +99,7 @@ export class DossierSingleTestComponent implements OnChanges { private getGrading(test: Test): string { return ( this.gradingScale?.Grades.find( - (grade) => grade.Id === this.getGradeId(test) + (grade) => grade.Id === this.getGradeId(test), )?.Designation || '-' ); } @@ -122,7 +114,7 @@ export class DossierSingleTestComponent implements OnChanges { } private static mapToOptions( - gradingScale: Option + gradingScale: Option, ): Option { return ( gradingScale?.Grades.map((gradeOption) => { diff --git a/src/app/shared/components/student-dossier/student-backlink/student-backlink.component.ts b/src/app/shared/components/student-dossier/student-backlink/student-backlink.component.ts index 225965633..3c5f39eb4 100644 --- a/src/app/shared/components/student-dossier/student-backlink/student-backlink.component.ts +++ b/src/app/shared/components/student-dossier/student-backlink/student-backlink.component.ts @@ -1,5 +1,5 @@ import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; -import { Params } from '@angular/router'; +import { Params, RouterLink } from '@angular/router'; import { Student } from 'src/app/shared/models/student.model'; @Component({ @@ -9,7 +9,7 @@ import { Student } from 'src/app/shared/models/student.model'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class StudentBacklinkComponent { - @Input() link: any[] | string = '/'; + @Input() link: RouterLink['routerLink'] = '/'; @Input() queryParams?: Params; @Input() studentId: number; @Input() studentName?: string; diff --git a/src/app/shared/components/student-dossier/student-dossier-absences/student-dossier-absences.component.ts b/src/app/shared/components/student-dossier/student-dossier-absences/student-dossier-absences.component.ts index bd17a6469..382df21fb 100644 --- a/src/app/shared/components/student-dossier/student-dossier-absences/student-dossier-absences.component.ts +++ b/src/app/shared/components/student-dossier/student-dossier-absences/student-dossier-absences.component.ts @@ -79,14 +79,14 @@ export class StudentDossierAbsencesComponent implements OnChanges { lessonPresences$ = this.lessonPresences$$.pipe( switchAll(), startWith(null), - shareReplay(1) + shareReplay(1), ); loading$ = this.lessonPresences$.pipe(map(not(isArray))); selectionService$ = new ReplaySubject(1); editable$ = this.selectionService$.pipe( map(() => true), - startWith(false) + startWith(false), ); private displayPresenceType$ = new BehaviorSubject(true); @@ -97,8 +97,8 @@ export class StudentDossierAbsencesComponent implements OnChanges { ]).pipe( map( ([lessonPresences, selection]) => - lessonPresences.length === selection.length - ) + lessonPresences.length === selection.length, + ), ); constructor(private presenceTypesService: PresenceTypesService) {} @@ -142,24 +142,24 @@ export class StudentDossierAbsencesComponent implements OnChanges { } if ( event.target !== checkbox && - !Boolean((event.target as HTMLElement).closest('.buttons')) + !(event.target as HTMLElement).closest('.buttons') ) { checkbox.click(); } } getPresenceTypeDesignation( - absence: LessonPresence + absence: LessonPresence, ): Observable> { return this.displayPresenceType$.pipe( switchMap((display) => - display ? this.presenceTypesService.displayedTypes$ : of([]) + display ? this.presenceTypesService.displayedTypes$ : of([]), ), map((types) => absence.TypeRef.Id ? types.find((t) => t.Id === absence.TypeRef.Id)?.Designation || null - : null - ) + : null, + ), ); } } diff --git a/src/app/shared/components/student-dossier/student-dossier-apprenticeship-company/student-dossier-apprenticeship-company.component.ts b/src/app/shared/components/student-dossier/student-dossier-apprenticeship-company/student-dossier-apprenticeship-company.component.ts index ea0025cf9..b1434656d 100644 --- a/src/app/shared/components/student-dossier/student-dossier-apprenticeship-company/student-dossier-apprenticeship-company.component.ts +++ b/src/app/shared/components/student-dossier/student-dossier-apprenticeship-company/student-dossier-apprenticeship-company.component.ts @@ -1,9 +1,4 @@ -import { - Component, - OnInit, - Input, - ChangeDetectionStrategy, -} from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; import { ApprenticeshipCompany } from '../../../services/student-profile.service'; @Component({ diff --git a/src/app/shared/components/switch/switch.component.spec.ts b/src/app/shared/components/switch/switch.component.spec.ts index 1c5d14c60..8ad2225f6 100644 --- a/src/app/shared/components/switch/switch.component.spec.ts +++ b/src/app/shared/components/switch/switch.component.spec.ts @@ -12,7 +12,7 @@ describe('SwitchComponent', () => { await TestBed.configureTestingModule( buildTestModuleMetadata({ declarations: [SwitchComponent], - }) + }), ).compileComponents(); }); @@ -68,13 +68,13 @@ describe('SwitchComponent', () => { function getInput(): HTMLInputElement { const input = element.querySelector( - 'input[type="checkbox"]' + 'input[type="checkbox"]', ); expect(input).toBeDefined(); return input!; } - function waitForRender(): Promise { + function waitForRender() { fixture.detectChanges(); return fixture.whenStable(); } diff --git a/src/app/shared/components/toast/toast.component.spec.ts b/src/app/shared/components/toast/toast.component.spec.ts index c8fac7daa..48f14ee43 100644 --- a/src/app/shared/components/toast/toast.component.spec.ts +++ b/src/app/shared/components/toast/toast.component.spec.ts @@ -11,7 +11,7 @@ import { ToastService } from '../../services/toast.service'; import { ToastComponent } from './toast.component'; describe('ToastComponent', () => { - let component: ToastComponent; + // let component: ToastComponent; let fixture: ComponentFixture; let element: HTMLElement; let service: ToastService; @@ -27,11 +27,11 @@ describe('ToastComponent', () => { useValue: { delay: 5000, animation: false }, }, ], - }) + }), ).compileComponents(); fixture = TestBed.createComponent(ToastComponent); - component = fixture.componentInstance; + // component = fixture.componentInstance; element = fixture.debugElement.nativeElement; service = TestBed.inject(ToastService); diff --git a/src/app/shared/directives/let.directive.ts b/src/app/shared/directives/let.directive.ts index 746023dd2..e5bafb582 100644 --- a/src/app/shared/directives/let.directive.ts +++ b/src/app/shared/directives/let.directive.ts @@ -27,8 +27,8 @@ import { } from '@angular/core'; export class LetContext { - $implicit: any = null; - erzLet: any = null; + $implicit: unknown = null; + erzLet: unknown = null; } @Directive({ @@ -38,13 +38,13 @@ export class LetDirective implements OnInit { private context = new LetContext(); @Input() - set erzLet(value: any) { + set erzLet(value: unknown) { this.context.$implicit = this.context.erzLet = value; } constructor( private vcr: ViewContainerRef, - private templateRef: TemplateRef + private templateRef: TemplateRef, ) {} ngOnInit(): void { diff --git a/src/app/shared/models/apprenticeship-contract.model.ts b/src/app/shared/models/apprenticeship-contract.model.ts index 709101b02..8178816c5 100644 --- a/src/app/shared/models/apprenticeship-contract.model.ts +++ b/src/app/shared/models/apprenticeship-contract.model.ts @@ -1,5 +1,5 @@ import * as t from 'io-ts'; -import { Maybe, Option, LocalDateTimeFromString } from './common-types'; +import { Option, LocalDateTimeFromString } from './common-types'; const ApprenticeshipContract = t.type({ Id: t.number, diff --git a/src/app/shared/models/job-trainer.model.ts b/src/app/shared/models/job-trainer.model.ts index 95b3066b1..400c3e61b 100644 --- a/src/app/shared/models/job-trainer.model.ts +++ b/src/app/shared/models/job-trainer.model.ts @@ -1,5 +1,5 @@ import * as t from 'io-ts'; -import { Maybe, Option } from './common-types'; +import { Option } from './common-types'; const JobTrainer = t.type({ // HRef: t.string, diff --git a/src/app/shared/models/student-grades.spec.ts b/src/app/shared/models/student-grades.spec.ts index 99d2aa7d2..0cef36894 100644 --- a/src/app/shared/models/student-grades.spec.ts +++ b/src/app/shared/models/student-grades.spec.ts @@ -26,11 +26,11 @@ describe('student-grade utils', () => { buildTest( course.Id, id, - [100, 200].map((studentid) => buildResult(id, studentid)) - ) + [100, 200].map((studentid) => buildResult(id, studentid)), + ), ); course.Gradings = course.ParticipatingStudents.map( - (student) => student.Id + (student) => student.Id, ).map((studentId, index) => buildGrading(studentId, 5.75 - index)); // when @@ -38,7 +38,7 @@ describe('student-grade utils', () => { course.ParticipatingStudents, course.Tests, course.Gradings, - [] + [], ); }); it('should create a list of students with tests and grades - all grades available for all students', () => { @@ -57,18 +57,18 @@ describe('student-grade utils', () => { expect(results[1].grades.length).toBe(3); expect( - results[0].grades.some((grade) => grade.kind === 'no-result') + results[0].grades.some((grade) => grade.kind === 'no-result'), ).toBeFalsy(); expect( - results[1].grades.some((grade) => grade.kind === 'no-result') + results[1].grades.some((grade) => grade.kind === 'no-result'), ).toBeFalsy(); expect( results[0].grades.map((grade) => grade.kind !== 'no-result' ? [grade.result.TestId, grade.result.StudentId] - : '' - ) + : '', + ), ).toEqual([ [1, 100], [2, 100], @@ -78,8 +78,8 @@ describe('student-grade utils', () => { results[1].grades.map((grade) => grade.kind !== 'no-result' ? [grade.result.TestId, grade.result.StudentId] - : '' - ) + : '', + ), ).toEqual([ [1, 200], [2, 200], @@ -100,15 +100,15 @@ describe('student-grade utils', () => { course.ParticipatingStudents, course.Tests, course.Gradings, - [] + [], ); // then expect( - results[0].grades.every((grade) => grade.kind === 'no-result') + results[0].grades.every((grade) => grade.kind === 'no-result'), ).toBeTruthy(); expect( - results[1].grades.every((grade) => grade.kind === 'no-result') + results[1].grades.every((grade) => grade.kind === 'no-result'), ).toBeTruthy(); expect(results[0].finalGrade).toBeNull(); @@ -123,8 +123,8 @@ describe('student-grade utils', () => { buildTest( course.Id, id, - [100].map((studentid) => buildResult(id, studentid)) - ) + [100].map((studentid) => buildResult(id, studentid)), + ), ); course.Gradings = [buildGrading(100)]; @@ -133,7 +133,7 @@ describe('student-grade utils', () => { course.ParticipatingStudents, course.Tests, course.Gradings, - [] + [], ); // then @@ -141,8 +141,8 @@ describe('student-grade utils', () => { results[0].grades.map((grade) => grade.kind !== 'no-result' ? [grade.result.TestId, grade.result.StudentId] - : 'no-result' - ) + : 'no-result', + ), ).toEqual([ [1, 100], [2, 100], @@ -152,8 +152,8 @@ describe('student-grade utils', () => { results[1].grades.map((grade) => grade.kind !== 'no-result' ? [grade.result.TestId, grade.result.StudentId] - : 'no-result' - ) + : 'no-result', + ), ).toEqual([`no-result`, `no-result`, `no-result`]); expect(results[0].finalGrade?.average).toBe(2.275); @@ -167,10 +167,10 @@ describe('student-grade utils', () => { const course = buildCourse(123); course.ParticipatingStudents = [buildStudent(99)]; course.Tests = [1, 2, 3].map((id) => - buildTest(course.Id, id, id % 2 === 0 ? [buildResult(id, 99)] : []) + buildTest(course.Id, id, id % 2 === 0 ? [buildResult(id, 99)] : []), ); course.Gradings = course.ParticipatingStudents.map( - (student) => student.Id + (student) => student.Id, ).map((studentId) => buildGrading(studentId)); // when @@ -178,7 +178,7 @@ describe('student-grade utils', () => { course.ParticipatingStudents, course.Tests, course.Gradings, - [] + [], ); // then @@ -189,8 +189,8 @@ describe('student-grade utils', () => { results[0].grades.map((grade) => grade.kind !== 'no-result' ? [grade.result.TestId, grade.result.StudentId] - : 'no-result' - ) + : 'no-result', + ), ).toEqual(['no-result', [2, 99], 'no-result']); }); @@ -198,7 +198,7 @@ describe('student-grade utils', () => { let studentGrade: NoResult; beforeEach(() => { - let test = buildTest(1, 1, []); + const test = buildTest(1, 1, []); studentGrade = { kind: 'no-result', test: test, @@ -283,7 +283,7 @@ describe('student-grade utils', () => { it('should calculate mean of student grades of overwritten final grades using a given scale', () => { expect(averageOfGradesForScale(finalGrades, scale)).toBe( - 4.333333333333333 + 4.333333333333333, ); }); }); diff --git a/src/app/shared/models/student-grades.ts b/src/app/shared/models/student-grades.ts index 6fa42e078..651419c00 100644 --- a/src/app/shared/models/student-grades.ts +++ b/src/app/shared/models/student-grades.ts @@ -35,13 +35,13 @@ export type GradeOrNoResult = GradeKind | NoResult; export type SortKeys = 'FullName' | Test | 'FinalGrade' | 'TestsMean'; export function pluckFinalGrades( - studentGrades: ReadonlyArray + studentGrades: ReadonlyArray, ): ReadonlyArray { return studentGrades.map(({ finalGrade }) => finalGrade).filter(isFinalGrade); } function isFinalGrade( - finalGrade: Option + finalGrade: Option, ): finalGrade is FinalGrade { return finalGrade !== null; } @@ -50,7 +50,7 @@ export function transform( students: ReadonlyArray, tests: ReadonlyArray, gradings: ReadonlyArray, - finalGrades: ReadonlyArray + finalGrades: ReadonlyArray, ): StudentGrade[] { return students?.map((student) => { return { @@ -63,7 +63,7 @@ export function transform( function getGrades( student: Student, - tests: ReadonlyArray + tests: ReadonlyArray, ): GradeOrNoResult[] { return tests.map((test) => { if (test.Results === undefined || test.Results?.length === 0) { @@ -74,7 +74,7 @@ function getGrades( } const result: Result | undefined = test.Results?.find( - (result) => result.StudentId === student.Id + (result) => result.StudentId === student.Id, ); return result !== undefined @@ -93,14 +93,14 @@ function getGrades( function getFinalGrade( student: Student, gradings: ReadonlyArray, - finalGrades: ReadonlyArray + finalGrades: ReadonlyArray, ): Option { const grading: Maybe = gradings.find( - (grading) => grading.StudentId === student.Id + (grading) => grading.StudentId === student.Id, ); const finalGrading: Maybe = finalGrades.find( - (grading) => grading.StudentId === student.Id + (grading) => grading.StudentId === student.Id, ); if (!grading) return null; @@ -136,7 +136,7 @@ export const compareFn = modificator * compareNumbers( sg1.finalGrade.finalGradeId, - sg2.finalGrade.finalGradeId + sg2.finalGrade.finalGradeId, ) ); case 'TestsMean': @@ -154,7 +154,7 @@ export const compareFn = const compareGrades = ( test: Test, sg1: StudentGrade, - sg2: StudentGrade + sg2: StudentGrade, ): number => { const grades1: GradeKind | undefined = sg1.grades .filter(isGrade) @@ -188,7 +188,7 @@ function isGrade(g: GradeOrNoResult): g is GradeKind { } export function toMaxPoints(grade: GradeOrNoResult | null): number { - return grade?.test.MaxPointsAdjusted || grade?.test.MaxPoints!; + return (grade?.test?.MaxPointsAdjusted || grade?.test?.MaxPoints) ?? 0; } export function meanOf(finalGrades: ReadonlyArray): number { @@ -198,7 +198,7 @@ export function meanOf(finalGrades: ReadonlyArray): number { (averageGrade) => averageGrade !== null && averageGrade !== undefined && - averageGrade !== 0 + averageGrade !== 0, ) .map(Number); return average(averageGrades); @@ -206,7 +206,7 @@ export function meanOf(finalGrades: ReadonlyArray): number { export function averageOfGradesForScale( finalGrades: ReadonlyArray, - scale: ReadonlyArray + scale: ReadonlyArray, ): number { const freeHandGrades: number[] = finalGrades .map((finalGrade) => finalGrade.freeHandGrade) diff --git a/src/app/shared/models/user-settings.model.ts b/src/app/shared/models/user-settings.model.ts index a57d439d4..66763a840 100644 --- a/src/app/shared/models/user-settings.model.ts +++ b/src/app/shared/models/user-settings.model.ts @@ -1,5 +1,5 @@ import * as t from 'io-ts'; -import { Json, withFallback } from 'io-ts-types'; +import { withFallback } from 'io-ts-types'; import { JsonFromUnknown, Option } from './common-types'; import { DropDownItem } from './drop-down-item.model'; @@ -39,7 +39,7 @@ const NotificationChannels = JsonFromUnknown.pipe( mail: withFallback(t.boolean, false), gui: withFallback(t.boolean, false), phoneMobile: withFallback(t.boolean, false), - }) + }), ); /** @@ -67,7 +67,7 @@ const NotificationTypesInactive = new t.Type< : t.failure(input, context), // encode: - (output) => output.join(';') + (output) => output.join(';'), ); const NotificationDataEntry = t.type({ @@ -77,7 +77,7 @@ const NotificationDataEntry = t.type({ }); const NotificationData = JsonFromUnknown.pipe( - t.readonly(t.array(NotificationDataEntry)) + t.readonly(t.array(NotificationDataEntry)), ); export enum PresenceControlViewMode { @@ -92,7 +92,7 @@ const PresenceControlViewModeObject = JsonFromUnknown.pipe( grid: null, list: null, }), - }) + }), ); const PresenceControlGroupViewEntry = t.type({ @@ -101,7 +101,7 @@ const PresenceControlGroupViewEntry = t.type({ }); const PresenceControlGroupView = JsonFromUnknown.pipe( - t.readonly(t.array(PresenceControlGroupViewEntry)) + t.readonly(t.array(PresenceControlGroupViewEntry)), ); // diff --git a/src/app/shared/pipes/add-space.pipe.spec.ts b/src/app/shared/pipes/add-space.pipe.spec.ts index 9add11005..bdc1d21a3 100644 --- a/src/app/shared/pipes/add-space.pipe.spec.ts +++ b/src/app/shared/pipes/add-space.pipe.spec.ts @@ -1,4 +1,7 @@ import { AddSpacePipe } from './add-space.pipe'; + +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('AddSpacePipe', () => { let i18nService: any; diff --git a/src/app/shared/pipes/safe.pipe.spec.ts b/src/app/shared/pipes/safe.pipe.spec.ts index c97b3b106..9001bafe3 100644 --- a/src/app/shared/pipes/safe.pipe.spec.ts +++ b/src/app/shared/pipes/safe.pipe.spec.ts @@ -1,10 +1,12 @@ -import { DomSanitizer } from '@angular/platform-browser'; import { SafePipe } from './safe.pipe'; + +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('SafePipe', () => { let sanitizer: any; beforeEach(() => { - sanitizer = null; + sanitizer = {}; }); it('create an instance', () => { diff --git a/src/app/shared/pipes/safe.pipe.ts b/src/app/shared/pipes/safe.pipe.ts index a2c215576..df6b110ff 100644 --- a/src/app/shared/pipes/safe.pipe.ts +++ b/src/app/shared/pipes/safe.pipe.ts @@ -16,8 +16,9 @@ export class SafePipe implements PipeTransform { constructor(protected sanitizer: DomSanitizer) {} transform( + // eslint-disable-next-line @typescript-eslint/no-explicit-any value: any, - type: string + type: string, ): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl { switch (type) { case 'html': diff --git a/src/app/shared/services/apprenticeship-contracts-rest.service.spec.ts b/src/app/shared/services/apprenticeship-contracts-rest.service.spec.ts deleted file mode 100644 index 9343de041..000000000 --- a/src/app/shared/services/apprenticeship-contracts-rest.service.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { ApprenticeshipContractsRestService } from './apprenticeship-contracts-rest.service'; -import { buildTestModuleMetadata } from 'src/spec-helpers'; - -describe('ApprenticeshipContractsRestService', () => { - beforeEach(() => TestBed.configureTestingModule(buildTestModuleMetadata({}))); - - it('should be created', () => { - const service: ApprenticeshipContractsRestService = TestBed.inject( - ApprenticeshipContractsRestService - ); - expect(service).toBeTruthy(); - }); -}); diff --git a/src/app/shared/services/apprenticeship-contracts-rest.service.ts b/src/app/shared/services/apprenticeship-contracts-rest.service.ts deleted file mode 100644 index 8d61921c5..000000000 --- a/src/app/shared/services/apprenticeship-contracts-rest.service.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Injectable, Inject } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { SETTINGS, Settings } from '../../settings'; -import { RestService } from './rest.service'; -import { ApprenticeshipContract } from '../models/apprenticeship-contract.model'; - -@Injectable({ - providedIn: 'root', -}) -export class ApprenticeshipContractsRestService extends RestService< - typeof ApprenticeshipContract -> { - constructor(http: HttpClient, @Inject(SETTINGS) settings: Settings) { - super(http, settings, ApprenticeshipContract, 'ApprenticeshipContracts'); - } -} diff --git a/src/app/shared/services/confirm-absences-selection.service.spec.ts b/src/app/shared/services/confirm-absences-selection.service.spec.ts index d3fec4fe9..d925cc3b2 100644 --- a/src/app/shared/services/confirm-absences-selection.service.spec.ts +++ b/src/app/shared/services/confirm-absences-selection.service.spec.ts @@ -7,6 +7,8 @@ import { ConfirmAbsencesSelectionService } from './confirm-absences-selection.se import { LessonPresence } from 'src/app/shared/models/lesson-presence.model'; import { OpenAbsencesEntry } from 'src/app/open-absences/models/open-absences-entry.model'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('ConfirmAbsencesSelectionService', () => { let service: ConfirmAbsencesSelectionService; let presenceA: LessonPresence; @@ -20,7 +22,7 @@ describe('ConfirmAbsencesSelectionService', () => { beforeEach(() => { TestBed.configureTestingModule( - buildTestModuleMetadata({ providers: [ConfirmAbsencesSelectionService] }) + buildTestModuleMetadata({ providers: [ConfirmAbsencesSelectionService] }), ); service = TestBed.inject(ConfirmAbsencesSelectionService); diff --git a/src/app/shared/services/courses-rest.service.spec.ts b/src/app/shared/services/courses-rest.service.spec.ts index 217ab9761..0a599d450 100644 --- a/src/app/shared/services/courses-rest.service.spec.ts +++ b/src/app/shared/services/courses-rest.service.spec.ts @@ -12,6 +12,8 @@ import { } from '../models/course.model'; import { CoursesRestService } from './courses-rest.service'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('CoursesRestService', () => { let service: CoursesRestService; let httpTestingController: HttpTestingController; @@ -38,7 +40,7 @@ describe('CoursesRestService', () => { (req) => req.url === 'https://eventotest.api/Courses/?expand=EvaluationStatusRef,AttendanceRef,Classes,FinalGrades&filter.StatusId=;14030;14025;14017;14020;10350;10335;10355;10315;10330;1032510320;10340;10345;10230;10225;10240;10260;10217;10235;10220;10226;10227;10250;10300' && - req.headers.get('X-Role-Restriction') === 'TeacherRole' + req.headers.get('X-Role-Restriction') === 'TeacherRole', ) .flush(data); }); @@ -55,7 +57,7 @@ describe('CoursesRestService', () => { (req) => req.url === 'https://eventotest.api/Courses/?expand=EvaluationStatusRef,AttendanceRef,Classes,FinalGrades&filter.StatusId=;14030;14025;14017;14020;10350;10335;10355;10315;10330;1032510320;10340;10345;10230;10225;10240;10260;10217;10235;10220;10226;10227;10250;10300' && - req.headers.get('X-Role-Restriction') === 'TeacherRole' + req.headers.get('X-Role-Restriction') === 'TeacherRole', ); }); @@ -70,7 +72,7 @@ describe('CoursesRestService', () => { .expectOne( (req) => req.url === - `https://eventotest.api/Courses/${id}?expand=ParticipatingStudents,EvaluationStatusRef,Tests,Gradings,FinalGrades,Classes` + `https://eventotest.api/Courses/${id}?expand=ParticipatingStudents,EvaluationStatusRef,Tests,Gradings,FinalGrades,Classes`, ) .flush(Course.encode(mockCourse)); }); @@ -86,7 +88,7 @@ describe('CoursesRestService', () => { .expectOne( (req) => req.url === - 'https://eventotest.api/Courses/?expand=Tests,Gradings,FinalGrades,EvaluationStatusRef,ParticipatingStudents,Classes&filter.StatusId=;14030;14025;14017;14020;10350;10335;10355;10315;10330;1032510320;10340;10345;10230;10225;10240;10260;10217;10235;10220;10226;10227;10250;10300' + 'https://eventotest.api/Courses/?expand=Tests,Gradings,FinalGrades,EvaluationStatusRef,ParticipatingStudents,Classes&filter.StatusId=;14030;14025;14017;14020;10350;10335;10355;10315;10330;1032510320;10340;10345;10230;10225;10240;10260;10217;10235;10220;10226;10227;10250;10300', ) .flush(data); }); @@ -109,7 +111,7 @@ describe('CoursesRestService', () => { 33, false, 44, - 55 + 55, ) .subscribe(); @@ -128,7 +130,7 @@ describe('CoursesRestService', () => { MaxPointsAdjusted: 55, }, ], - }) + }), ); expect().nothing(); @@ -147,7 +149,7 @@ describe('CoursesRestService', () => { 33, false, null, - null + null, ) .subscribe(); @@ -168,7 +170,7 @@ describe('CoursesRestService', () => { MaxPointsAdjusted: null, }, ], - }) + }), ); expect().nothing(); @@ -190,7 +192,7 @@ describe('CoursesRestService', () => { `https://eventotest.api/Courses/${courseId}/Tests/Delete` && isEqual(req.body, { TestIds: [testId], - }) + }), ) .flush(testId); }); @@ -212,7 +214,7 @@ describe('CoursesRestService', () => { url === `https://eventotest.api/Courses/PublishTest` && isEqual(body, { TestIds: [testId], - }) + }), ) .flush(testId); }); @@ -234,7 +236,7 @@ describe('CoursesRestService', () => { url === `https://eventotest.api/Courses/UnpublishTest` && isEqual(body, { TestIds: [testId], - }) + }), ) .flush(testId); }); @@ -271,12 +273,12 @@ describe('CoursesRestService', () => { }); describe('manage grades', () => { - let averageTestResultResponse: AverageTestResultResponse = { + const averageTestResultResponse: AverageTestResultResponse = { Gradings: [], }; it('PUT: SetAverageTestResult, should set student average as final grade', () => { - let requestBody = { CourseIds: [1234] }; + const requestBody = { CourseIds: [1234] }; service.setAverageAsFinalGrade(requestBody).subscribe((result) => { expect(result).toEqual(averageTestResultResponse); @@ -287,7 +289,7 @@ describe('CoursesRestService', () => { ({ method, url, body }) => method === 'PUT' && url === 'https://eventotest.api/Courses/SetAverageTestResult' && - isEqual(body, requestBody) + isEqual(body, requestBody), ) .flush(averageTestResultResponse); }); @@ -295,7 +297,7 @@ describe('CoursesRestService', () => { function updateTestResult( requestBody: TestPointsResult | TestGradesResult, - responseBody: UpdatedTestResultResponse + responseBody: UpdatedTestResultResponse, ) { service .updateTestResult(buildCourse(1).Id, requestBody) @@ -304,14 +306,14 @@ describe('CoursesRestService', () => { function assertRequestAndFlush( requestBody: TestPointsResult | TestGradesResult, - responseBody: UpdatedTestResultResponse + responseBody: UpdatedTestResultResponse, ) { httpTestingController .expectOne( ({ method, url, body }) => method === 'PUT' && url === `https://eventotest.api/Courses/1/SetTestResult` && - isEqual(body, requestBody) + isEqual(body, requestBody), ) .flush(responseBody); } diff --git a/src/app/shared/services/dossier-grades.service.spec.ts b/src/app/shared/services/dossier-grades.service.spec.ts index 1b7e3ae05..fd00bd6ec 100644 --- a/src/app/shared/services/dossier-grades.service.spec.ts +++ b/src/app/shared/services/dossier-grades.service.spec.ts @@ -11,25 +11,18 @@ import { buildTestModuleMetadata } from 'src/spec-helpers'; import { Course, FinalGrading, Grading } from '../models/course.model'; import { CoursesRestService } from './courses-rest.service'; import { DossierGradesService } from './dossier-grades.service'; -import { GradingScalesRestService } from './grading-scales-rest.service'; import { StorageService } from './storage.service'; import { Grade } from '../models/grading-scale.model'; describe('DossierGradesService', () => { let service: DossierGradesService; let coursesRestService: jasmine.SpyObj; - let gradingScalesRestService: jasmine.SpyObj; beforeEach(() => { coursesRestService = jasmine.createSpyObj('CoursesRestService', [ 'getExpandedCoursesForDossier', ]); - gradingScalesRestService = jasmine.createSpyObj( - 'GradingScalesRestService', - ['getGradingScale'] - ); - TestBed.configureTestingModule( buildTestModuleMetadata({ providers: [ @@ -40,7 +33,7 @@ describe('DossierGradesService', () => { useValue: jasmine.createSpyObj('StorageService', ['getPayload']), }, ], - }) + }), ); service = TestBed.inject(DossierGradesService); }); @@ -72,7 +65,7 @@ describe('DossierGradesService', () => { const courses = [course1, course2, course3]; coursesRestService.getExpandedCoursesForDossier.and.returnValue( - of(courses) + of(courses), ); let result: Course[] = []; @@ -81,7 +74,8 @@ describe('DossierGradesService', () => { service.setStudentId(11); expect(result.length).toBe(2); - expect(result).toContain(course1, course3); + expect(result).toContain(course1); + expect(result).toContain(course3); }); }); @@ -119,7 +113,7 @@ describe('DossierGradesService', () => { const studentId = -1; expect( - service.getFinalGradeForStudent(course, studentId) + service.getFinalGradeForStudent(course, studentId), ).toBeUndefined(); }); @@ -133,7 +127,7 @@ describe('DossierGradesService', () => { const studentId = expectedFinalGrading.StudentId; expect(service.getFinalGradeForStudent(course, studentId)).toEqual( - expectedFinalGrading + expectedFinalGrading, ); }); @@ -141,7 +135,7 @@ describe('DossierGradesService', () => { const studentId = expectedGrading.StudentId; expect(service.getGradingForStudent(course, studentId)).toEqual( - expectedGrading + expectedGrading, ); }); }); diff --git a/src/app/shared/services/dossier-grades.service.ts b/src/app/shared/services/dossier-grades.service.ts index e56dc34be..ed4e7c8d7 100644 --- a/src/app/shared/services/dossier-grades.service.ts +++ b/src/app/shared/services/dossier-grades.service.ts @@ -21,9 +21,8 @@ import { LoadingService } from './loading-service'; import { ReportsService } from './reports.service'; import { SubscriptionsRestService } from './subscriptions-rest.service'; import { gradingScaleOfTest, resultOfStudent } from '../../events/utils/tests'; -import { FinalGrade } from '../models/student-grades'; -import { average, ValueWithWeight, weightedAverage } from '../utils/math'; -import { startWith, withLatestFrom } from 'rxjs/operators'; +import { ValueWithWeight } from '../utils/math'; +import { withLatestFrom } from 'rxjs/operators'; @Injectable() export class DossierGradesService { @@ -35,25 +34,25 @@ export class DossierGradesService { distinctUntilChanged(), switchMap(this.loadCourses.bind(this)), map((courses) => - courses.sort((c1, c2) => c1.Designation.localeCompare(c2.Designation)) + courses.sort((c1, c2) => c1.Designation.localeCompare(c2.Designation)), ), - shareReplay(1) + shareReplay(1), ); private updatedStudentCourses$ = this.updateTest$.pipe( withLatestFrom(this.initialStudentCourses$), - map(([test, courses]) => this.updateCourses(courses, test)) + map(([test, courses]) => this.updateCourses(courses, test)), ); studentCourses$ = merge( this.initialStudentCourses$, - this.updatedStudentCourses$ + this.updatedStudentCourses$, ).pipe(shareReplay(1)); loading$ = this.loadingService.loading$; private studentCourseIds$ = this.studentCourses$.pipe( - map((courses: Course[]) => courses.flatMap((course) => course.Id)) + map((courses: Course[]) => courses.flatMap((course) => course.Id)), ); private idSubscriptions$ = combineLatest([ @@ -63,22 +62,22 @@ export class DossierGradesService { switchMap(([studentId, courseIds]) => this.subscriptionRestService.getIdSubscriptionsByStudentAndCourse( studentId, - courseIds - ) - ) + courseIds, + ), + ), ); private ids$ = this.idSubscriptions$.pipe( - map((subscriptions) => subscriptions.map((s) => s.Id)) + map((subscriptions) => subscriptions.map((s) => s.Id)), ); testReportUrl$ = this.ids$.pipe( map((ids) => this.reportsService.getSubscriptionReportUrl( this.settings.testsBySubscriptionReportIdTeacher, - ids - ) - ) + ids, + ), + ), ); constructor( @@ -87,7 +86,7 @@ export class DossierGradesService { private reportsService: ReportsService, private loadingService: LoadingService, private gradingScalesRestService: GradingScalesRestService, - @Inject(SETTINGS) private settings: Settings + @Inject(SETTINGS) private settings: Settings, ) {} setStudentId(id: number) { @@ -96,10 +95,10 @@ export class DossierGradesService { getFinalGradeForStudent( course: Course, - studentId: number + studentId: number, ): FinalGrading | undefined { return course?.FinalGrades?.find( - (finaleGrade) => finaleGrade.StudentId === studentId + (finaleGrade) => finaleGrade.StudentId === studentId, ); } @@ -109,22 +108,22 @@ export class DossierGradesService { getGradingScaleOfCourse(course: Course, gradingScales: GradingScale[]) { return gradingScales?.find( - (gradingScale) => gradingScale.Id === course.GradingScaleId + (gradingScale) => gradingScale.Id === course.GradingScaleId, ); } getGradesForStudent( course: Course, studentId: number, - gradingScales: GradingScale[] + gradingScales: GradingScale[], ): ValueWithWeight[] { return ( course.Tests?.flatMap((test) => { const grade = Number( gradingScaleOfTest(test, gradingScales)?.Grades.find( (grade: Grade) => - grade.Id === resultOfStudent(studentId, test)?.GradeId - )?.Designation + grade.Id === resultOfStudent(studentId, test)?.GradeId, + )?.Designation, ); return { @@ -141,13 +140,14 @@ export class DossierGradesService { .getExpandedCoursesForDossier() .pipe( map((courses) => - courses.filter((course) => - course.ParticipatingStudents?.find( - (student) => student.Id === studentId - ) - ) - ) - ) + courses.filter( + (course) => + course.ParticipatingStudents?.find( + (student) => student.Id === studentId, + ), + ), + ), + ), ); } @@ -157,16 +157,16 @@ export class DossierGradesService { private tests$ = this.studentCourses$.pipe( map((courses: Course[]) => - courses.flatMap((course: Course) => course.Tests).filter(notNull) - ) + courses.flatMap((course: Course) => course.Tests).filter(notNull), + ), ); private gradingScaleIdsFromTests$ = this.tests$.pipe( map((tests: Test[]) => [...tests.map((test: Test) => test.GradingScaleId)] .filter(notNull) - .filter(unique) - ) + .filter(unique), + ), ); private gradingScaleIdsFromCourses$ = this.studentCourses$.pipe( @@ -174,8 +174,8 @@ export class DossierGradesService { courses .flatMap((course: Course) => course.GradingScaleId) .filter(notNull) - .filter(unique) - ) + .filter(unique), + ), ); private gradingScaleIds$ = combineLatest([ @@ -183,18 +183,18 @@ export class DossierGradesService { this.gradingScaleIdsFromTests$, ]).pipe( map(([courseGradingsScaleIds, testGradingScaleIds]: [number[], number[]]) => - courseGradingsScaleIds.concat(testGradingScaleIds).filter(unique) - ) + courseGradingsScaleIds.concat(testGradingScaleIds).filter(unique), + ), ); gradingScales$ = this.gradingScaleIds$.pipe( switchMap((ids) => forkJoin( ids.map((id: number) => - this.gradingScalesRestService.getGradingScale(id) - ) - ) - ) + this.gradingScalesRestService.getGradingScale(id), + ), + ), + ), ); private updateCourses(courses: Course[], updatedTest: Test): Course[] { @@ -203,7 +203,7 @@ export class DossierGradesService { Tests: course.Tests !== null ? course.Tests.map((test) => - test.Id === updatedTest.Id ? updatedTest : test + test.Id === updatedTest.Id ? updatedTest : test, ) : null, })); diff --git a/src/app/shared/services/events-rest.service.spec.ts b/src/app/shared/services/events-rest.service.spec.ts index 8245212a9..545ade867 100644 --- a/src/app/shared/services/events-rest.service.spec.ts +++ b/src/app/shared/services/events-rest.service.spec.ts @@ -4,6 +4,8 @@ import { buildTestModuleMetadata } from '../../../spec-helpers'; import { EventsRestService } from './events-rest.service'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('EventsRestService', () => { let service: EventsRestService; let httpTestingController: HttpTestingController; @@ -15,9 +17,8 @@ describe('EventsRestService', () => { }); describe('.getSubscriptionDetailsDefinitions', () => { - const data: any[] = []; - it('gets the list of subscription details definitions for the given event id', () => { + const data: any[] = []; const url = 'https://eventotest.api/Events/1234/SubscriptionDetails'; service diff --git a/src/app/shared/services/legal-representatives-rest.service.spec.ts b/src/app/shared/services/legal-representatives-rest.service.spec.ts deleted file mode 100644 index 990d49e1c..000000000 --- a/src/app/shared/services/legal-representatives-rest.service.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { LegalRepresentativesRestService } from './legal-representatives-rest.service'; -import { buildTestModuleMetadata } from 'src/spec-helpers'; - -describe('LegalRepresentativesRestService', () => { - beforeEach(() => TestBed.configureTestingModule(buildTestModuleMetadata({}))); - - it('should be created', () => { - const service: LegalRepresentativesRestService = TestBed.inject( - LegalRepresentativesRestService - ); - expect(service).toBeTruthy(); - }); -}); diff --git a/src/app/shared/services/legal-representatives-rest.service.ts b/src/app/shared/services/legal-representatives-rest.service.ts deleted file mode 100644 index 5a763ed37..000000000 --- a/src/app/shared/services/legal-representatives-rest.service.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injectable, Inject } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; - -import { RestService } from './rest.service'; -import { SETTINGS, Settings } from '../../settings'; -import { LegalRepresentative } from '../models/legal-representative.model'; - -@Injectable({ - providedIn: 'root', -}) -export class LegalRepresentativesRestService extends RestService< - typeof LegalRepresentative -> { - constructor(http: HttpClient, @Inject(SETTINGS) settings: Settings) { - super(http, settings, LegalRepresentative, 'LegalRepresentatives'); - } -} diff --git a/src/app/shared/services/lesson-absences-rest.service.spec.ts b/src/app/shared/services/lesson-absences-rest.service.spec.ts deleted file mode 100644 index 5c9ce2164..000000000 --- a/src/app/shared/services/lesson-absences-rest.service.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { buildTestModuleMetadata } from 'src/spec-helpers'; -import { LessonAbsencesRestService } from './lesson-absences-rest.service'; - -describe('LessonAbsencesRestService', () => { - beforeEach(() => TestBed.configureTestingModule(buildTestModuleMetadata({}))); - - it('should be created', () => { - const service: LessonAbsencesRestService = TestBed.inject( - LessonAbsencesRestService - ); - expect(service).toBeTruthy(); - }); -}); diff --git a/src/app/shared/services/lesson-absences-rest.service.ts b/src/app/shared/services/lesson-absences-rest.service.ts deleted file mode 100644 index 7a95dff5a..000000000 --- a/src/app/shared/services/lesson-absences-rest.service.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injectable, Inject } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; - -import { RestService } from './rest.service'; -import { SETTINGS, Settings } from '../../settings'; -import { LessonAbsence } from '../models/lesson-absence.model'; - -@Injectable({ - providedIn: 'root', -}) -export class LessonAbsencesRestService extends RestService< - typeof LessonAbsence -> { - constructor(http: HttpClient, @Inject(SETTINGS) settings: Settings) { - super(http, settings, LessonAbsence, 'LessonAbsences'); - } -} diff --git a/src/app/shared/services/lesson-dispensations-rest.service.spec.ts b/src/app/shared/services/lesson-dispensations-rest.service.spec.ts deleted file mode 100644 index 1d2ffcc57..000000000 --- a/src/app/shared/services/lesson-dispensations-rest.service.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { LessonDispensationsRestService } from './lesson-dispensations-rest.service'; -import { buildTestModuleMetadata } from 'src/spec-helpers'; - -describe('LessonDispensationsRestService', () => { - beforeEach(() => TestBed.configureTestingModule(buildTestModuleMetadata({}))); - - it('should be created', () => { - const service: LessonDispensationsRestService = TestBed.inject( - LessonDispensationsRestService - ); - expect(service).toBeTruthy(); - }); -}); diff --git a/src/app/shared/services/lesson-dispensations-rest.service.ts b/src/app/shared/services/lesson-dispensations-rest.service.ts deleted file mode 100644 index 6a2378a9d..000000000 --- a/src/app/shared/services/lesson-dispensations-rest.service.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injectable, Inject } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; - -import { RestService } from './rest.service'; -import { SETTINGS, Settings } from '../../settings'; -import { LessonDispensation } from '../models/lesson-dispensation.model'; - -@Injectable({ - providedIn: 'root', -}) -export class LessonDispensationsRestService extends RestService< - typeof LessonDispensation -> { - constructor(http: HttpClient, @Inject(SETTINGS) settings: Settings) { - super(http, settings, LessonDispensation, 'LessonDispensations'); - } -} diff --git a/src/app/shared/services/lesson-incidents-rest.service.spec.ts b/src/app/shared/services/lesson-incidents-rest.service.spec.ts deleted file mode 100644 index 0aa940269..000000000 --- a/src/app/shared/services/lesson-incidents-rest.service.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { LessonIncidentsRestService } from './lesson-incidents-rest.service'; -import { buildTestModuleMetadata } from 'src/spec-helpers'; - -describe('LessonIncidentsRestService', () => { - beforeEach(() => TestBed.configureTestingModule(buildTestModuleMetadata({}))); - - it('should be created', () => { - const service: LessonIncidentsRestService = TestBed.inject( - LessonIncidentsRestService - ); - expect(service).toBeTruthy(); - }); -}); diff --git a/src/app/shared/services/lesson-incidents-rest.service.ts b/src/app/shared/services/lesson-incidents-rest.service.ts deleted file mode 100644 index b0c54f21f..000000000 --- a/src/app/shared/services/lesson-incidents-rest.service.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injectable, Inject } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; - -import { SETTINGS, Settings } from '../../settings'; -import { RestService } from './rest.service'; -import { LessonIncident } from '../models/lesson-incident.model'; - -@Injectable({ - providedIn: 'root', -}) -export class LessonIncidentsRestService extends RestService< - typeof LessonIncident -> { - constructor(http: HttpClient, @Inject(SETTINGS) settings: Settings) { - super(http, settings, LessonIncident, 'LessonIncidents'); - } -} diff --git a/src/app/shared/services/lesson-presences-rest.service.spec.ts b/src/app/shared/services/lesson-presences-rest.service.spec.ts index f544cc5f1..6b3511bf6 100644 --- a/src/app/shared/services/lesson-presences-rest.service.spec.ts +++ b/src/app/shared/services/lesson-presences-rest.service.spec.ts @@ -12,6 +12,8 @@ import { buildLesson, buildLessonPresence } from 'src/spec-builders'; import { Sorting } from './sort.service'; import { format } from 'date-fns'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + const CLASS_TEACHER_TOKEN = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJvYXV0aCIsImF1ZCI6Imh0dHBzOi8vZGV2NDIwMC8iLCJuYmYiOjE1NjkzOTM5NDMsImV4cCI6MTU2OTQwODM0MywidG9rZW5fcHVycG9zZSI6IlVzZXIiLCJzY29wZSI6IlRlc3QiLCJjb25zdW1lcl9pZCI6ImRldiIsInVzZXJuYW1lIjoiam9obiIsImluc3RhbmNlX2lkIjoiVEVTVCIsImN1bHR1cmVfaW5mbyI6ImRlLUNIIiwicmVkaXJlY3RfdXJpIjoiaHR0cDovL2xvY2FsaG9zdDo0MjAwIiwiaWRfbWFuZGFudCI6IjEyMyIsImlkX3BlcnNvbiI6IjQ1NiIsImZ1bGxuYW1lIjoiSm9obiBEb2UiLCJyb2xlcyI6Ikxlc3NvblRlYWNoZXJSb2xlO0NsYXNzVGVhY2hlclJvbGUiLCJ0b2tlbl9pZCI6IjEyMzQ1NiJ9.erGO0ORYWA7LAjuWSrz924rkgC2Gqg6_Wu3GUZiMOyI'; @@ -33,10 +35,10 @@ describe('LessonPresencesRestService', () => { storeMock = {}; spyOn(localStorage, 'getItem').and.callFake( - (key: string) => storeMock[key] || null + (key: string) => storeMock[key] || null, ); spyOn(localStorage, 'setItem').and.callFake( - (key: string) => storeMock[key] || null + (key: string) => storeMock[key] || null, ); }); @@ -74,10 +76,10 @@ describe('LessonPresencesRestService', () => { it('decodes ISO date strings to date objects', () => { service.get(123).subscribe((result) => { expect(result.LessonDateTimeFrom).toEqual( - new Date('2019-04-25T07:45:00') + new Date('2019-04-25T07:45:00'), ); expect(result.LessonDateTimeTo).toEqual( - new Date('2019-04-25T08:30:00') + new Date('2019-04-25T08:30:00'), ); expect(result.Date).toEqual(new Date('2019-04-18T00:00:00')); }); @@ -98,21 +100,21 @@ describe('LessonPresencesRestService', () => { new Date(2000, 0, 23, 9, 0), new Date(2000, 0, 23, 10, 0), 'Mathematik', - '' + '', ), buildLesson( 2, new Date(2000, 0, 23, 10, 0), new Date(2000, 0, 23, 11, 0), 'Französisch', - '' + '', ), buildLesson( 3, new Date(2000, 0, 23, 11, 0), new Date(2000, 0, 23, 12, 0), 'Turnen', - '' + '', ), ]; @@ -129,10 +131,10 @@ describe('LessonPresencesRestService', () => { ...lesson, LessonDateTimeFrom: format( LessonDateTimeFrom, - "yyyy-MM-dd'T'HH:mm:ss" + "yyyy-MM-dd'T'HH:mm:ss", ), LessonDateTimeTo: format(LessonDateTimeTo, "yyyy-MM-dd'T'HH:mm:ss"), - })) + })), ); httpTestingController.verify(); @@ -208,7 +210,7 @@ describe('LessonPresencesRestService', () => { (req) => req.urlWithParams === lessonTeacherRequestUrl && req.headers.get('X-Role-Restriction') === 'LessonTeacherRole', - lessonTeacherRequestUrl + lessonTeacherRequestUrl, ) .flush(t.array(LessonPresence).encode([presence1])); @@ -233,30 +235,30 @@ describe('LessonPresencesRestService', () => { const calls = httpTestingController.match( (request) => request.urlWithParams === classTeacherRequestUrl || - request.urlWithParams === lessonTeacherRequestUrl + request.urlWithParams === lessonTeacherRequestUrl, ); expect(calls.length).toBe(2); const classTeacherRequest = calls.find( - (r) => r.request.urlWithParams === classTeacherRequestUrl + (r) => r.request.urlWithParams === classTeacherRequestUrl, ); expect(classTeacherRequest).toBeDefined(); expect( - classTeacherRequest?.request.headers.get('X-Role-Restriction') + classTeacherRequest?.request.headers.get('X-Role-Restriction'), ).toBe('ClassTeacherRole'); classTeacherRequest?.flush( - t.array(LessonPresence).encode([presence1, presence2]) + t.array(LessonPresence).encode([presence1, presence2]), ); const lessonTeacherRequest = calls.find( - (r) => r.request.urlWithParams === lessonTeacherRequestUrl + (r) => r.request.urlWithParams === lessonTeacherRequestUrl, ); expect(lessonTeacherRequest).toBeDefined(); expect( - lessonTeacherRequest?.request.headers.get('X-Role-Restriction') + lessonTeacherRequest?.request.headers.get('X-Role-Restriction'), ).toBe('LessonTeacherRole'); lessonTeacherRequest?.flush( - t.array(LessonPresence).encode([presence2, presence3]) + t.array(LessonPresence).encode([presence2, presence3]), ); }); }); @@ -277,7 +279,7 @@ describe('LessonPresencesRestService', () => { req.urlWithParams === absenceAdministratorRequestUrl && req.headers.get('X-Role-Restriction') === 'AbsenceAdministratorRole', - absenceAdministratorRequestUrl + absenceAdministratorRequestUrl, ) .flush(t.array(LessonPresence).encode([presence3])); diff --git a/src/app/shared/services/lesson-presences-update-rest.service.spec.ts b/src/app/shared/services/lesson-presences-update-rest.service.spec.ts index 6a8043c6e..065bf2762 100644 --- a/src/app/shared/services/lesson-presences-update-rest.service.spec.ts +++ b/src/app/shared/services/lesson-presences-update-rest.service.spec.ts @@ -5,6 +5,8 @@ import { buildTestModuleMetadata } from 'src/spec-helpers'; import { LessonPresencesUpdateRestService } from './lesson-presences-update-rest.service'; import { HttpTestingController } from '@angular/common/http/testing'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('LessonPresencesUpdateRestService', () => { let service: LessonPresencesUpdateRestService; let httpTestingController: HttpTestingController; @@ -109,12 +111,12 @@ describe('LessonPresencesUpdateRestService', () => { function expectRequestWithBody( url: string, body: any, - result: any = {} + result: any = {}, ): void { httpTestingController .expectOne( (req) => req.urlWithParams === url && isEqual(req.body, body), - url + url, ) .flush(result); } diff --git a/src/app/shared/services/lesson-presences-update-rest.service.ts b/src/app/shared/services/lesson-presences-update-rest.service.ts index ebc5592ff..d0476f1a1 100644 --- a/src/app/shared/services/lesson-presences-update-rest.service.ts +++ b/src/app/shared/services/lesson-presences-update-rest.service.ts @@ -11,7 +11,7 @@ import { SETTINGS, Settings } from 'src/app/settings'; export class LessonPresencesUpdateRestService { constructor( private http: HttpClient, - @Inject(SETTINGS) private settings: Settings + @Inject(SETTINGS) private settings: Settings, ) {} editLessonPresences( @@ -19,9 +19,9 @@ export class LessonPresencesUpdateRestService { personIds: ReadonlyArray, presenceTypeId?: Option, confirmationValue?: Option, - params?: HttpParams + params?: HttpParams, ): Observable { - const body: Dict = { + const body: Dict = { LessonIds: lessonIds, PersonIds: personIds, }; @@ -42,7 +42,7 @@ export class LessonPresencesUpdateRestService { removeLessonPresences( lessonIds: ReadonlyArray, personIds: ReadonlyArray, - params?: HttpParams + params?: HttpParams, ): Observable { return this.http .put( @@ -52,7 +52,7 @@ export class LessonPresencesUpdateRestService { PersonIds: personIds, WithComment: true, }, - { params } + { params }, ) .pipe(map(() => undefined)); } @@ -61,9 +61,9 @@ export class LessonPresencesUpdateRestService { lessonIds: ReadonlyArray, personIds: ReadonlyArray, absenceTypeId: number, - confirmationValue: number + confirmationValue: number, ): Observable { - const body: Dict = { + const body: Dict = { LessonIds: lessonIds, PersonIds: personIds, AbsenceTypeId: absenceTypeId, diff --git a/src/app/shared/services/lesson-presences-update.service.spec.ts b/src/app/shared/services/lesson-presences-update.service.spec.ts index 6d63de684..85f390fb0 100644 --- a/src/app/shared/services/lesson-presences-update.service.spec.ts +++ b/src/app/shared/services/lesson-presences-update.service.spec.ts @@ -39,10 +39,10 @@ describe('LessonPresencesUpdateService', () => { let entryDeutschWalser: PresenceControlEntry; let entryDeutschFrisch: PresenceControlEntry; - absent = buildPresenceType(11, true, false); - late = buildPresenceType(12, false, true); - beforeEach(() => { + absent = buildPresenceType(11, true, false); + late = buildPresenceType(12, false, true); + restServiceMock = { editLessonPresences: jasmine .createSpy('editLessonPresences') @@ -75,7 +75,7 @@ describe('LessonPresencesUpdateService', () => { { provide: PresenceTypesService, useValue: presenceTypeServiceMock }, { provide: ToastService, useValue: toastServiceMock }, ], - }) + }), ); service = TestBed.inject(LessonPresencesUpdateService); @@ -87,7 +87,7 @@ describe('LessonPresencesUpdateService', () => { new Date(2000, 0, 23, 7, 0), new Date(2000, 0, 23, 8, 0), 'Turnen', - 'Frisch Max' + 'Frisch Max', ); turnenFrisch.StudentRef = buildReference(10); @@ -98,7 +98,7 @@ describe('LessonPresencesUpdateService', () => { 'Deutsch', 'Einstein Albert', 'Dora Durrer', - absent.Id + absent.Id, ); deutschEinsteinAbwesend.StudentRef = buildReference(20); @@ -107,7 +107,7 @@ describe('LessonPresencesUpdateService', () => { new Date(2000, 0, 23, 8, 0), new Date(2000, 0, 23, 9, 0), 'Deutsch', - 'Frisch Max' + 'Frisch Max', ); deutschFrisch.StudentRef = buildReference(10); @@ -116,12 +116,12 @@ describe('LessonPresencesUpdateService', () => { new Date(2000, 0, 23, 8, 0), new Date(2000, 0, 23, 9, 0), 'Deutsch', - 'Walser Robert' + 'Walser Robert', ); deutschWalser.StudentRef = buildReference(30); entryDeutschEinsteinAbwesend = buildPresenceControlEntry( - deutschEinsteinAbwesend + deutschEinsteinAbwesend, ); entryDeutschWalser = buildPresenceControlEntry(deutschWalser); entryDeutschFrisch = buildPresenceControlEntry(deutschFrisch); @@ -168,7 +168,7 @@ describe('LessonPresencesUpdateService', () => { (stateUpdatesCallback as jasmine.Spy).calls.reset(); tick(UPDATE_REQUEST_DEBOUNCE_TIME); expect( - (restServiceMock.editLessonPresences as jasmine.Spy).calls.count() + (restServiceMock.editLessonPresences as jasmine.Spy).calls.count(), ).toBe(1); expect(restServiceMock.editLessonPresences).toHaveBeenCalledWith( [deutschEinsteinAbwesend.LessonRef.Id], @@ -179,7 +179,7 @@ describe('LessonPresencesUpdateService', () => { ], late.Id, undefined, - withConfig({ disableErrorHandling: true }) + withConfig({ disableErrorHandling: true }), ); expect(restServiceMock.removeLessonPresences).not.toHaveBeenCalled(); expect(stateUpdatesCallback).not.toHaveBeenCalled(); @@ -203,12 +203,12 @@ describe('LessonPresencesUpdateService', () => { return throwError(() => 'error thrown in mock'); } return of(); - } + }, ); // Change Einstein & Frisch to 'late', Walser to 'absent' [entryDeutschEinsteinAbwesend, entryDeutschFrisch].forEach((entry) => - service.updatePresenceType(entry, late.Id) + service.updatePresenceType(entry, late.Id), ); service.updatePresenceType(entryDeutschWalser, absent.Id); @@ -230,21 +230,21 @@ describe('LessonPresencesUpdateService', () => { (stateUpdatesCallback as jasmine.Spy).calls.reset(); tick(UPDATE_REQUEST_DEBOUNCE_TIME); expect( - (restServiceMock.editLessonPresences as jasmine.Spy).calls.count() + (restServiceMock.editLessonPresences as jasmine.Spy).calls.count(), ).toBe(2); expect(restServiceMock.editLessonPresences).toHaveBeenCalledWith( [deutschEinsteinAbwesend.LessonRef.Id], [deutschEinsteinAbwesend.StudentRef.Id, deutschFrisch.StudentRef.Id], late.Id, undefined, - withConfig({ disableErrorHandling: true }) + withConfig({ disableErrorHandling: true }), ); expect(restServiceMock.removeLessonPresences).not.toHaveBeenCalled(); expect(stateUpdatesCallback).toHaveBeenCalledWith([ { presence: deutschWalser, newPresenceTypeId: 123 }, ]); expect(toastServiceMock.error).toHaveBeenCalledWith( - 'shared.lesson-presences-update.error' + 'shared.lesson-presences-update.error', ); // Nothing happens afterwards @@ -276,12 +276,12 @@ describe('LessonPresencesUpdateService', () => { tick(UPDATE_REQUEST_DEBOUNCE_TIME); expect(restServiceMock.editLessonPresences).not.toHaveBeenCalled(); expect( - (restServiceMock.removeLessonPresences as jasmine.Spy).calls.count() + (restServiceMock.removeLessonPresences as jasmine.Spy).calls.count(), ).toBe(1); expect(restServiceMock.removeLessonPresences).toHaveBeenCalledWith( [deutschEinsteinAbwesend.LessonRef.Id], [deutschEinsteinAbwesend.StudentRef.Id], - withConfig({ disableErrorHandling: true }) + withConfig({ disableErrorHandling: true }), ); expect(stateUpdatesCallback).not.toHaveBeenCalled(); diff --git a/src/app/shared/services/lesson-presences-update.service.ts b/src/app/shared/services/lesson-presences-update.service.ts index 127918b15..9adc77f84 100644 --- a/src/app/shared/services/lesson-presences-update.service.ts +++ b/src/app/shared/services/lesson-presences-update.service.ts @@ -71,9 +71,9 @@ export class LessonPresencesUpdateService implements OnDestroy { private pendingUpdates$ = this.action$.pipe( scan( this.reduceUpdates.bind(this), - [] as ReadonlyArray + [] as ReadonlyArray, ), - share() + share(), ); private revertUpdates$ = new Subject>(); @@ -81,13 +81,13 @@ export class LessonPresencesUpdateService implements OnDestroy { private performUpdates$ = this.pendingUpdates$.pipe( debounceTime(UPDATE_REQUEST_DEBOUNCE_TIME), filter(not(isEmptyArray)), - concatMap(this.performUpdates.bind(this)) // Execute each request after another to not DOS the backend + concatMap(this.performUpdates.bind(this)), // Execute each request after another to not DOS the backend ); // Update the UI state right-away (latency-compensation) stateUpdates$ = merge(this.pendingUpdates$, this.revertUpdates$).pipe( debounceTime(UPDATE_STATE_DEBOUNCE_TIME), // Ensure removing of multiple items causes one event - filter(not(isEmptyArray)) + filter(not(isEmptyArray)), ); constructor( @@ -95,7 +95,7 @@ export class LessonPresencesUpdateService implements OnDestroy { private translate: TranslateService, private restService: LessonPresencesUpdateRestService, private presenceTypesService: PresenceTypesService, - @Inject(SETTINGS) private settings: Settings + @Inject(SETTINGS) private settings: Settings, ) { this.performUpdates$.pipe(takeUntil(this.destroy$)).subscribe(); } @@ -106,16 +106,16 @@ export class LessonPresencesUpdateService implements OnDestroy { updatePresenceType( selectedPresenceControlEntry: PresenceControlEntry, - newPresenceTypeId: Option = null + newPresenceTypeId: Option = null, ): void { this.dispatchAddUpdate( selectedPresenceControlEntry.lessonPresence, - newPresenceTypeId + newPresenceTypeId, ); } private performUpdates( - updates: ReadonlyArray + updates: ReadonlyArray, ): Observable { const groupedUpdates = this.groupUpdates(updates); return combineLatest( @@ -126,7 +126,7 @@ export class LessonPresencesUpdateService implements OnDestroy { result.push(this.performUpdateForGroup(lessonGroup)); }); return result; - }, [] as Observable[]) + }, [] as Observable[]), ).pipe(map(() => groupedUpdates)); } @@ -135,7 +135,7 @@ export class LessonPresencesUpdateService implements OnDestroy { * from the same lesson. */ private performUpdateForGroup( - updates: ReadonlyArray + updates: ReadonlyArray, ): Observable { // Remove (i.e. consume) entries from pending updates queue updates.forEach((u) => this.dispatchRemoveUpdate(u.presence)); @@ -144,7 +144,7 @@ export class LessonPresencesUpdateService implements OnDestroy { return this.performLessonPresencesUpdatesByIds( updates[0].presence.LessonRef.Id, updates.map((u) => u.presence.StudentRef.Id), - updates[0].newPresenceTypeId + updates[0].newPresenceTypeId, ).pipe(catchError((error) => this.revertUpdatesAfterError(updates, error))); } @@ -156,7 +156,7 @@ export class LessonPresencesUpdateService implements OnDestroy { private performLessonPresencesUpdatesByIds( lessonId: number, personIds: ReadonlyArray, - newPresenceTypeId: Option = null + newPresenceTypeId: Option = null, ): Observable { if (newPresenceTypeId) { const presenceType$: Observable> = newPresenceTypeId @@ -169,27 +169,27 @@ export class LessonPresencesUpdateService implements OnDestroy { personIds, type?.Id, getNewConfirmationStateId(type, this.settings) || undefined, - withConfig({ disableErrorHandling: true }) - ) - ) + withConfig({ disableErrorHandling: true }), + ), + ), ); } return this.restService.removeLessonPresences( [lessonId], personIds, - withConfig({ disableErrorHandling: true }) + withConfig({ disableErrorHandling: true }), ); } private revertUpdatesAfterError( updates: ReadonlyArray, - error: any + error: unknown, ): Observable { console.error('Bulk-update of lesson presences failed'); console.error(error); this.toastService.error( - this.translate.instant('shared.lesson-presences-update.error') + this.translate.instant('shared.lesson-presences-update.error'), ); // Revert UI back to it's original state @@ -197,7 +197,7 @@ export class LessonPresencesUpdateService implements OnDestroy { updates.map((u) => ({ ...u, newPresenceTypeId: u.presence.TypeRef.Id, - })) + })), ); return of(undefined); } @@ -206,11 +206,11 @@ export class LessonPresencesUpdateService implements OnDestroy { * Groups the updates array first by presence type, then by lesson. */ private groupUpdates( - updates: ReadonlyArray + updates: ReadonlyArray, ): GroupedLessonPresenceUpdates { return updates.reduce((grouped, update) => { const presenceTypeId = String( - update.newPresenceTypeId && update.newPresenceTypeId + update.newPresenceTypeId && update.newPresenceTypeId, ); if (!grouped[presenceTypeId]) { grouped[presenceTypeId] = {}; @@ -232,10 +232,10 @@ export class LessonPresencesUpdateService implements OnDestroy { */ private reduceUpdates( updates: ReadonlyArray, - action: UpdateAction + action: UpdateAction, ): ReadonlyArray { switch (action.type) { - case UpdateActionTypes.AddUpdateAction: + case UpdateActionTypes.AddUpdateAction: { const { presence, newPresenceTypeId } = action.payload; const index = updates.findIndex(equalsUpdate(presence)); if (index === -1) { @@ -246,6 +246,7 @@ export class LessonPresencesUpdateService implements OnDestroy { { presence: updates[index].presence, newPresenceTypeId }, ...updates.slice(index + 1), ]; + } case UpdateActionTypes.RemoveUpdateAction: return updates.filter(not(equalsUpdate(action.payload))); default: @@ -255,7 +256,7 @@ export class LessonPresencesUpdateService implements OnDestroy { private dispatchAddUpdate( presence: LessonPresence, - newPresenceTypeId: Option + newPresenceTypeId: Option, ): void { this.action$.next({ type: UpdateActionTypes.AddUpdateAction, @@ -272,7 +273,7 @@ export class LessonPresencesUpdateService implements OnDestroy { } function equalsUpdate( - lessonPresence: LessonPresence + lessonPresence: LessonPresence, ): (update: LessonPresenceUpdate) => boolean { return (update) => update.presence.LessonRef.Id === lessonPresence.LessonRef.Id && diff --git a/src/app/shared/services/presence-types.service.spec.ts b/src/app/shared/services/presence-types.service.spec.ts index 822efca4f..09664d6c6 100644 --- a/src/app/shared/services/presence-types.service.spec.ts +++ b/src/app/shared/services/presence-types.service.spec.ts @@ -1,7 +1,6 @@ import { TestBed } from '@angular/core/testing'; import { HttpTestingController } from '@angular/common/http/testing'; import * as t from 'io-ts/lib/index'; -import { skip, take } from 'rxjs/operators'; import { buildTestModuleMetadata } from 'src/spec-helpers'; import { PresenceTypesService } from './presence-types.service'; @@ -208,7 +207,7 @@ describe('PresenceTypesService', () => { military, other, comment, - ]) + ]), ); httpTestingController.verify(); diff --git a/src/app/shared/services/presence-types.service.ts b/src/app/shared/services/presence-types.service.ts index 17e3f1f79..c43315568 100644 --- a/src/app/shared/services/presence-types.service.ts +++ b/src/app/shared/services/presence-types.service.ts @@ -1,5 +1,5 @@ import { Injectable, Inject } from '@angular/core'; -import { Observable, throwError } from 'rxjs'; +import { Observable } from 'rxjs'; import { shareReplay, map, @@ -28,7 +28,7 @@ export class PresenceTypesService { */ activePresenceTypes$ = this.presenceTypes$.pipe( map(this.filterActiveTypes.bind(this)), - shareReplay(1) + shareReplay(1), ); /** @@ -36,7 +36,7 @@ export class PresenceTypesService { */ confirmationTypes$ = this.presenceTypes$.pipe( map(this.filterConfirmationTypes.bind(this)), - shareReplay(1) + shareReplay(1), ); /** @@ -44,7 +44,7 @@ export class PresenceTypesService { */ incidentTypes$ = this.presenceTypes$.pipe( map(this.filterIncidentTypes.bind(this)), - shareReplay(1) + shareReplay(1), ); /** @@ -53,7 +53,7 @@ export class PresenceTypesService { */ displayedTypes$ = this.presenceTypes$.pipe( map(this.filterDisplayedTypes.bind(this)), - shareReplay(1) + shareReplay(1), ); /** @@ -63,12 +63,12 @@ export class PresenceTypesService { map(this.isHalfDayActive.bind(this)), startWith(false), distinctUntilChanged(), - shareReplay(1) + shareReplay(1), ); constructor( private restService: PresenceTypesRestService, - @Inject(SETTINGS) private settings: Settings + @Inject(SETTINGS) private settings: Settings, ) {} public getPresenceType(id: number): Observable { @@ -79,7 +79,7 @@ export class PresenceTypesService { throw new Error('presence type not found'); } return type; - }) + }), ); } @@ -88,40 +88,40 @@ export class PresenceTypesService { } private filterActiveTypes( - presenceTypes: ReadonlyArray + presenceTypes: ReadonlyArray, ): ReadonlyArray { return presenceTypes.filter((t) => t.Active); } private filterConfirmationTypes( - presenceTypes: ReadonlyArray + presenceTypes: ReadonlyArray, ): ReadonlyArray { return presenceTypes.filter( (t) => t.NeedsConfirmation && t.Active && - t.Id !== this.settings.absencePresenceTypeId + t.Id !== this.settings.absencePresenceTypeId, ); } private filterIncidentTypes( - presenceTypes: ReadonlyArray + presenceTypes: ReadonlyArray, ): ReadonlyArray { return presenceTypes.filter((t) => t.IsIncident && t.Active); } private filterDisplayedTypes( - presenceTypes: ReadonlyArray + presenceTypes: ReadonlyArray, ): ReadonlyArray { return presenceTypes.filter( - (t) => t.Id !== this.settings.absencePresenceTypeId + (t) => t.Id !== this.settings.absencePresenceTypeId, ); } private isHalfDayActive(presenceTypes: ReadonlyArray): boolean { return Boolean( presenceTypes.find((t) => t.Id === this.settings.halfDayPresenceTypeId) - ?.Active + ?.Active, ); } } diff --git a/src/app/shared/services/rest.service.ts b/src/app/shared/services/rest.service.ts index 787466b43..38a5c6ba2 100644 --- a/src/app/shared/services/rest.service.ts +++ b/src/app/shared/services/rest.service.ts @@ -17,12 +17,13 @@ export const enum HTTP_STATUS { GATEWAY_TIMEOUT = 504, } +// eslint-disable-next-line @typescript-eslint/no-explicit-any export abstract class RestService> { constructor( protected http: HttpClient, protected settings: Settings, protected codec: T, - protected resourcePath: string + protected resourcePath: string, ) {} get( @@ -30,7 +31,7 @@ export abstract class RestService> { options?: { headers?: HttpHeaders | Dict; params?: HttpParams | Dict; - } + }, ): Observable> { return this.http .get(`${this.baseUrl}/${id}`, options) diff --git a/src/app/shared/services/scroll-position.service.ts b/src/app/shared/services/scroll-position.service.ts index c81d18a76..3877fc73a 100644 --- a/src/app/shared/services/scroll-position.service.ts +++ b/src/app/shared/services/scroll-position.service.ts @@ -68,7 +68,7 @@ export class ScrollPositionService implements OnDestroy { // "old" component is still correctly rendered private scrollPosition$ = this.router.events.pipe( filter(isNavigationStart), - map(this.getScrollPosition.bind(this)) + map(this.getScrollPosition.bind(this)), ); private activationEnd$ = this.router.events.pipe(filter(isActivationEnd)); @@ -80,17 +80,17 @@ export class ScrollPositionService implements OnDestroy { mergeMap((first) => [ of(first), this.navigationEnd$.pipe( - switchMap(() => this.activationEnd$.pipe(take(1))) + switchMap(() => this.activationEnd$.pipe(take(1))), ), ]), switchAll(), map((event) => event.snapshot), - shareReplay(1) + shareReplay(1), ); constructor( private router: Router, - private viewportScroller: ViewportScroller + private viewportScroller: ViewportScroller, ) { this.scrollPosition$ .pipe(takeUntil(this.destroy$)) @@ -128,7 +128,7 @@ export class ScrollPositionService implements OnDestroy { skip(1), take(1), takeUntil(this.destroy$), - filter((nextRoute) => this.shouldStoreFor(currentRoute, nextRoute)) + filter((nextRoute) => this.shouldStoreFor(currentRoute, nextRoute)), ) .subscribe(() => { const storeRouteUrl = this.getPath(currentRoute); @@ -170,7 +170,7 @@ export class ScrollPositionService implements OnDestroy { route.routeConfig && route.routeConfig.data && Array.isArray(route.routeConfig.data.restoreScrollPositionFrom) && - route.routeConfig.data.restoreScrollPositionFrom.length > 0 + route.routeConfig.data.restoreScrollPositionFrom.length > 0, ); } @@ -181,7 +181,7 @@ export class ScrollPositionService implements OnDestroy { */ private shouldStoreFor( storeRoute: ActivatedRouteSnapshot, - forRoute: ActivatedRouteSnapshot + forRoute: ActivatedRouteSnapshot, ): boolean { const restoreScrollPositionFrom = storeRoute && @@ -194,14 +194,14 @@ export class ScrollPositionService implements OnDestroy { } } -function isActivationEnd(event: any): event is ActivationEnd { +function isActivationEnd(event: unknown): event is ActivationEnd { return event instanceof ActivationEnd; } -function isNavigationStart(event: any): event is NavigationStart { +function isNavigationStart(event: unknown): event is NavigationStart { return event instanceof NavigationStart; } -function isNavigationEnd(event: any): event is NavigationEnd { +function isNavigationEnd(event: unknown): event is NavigationEnd { return event instanceof NavigationEnd; } diff --git a/src/app/shared/services/sort.service.spec.ts b/src/app/shared/services/sort.service.spec.ts index faa9a4dbd..89542b6e1 100644 --- a/src/app/shared/services/sort.service.spec.ts +++ b/src/app/shared/services/sort.service.spec.ts @@ -61,6 +61,7 @@ describe('SortService', () => { it('should get no char if different column is sorted', (done) => { // given const sorting: Sorting = { key: 'one', ascending: true }; + service.setSorting(sorting); // when service.getSortingChar$('two').subscribe((char) => { diff --git a/src/app/shared/services/storage.service.spec.ts b/src/app/shared/services/storage.service.spec.ts index 61f050e67..2585d6a30 100644 --- a/src/app/shared/services/storage.service.spec.ts +++ b/src/app/shared/services/storage.service.spec.ts @@ -1,7 +1,8 @@ import { TestBed } from '@angular/core/testing'; import { StorageService } from './storage.service'; -/*import { buildPayLoad } from 'src/spec-builders';*/ + +/* eslint-disable @typescript-eslint/no-explicit-any */ describe('StorageService', () => { let service: StorageService; @@ -14,18 +15,18 @@ describe('StorageService', () => { localStoreMock = {}; spyOn(localStorage, 'getItem').and.callFake( - (key: string) => localStoreMock[key] || null + (key: string) => localStoreMock[key] || null, ); spyOn(localStorage, 'setItem').and.callFake( - (key: string) => localStoreMock[key] || null + (key: string) => localStoreMock[key] || null, ); sessionStoreMock = {}; spyOn(sessionStorage, 'getItem').and.callFake( - (key: string) => sessionStoreMock[key] || null + (key: string) => sessionStoreMock[key] || null, ); spyOn(sessionStorage, 'setItem').and.callFake( - (key: string) => sessionStoreMock[key] || null + (key: string) => sessionStoreMock[key] || null, ); }); diff --git a/src/app/shared/services/storage.service.ts b/src/app/shared/services/storage.service.ts index 074ac768d..840c6a8d9 100644 --- a/src/app/shared/services/storage.service.ts +++ b/src/app/shared/services/storage.service.ts @@ -16,7 +16,7 @@ export class StorageService { getAccessToken(): Option { const token = this.getValue(ACCESS_TOKEN_KEY); - return token ? token.replace(/^\"+|\"+$/g, '') : null; + return token ? token.replace(/^"+|"+$/g, '') : null; } getRefreshToken(): Option { @@ -33,10 +33,9 @@ export class StorageService { const base64 = base64Url ? base64Url.replace('-', '+').replace('_', '/') : null; - let payload = JSON.parse(window.atob(base64 ? base64 : '')); - payload.roles = payload.hasOwnProperty('holder_roles') - ? payload.holder_roles - : payload.roles; + const payload = JSON.parse(window.atob(base64 ? base64 : '')); + payload.roles = + 'holder_roles' in payload ? payload.holder_roles : payload.roles; return payload; } diff --git a/src/app/shared/services/typeahead-rest.service.ts b/src/app/shared/services/typeahead-rest.service.ts index 32252a3b8..d9632479b 100644 --- a/src/app/shared/services/typeahead-rest.service.ts +++ b/src/app/shared/services/typeahead-rest.service.ts @@ -16,17 +16,18 @@ export class HttpParams { export interface TypeaheadService { getTypeaheadItems( term: string, - additionalParams?: HttpParams + additionalParams?: HttpParams, ): Observable>; getTypeaheadItemByKey(key: DropDownItem['Key']): Observable; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any export abstract class TypeaheadRestService> extends RestService implements TypeaheadService { protected typeaheadCodec = t.type( - pick(this.codec.props, [this.keyAttr, this.labelAttr]) + pick(this.codec.props, [this.keyAttr, this.labelAttr]), ); constructor( @@ -35,14 +36,14 @@ export abstract class TypeaheadRestService> codec: T, resourcePath: string, protected labelAttr: string, - protected keyAttr = 'Id' + protected keyAttr = 'Id', ) { super(http, settings, codec, resourcePath); } getTypeaheadItems( term: string, - additionalParams?: HttpParams + additionalParams?: HttpParams, ): Observable> { const params = { params: { @@ -56,13 +57,16 @@ export abstract class TypeaheadRestService> `${this.baseUrl}/`, additionalParams ? this.mergeHttpParams(params, additionalParams) - : params + : params, ) .pipe( switchMap(decodeArray(this.typeaheadCodec)), map((items) => - items.map((i) => ({ Key: i[this.keyAttr], Value: i[this.labelAttr] })) - ) + items.map((i) => ({ + Key: i[this.keyAttr], + Value: i[this.labelAttr], + })), + ), ); } @@ -78,13 +82,13 @@ export abstract class TypeaheadRestService> map((item) => ({ Key: item[this.keyAttr], Value: item[this.labelAttr], - })) + })), ); } private mergeHttpParams( typeaheadParams: HttpParams, - additionalParams: HttpParams + additionalParams: HttpParams, ): HttpParams { const merged = { params: { ...typeaheadParams.params, ...additionalParams.params }, @@ -92,7 +96,7 @@ export abstract class TypeaheadRestService> if (additionalParams.params.fields) { merged.params.fields = typeaheadParams.params.fields.concat( ',', - additionalParams.params.fields + additionalParams.params.fields, ); } return merged; diff --git a/src/app/shared/services/user-settings-rest.service.ts b/src/app/shared/services/user-settings-rest.service.ts index 967d26755..a0ba94f68 100644 --- a/src/app/shared/services/user-settings-rest.service.ts +++ b/src/app/shared/services/user-settings-rest.service.ts @@ -17,14 +17,14 @@ export class UserSettingsRestService extends RestService { } getUserSettingsCst( - params?: HttpParams | Dict + params?: HttpParams | Dict, ): Observable { return this.http .get(`${this.baseUrl}/Cst`, { params }) .pipe(switchMap(decode(this.codec))); } - updateUserSettingsCst(updatedSettings: UserSettings): Observable { + updateUserSettingsCst(updatedSettings: UserSettings): Observable { return this.http.patch(`${this.baseUrl}/Cst`, updatedSettings); } } diff --git a/src/app/shared/services/user-settings.service.ts b/src/app/shared/services/user-settings.service.ts index 3b406a4d3..32790cc0c 100644 --- a/src/app/shared/services/user-settings.service.ts +++ b/src/app/shared/services/user-settings.service.ts @@ -45,7 +45,7 @@ export class UserSettingsService { debounceTime(REFETCH_DEBOUNCE_TIME), // Avoid making two requests initially, when the component is triggering a refetch in `ngOnInit` switchMap(() => this.settingsRestService.getUserSettingsCst()), map((userSettings) => userSettings.Settings), - shareReplay(1) + shareReplay(1), ); constructor(private settingsRestService: UserSettingsRestService) {} @@ -63,7 +63,7 @@ export class UserSettingsService { */ getSetting(key: SettingKey): Observable> { return this.settings$.pipe( - map((settings) => settings.find((p) => p.Key === key)?.Value ?? null) + map((settings) => settings.find((p) => p.Key === key)?.Value ?? null), ); } @@ -72,7 +72,7 @@ export class UserSettingsService { * * The `Observable`s of the save* methods complete after one value. */ - saveSetting(key: SettingKey, value: SettingValue): Observable { + saveSetting(key: SettingKey, value: SettingValue): Observable { return this.settingsRestService .updateUserSettingsCst(this.buildSettings(key, value)) .pipe(tap(() => this.refetch$.next())); @@ -86,74 +86,76 @@ export class UserSettingsService { return this.getSetting(PRESENCE_CONTROL_VIEW_MODE_KEY).pipe( defaultValue('{"presenceControl":"grid"}'), // Default view mode is grid if setting is not available switchMap(decode(PresenceControlViewModeObject)), - map(({ presenceControl }) => presenceControl as PresenceControlViewMode) + map(({ presenceControl }) => presenceControl as PresenceControlViewMode), ); } - savePresenceControlViewMode(value: PresenceControlViewMode): Observable { + savePresenceControlViewMode( + value: PresenceControlViewMode, + ): Observable { return this.saveSetting( PRESENCE_CONTROL_VIEW_MODE_KEY, - PresenceControlViewModeObject.encode({ presenceControl: value }) + PresenceControlViewModeObject.encode({ presenceControl: value }), ); } getPresenceControlGroupView(): Observable { return this.getSetting(PRESENCE_CONTROL_GROUP_VIEW_KEY).pipe( defaultValue('[]'), - switchMap(decode(PresenceControlGroupView)) + switchMap(decode(PresenceControlGroupView)), ); } savePresenceControlGroupView( - value: PresenceControlGroupView - ): Observable { + value: PresenceControlGroupView, + ): Observable { return this.saveSetting( PRESENCE_CONTROL_GROUP_VIEW_KEY, - PresenceControlGroupView.encode(value) + PresenceControlGroupView.encode(value), ); } getNotificationChannels(): Observable { return this.getSetting(NOTIFICATION_CHANNELS_KEY).pipe( defaultValue('{}'), // Use empty object if not available, properties will be set to default value by decoder - switchMap(decode(NotificationChannels)) + switchMap(decode(NotificationChannels)), ); } - saveNotificationChannels(value: NotificationChannels): Observable { + saveNotificationChannels(value: NotificationChannels): Observable { return this.saveSetting( NOTIFICATION_CHANNELS_KEY, - NotificationChannels.encode(value) + NotificationChannels.encode(value), ); } getNotificationTypesInactive(): Observable { return this.getSetting(NOTIFICATION_TYPES_INACTIVE_KEY).pipe( defaultValue(''), // Per default, no notification types are inactive (all are subscribed) - switchMap(decode(NotificationTypesInactive)) + switchMap(decode(NotificationTypesInactive)), ); } saveNotificationTypesInactive( - value: NotificationTypesInactive - ): Observable { + value: NotificationTypesInactive, + ): Observable { return this.saveSetting( NOTIFICATION_TYPES_INACTIVE_KEY, - NotificationTypesInactive.encode(value) + NotificationTypesInactive.encode(value), ); } getNotificationData(): Observable { return this.getSetting(NOTIFICATION_DATA_KEY).pipe( defaultValue('[]'), - switchMap(decode(NotificationData)) + switchMap(decode(NotificationData)), ); } - saveNotificationData(value: NotificationData): Observable { + saveNotificationData(value: NotificationData): Observable { return this.saveSetting( NOTIFICATION_DATA_KEY, - NotificationData.encode(value) + NotificationData.encode(value), ); } diff --git a/src/app/shared/tokens/confirm-absences-service.ts b/src/app/shared/tokens/confirm-absences-service.ts index 0e9ce7311..943fdb6bf 100644 --- a/src/app/shared/tokens/confirm-absences-service.ts +++ b/src/app/shared/tokens/confirm-absences-service.ts @@ -1,8 +1,8 @@ import { InjectionToken } from '@angular/core'; -import { Params } from '@angular/router'; +import { Params, Router } from '@angular/router'; export interface IConfirmAbsencesService { - confirmBackLink?: any[]; + confirmBackLink?: Parameters[0]; confirmBackLinkParams?: Params; updateAfterConfirm?: () => void; } diff --git a/src/app/shared/utils/absences-filter.ts b/src/app/shared/utils/absences-filter.ts index c245bdcf6..f8fcb082b 100644 --- a/src/app/shared/utils/absences-filter.ts +++ b/src/app/shared/utils/absences-filter.ts @@ -5,10 +5,12 @@ import { EditAbsencesFilter } from 'src/app/edit-absences/services/edit-absences import { EvaluateAbsencesFilter } from 'src/app/evaluate-absences/services/evaluate-absences-state.service'; export function buildParamsFromAbsenceFilter( - filter: EditAbsencesFilter | EvaluateAbsencesFilter + filter: EditAbsencesFilter | EvaluateAbsencesFilter, ): Params { return Object.keys(filter).reduce((acc, name) => { - const value = serializeFilterValue((filter as any)[name]); + const value = serializeFilterValue( + (filter as unknown as Record)[name], + ); if (value) { return { ...acc, [name]: value }; } @@ -16,9 +18,9 @@ export function buildParamsFromAbsenceFilter( }, {}); } -function serializeFilterValue(value: any): Option { +function serializeFilterValue(value: unknown): Option { if (!value) { - return value; + return null; } if (value instanceof Date) { return format(value, 'yyyy-MM-dd'); diff --git a/src/app/shared/utils/array.spec.ts b/src/app/shared/utils/array.spec.ts index befb99c21..c1e02145e 100644 --- a/src/app/shared/utils/array.spec.ts +++ b/src/app/shared/utils/array.spec.ts @@ -6,6 +6,8 @@ import { isArray, } from './array'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + describe('array utils', () => { describe('previousElement', () => { const array: ReadonlyArray<{ id: number }> = [ @@ -25,7 +27,7 @@ describe('array utils', () => { it('returns null if entries are empty', () => { expect( - previousElement(eq)({ id: 2 }, [] as ReadonlyArray) + previousElement(eq)({ id: 2 }, [] as ReadonlyArray), ).toBeNull(); }); @@ -52,7 +54,7 @@ describe('array utils', () => { it('returns null if entries are empty', () => { expect( - nextElement(eq)({ id: 2 }, [] as ReadonlyArray) + nextElement(eq)({ id: 2 }, [] as ReadonlyArray), ).toBeNull(); }); diff --git a/src/app/shared/utils/array.ts b/src/app/shared/utils/array.ts index ae8ea51b2..db33363a5 100644 --- a/src/app/shared/utils/array.ts +++ b/src/app/shared/utils/array.ts @@ -4,7 +4,7 @@ * equality function. */ export function previousElement( - equal: (a: T, b: T) => boolean = (a, b) => a === b + equal: (a: T, b: T) => boolean = (a, b) => a === b, ): (entry: Option, entries: ReadonlyArray) => Option { return (entry, entries) => { if (entry && entries.length > 0) { @@ -23,7 +23,7 @@ export function previousElement( * equality function. */ export function nextElement( - equal: (a: T, b: T) => boolean = (a, b) => a === b + equal: (a: T, b: T) => boolean = (a, b) => a === b, ): (entry: Option, entries: ReadonlyArray) => Option { return (entry, entries) => { if (entry && entries.length > 0) { @@ -37,22 +37,22 @@ export function nextElement( } export function isFirstElement( - equal: (a: T, b: T) => boolean = (a, b) => a === b + equal: (a: T, b: T) => boolean = (a, b) => a === b, ): (entry: Option, entries: ReadonlyArray) => boolean { return (entry, entries) => Boolean(entry && entries.length > 0 && equal(entry, entries[0])); } export function isLastElement( - equal: (a: T, b: T) => boolean = (a, b) => a === b + equal: (a: T, b: T) => boolean = (a, b) => a === b, ): (entry: Option, entries: ReadonlyArray) => boolean { return (entry, entries) => Boolean( - entry && entries.length > 0 && equal(entry, entries[entries.length - 1]) + entry && entries.length > 0 && equal(entry, entries[entries.length - 1]), ); } -export function isEmptyArray(array: any[] | ReadonlyArray): boolean { +export function isEmptyArray(array: Array | ReadonlyArray): boolean { return array.length === 0; } @@ -60,6 +60,6 @@ export function length(array: T): number { return array.length; } -export function isArray(value: any): boolean { +export function isArray(value: unknown): boolean { return Array.isArray(value); } diff --git a/src/app/shared/utils/filter.ts b/src/app/shared/utils/filter.ts index b8f61f8bf..b691f5382 100644 --- a/src/app/shared/utils/filter.ts +++ b/src/app/shared/utils/filter.ts @@ -15,7 +15,7 @@ export function not(fn: (arg: A) => boolean): (arg: A) => boolean { } export function longerOrEqual( - length: number + length: number, ): (value: T) => boolean { return (value) => value.length >= length; } @@ -27,12 +27,9 @@ export function isTruthy(value: T): value is Exclude { } export function isInstanceOf( - type: Constructor -): (value: any) => value is T { - // eslint-disable-next-line - return function (value: any): value is T { - return value instanceof type; - }; + type: Constructor, +): (value: unknown) => value is T { + return (value): value is T => value instanceof type; } export function unique(value: T, index: number, array: T[]): boolean { diff --git a/src/app/shared/utils/form.ts b/src/app/shared/utils/form.ts index 5f0b9d5eb..85bcdb2ee 100644 --- a/src/app/shared/utils/form.ts +++ b/src/app/shared/utils/form.ts @@ -21,8 +21,14 @@ import { startWith, map, switchMap, filter, shareReplay } from 'rxjs/operators'; export function getValidationErrors( formGroup$: Observable>, submitted$: Observable, - controlName?: string -): Observable> { + controlName?: string, +): Observable< + ReadonlyArray<{ + error: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + params: any; + }> +> { return combineLatest([formGroup$, submitted$]).pipe( filter(([_, submitted]) => submitted), switchMap(([group, _]) => { @@ -30,40 +36,44 @@ export function getValidationErrors( if (control) { return control.statusChanges.pipe( startWith(control.status), - map(() => validatationErrorsToArray(control)) + map(() => validatationErrorsToArray(control)), ); } return of([]); }), startWith([]), - shareReplay(1) + shareReplay(1), ); } export function getControl( formGroup$: Observable, - controlName: string + controlName: string, ): Observable> { return formGroup$.pipe( map((formGroup) => { const control = formGroup.get(controlName); return control || null; - }) + }), ); } export function getControlValueChanges( formGroup$: Observable, - controlName: string + controlName: string, ): Observable { return getControl(formGroup$, controlName).pipe( - switchMap((control) => (control ? control.valueChanges : EMPTY)) + switchMap((control) => (control ? control.valueChanges : EMPTY)), ); } function validatationErrorsToArray( - control: AbstractControl | null -): ReadonlyArray<{ error: string; params: any }> { + control: AbstractControl | null, +): ReadonlyArray<{ + error: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + params: any; +}> { if (!control) { return []; } diff --git a/src/app/shared/utils/function.ts b/src/app/shared/utils/function.ts index 86d14219f..b46c9afc1 100644 --- a/src/app/shared/utils/function.ts +++ b/src/app/shared/utils/function.ts @@ -7,8 +7,8 @@ * function repeatStr(str: string, num: number): string { ... } * tuples.map(spread(repeatStr)) */ -export function spread( - fn: (...args: A) => R +export function spread( + fn: (...args: A) => R, ): (args: A) => R { return (args) => fn(...args); } diff --git a/src/app/shared/utils/observable.ts b/src/app/shared/utils/observable.ts index 010d85658..84ad0db60 100644 --- a/src/app/shared/utils/observable.ts +++ b/src/app/shared/utils/observable.ts @@ -21,8 +21,9 @@ import { startWith, } from 'rxjs/operators'; +/* eslint-disable @typescript-eslint/no-explicit-any */ export function catch404>( - returnValue?: any + returnValue?: any, ): OperatorFunction>> { return catchError((error) => { if (error instanceof HttpErrorResponse && error.status === 404) { @@ -32,6 +33,7 @@ export function catch404>( } }); } +/* eslint-enable @typescript-eslint/no-explicit-any */ /** * For debugging purposes, logs message an value for each value in the @@ -39,11 +41,11 @@ export function catch404>( * foo$.pipe(log('foo$')).subscribe() */ export function log( - message: Option = null + message: Option = null, ): MonoTypeOperatorFunction { return (input$) => input$.pipe( - tap((x: T) => (message ? console.log(message, x) : console.log(x))) + tap((x: T) => (message ? console.log(message, x) : console.log(x))), ); } @@ -52,7 +54,7 @@ export function log( * foo$.pipe(prepare(() => console.log('subscribed'))) */ export function prepare( - callback: () => void + callback: () => void, ): (source: Observable) => Observable { return (source: Observable): Observable => defer(() => { @@ -67,12 +69,12 @@ export function prepare( * without having emitted any value. */ export function defaultValue( - defaultValue: T + defaultValue: T, ): OperatorFunction, T> { return ($input) => $input.pipe( map((value) => (value == null ? defaultValue : value)), - defaultIfEmpty(defaultValue) + defaultIfEmpty(defaultValue), ); } @@ -82,15 +84,15 @@ export function defaultValue( */ export function reemitOnTrigger( source$: Observable, - trigger$: Observable + trigger$: Observable, ): Observable { return source$.pipe( switchMap((value) => trigger$.pipe( startWith(value), - map(() => value) - ) - ) + map(() => value), + ), + ), ); } @@ -100,13 +102,13 @@ export function reemitOnTrigger( */ export function intervalOnInactivity( period: number, - eventSource: Node = window.document + eventSource: Node = window.document, ) { return merge( - ...['click', 'keydown'].map((type) => fromEvent(eventSource, type)) + ...['click', 'keydown'].map((type) => fromEvent(eventSource, type)), ).pipe( startWith(null), switchMap(() => interval(period)), - map(() => undefined) + map(() => undefined), ); } diff --git a/src/app/shared/utils/persons.spec.ts b/src/app/shared/utils/persons.spec.ts index a5bf95e7e..b9c172ac8 100644 --- a/src/app/shared/utils/persons.spec.ts +++ b/src/app/shared/utils/persons.spec.ts @@ -42,10 +42,4 @@ describe('persons utilities', () => { student.Birthdate = birthday; return student; } - - function buildPersonWithFormOfAddress(formOfAddress: string): Person { - const person = buildPerson(123); - person.FormOfAddress = formOfAddress; - return person; - } }); diff --git a/src/app/shared/utils/presence-types.ts b/src/app/shared/utils/presence-types.ts index 5002d53af..ea912a897 100644 --- a/src/app/shared/utils/presence-types.ts +++ b/src/app/shared/utils/presence-types.ts @@ -1,12 +1,12 @@ import { PresenceType } from '../models/presence-type.model'; -import { DropDownItem } from '../models/drop-down-item.model'; import { DropDownGroupedItem } from '../models/drop-down-grouped-item.model'; +import { DropDownItem } from '../models/drop-down-item.model'; /** * Sorts an array of presence types by the `Sort` attribute. */ export function sortPresenceTypes( - presenceTypes: ReadonlyArray + presenceTypes: ReadonlyArray, ): ReadonlyArray { return presenceTypes.slice().sort((a, b) => a.Sort - b.Sort); } @@ -16,7 +16,7 @@ export function sortPresenceTypes( * types. */ export function createPresenceTypesDropdownItems( - presenceTypes: ReadonlyArray + presenceTypes: ReadonlyArray, ): ReadonlyArray { return presenceTypes.map((presenceType) => ({ Key: presenceType.Id, @@ -29,11 +29,11 @@ export function createPresenceTypesDropdownItems( */ export function addGroupToDropdownItem( items: ReadonlyArray, - group: string + group: string, ): ReadonlyArray { return items.map((i) => Object.assign(i, { Group: group, - }) + }), ); } diff --git a/src/app/shared/utils/url.ts b/src/app/shared/utils/url.ts index 51a5ed23f..d2d1fcfbd 100644 --- a/src/app/shared/utils/url.ts +++ b/src/app/shared/utils/url.ts @@ -9,7 +9,7 @@ import { /** * Parses given query string to params object */ -export function parseQueryString(queryString: any): Params { +export function parseQueryString(queryString: unknown): Params { return String(queryString || '') .split('&') .reduce((acc, pair) => { diff --git a/src/app/unauthenticated.component.ts b/src/app/unauthenticated.component.ts index c34845e0d..d3476745a 100644 --- a/src/app/unauthenticated.component.ts +++ b/src/app/unauthenticated.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; @Component({ selector: 'erz-unauthenticated', diff --git a/src/spec-builders.ts b/src/spec-builders.ts index 69635e7c4..48169c3d7 100644 --- a/src/spec-builders.ts +++ b/src/spec-builders.ts @@ -35,14 +35,15 @@ import { import { TimetableEntry } from './app/shared/models/timetable-entry.model'; import { LessonDispensation } from './app/shared/models/lesson-dispensation.model'; import { TokenPayload } from './app/shared/models/token-payload.model'; -import {DropDownItem} from "./app/shared/models/drop-down-item.model"; + +/* eslint-disable @typescript-eslint/no-explicit-any */ export function buildReference(id = 123, href?: string): Reference { return { Id: id, HRef: href || `/${id}` }; } export function buildOptionalReference( - id: Option = null + id: Option = null, ): OptionalReference { return { Id: id, HRef: null }; } @@ -57,7 +58,7 @@ export function buildLessonPresence( presenceTypeId?: number, eventRefId?: number, studentRefId?: number, - confirmationStateId?: number + confirmationStateId?: number, ): LessonPresence { return { Id: lessonId && studentRefId ? [lessonId, studentRefId].join('_') : '1', @@ -91,7 +92,7 @@ export function buildLessonPresenceWithIds( studentId: number, presenceTypeId: number, dateFrom = new Date(), - dateTo = new Date() + dateTo = new Date(), ): LessonPresence { const presence = buildLessonPresence(lessonId, dateFrom, dateTo, ''); presence.StudentRef = buildReference(studentId); @@ -100,7 +101,7 @@ export function buildLessonPresenceWithIds( } export function buildLessonPresenceFromTimetableEntry( - timetableEntry: TimetableEntry + timetableEntry: TimetableEntry, ): LessonPresence { return { Id: '', @@ -160,7 +161,7 @@ export function buildLesson( eventDesignation: string, teacherInformation: string, studyClassNumber?: string, - eventId?: number + eventId?: number, ): Lesson { return { LessonRef: buildReference(lessonId), @@ -176,12 +177,12 @@ export function buildLesson( export function buildPresenceControlEntry( lessonPresence: LessonPresence, presenceType?: Option, - precedingAbsences?: ReadonlyArray + precedingAbsences?: ReadonlyArray, ): PresenceControlEntry { return new PresenceControlEntry( lessonPresence, presenceType || null, - precedingAbsences || [] + precedingAbsences || [], ); } @@ -189,7 +190,7 @@ export function buildPresenceType( id: number, isAbsence: boolean, isIncident: boolean, - isComment = false + isComment = false, ): PresenceType { return { Id: id, @@ -208,7 +209,7 @@ export function buildPresenceType( } export function buildLessonPresenceStatistic( - studentId: number + studentId: number, ): LessonPresenceStatistic { return { StudentRef: buildReference(studentId), @@ -246,7 +247,7 @@ export function buildStudent(id: number): Student { export function buildApprenticeshipContract( id: number, jobTrainerId = 0, - apprenticeshipManagerId = 0 + apprenticeshipManagerId = 0, ): ApprenticeshipContract { return { Id: id, @@ -270,7 +271,7 @@ export function buildApprenticeshipContract( export function buildLegalRepresentative( id: number, - representativeId?: number + representativeId?: number, ): LegalRepresentative { return { Id: id, @@ -335,7 +336,7 @@ export function buildJobTrainer(id: number): JobTrainer { export function buildPayLoad( personId = '2431', - instanceId = 'GYmTEST' + instanceId = 'GYmTEST', ): TokenPayload { return { culture_info: 'de-CH', @@ -392,7 +393,7 @@ export function buildPersonWithEmails( id: number, displayEmail?: string, email?: string, - email2?: string + email2?: string, ): Person { const person = buildPerson(id); person.DisplayEmail = displayEmail || null; @@ -404,7 +405,7 @@ export function buildPersonWithEmails( export function buildJobTrainerWithEmails( id: number, email: string, - email2: Option = null + email2: Option = null, ): JobTrainer { const trainer = buildJobTrainer(id); trainer.Email = email; @@ -415,7 +416,7 @@ export function buildJobTrainerWithEmails( export function buildApprenticeshipManagerWithEmails( id: number, email: string, - email2: Option = null + email2: Option = null, ): ApprenticeshipManager { const manager = buildApprenticeshipManager(id); manager.Email = email; @@ -424,7 +425,7 @@ export function buildApprenticeshipManagerWithEmails( } export function buildUserSettings( - settings: UserSettings['Settings'] = [] + settings: UserSettings['Settings'] = [], ): UserSettings { return { Id: 'Cst', @@ -435,7 +436,7 @@ export function buildUserSettings( export function buildUserSettingsWithNotificationSetting( gui: boolean, mail: boolean, - phoneMobile: boolean + phoneMobile: boolean, ): UserSettings { const setting = buildUserSettings(); const notification = { @@ -448,7 +449,7 @@ export function buildUserSettingsWithNotificationSetting( export function buildUserSettingsWithNotificationData( id: number, subject: string, - body: string + body: string, ): UserSettings { const setting = buildUserSettings(); const notification = { @@ -460,7 +461,7 @@ export function buildUserSettingsWithNotificationData( export function buildSubscriptionDetail( vssId: number, - value?: string + value?: string, ): SubscriptionDetail { return { Id: '1', @@ -470,15 +471,17 @@ export function buildSubscriptionDetail( Value: value || '', EventId: 1, ShowAsRadioButtons: false, - DropdownItems: [{Key: 1, Value: "item 1"}, {Key: "2", Value: "item 2"}], + DropdownItems: [ + { Key: 1, Value: 'item 1' }, + { Key: '2', Value: 'item 2' }, + ], }; } - export function buildIdSubscription( id: number, eventId: number, - personId: number + personId: number, ): IdSubscription { return { Id: id, @@ -528,7 +531,7 @@ export function buildCourse( attendance?: AttendanceRef, evaluationStatus?: EvaluationStatusRef, classes?: StudyClass[], - statusId?: number + statusId?: number, ): Course { return { HRef: '', @@ -578,7 +581,7 @@ export function buildCourse( export function buildTimetableEntry( id: number, from: Date, - to: Date + to: Date, ): TimetableEntry { return { Id: id, @@ -593,7 +596,7 @@ export function buildTimetableEntry( export function buildTest( courseId: number, testId: number, - results: Result[] | null + results: Result[] | null, ): Test { return { Id: testId, @@ -618,7 +621,7 @@ export function buildTest( export function buildResult( testId: number, studentId: number, - courseRegistrationId: number = 123456 + courseRegistrationId: number = 123456, ): Result { return { TestId: testId, @@ -635,7 +638,7 @@ export function buildResult( export function buildGrading( studentId: number, averageGrade: number = 2.275, - gradeId: number = 3 + gradeId: number = 3, ): Grading { return { AverageTestResult: averageGrade, @@ -691,7 +694,7 @@ export function buildFinalGrading(id: number): FinalGrading { export function buildStudentGrade( student: Student, - gradesOrNoResults: GradeOrNoResult[] + gradesOrNoResults: GradeOrNoResult[], ): StudentGrade { return { student: student, @@ -703,7 +706,7 @@ export function buildStudentGrade( export function buildGradeKind( kind: any, result: Result, - test: Test + test: Test, ): GradeKind { return { kind: kind, diff --git a/src/spec-helpers.ts b/src/spec-helpers.ts index fad2584b9..93e3acb70 100644 --- a/src/spec-helpers.ts +++ b/src/spec-helpers.ts @@ -18,6 +18,8 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader { return new TranslateHttpLoader(http, './assets/locales/', '.json'); } +/* eslint-disable @typescript-eslint/no-explicit-any */ + export const settings: Settings = { apiUrl: 'https://eventotest.api', scriptsAndAssetsPath: '.', @@ -120,7 +122,7 @@ const baseTestModuleMetadata: TestModuleMetadata = { }; export function buildTestModuleMetadata( - data: TestModuleMetadata = {} + data: TestModuleMetadata = {}, ): TestModuleMetadata { const result: any = { ...data }; Object.keys(baseTestModuleMetadata).forEach((key) => { @@ -133,17 +135,17 @@ export function buildTestModuleMetadata( } export function changeInputs< - T extends { ngOnChanges?(changes?: SimpleChanges): void } + T extends { ngOnChanges?(changes?: SimpleChanges): void }, >( component: T, - changes: { property: keyof T; value: T[keyof T]; firstChange?: boolean }[] + changes: { property: keyof T; value: T[keyof T]; firstChange?: boolean }[], ): void { const simpleChanges: SimpleChanges = changes.reduce( (acc, { property, value, firstChange }) => Object.assign(acc, { [property]: createInputChange(component, property, value, firstChange), }), - {} + {}, ); if (typeof component.ngOnChanges === 'function') { @@ -152,24 +154,24 @@ export function changeInputs< } export function changeInput< - T extends { ngOnChanges?(changes?: SimpleChanges): void } + T extends { ngOnChanges?(changes?: SimpleChanges): void }, >( component: T, property: keyof T, value: T[keyof T], - firstChange = false + firstChange = false, ): T[keyof T] { changeInputs(component, [{ property, value, firstChange }]); return value; } function createInputChange< - T extends { ngOnChanges?(changes?: SimpleChanges): void } + T extends { ngOnChanges?(changes?: SimpleChanges): void }, >( component: T, property: keyof T, value: T[keyof T], - firstChange = false + firstChange = false, ): SimpleChange { const previousValue = component[property]; const change = new SimpleChange(previousValue, value, firstChange); diff --git a/src/typings.d.ts b/src/typings.d.ts index e4814d841..b449f91fe 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -6,7 +6,8 @@ interface Dict { } interface Constructor { + // eslint-disable-next-line @typescript-eslint/no-explicit-any new (...args: any[]): T; } -declare var __webpack_public_path__: string; +declare let __webpack_public_path__: string;