diff --git a/.gitignore b/.gitignore index 8b111b7fa..5760f05cf 100644 --- a/.gitignore +++ b/.gitignore @@ -54,4 +54,7 @@ apps/consolidator/src/assets/config/instanceFavicon.ico apps/linker/src/assets/config/instanceConfig.json apps/linker/src/assets/config/instanceFavicon.ico +#e2e dist files +apps/admin-gui-e2e/dist + .angular diff --git a/angular.json b/angular.json index d021ca2c4..be73f7ccc 100644 --- a/angular.json +++ b/angular.json @@ -2,6 +2,7 @@ "version": 1, "projects": { "admin-gui": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "application", "schematics": { "@nrwl/angular:component": { @@ -122,7 +123,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "apps/admin-gui/jest.config.js", + "jestConfig": "apps/admin-gui/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/apps/admin-gui"] @@ -131,6 +132,7 @@ "tags": [] }, "admin-gui-e2e": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "root": "apps/admin-gui-e2e", "sourceRoot": "apps/admin-gui-e2e/src", "projectType": "application", @@ -138,9 +140,10 @@ "e2e": { "builder": "@nrwl/cypress:cypress", "options": { - "cypressConfig": "apps/admin-gui-e2e/cypress.json", + "cypressConfig": "apps/admin-gui-e2e/cypress.config.ts", "tsConfig": "apps/admin-gui-e2e/tsconfig.e2e.json", - "devServerTarget": "admin-gui:serve" + "devServerTarget": "admin-gui:serve", + "testingType": "e2e" }, "configurations": { "production": { @@ -160,6 +163,7 @@ "implicitDependencies": ["admin-gui"] }, "config": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/config", "sourceRoot": "libs/config/src", @@ -175,7 +179,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/config/jest.config.js", + "jestConfig": "libs/config/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/config"] @@ -189,6 +193,7 @@ "tags": [] }, "config-table-config": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/config/table-config", "sourceRoot": "libs/config/table-config/src", @@ -207,7 +212,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/config/table-config/jest.config.js", + "jestConfig": "libs/config/table-config/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/config/table-config"] @@ -221,122 +226,7 @@ "tags": [] }, "consolidator": { - "projectType": "application", - "root": "apps/consolidator", - "sourceRoot": "apps/consolidator/src", - "prefix": "perun-web-apps", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/consolidator", - "index": "apps/consolidator/src/index.html", - "main": "apps/consolidator/src/main.ts", - "polyfills": "apps/consolidator/src/polyfills.ts", - "tsConfig": "apps/consolidator/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": ["apps/consolidator/src/favicon.ico", "apps/consolidator/src/assets"], - "styles": ["apps/consolidator/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "fileReplacements": [ - { - "replace": "apps/consolidator/src/environments/environment.ts", - "with": "apps/consolidator/src/environments/environment.prod.ts" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "browserTarget": "consolidator:build:production" - }, - "development": { - "browserTarget": "consolidator:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "consolidator:build" - } - }, - "lint": { - "builder": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": ["apps/consolidator/src/**/*.ts", "apps/consolidator/src/**/*.html"] - } - }, - "test": { - "builder": "@nrwl/jest:jest", - "outputs": ["coverage/apps/consolidator"], - "options": { - "jestConfig": "apps/consolidator/jest.config.js", - "passWithNoTests": true - } - } - }, - "tags": [] - }, - "consolidator-e2e": { - "root": "apps/consolidator-e2e", - "sourceRoot": "apps/consolidator-e2e/src", - "projectType": "application", - "architect": { - "e2e": { - "builder": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/consolidator-e2e/cypress.json", - "devServerTarget": "consolidator:serve:development" - }, - "configurations": { - "production": { - "devServerTarget": "consolidator:serve:production" - } - } - }, - "lint": { - "builder": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/consolidator-e2e/**/*.{js,ts}"] - } - } - }, - "tags": [], - "implicitDependencies": ["consolidator"] - }, - "consolidator": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "application", "schematics": { "@nrwl/angular:component": { @@ -357,10 +247,7 @@ "polyfills": "apps/consolidator/src/polyfills.ts", "tsConfig": "apps/consolidator/tsconfig.app.json", "aot": true, - "assets": [ - "apps/consolidator/src/favicon.ico", - "apps/consolidator/src/assets" - ], + "assets": ["apps/consolidator/src/favicon.ico", "apps/consolidator/src/assets"], "styles": [ "apps/consolidator/src/styles.scss", "./node_modules/bootstrap/dist/css/bootstrap.css" @@ -449,23 +336,21 @@ "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "apps/consolidator/src/**/*.ts", - "apps/consolidator/src/**/*.html" - ] + "lintFilePatterns": ["apps/consolidator/src/**/*.ts", "apps/consolidator/src/**/*.html"] } }, "test": { "builder": "@nrwl/jest:jest", "outputs": ["coverage/apps/consolidator"], "options": { - "jestConfig": "apps/consolidator/jest.config.js", + "jestConfig": "apps/consolidator/jest.config.ts", "passWithNoTests": true } } } }, "consolidator-e2e": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "root": "apps/consolidator-e2e", "sourceRoot": "apps/consolidator-e2e/src", "projectType": "application", @@ -473,9 +358,10 @@ "e2e": { "builder": "@nrwl/cypress:cypress", "options": { - "cypressConfig": "apps/consolidator-e2e/cypress.json", + "cypressConfig": "apps/consolidator-e2e/cypress.config.ts", "tsConfig": "apps/consolidator-e2e/tsconfig.e2e.json", - "devServerTarget": "consolidator:serve:development" + "devServerTarget": "consolidator:serve:development", + "testingType": "e2e" }, "configurations": { "production": { @@ -492,6 +378,7 @@ } }, "general": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/general", "sourceRoot": "libs/general/src", @@ -507,7 +394,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/general/jest.config.js", + "jestConfig": "libs/general/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/general"] @@ -520,123 +407,8 @@ }, "tags": [] }, - "linker": { - "projectType": "application", - "root": "apps/linker", - "sourceRoot": "apps/linker/src", - "prefix": "perun-web-apps", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/linker", - "index": "apps/linker/src/index.html", - "main": "apps/linker/src/main.ts", - "polyfills": "apps/linker/src/polyfills.ts", - "tsConfig": "apps/linker/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": ["apps/linker/src/favicon.ico", "apps/linker/src/assets"], - "styles": ["apps/linker/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "fileReplacements": [ - { - "replace": "apps/linker/src/environments/environment.ts", - "with": "apps/linker/src/environments/environment.prod.ts" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "browserTarget": "linker:build:production" - }, - "development": { - "browserTarget": "linker:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "linker:build" - } - }, - "lint": { - "builder": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": ["apps/linker/src/**/*.ts", "apps/linker/src/**/*.html"] - } - }, - "test": { - "builder": "@nrwl/jest:jest", - "outputs": ["coverage/apps/linker"], - "options": { - "jestConfig": "apps/linker/jest.config.js", - "passWithNoTests": true - } - } - }, - "tags": [] - }, - "linker-e2e": { - "root": "apps/linker-e2e", - "sourceRoot": "apps/linker-e2e/src", - "projectType": "application", - "architect": { - "e2e": { - "builder": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/linker-e2e/cypress.json", - "devServerTarget": "linker:serve:development" - }, - "configurations": { - "production": { - "devServerTarget": "linker:serve:production" - } - } - }, - "lint": { - "builder": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/linker-e2e/**/*.{js,ts}"] - } - } - }, - "tags": [], - "implicitDependencies": ["linker"] - }, "lib-linker": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/lib-linker", "sourceRoot": "libs/lib-linker/src", @@ -646,22 +418,20 @@ "builder": "@nrwl/jest:jest", "outputs": ["coverage/libs/lib-linker"], "options": { - "jestConfig": "libs/lib-linker/jest.config.js", + "jestConfig": "libs/lib-linker/jest.config.ts", "passWithNoTests": true } }, "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "libs/lib-linker/src/**/*.ts", - "libs/lib-linker/src/**/*.html" - ] + "lintFilePatterns": ["libs/lib-linker/src/**/*.ts", "libs/lib-linker/src/**/*.html"] } } } }, "linker": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "application", "root": "apps/linker", "sourceRoot": "apps/linker/src", @@ -764,23 +534,21 @@ "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "apps/linker/src/**/*.ts", - "apps/linker/src/**/*.html" - ] + "lintFilePatterns": ["apps/linker/src/**/*.ts", "apps/linker/src/**/*.html"] } }, "test": { "builder": "@nrwl/jest:jest", "outputs": ["coverage/apps/linker"], "options": { - "jestConfig": "apps/linker/jest.config.js", + "jestConfig": "apps/linker/jest.config.ts", "passWithNoTests": true } } } }, "linker-e2e": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "root": "apps/linker-e2e", "sourceRoot": "apps/linker-e2e/src", "projectType": "application", @@ -788,9 +556,10 @@ "e2e": { "builder": "@nrwl/cypress:cypress", "options": { - "cypressConfig": "apps/linker-e2e/cypress.json", + "cypressConfig": "apps/linker-e2e/cypress.config.ts", "tsConfig": "apps/linker-e2e/tsconfig.e2e.json", - "devServerTarget": "linker:serve:development" + "devServerTarget": "linker:serve:development", + "testingType": "e2e" }, "configurations": { "production": { @@ -807,6 +576,7 @@ } }, "password-reset": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "application", "schematics": { "@schematics/angular:component": { @@ -925,7 +695,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "apps/password-reset/jest.config.js", + "jestConfig": "apps/password-reset/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/apps/password-reset"] @@ -934,6 +704,7 @@ "tags": [] }, "password-reset-e2e": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "root": "apps/password-reset-e2e", "sourceRoot": "apps/password-reset-e2e/src", "projectType": "application", @@ -941,9 +712,10 @@ "e2e": { "builder": "@nrwl/cypress:cypress", "options": { - "cypressConfig": "apps/password-reset-e2e/cypress.json", + "cypressConfig": "apps/password-reset-e2e/cypress.config.ts", "tsConfig": "apps/password-reset-e2e/tsconfig.e2e.json", - "devServerTarget": "password-reset:serve" + "devServerTarget": "password-reset:serve", + "testingType": "e2e" }, "configurations": { "production": { @@ -963,6 +735,7 @@ "implicitDependencies": ["password-reset"] }, "perun-animations": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/perun/animations", "sourceRoot": "libs/perun/animations/src", @@ -981,7 +754,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/animations/jest.config.js", + "jestConfig": "libs/perun/animations/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/animations"] @@ -995,6 +768,7 @@ "tags": [] }, "perun-components": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/perun/components", "sourceRoot": "libs/perun/components/src", @@ -1013,19 +787,19 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/components/jest.config.js", + "jestConfig": "libs/perun/components/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/components"] } }, "schematics": { - "@nrwl/angular:component": { - } + "@nrwl/angular:component": {} }, "tags": [] }, "perun-dialogs": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/perun/dialogs", "sourceRoot": "libs/perun/dialogs/src", @@ -1044,7 +818,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/dialogs/jest.config.js", + "jestConfig": "libs/perun/dialogs/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/dialogs"] @@ -1058,6 +832,7 @@ "tags": [] }, "perun-directives": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/perun/directives", "sourceRoot": "libs/perun/directives/src", @@ -1076,7 +851,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/directives/jest.config.js", + "jestConfig": "libs/perun/directives/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/directives"] @@ -1090,6 +865,7 @@ "tags": [] }, "perun-facility-services-config": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/perun/facility-services-config", "sourceRoot": "libs/perun/facility-services-config/src", @@ -1108,7 +884,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/facility-services-config/jest.config.js", + "jestConfig": "libs/perun/facility-services-config/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/facility-services-config"] @@ -1122,6 +898,7 @@ "tags": [] }, "perun-login": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/perun/login", "sourceRoot": "libs/perun/login/src", @@ -1137,7 +914,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/login/jest.config.js", + "jestConfig": "libs/perun/login/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/login"] @@ -1151,6 +928,7 @@ "tags": [] }, "perun-models": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "root": "libs/perun/models", "sourceRoot": "libs/perun/models/src", "projectType": "library", @@ -1166,7 +944,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/models/jest.config.js", + "jestConfig": "libs/perun/models/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/models"] @@ -1175,6 +953,7 @@ "tags": [] }, "perun-namespace-password-form": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/perun/namespace-password-form", "sourceRoot": "libs/perun/namespace-password-form/src", @@ -1184,7 +963,7 @@ "builder": "@nrwl/jest:jest", "outputs": ["coverage/libs/perun/namespace-password-form"], "options": { - "jestConfig": "libs/perun/namespace-password-form/jest.config.js", + "jestConfig": "libs/perun/namespace-password-form/jest.config.ts", "passWithNoTests": true } }, @@ -1202,6 +981,7 @@ "tags": [] }, "perun-openapi": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/perun/openapi", "sourceRoot": "libs/perun/openapi/src", @@ -1220,7 +1000,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/openapi/jest.config.js", + "jestConfig": "libs/perun/openapi/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/openapi"] @@ -1230,6 +1010,7 @@ "tags": [] }, "perun-pipes": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/perun/pipes", "sourceRoot": "libs/perun/pipes/src", @@ -1245,7 +1026,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/pipes/jest.config.js", + "jestConfig": "libs/perun/pipes/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/pipes"] @@ -1259,6 +1040,7 @@ "tags": [] }, "perun-services": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "root": "libs/perun/services", "sourceRoot": "libs/perun/services/src", "projectType": "library", @@ -1277,7 +1059,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/services/jest.config.js", + "jestConfig": "libs/perun/services/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/services"] @@ -1286,6 +1068,7 @@ "tags": [] }, "perun-session-expiration": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/perun/session-expiration", "sourceRoot": "libs/perun/session-expiration/src", @@ -1304,7 +1087,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/session-expiration/jest.config.js", + "jestConfig": "libs/perun/session-expiration/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/session-expiration"] @@ -1318,6 +1101,7 @@ "tags": [] }, "perun-tokens": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "root": "libs/perun/tokens", "sourceRoot": "libs/perun/tokens/src", "projectType": "library", @@ -1333,7 +1117,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/tokens/jest.config.js", + "jestConfig": "libs/perun/tokens/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/tokens"] @@ -1342,6 +1126,7 @@ "tags": [] }, "perun-urns": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "root": "libs/perun/urns", "sourceRoot": "libs/perun/urns/src", "projectType": "library", @@ -1357,7 +1142,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/urns/jest.config.js", + "jestConfig": "libs/perun/urns/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/urns"] @@ -1366,6 +1151,7 @@ "tags": [] }, "perun-utils": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "root": "libs/perun/utils", "sourceRoot": "libs/perun/utils/src", "projectType": "library", @@ -1381,7 +1167,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/perun/utils/jest.config.js", + "jestConfig": "libs/perun/utils/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/perun/utils"] @@ -1390,6 +1176,7 @@ "tags": [] }, "publications": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "application", "schematics": { "@schematics/angular:component": { @@ -1527,7 +1314,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "apps/publications/jest.config.js", + "jestConfig": "apps/publications/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/apps/publications"] @@ -1536,6 +1323,7 @@ "tags": [] }, "publications-e2e": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "root": "apps/publications-e2e", "sourceRoot": "apps/publications-e2e/src", "projectType": "application", @@ -1543,9 +1331,10 @@ "e2e": { "builder": "@nrwl/cypress:cypress", "options": { - "cypressConfig": "apps/publications-e2e/cypress.json", + "cypressConfig": "apps/publications-e2e/cypress.config.ts", "tsConfig": "apps/publications-e2e/tsconfig.e2e.json", - "devServerTarget": "publications:serve" + "devServerTarget": "publications:serve", + "testingType": "e2e" }, "configurations": { "production": { @@ -1565,6 +1354,7 @@ "implicitDependencies": ["publications"] }, "ui": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/ui", "sourceRoot": "libs/ui/src", @@ -1580,7 +1370,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/ui/jest.config.js", + "jestConfig": "libs/ui/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/ui"] @@ -1594,6 +1384,7 @@ "tags": [] }, "ui-alerts": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "root": "libs/ui/alerts", "sourceRoot": "libs/ui/alerts/src", "projectType": "library", @@ -1609,7 +1400,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/ui/alerts/jest.config.js", + "jestConfig": "libs/ui/alerts/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/ui/alerts"] @@ -1618,6 +1409,7 @@ "tags": [] }, "ui-material": { + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "root": "libs/ui/material", "sourceRoot": "libs/ui/material/src", @@ -1633,7 +1425,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "libs/ui/material/jest.config.js", + "jestConfig": "libs/ui/material/jest.config.ts", "passWithNoTests": true }, "outputs": ["coverage/libs/ui/material"] @@ -1647,6 +1439,7 @@ "tags": [] }, "user-profile": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "application", "schematics": { "@nrwl/angular:component": { @@ -1763,7 +1556,7 @@ "test": { "builder": "@nrwl/jest:jest", "options": { - "jestConfig": "apps/user-profile/jest.config.js" + "jestConfig": "apps/user-profile/jest.config.ts" }, "outputs": ["coverage/apps/user-profile"] } @@ -1771,6 +1564,7 @@ "tags": [] }, "user-profile-e2e": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "root": "apps/user-profile-e2e", "sourceRoot": "apps/user-profile-e2e/src", "projectType": "application", @@ -1778,9 +1572,10 @@ "e2e": { "builder": "@nrwl/cypress:cypress", "options": { - "cypressConfig": "apps/user-profile-e2e/cypress.json", + "cypressConfig": "apps/user-profile-e2e/cypress.config.ts", "tsConfig": "apps/user-profile-e2e/tsconfig.e2e.json", - "devServerTarget": "user-profile:serve" + "devServerTarget": "user-profile:serve", + "testingType": "e2e" }, "configurations": { "production": { diff --git a/apps/admin-gui-e2e/cypress.config.ts b/apps/admin-gui-e2e/cypress.config.ts new file mode 100644 index 000000000..f7c13f457 --- /dev/null +++ b/apps/admin-gui-e2e/cypress.config.ts @@ -0,0 +1,30 @@ +import { defineConfig } from 'cypress'; +import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; + +export default defineConfig({ + e2e: { + ...nxE2EPreset(__dirname), + fileServerFolder: '.', + fixturesFolder: './src/fixtures', + video: true, + videosFolder: '../../dist/cypress/apps/admin-gui-e2e/videos', + screenshotsFolder: '../../dist/cypress/apps/admin-gui-e2e/screenshots', + chromeWebSecurity: false, + baseUrl: 'http://localhost:4200', + env: { + BA_USERNAME: 'perun', + BA_PASSWORD: 'test', + BA_USERNAME_VO_MANAGER: 'voManager', + BA_PASSWORD_VO_MANAGER: 'test', + BA_USERNAME_GROUP_MANAGER: 'groupManager', + BA_PASSWORD_GROUP_MANAGER: 'test', + BA_USERNAME_FACILITY_MANAGER: 'facilityManager', + BA_PASSWORD_FACILITY_MANAGER: 'test', + BA_USERNAME_RESOURCE_MANAGER: 'resourceManager', + BA_PASSWORD_RESOURCE_MANAGER: 'test', + BA_PASSWORD_TOP_GROUP_CREATOR: 'topGroupCreator', + }, + specPattern: 'src/e2e/**/*.cy.{js,jsx,ts,tsx}', + supportFile: false, + }, +}); diff --git a/apps/admin-gui-e2e/cypress.json b/apps/admin-gui-e2e/cypress.json deleted file mode 100644 index 176a4b4d7..000000000 --- a/apps/admin-gui-e2e/cypress.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "fileServerFolder": ".", - "fixturesFolder": "./src/fixtures", - "integrationFolder": "./src/integration", - "pluginsFile": false, - "supportFile": false, - "video": true, - "videosFolder": "../../dist/cypress/apps/admin-gui-e2e/videos", - "screenshotsFolder": "../../dist/cypress/apps/admin-gui-e2e/screenshots", - "chromeWebSecurity": false, - "baseUrl": "http://localhost:4200", - "env": { - "BA_USERNAME": "perun", - "BA_PASSWORD": "test", - "BA_USERNAME_VO_MANAGER": "voManager", - "BA_PASSWORD_VO_MANAGER": "test", - "BA_USERNAME_GROUP_MANAGER": "groupManager", - "BA_PASSWORD_GROUP_MANAGER": "test", - "BA_USERNAME_FACILITY_MANAGER": "facilityManager", - "BA_PASSWORD_FACILITY_MANAGER": "test", - "BA_USERNAME_RESOURCE_MANAGER": "resourceManager", - "BA_PASSWORD_RESOURCE_MANAGER": "test" - } -} diff --git a/apps/admin-gui-e2e/src/integration/facility-management-perun_admin.spec.js b/apps/admin-gui-e2e/src/e2e/facility-management-perun_admin.cy.js similarity index 77% rename from apps/admin-gui-e2e/src/integration/facility-management-perun_admin.spec.js rename to apps/admin-gui-e2e/src/e2e/facility-management-perun_admin.cy.js index 0586122a9..9066d22fd 100644 --- a/apps/admin-gui-e2e/src/integration/facility-management-perun_admin.spec.js +++ b/apps/admin-gui-e2e/src/e2e/facility-management-perun_admin.cy.js @@ -16,17 +16,17 @@ context('Actions', () => { sessionStorage.setItem('basicPassword', Cypress.env('BA_PASSWORD_FACILITY_MANAGER')); cy.visit('service-access'); } - }) + }); beforeEach(() => { // save route for correct authorization localStorage.setItem('routeAuthGuard', '/facilities'); cy.visit('facilities'); - }) + }); it('test create facility', () => { - - cy.intercept('**/facilitiesManager/getFacilities').as('getFacilities') + cy.intercept('**/facilitiesManager/getFacilities') + .as('getFacilities') .get('[data-cy=new-facility-button]') .click() .wait('@getFacilities') @@ -36,18 +36,19 @@ context('Actions', () => { .type('test-e2e-facility-description') .get('[data-cy=create-facility-button]') .click() - .intercept('**/facilitiesManager/getEnrichedFacilities').as('getEnrichedFacilities') + .intercept('**/facilitiesManager/getEnrichedFacilities') + .as('getEnrichedFacilities') .wait('@getEnrichedFacilities') // assert that the facility was created .get('[data-cy=auto-focused-filter]') .type('test-e2e-facility') .get('[data-cy=test-e2e-facility-checkbox]') - .should('exist') + .should('exist'); }); it('test delete facility', () => { - - cy.intercept('**/facilitiesManager/getEnrichedFacilities').as('getEnrichedFacilities') + cy.intercept('**/facilitiesManager/getEnrichedFacilities') + .as('getEnrichedFacilities') .wait('@getEnrichedFacilities') .get(`[data-cy=${dbFacilityName1}-checkbox]`) .click() @@ -57,13 +58,14 @@ context('Actions', () => { .click() .wait('@getEnrichedFacilities') .get(`[data-cy=${dbFacilityName1}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test create resource', () => { - - cy.intercept('**/facilitiesManager/getEnrichedFacilities').as('getEnrichedFacilities') - .intercept('**/vosManager/getAllVos').as('getAllVos') + cy.intercept('**/facilitiesManager/getEnrichedFacilities') + .as('getEnrichedFacilities') + .intercept('**/vosManager/getAllVos') + .as('getAllVos') .wait('@getEnrichedFacilities') .get(`[data-cy=${dbFacilityName2}]`) .click() @@ -81,16 +83,18 @@ context('Actions', () => { .type('test-e2e-resource') .get('[data-cy=create-resource-dialog-button]') .click() - .intercept('**/facilitiesManager/getAssignedRichResources?**').as('getAssignedResources') + .intercept('**/facilitiesManager/getAssignedRichResources?**') + .as('getAssignedResources') .wait('@getAssignedResources') .get('[data-cy=test-e2e-resource-checkbox]') - .should('exist') + .should('exist'); }); it('test delete resource', () => { - - cy.intercept('**/facilitiesManager/getEnrichedFacilities').as('getEnrichedFacilities') - .intercept('**/facilitiesManager/getAssignedRichResources?**').as('getAssignedResources') + cy.intercept('**/facilitiesManager/getEnrichedFacilities') + .as('getEnrichedFacilities') + .intercept('**/facilitiesManager/getAssignedRichResources?**') + .as('getAssignedResources') .wait('@getEnrichedFacilities') .get(`[data-cy=${dbFacilityName2}]`) .click() @@ -105,12 +109,12 @@ context('Actions', () => { .click() .wait('@getAssignedResources') .get(`[data-cy=${dbResourceName}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test add attribute', () => { - - cy.intercept('**/facilitiesManager/getEnrichedFacilities').as('getEnrichedFacilities') + cy.intercept('**/facilitiesManager/getEnrichedFacilities') + .as('getEnrichedFacilities') .wait('@getEnrichedFacilities') .get(`[data-cy=${dbFacilityName2}]`) .click() @@ -124,16 +128,17 @@ context('Actions', () => { .type('einfra') .get('[data-cy=save-selected-attributes]') .click() - .intercept('**/attributesManager/getAttributes/**').as('getAttributes') + .intercept('**/attributesManager/getAttributes/**') + .as('getAttributes') .wait('@getAttributes') // assert that attribute exists .get(`[data-cy=${addedAttribute}-value]`) - .should('exist') + .should('exist'); }); it('test delete attribute', () => { - - cy.intercept('**/facilitiesManager/getEnrichedFacilities').as('getEnrichedFacilities') + cy.intercept('**/facilitiesManager/getEnrichedFacilities') + .as('getEnrichedFacilities') .wait('@getEnrichedFacilities') .get(`[data-cy=${dbFacilityName2}]`) .click() @@ -145,17 +150,19 @@ context('Actions', () => { .click() .get('[data-cy=delete-attributes]') .click() - .intercept('**/attributesManager/getAttributes/**').as('getAttributes') + .intercept('**/attributesManager/getAttributes/**') + .as('getAttributes') .wait('@getAttributes') // assert that attribute exists .get(`[data-cy=${deleteAttribute}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test add facility manager', () => { - - cy.intercept('**/facilitiesManager/getEnrichedFacilities').as('getEnrichedFacilities') - .intercept('**/usersManager/findRichUsersWithAttributes?**').as('findRichUsers') + cy.intercept('**/facilitiesManager/getEnrichedFacilities') + .as('getEnrichedFacilities') + .intercept('**/usersManager/findRichUsersWithAttributes?**') + .as('findRichUsers') .wait('@getEnrichedFacilities') .get(`[data-cy=${dbFacilityName2}]`) .click() @@ -174,16 +181,17 @@ context('Actions', () => { .click() .get('[data-cy=add-manager-button-dialog]') .click() - .intercept('**/authzResolver/getRichAdmins?**').as('getRichAdmins') + .intercept('**/authzResolver/getRichAdmins?**') + .as('getRichAdmins') .wait('@getRichAdmins') // assert that manager was added .get(`[data-cy=${addManagerUser}-checkbox]`) - .should('exist') + .should('exist'); }); it('test remove facility manager', () => { - - cy.intercept('**/facilitiesManager/getEnrichedFacilities').as('getEnrichedFacilities') + cy.intercept('**/facilitiesManager/getEnrichedFacilities') + .as('getEnrichedFacilities') .wait('@getEnrichedFacilities') .get(`[data-cy=${dbFacilityName2}]`) .click() @@ -197,10 +205,11 @@ context('Actions', () => { .click() .get('[data-cy=remove-manager-button-dialog]') .click() - .intercept('**/authzResolver/getRichAdmins?**').as('getRichAdmins') + .intercept('**/authzResolver/getRichAdmins?**') + .as('getRichAdmins') .wait('@getRichAdmins') // assert that manager doesn't exist .get(`[data-cy=${removeManagerUser}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); -}) +}); diff --git a/apps/admin-gui-e2e/src/integration/group-management-perun_admin.spec.js b/apps/admin-gui-e2e/src/e2e/group-management-perun_admin.cy.js similarity index 76% rename from apps/admin-gui-e2e/src/integration/group-management-perun_admin.spec.js rename to apps/admin-gui-e2e/src/e2e/group-management-perun_admin.cy.js index 239950d68..4ab45396b 100644 --- a/apps/admin-gui-e2e/src/integration/group-management-perun_admin.spec.js +++ b/apps/admin-gui-e2e/src/e2e/group-management-perun_admin.cy.js @@ -19,14 +19,12 @@ context('Actions', () => { }); beforeEach(() => { - cy.visit('home') - .get(`[data-cy=${dbGroupName}]`) - .click(); + cy.visit('home').get(`[data-cy=${dbGroupName}]`).click(); }); it('test create subgroup', () => { - - cy.intercept('**/groupsManager/createGroup/**').as('createGroup') + cy.intercept('**/groupsManager/createGroup/**') + .as('createGroup') .get(`[data-cy=subgroups]`) .click() .get('[data-cy=new-subgroup-button]') @@ -35,19 +33,20 @@ context('Actions', () => { .type('test-group') .get('[data-cy=group-description]') .type('test-group-description') - .intercept('**/groupsManager/getAllRichSubGroupsWithAttributesByNames**').as('getRichSubGroups') + .intercept('**/groupsManager/getAllRichSubGroupsWithAttributesByNames**') + .as('getRichSubGroups') .get('[data-cy=create-group-button-dialog]') .click() .wait('@createGroup') .wait('@getRichSubGroups') // assert that group was created .get('[data-cy=test-group-checkbox]') - .should('exist') - }); + .should('exist'); + }); it('test remove subgroup', () => { - - cy.intercept('**/groupsManager/deleteGroups').as('deleteGroups') + cy.intercept('**/groupsManager/deleteGroups') + .as('deleteGroups') .get('[data-cy=subgroups]') .click() .get(`[data-cy=${dbSubGroupName}-checkbox]`) @@ -57,16 +56,17 @@ context('Actions', () => { .get('[data-cy=delete-button-dialog]') .click() .wait('@deleteGroups') - .intercept('**/groupsManager/getAllRichSubGroupsWithAttributesByNames**').as('getRichSubGroups') + .intercept('**/groupsManager/getAllRichSubGroupsWithAttributesByNames**') + .as('getRichSubGroups') .wait('@getRichSubGroups') // assert that group was deleted .get(`[data-cy=${dbSubGroupName}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test add attribute', () => { - - cy.intercept('**/attributesManager/setAttributes/**').as('setAttributes') + cy.intercept('**/attributesManager/setAttributes/**') + .as('setAttributes') .get('[data-cy=attributes]') .click() .get('[data-cy=add-attributes]') @@ -78,35 +78,37 @@ context('Actions', () => { .get('[data-cy=save-selected-attributes]') .click() .wait('@setAttributes') - .intercept('**/attributesManager/getAttributes/g**').as('getAttributes') + .intercept('**/attributesManager/getAttributes/g**') + .as('getAttributes') .wait('@getAttributes') // assert that attribute exists .get(`[data-cy=${addedAttribute}-value]`) - .should('exist') + .should('exist'); }); it('test delete attribute', () => { - - cy.intercept('**/attributesManager/removeAttributes/**').as('removeAttributes') + cy.intercept('**/attributesManager/removeAttributes/**') + .as('removeAttributes') .get('[data-cy=attributes]') .click() .get(`[data-cy=${dbGroupAttribute}-checkbox]`) .click() .get('[data-cy=remove-attributes]') .click() - .intercept('**/attributesManager/getAttributes/g**').as('getAttributes') + .intercept('**/attributesManager/getAttributes/g**') + .as('getAttributes') .get('[data-cy=delete-attributes]') .click() .wait('@removeAttributes') .wait('@getAttributes') // assert that attribute exists .get(`[data-cy=${dbGroupAttribute}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test add group member', () => { - - cy.intercept('**/groupsManager/addMember**').as('addMember') + cy.intercept('**/groupsManager/addMember**') + .as('addMember') .get('[data-cy=members]') .click() .get('[data-cy=add-members]') @@ -118,16 +120,17 @@ context('Actions', () => { .get('[data-cy=add-button]') .click() .wait('@addMember') - .intercept('**/membersManager/getMembersPage').as('getMembers') + .intercept('**/membersManager/getMembersPage') + .as('getMembers') .wait('@getMembers') // assert that member was created .get(`[data-cy=${dbUser}-checkbox]`) - .should('exist') + .should('exist'); }); it('test remove group member', () => { - - cy.intercept('**/groupsManager/removeMember**').as('removeMember') + cy.intercept('**/groupsManager/removeMember**') + .as('removeMember') .get('[data-cy=members]') .click() .get(`[data-cy=${dbGroupManager}-checkbox]`) @@ -137,16 +140,17 @@ context('Actions', () => { .get('[data-cy=remove-members-dialog]') .click() .wait('@removeMember') - .intercept('**/membersManager/getMembersPage').as('getMembers') + .intercept('**/membersManager/getMembersPage') + .as('getMembers') .wait('@getMembers') // assert that member was removed .get(`[data-cy=${dbGroupManager}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test create group application form item', () => { - - cy.intercept('**/registrarManager/updateFormItems/**').as('addFormItem') + cy.intercept('**/registrarManager/updateFormItems/**') + .as('addFormItem') .get('[data-cy=advanced-settings]') .click() .get('[data-cy=application-form]') @@ -159,7 +163,8 @@ context('Actions', () => { .click() .get('[data-cy=edit-form-item-button-dialog]') .click() - .intercept('**/registrarManager/getFormItems/group**').as('getAttributes') + .intercept('**/registrarManager/getFormItems/group**') + .as('getAttributes') .get('[data-cy=save-application-form]') .click() .wait('@getAttributes') @@ -169,18 +174,20 @@ context('Actions', () => { // assert that form item exists .wait('@getAttributes') .get('[data-cy=header-delete]') - .should('exist') - }); + .should('exist'); + }); it('test delete group application form item', () => { - cy.intercept('**/registrarManager/updateFormItems/**').as('deleteFormItem') + cy.intercept('**/registrarManager/updateFormItems/**') + .as('deleteFormItem') .get('[data-cy=advanced-settings]') .click() .get('[data-cy=application-form]') .click() .get(`[data-cy=${dbApplicationItemTextFieldName}-delete]`) .click() - .intercept('**/registrarManager/getFormItems/group**').as('getGroupFormItems') + .intercept('**/registrarManager/getFormItems/group**') + .as('getGroupFormItems') .get('[data-cy=delete-application-form-item-dialog]') .click() .get('[data-cy=save-application-form]') @@ -192,12 +199,12 @@ context('Actions', () => { .wait('@getGroupFormItems') // assert that form item doesn't exist .get(`[data-cy=${dbApplicationItemTextFieldName}-delete]`) - .should('not.exist') + .should('not.exist'); }); it('test add group manager', () => { - - cy.intercept('**/authzResolver/setRole/**').as('setRole') + cy.intercept('**/authzResolver/setRole/**') + .as('setRole') .get('[data-cy=advanced-settings]') .click() .get('[data-cy=managers]') @@ -210,19 +217,20 @@ context('Actions', () => { .click() .get(`[data-cy=${dbUser}-checkbox]`) .click() - .intercept('**/authzResolver/getRichAdmins**').as('getRichAdmins') + .intercept('**/authzResolver/getRichAdmins**') + .as('getRichAdmins') .get('[data-cy=add-manager-button-dialog]') .click() .wait('@setRole') .wait('@getRichAdmins') // assert that manager was added .get(`[data-cy=${dbUser}-checkbox]`) - .should('exist') + .should('exist'); }); it('test remove group manager', () => { - - cy.intercept('**/authzResolver/unsetRole/**').as('unsetRole') + cy.intercept('**/authzResolver/unsetRole/**') + .as('unsetRole') .get('[data-cy=advanced-settings]') .click() .get('[data-cy=managers]') @@ -231,13 +239,14 @@ context('Actions', () => { .click() .get('[data-cy=remove-manager-button]') .click() - .intercept('**/authzResolver/getRichAdmins**').as('getRichAdmins') + .intercept('**/authzResolver/getRichAdmins**') + .as('getRichAdmins') .get('[data-cy=remove-manager-button-dialog]') .click() .wait('@unsetRole') .wait('@getRichAdmins') // assert that manager doesn't exist .get(`[data-cy=${dbGroupManager}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); }); diff --git a/apps/admin-gui-e2e/src/integration/perun-admin-management-perun_admin.spec.js b/apps/admin-gui-e2e/src/e2e/perun-admin-management-perun_admin.cy.js similarity index 79% rename from apps/admin-gui-e2e/src/integration/perun-admin-management-perun_admin.spec.js rename to apps/admin-gui-e2e/src/e2e/perun-admin-management-perun_admin.cy.js index 1fc011ec5..3864b73da 100644 --- a/apps/admin-gui-e2e/src/integration/perun-admin-management-perun_admin.spec.js +++ b/apps/admin-gui-e2e/src/e2e/perun-admin-management-perun_admin.cy.js @@ -17,18 +17,19 @@ context('Actions', () => { sessionStorage.setItem('basicPassword', Cypress.env('BA_PASSWORD')); cy.visit('service-access'); } - }) + }); beforeEach(() => { // save route for correct authorization localStorage.setItem('routeAuthGuard', '/admin'); cy.visit('admin'); - }) + }); it('test create attribute', () => { - - cy.intercept('**/attributesManager/createAttribute**').as('createAttribute') - .intercept('**/attributesManager/getAttributesDefinition**').as('getAttributesDefinition') + cy.intercept('**/attributesManager/createAttribute**') + .as('createAttribute') + .intercept('**/attributesManager/getAttributesDefinition**') + .as('getAttributesDefinition') .get('[data-cy=attribute-definitions]') .click() .get('[data-cy=new-attr-definition-button]') @@ -62,13 +63,14 @@ context('Actions', () => { .get('[data-cy=unfocused-filter]') .type('testAttrE2E') .get('[data-cy=testattre2e-checkbox]') - .should('exist') + .should('exist'); }); it('test delete attribute', () => { - - cy.intercept('**/attributesManager/deleteAttributes**').as('deleteAttributes') - .intercept('**/attributesManager/getAttributesDefinition**').as('getAttributesDefinition') + cy.intercept('**/attributesManager/deleteAttributes**') + .as('deleteAttributes') + .intercept('**/attributesManager/getAttributesDefinition**') + .as('getAttributesDefinition') .get('[data-cy=attribute-definitions]') .click() .get('[data-cy=e2e-test-attr-from-db-checkbox]') @@ -81,13 +83,14 @@ context('Actions', () => { .wait('@getAttributesDefinition') // assert that attribute doesn't exist .get(`[data-cy=e2e-test-attr-from-db-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test change users name', () => { - - cy.intercept('**/usersManager/updateUser**').as('updateUser') - .intercept('**/usersManager/getUserById**').as('getUserById') + cy.intercept('**/usersManager/updateUser**') + .as('updateUser') + .intercept('**/usersManager/getUserById**') + .as('getUserById') .get('[data-cy=users]') .click() .get('[data-cy=test5-td]') @@ -96,41 +99,43 @@ context('Actions', () => { .click() .get('[data-cy=user-first-name-input]') .clear() - .type("Test555") + .type('Test555') .get('[data-cy=user-save-button]') .click() .wait('@updateUser') .wait('@getUserById') // assert that the name changed .get('[data-cy=user-name-link]') - .contains('Test555 User14') + .contains('Test555 User14'); }); it('test create service', () => { - - cy.intercept('**/servicesManager/createService**').as('createService') - .intercept('**/servicesManager/getServices**').as('getServices') + cy.intercept('**/servicesManager/createService**') + .as('createService') + .intercept('**/servicesManager/getServices**') + .as('getServices') .get('[data-cy=services]') .click() .get('[data-cy=service-create-button]') .click() .get('[data-cy=service-name-input]') - .type("e2e_test_service") + .type('e2e_test_service') .get('[data-cy=service-description-input]') - .type("testing service") + .type('testing service') .get('[data-cy=service-create-edit-dialog-button]') .click() .wait('@createService') .wait('@getServices') // assert that service exists .get('[data-cy=e2e_test_service-checkbox]') - .should('exist') + .should('exist'); }); it('test delete service', () => { - - cy.intercept('**/servicesManager/deleteService**').as('deleteService') - .intercept('**/servicesManager/getServices**').as('getServices') + cy.intercept('**/servicesManager/deleteService**') + .as('deleteService') + .intercept('**/servicesManager/getServices**') + .as('getServices') .get('[data-cy=services]') .click() .get(`[data-cy=${dbServiceName.toLowerCase()}-checkbox]`) @@ -143,13 +148,14 @@ context('Actions', () => { .wait('@getServices') // assert that service doesn't exist .get(`[data-cy=${dbServiceName.toLowerCase()}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test rename service', () => { - - cy.intercept('**/servicesManager/updateService**').as('updateService') - .intercept('**/servicesManager/getServiceById**').as('getServiceById') + cy.intercept('**/servicesManager/updateService**') + .as('updateService') + .intercept('**/servicesManager/getServiceById**') + .as('getServiceById') .get('[data-cy=services]') .click() .get(`[data-cy=${dbServiceName2.toLowerCase()}-name-td]`) @@ -165,35 +171,28 @@ context('Actions', () => { .wait('@getServiceById') // assert that service is renamed .get(`[data-cy=service-name-link]`) - .contains(dbServiceName2 + 'edit') + .contains(dbServiceName2 + 'edit'); }); it('test list ext sources', () => { - cy.get('[data-cy=external-sources]') .click() .get(`[data-cy=${dbExtSourceName.toLowerCase()}-name-td]`) - .should('exist') + .should('exist'); }); it('test list audit messages', () => { - - cy.get('[data-cy=audit-log]') - .click() - .get(`[data-cy=audit-message-td]`) - .should('exist') + cy.get('[data-cy=audit-log]').click().get(`[data-cy=audit-message-td]`).should('exist'); }); it('test list consent hubs', () => { - cy.get('[data-cy=consent-hubs]') .click() .get(`[data-cy=${dbConsentHubName.toLowerCase()}-name-td]`) - .should('exist') + .should('exist'); }); it('test search attribute', () => { - cy.get('[data-cy=searcher]') .click() .get(`[data-cy=filter-input]`) @@ -206,6 +205,6 @@ context('Actions', () => { .get('[data-cy=searcher-search-button]') .click() .get(`[data-cy=${dbSearcherUserFirstName.toLowerCase()}-firstName-td]`) - .should('exist') + .should('exist'); }); -}) +}); diff --git a/apps/admin-gui-e2e/src/integration/resource-management-perun_admin.spec.js b/apps/admin-gui-e2e/src/e2e/resource-management-perun_admin.cy.js similarity index 81% rename from apps/admin-gui-e2e/src/integration/resource-management-perun_admin.spec.js rename to apps/admin-gui-e2e/src/e2e/resource-management-perun_admin.cy.js index f902a3c1d..3f5b17236 100644 --- a/apps/admin-gui-e2e/src/integration/resource-management-perun_admin.spec.js +++ b/apps/admin-gui-e2e/src/e2e/resource-management-perun_admin.cy.js @@ -29,47 +29,46 @@ context('Actions', () => { .get('[data-cy=resource-list]') .click() .get(`[data-cy=${dbResourceName}]`) - .click() - }) + .click(); + }); it('test add attribute', () => { - cy.get('[data-cy=attributes]') .click() .get('[data-cy=add-attributes]') .click() .get(`[data-cy=${dbAttributeToAdd}-value]`) .type('test') - .intercept('**/attributesManager/getAttributes/r**').as('getAttributes') + .intercept('**/attributesManager/getAttributes/r**') + .as('getAttributes') .get('[data-cy=save-selected-attributes]') .click() .wait('@getAttributes') // check that attribute was added .get(`[data-cy=${dbAttributeToAdd}-value]`) - .should('exist') + .should('exist'); }); it('test delete attribute', () => { - cy.get('[data-cy=attributes]') .click() .get(`[data-cy=${dbAttributeToDelete}-checkbox]`) .click() .get('[data-cy=remove-attributes]') .click() - .intercept('**/attributesManager/getAttributes/r**').as('getAttributes') + .intercept('**/attributesManager/getAttributes/r**') + .as('getAttributes') .get('[data-cy=delete-attributes]') .click() .wait('@getAttributes') // check that attribute was deleted .get(`[data-cy=${dbAttributeToDelete}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test add resource manager', () => { - cy.get('[data-cy=advanced-settings]') .click() .get('[data-cy=managers]') @@ -82,18 +81,18 @@ context('Actions', () => { .click() .get(`[data-cy=${dbAddManager}-checkbox]`) .click() - .intercept('**/authzResolver/getRichAdmins**').as('getRichAdmins') + .intercept('**/authzResolver/getRichAdmins**') + .as('getRichAdmins') .get('[data-cy=add-manager-button-dialog]') .click() .wait('@getRichAdmins') // assert that manager was added .get(`[data-cy=${dbAddManager}-checkbox]`) - .should('exist') + .should('exist'); }); it('test remove resource manager', () => { - cy.get('[data-cy=advanced-settings]') .click() .get('[data-cy=managers]') @@ -102,18 +101,18 @@ context('Actions', () => { .click() .get('[data-cy=remove-manager-button]') .click() - .intercept('**/authzResolver/getRichAdmins**').as('getRichAdmins') + .intercept('**/authzResolver/getRichAdmins**') + .as('getRichAdmins') .get('[data-cy=remove-manager-button-dialog]') .click() .wait('@getRichAdmins') // assert that manager was removed .get(`[data-cy=${dbRemoveManager}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); - it( 'test assign group to resource', () => { - + it('test assign group to resource', () => { cy.get('[data-cy=assigned-groups]') .click() .get('[data-cy=add-group-button]') @@ -122,31 +121,32 @@ context('Actions', () => { .click() .get('[data-cy=next-button]') .click() - .intercept('**/resourcesManager/getGroupAssignments**').as('getGroupAssignments') + .intercept('**/resourcesManager/getGroupAssignments**') + .as('getGroupAssignments') .get('[data-cy=assign-button]') .click() .wait('@getGroupAssignments') - // assert that group was added + // assert that group was added .get(`[data-cy=${dbGroupToAssign}-checkbox]`) - .should('exist') - }) - - it( 'test remove group from resource', () => { + .should('exist'); + }); + it('test remove group from resource', () => { cy.get('[data-cy=assigned-groups]') .click() .get(`[data-cy=${dbGroupToRemove}-checkbox]`) .click() .get('[data-cy=remove-group-button]') .click() - .intercept('**/resourcesManager/getGroupAssignments**').as('getGroupAssignments') + .intercept('**/resourcesManager/getGroupAssignments**') + .as('getGroupAssignments') .get('[data-cy=delete-button]') .click() .wait('@getGroupAssignments') // assert that group was removed .get(`[data-cy=${dbGroupToRemove}-checkbox]`) - .should('not.exist') - }) -}) + .should('not.exist'); + }); +}); diff --git a/apps/admin-gui-e2e/src/e2e/top-group-creator-perun_admin.cy.js b/apps/admin-gui-e2e/src/e2e/top-group-creator-perun_admin.cy.js new file mode 100644 index 000000000..2aba20b52 --- /dev/null +++ b/apps/admin-gui-e2e/src/e2e/top-group-creator-perun_admin.cy.js @@ -0,0 +1,38 @@ +context('Actions', () => { + const dbVoName = 'test-e2e-vo-from-db-4'; + const groupName = 'test'; + + before(() => { + if (Cypress.env('BA_PASSWORD_TOP_GROUP_CREATOR')) { + sessionStorage.setItem('baPrincipal', '{"name": "topGroupCreator"}'); + sessionStorage.setItem('basicUsername', Cypress.env('BA_PASSWORD_TOP_GROUP_CREATOR')); + sessionStorage.setItem('basicPassword', Cypress.env('BA_PASSWORD_TOP_GROUP_CREATOR')); + cy.visit('service-access'); + } + }); + + beforeEach(() => { + cy.visit('organizations') + .get(`[data-cy=${dbVoName}]`) + .click() + .get('[data-cy=groups]') + .click() + }) + + it( 'test create top group', () => { + cy.intercept('**/groupsManager/createGroup/**').as('createGroup') + .get('[data-cy=create-group-button]') + .click() + .get('[data-cy=group-name]') + .type(groupName) + .get('[data-cy=create-group-button-dialog]') + .click() + .wait('@createGroup') + .intercept('**/groupsManager/getAllRichGroupsWithAttributesByNames**').as('getRichGroups') + .wait('@getRichGroups') + // assert that top group was created + .get(`[data-cy=${groupName}-checkbox]`) + .should('exist'); + }); + +}) diff --git a/apps/admin-gui-e2e/src/integration/vo-management-perun_admin.spec.js b/apps/admin-gui-e2e/src/e2e/vo-management-perun_admin.cy.js similarity index 78% rename from apps/admin-gui-e2e/src/integration/vo-management-perun_admin.spec.js rename to apps/admin-gui-e2e/src/e2e/vo-management-perun_admin.cy.js index 372dbf465..895f43882 100644 --- a/apps/admin-gui-e2e/src/integration/vo-management-perun_admin.spec.js +++ b/apps/admin-gui-e2e/src/e2e/vo-management-perun_admin.cy.js @@ -16,16 +16,17 @@ context('Actions', () => { sessionStorage.setItem('basicPassword', Cypress.env('BA_PASSWORD_VO_MANAGER')); cy.visit('service-access'); } - }) + }); beforeEach(() => { cy.visit('organizations'); - }) + }); it('test create vo', () => { - - cy.intercept('**/vosManager/createVo/**').as('createVo') - .intercept('**/vosManager/getEnrichedVoById**').as('getVoById') + cy.intercept('**/vosManager/createVo/**') + .as('createVo') + .intercept('**/vosManager/getEnrichedVoById**') + .as('getVoById') .get('[data-cy=new-vo-button]') .click() .get('[data-cy=vo-name-input]') @@ -40,13 +41,13 @@ context('Actions', () => { .get('[data-cy=vo-name-link]') .contains('test-e2e-vo') .invoke('text') - .then((text) => text === "test-e2e-vo") - .should('exist') + .then((text) => text === 'test-e2e-vo') + .should('exist'); }); it('test add attribute', () => { - - cy.intercept('**/attributesManager/setAttributes/vo').as('setAttributes') + cy.intercept('**/attributesManager/setAttributes/vo') + .as('setAttributes') .get(`[data-cy=${dbVoName}]`) .click() .get('[data-cy=attributes]') @@ -56,19 +57,20 @@ context('Actions', () => { // get attribute Notification default language .get(`[data-cy=${addedAttribute}-value]`) .type('en') - .intercept('**/attributesManager/getAttributes/vo**').as('getAttributes') + .intercept('**/attributesManager/getAttributes/vo**') + .as('getAttributes') .get('[data-cy=save-selected-attributes]') .click() .wait('@setAttributes') .wait('@getAttributes') // assert that attribute exists .get(`[data-cy=${addedAttribute}-value]`) - .should('exist') + .should('exist'); }); it('test delete attribute', () => { - - cy.intercept('**/attributesManager/removeAttributes/**').as('removeAttributes') + cy.intercept('**/attributesManager/removeAttributes/**') + .as('removeAttributes') .get(`[data-cy=${dbVoName}]`) .click() .get('[data-cy=attributes]') @@ -78,19 +80,20 @@ context('Actions', () => { .click() .get('[data-cy=remove-attributes]') .click() - .intercept('**/attributesManager/getAttributes/vo**').as('getAttributes') + .intercept('**/attributesManager/getAttributes/vo**') + .as('getAttributes') .get('[data-cy=delete-attributes]') .click() .wait('@removeAttributes') .wait('@getAttributes') // assert that attribute exists .get('[data-cy=link-to-aup-checkbox]') - .should('not.exist') + .should('not.exist'); }); it('test add vo member', () => { - - cy.intercept('**/membersManager/createMember/u').as('createMember') + cy.intercept('**/membersManager/createMember/u') + .as('createMember') .get(`[data-cy=${dbVoName}]`) .click() .get('[data-cy=members]') @@ -103,17 +106,18 @@ context('Actions', () => { .click() .get('[data-cy=add-button]') .click() - .intercept('**/membersManager/getMembersPage').as('getMembers') + .intercept('**/membersManager/getMembersPage') + .as('getMembers') .wait('@createMember') .wait('@getMembers') // assert that member was created .get(`[data-cy=${dbUser}-checkbox]`) - .should('exist') + .should('exist'); }); it('test remove vo member', () => { - - cy.intercept('**/membersManager/deleteMembers**').as('deleteMembers') + cy.intercept('**/membersManager/deleteMembers**') + .as('deleteMembers') .get(`[data-cy=${dbVoName}]`) .click() .get('[data-cy=members]') @@ -124,17 +128,18 @@ context('Actions', () => { .click() .get('[data-cy=remove-members-dialog]') .click() - .intercept('**/membersManager/getMembersPage').as('getMembers') + .intercept('**/membersManager/getMembersPage') + .as('getMembers') .wait('@deleteMembers') .wait('@getMembers') // assert that member was removed .get(`[data-cy=${dbVoManager}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test add group', () => { - - cy.intercept('**/groupsManager/createGroup/**').as('createGroup') + cy.intercept('**/groupsManager/createGroup/**') + .as('createGroup') .get(`[data-cy=${dbVoName}]`) .click() .get('[data-cy=groups]') @@ -148,16 +153,17 @@ context('Actions', () => { .get('[data-cy=create-group-button-dialog]') .click() .wait('@createGroup') - .intercept('**/groupsManager/getAllRichGroupsWithAttributesByNames**').as('getGroups') + .intercept('**/groupsManager/getAllRichGroupsWithAttributesByNames**') + .as('getGroups') .wait('@getGroups') // assert that group was created .get('[data-cy=test-group-checkbox]') - .should('exist') + .should('exist'); }); it('test remove group', () => { - - cy.intercept('**/groupsManager/deleteGroups').as('deleteGroups') + cy.intercept('**/groupsManager/deleteGroups') + .as('deleteGroups') .get(`[data-cy=${dbVoName}]`) .click() .get('[data-cy=groups]') @@ -169,16 +175,17 @@ context('Actions', () => { .get('[data-cy=delete-button-dialog]') .click() .wait('@deleteGroups') - .intercept('**/groupsManager/getAllRichGroupsWithAttributesByNames**').as('getGroups') + .intercept('**/groupsManager/getAllRichGroupsWithAttributesByNames**') + .as('getGroups') .wait('@getGroups') // assert that group was deleted .get(`[data-cy=${dbGroupName}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test create vo application form item', () => { - - cy.intercept('**/registrarManager/updateFormItems/**').as('addFormItem') + cy.intercept('**/registrarManager/updateFormItems/**') + .as('addFormItem') .get(`[data-cy=${dbVoName}]`) .click() .get('[data-cy=advanced-settings]') @@ -193,7 +200,8 @@ context('Actions', () => { .click() .get('[data-cy=edit-form-item-button-dialog]') .click() - .intercept('**/registrarManager/getFormItems/vo**').as('getFormItems') + .intercept('**/registrarManager/getFormItems/vo**') + .as('getFormItems') .get('[data-cy=save-application-form]') .click() .wait('@addFormItem') @@ -203,13 +211,14 @@ context('Actions', () => { .wait('@getFormItems') // assert that form item exists .get('[data-cy=header-delete]') - .should('exist') + .should('exist'); }); it('test delete vo application form item', () => { - - cy.intercept('**/registrarManager/updateFormItems/**').as('deleteFormItem') - .intercept('**/registrarManager/getFormItems/vo**').as('getFormItems') + cy.intercept('**/registrarManager/updateFormItems/**') + .as('deleteFormItem') + .intercept('**/registrarManager/getFormItems/vo**') + .as('getFormItems') .get(`[data-cy=${dbVoName}]`) .click() .get('[data-cy=advanced-settings]') @@ -228,12 +237,12 @@ context('Actions', () => { .click() // assert that form item doesn't exist .get(`[data-cy=${dbApplicationItemTextFieldName}-delete]`) - .should('not.exist') + .should('not.exist'); }); it('test add vo manager', () => { - - cy.intercept('**/authzResolver/setRole/**').as('setRole') + cy.intercept('**/authzResolver/setRole/**') + .as('setRole') .get(`[data-cy=${dbVoName}]`) .click() .get('[data-cy=advanced-settings]') @@ -250,17 +259,18 @@ context('Actions', () => { .click() .get('[data-cy=add-manager-button-dialog]') .click() - .intercept('**/authzResolver/getRichAdmins**').as('getRichAdmins') + .intercept('**/authzResolver/getRichAdmins**') + .as('getRichAdmins') .wait('@setRole') .wait('@getRichAdmins') // assert that manager was added .get(`[data-cy=${dbUser}-checkbox]`) - .should('exist') + .should('exist'); }); it('test remove vo manager', () => { - - cy.intercept('**/authzResolver/unsetRole/**').as('unsetRole') + cy.intercept('**/authzResolver/unsetRole/**') + .as('unsetRole') .get(`[data-cy=${dbVoName}]`) .click() .get('[data-cy=advanced-settings]') @@ -271,25 +281,26 @@ context('Actions', () => { .click() .get('[data-cy=remove-manager-button]') .click() - .intercept('**/authzResolver/getRichAdmins**').as('getRichAdmins') + .intercept('**/authzResolver/getRichAdmins**') + .as('getRichAdmins') .get('[data-cy=remove-manager-button-dialog]') .click() .wait('@unsetRole') .wait('@getRichAdmins') // assert that manager doesn't exist .get(`[data-cy=${dbVoManager}-checkbox]`) - .should('not.exist') + .should('not.exist'); }); it('test delete vo (perun admin)', () => { - // change role to perun admin sessionStorage.setItem('baPrincipal', '{"name": "perun"}'); sessionStorage.setItem('basicUsername', Cypress.env('BA_USERNAME')); sessionStorage.setItem('basicPassword', Cypress.env('BA_PASSWORD')); cy.reload(); - cy.intercept('**/vosManager/deleteVo**').as('deleteVo') + cy.intercept('**/vosManager/deleteVo**') + .as('deleteVo') .get('[data-cy=auto-focused-filter]') .type(`${dbVoName}`) .get(`[data-cy=${dbVoName}]`) @@ -308,6 +319,6 @@ context('Actions', () => { .get('[data-cy=auto-focused-filter]') .type(`${dbVoName}`) .get(`[data-cy=${dbVoName}]`) - .should('not.exist') + .should('not.exist'); }); -}) +}); diff --git a/apps/admin-gui-e2e/src/support/index.ts b/apps/admin-gui-e2e/src/support/e2e.ts similarity index 100% rename from apps/admin-gui-e2e/src/support/index.ts rename to apps/admin-gui-e2e/src/support/e2e.ts diff --git a/apps/admin-gui-e2e/tsconfig.e2e.json b/apps/admin-gui-e2e/tsconfig.e2e.json index 25a1192c9..a15dd6735 100644 --- a/apps/admin-gui-e2e/tsconfig.e2e.json +++ b/apps/admin-gui-e2e/tsconfig.e2e.json @@ -4,5 +4,5 @@ "sourceMap": false, "outDir": "../../dist/out-tsc" }, - "include": ["src/**/*.ts", "src/**/*.js", "src/plugins/index.js"] + "include": ["src/**/*.ts", "src/**/*.js", "src/plugins/index.js", "cypress.config.ts"] } diff --git a/apps/admin-gui/jest.config.js b/apps/admin-gui/jest.config.ts similarity index 79% rename from apps/admin-gui/jest.config.js rename to apps/admin-gui/jest.config.ts index 946f1ef68..4fe818967 100644 --- a/apps/admin-gui/jest.config.js +++ b/apps/admin-gui/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { preset: '../../jest.preset.js', coverageDirectory: '../../coverage/apps/admin-gui', @@ -8,6 +9,6 @@ module.exports = { snapshotSerializers: [ 'jest-preset-angular/build/serializers/no-ng-attributes', 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment' - ] + 'jest-preset-angular/build/serializers/html-comment', + ], }; diff --git a/apps/admin-gui/src/app/admin/pages/admin-page/admin-consent-hubs/admin-consent-hubs.component.html b/apps/admin-gui/src/app/admin/pages/admin-page/admin-consent-hubs/admin-consent-hubs.component.html index 448a2b720..80b568e47 100644 --- a/apps/admin-gui/src/app/admin/pages/admin-page/admin-consent-hubs/admin-consent-hubs.component.html +++ b/apps/admin-gui/src/app/admin/pages/admin-page/admin-consent-hubs/admin-consent-hubs.component.html @@ -1,16 +1,22 @@

{{'ADMIN.CONSENT_HUBS.TITLE' | translate}}

- + + {{'ADMIN.CONSENT_HUBS.GLOBAL_DISABLED' | translate}} + - + + + diff --git a/apps/admin-gui/src/app/admin/pages/admin-page/admin-consent-hubs/admin-consent-hubs.component.ts b/apps/admin-gui/src/app/admin/pages/admin-page/admin-consent-hubs/admin-consent-hubs.component.ts index 15b9980a3..08a976de0 100644 --- a/apps/admin-gui/src/app/admin/pages/admin-page/admin-consent-hubs/admin-consent-hubs.component.ts +++ b/apps/admin-gui/src/app/admin/pages/admin-page/admin-consent-hubs/admin-consent-hubs.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { ConsentHub, ConsentsManagerService } from '@perun-web-apps/perun/openapi'; import { TABLE_CONSENT_HUBS } from '@perun-web-apps/config/table-config'; import { SelectionModel } from '@angular/cdk/collections'; -import { GuiAuthResolver, NotificatorService } from '@perun-web-apps/perun/services'; +import { GuiAuthResolver, NotificatorService, StoreService } from '@perun-web-apps/perun/services'; import { getDefaultDialogConfig } from '@perun-web-apps/perun/utils'; import { UniversalConfirmationItemsDialogComponent } from '@perun-web-apps/perun/dialogs'; import { TranslateService } from '@ngx-translate/core'; @@ -19,16 +19,19 @@ export class AdminConsentHubsComponent implements OnInit { selection = new SelectionModel(true, []); filterValue = ''; consentHubs: ConsentHub[] = []; + globalForceConsents: boolean; constructor( private consentsManager: ConsentsManagerService, public authResolver: GuiAuthResolver, private notificator: NotificatorService, private translate: TranslateService, + private store: StoreService, private dialog: MatDialog ) {} ngOnInit(): void { + this.globalForceConsents = this.store.getProperty('enforce_consents'); this.refreshTable(); } diff --git a/apps/admin-gui/src/app/admin/pages/admin-page/admin-visualizer/user-destination-relationship/user-destination-relationship.component.ts b/apps/admin-gui/src/app/admin/pages/admin-page/admin-visualizer/user-destination-relationship/user-destination-relationship.component.ts index da0e4bae1..b30b08d81 100644 --- a/apps/admin-gui/src/app/admin/pages/admin-page/admin-visualizer/user-destination-relationship/user-destination-relationship.component.ts +++ b/apps/admin-gui/src/app/admin/pages/admin-page/admin-visualizer/user-destination-relationship/user-destination-relationship.component.ts @@ -1,5 +1,5 @@ import { Component, HostBinding, OnInit } from '@angular/core'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; import { Observable } from 'rxjs'; import { debounceTime, distinctUntilChanged, switchMap, tap } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; @@ -21,7 +21,7 @@ import { export class UserDestinationRelationshipComponent implements OnInit { @HostBinding('class.router-component') true; - searchField: FormControl = new FormControl(); + searchField: UntypedFormControl = new UntypedFormControl(); users: Observable; chosenService = ''; availableServices: string[] = []; diff --git a/apps/admin-gui/src/app/core/services/common/cache-route-reuse-strategy.ts b/apps/admin-gui/src/app/core/services/common/cache-route-reuse-strategy.ts index 29b8ee8f9..8dd318875 100644 --- a/apps/admin-gui/src/app/core/services/common/cache-route-reuse-strategy.ts +++ b/apps/admin-gui/src/app/core/services/common/cache-route-reuse-strategy.ts @@ -1,5 +1,5 @@ -import { RouteReuseStrategy } from '@angular/router/'; -import { ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router'; +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router'; import { VoMembersComponent } from '../../../vos/pages/vo-detail-page/vo-members/vo-members.component'; import { VoGroupsComponent } from '../../../vos/pages/vo-detail-page/vo-groups/vo-groups.component'; import { VoApplicationsComponent } from '../../../vos/pages/vo-detail-page/vo-applications/vo-applications.component'; @@ -15,7 +15,6 @@ import { VoResourcesStatesComponent } from '../../../vos/pages/vo-detail-page/vo import { AdminUsersComponent } from '../../../admin/pages/admin-page/admin-users/admin-users.component'; import { VoSettingsApplicationFormComponent } from '../../../vos/pages/vo-detail-page/vo-settings/vo-settings-application-form/vo-settings-application-form.component'; import { GroupSettingsApplicationFormComponent } from '../../../vos/pages/group-detail-page/group-settings/group-settings-application-form/group-settings-application-form.component'; -import { Injectable } from '@angular/core'; import { VoSelectPageComponent } from '../../../vos/pages/vo-select-page/vo-select-page.component'; import { FacilitySelectPageComponent } from '../../../facilities/pages/facility-select-page/facility-select-page.component'; import { VoSettingsSponsoredMembersComponent } from '../../../vos/pages/vo-detail-page/vo-settings/vo-settings-sponsored-members/vo-settings-sponsored-members.component'; @@ -31,124 +30,38 @@ export class CachedRoute { @Injectable() export class CacheRouteReuseStrategy implements RouteReuseStrategy { - // typeToComponentToHandlers: Map>; - private typeToComponentToHandlers: Map>; - - private allowCachePages = [ - { - type: 'vo', - components: [ - VoMembersComponent.id, - VoGroupsComponent.id, - VoApplicationsComponent.id, - VoResourcesPreviewComponent.id, - VoResourcesStatesComponent.id, - VoSettingsApplicationFormComponent.id, - VoSettingsSponsoredMembersComponent.id, - ], - }, - { - type: 'group', - components: [ - GroupMembersComponent.id, - GroupSubgroupsComponent.id, - GroupResourcesComponent.id, - GroupRolesComponent.id, - GroupApplicationsComponent.id, - GroupSettingsApplicationFormComponent.id, - ], - }, - { - type: 'facility', - components: [ - FacilityAllowedGroupsComponent.id, - FacilityResourcesComponent.id, - FacilityAllowedUsersComponent.id, - ], - }, - { - type: 'member', - components: [MemberGroupsComponent.id], - }, - { - type: 'admin', - components: [AdminUsersComponent.id, AdminSearcherComponent.id, AdminServicesComponent.id], - }, - { - type: 'entitySelect', - components: [VoSelectPageComponent.id, FacilitySelectPageComponent.id], - }, - ]; + private handlers = new Map(); + private cachedComponents = new Set([ + VoMembersComponent.id, + VoGroupsComponent.id, + VoApplicationsComponent.id, + VoResourcesPreviewComponent.id, + VoResourcesStatesComponent.id, + VoSettingsApplicationFormComponent.id, + VoSettingsSponsoredMembersComponent.id, + GroupMembersComponent.id, + GroupSubgroupsComponent.id, + GroupResourcesComponent.id, + GroupRolesComponent.id, + GroupApplicationsComponent.id, + GroupSettingsApplicationFormComponent.id, + FacilityAllowedGroupsComponent.id, + FacilityResourcesComponent.id, + FacilityAllowedUsersComponent.id, + MemberGroupsComponent.id, + AdminUsersComponent.id, + AdminSearcherComponent.id, + AdminServicesComponent.id, + VoSelectPageComponent.id, + FacilitySelectPageComponent.id, + ]); private cacheTimeMs = 300_000; - private resets = [ - { - lastValue: null, - resetType: 'vo', - resetPath: ':voId', - param: 'voId', - }, - { - lastValue: null, - resetType: 'group', - resetPath: ':voId/groups/:groupId', - param: 'groupId', - }, - { - lastValue: null, - resetType: 'facility', - resetPath: ':facilityId', - param: 'facilityId', - }, - { - lastValue: null, - resetType: 'member', - resetPath: ':voId/members/:memberId', - param: 'memberId', - }, - { - lastValue: null, - resetType: 'admin', - resetPath: 'admin/users', - }, - ]; - private isUserNavigatingBack = false; - constructor() { - this.typeToComponentToHandlers = new Map>(); - for (const pages of this.allowCachePages) { - this.typeToComponentToHandlers.set(pages.type, new Map()); - } - } - - private static getCurrentTimestamp(): number { - return +Date.now(); - } - - /** - * Parses component name from its source. - * - * @param component in string format - */ - private static getComponentName(component): string { - // eslint-disable-next-line - return component.id as string; - } - - /** - * Returns path from given route. - * - * @param route route - */ - private static getPath(route: ActivatedRouteSnapshot): string { - return route.routeConfig?.path ?? ''; - } - - shouldReuseRoute(before: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { - this.checkResets(curr); - return before.routeConfig === curr.routeConfig; + shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { + return future.routeConfig === curr.routeConfig; } /** @@ -157,18 +70,10 @@ export class CacheRouteReuseStrategy implements RouteReuseStrategy { * @param route route */ retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null { - if (route.component) { - const componentName = CacheRouteReuseStrategy.getComponentName(route.component); - for (const pages of this.allowCachePages) { - if (pages.components.includes(componentName)) { - const cachedData = this.typeToComponentToHandlers.get(pages.type).get(componentName); + const key = this.getKey(route); + if (!this.handlers.has(key)) return null; - return cachedData === undefined ? null : cachedData.routeHandle; - } - } - } - - return null; + return this.handlers.get(key).routeHandle; } /** @@ -177,24 +82,12 @@ export class CacheRouteReuseStrategy implements RouteReuseStrategy { * @param route route */ shouldAttach(route: ActivatedRouteSnapshot): boolean { - if (!this.isUserNavigatingBack) { + if (!this.isUserNavigatingBack || !route.component) { return false; } - if (route.component) { - const componentName = CacheRouteReuseStrategy.getComponentName(route.component); - for (const pages of this.allowCachePages) { - const cachedData = this.typeToComponentToHandlers.get(pages.type).get(componentName); - if ( - cachedData !== undefined && - CacheRouteReuseStrategy.getCurrentTimestamp() - cachedData.saveTimeStamp < - this.cacheTimeMs - ) { - return true; - } - } - } - return false; + const cachedData = this.handlers.get(this.getKey(route)); + return cachedData && this.getCurrentTimestamp() - cachedData.saveTimeStamp < this.cacheTimeMs; } /** @@ -203,15 +96,8 @@ export class CacheRouteReuseStrategy implements RouteReuseStrategy { * @param route route */ shouldDetach(route: ActivatedRouteSnapshot): boolean { - if (route.component) { - const componentName = CacheRouteReuseStrategy.getComponentName(route.component); - for (const pages of this.allowCachePages) { - if (pages.components.includes(componentName)) { - return true; - } - } - } - return false; + const componentId = this.getComponentId(route.component); + return this.cachedComponents.has(componentId); } /** @@ -221,18 +107,15 @@ export class CacheRouteReuseStrategy implements RouteReuseStrategy { * @param detachedTree handlers */ store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void { - if (route.component) { - while (document.getElementsByTagName('mat-tooltip-component').length > 0) { - document.getElementsByTagName('mat-tooltip-component')[0].remove(); - } - const type = this.getComponentType(route); - this.typeToComponentToHandlers - .get(type) - .set(CacheRouteReuseStrategy.getComponentName(route.component), { - routeHandle: detachedTree, - saveTimeStamp: CacheRouteReuseStrategy.getCurrentTimestamp(), - }); + // Removes active tooltips, so they are not cached + while (document.getElementsByTagName('mat-tooltip-component').length > 0) { + document.getElementsByTagName('mat-tooltip-component')[0].remove(); } + + this.handlers.set(this.getKey(route), { + routeHandle: detachedTree, + saveTimeStamp: this.getCurrentTimestamp(), + }); } setLastNavigationType(type: 'back' | 'direct'): void { @@ -240,44 +123,23 @@ export class CacheRouteReuseStrategy implements RouteReuseStrategy { } /** - * Checks if some resets should be done on given route. - * - * Checks all resets and if their reset condition is fulfilled, pages of - * given type are removed from cache. - * - * @param newRoute new route + * Parses component id from its source. + * @param component as a class */ - private checkResets(newRoute: ActivatedRouteSnapshot): void { - const newPath = CacheRouteReuseStrategy.getPath(newRoute); - - for (const reset of this.resets) { - // if the reset should be used and update it - if (reset.resetPath === newPath) { - const newParamValue = String(newRoute.params[reset.param]); - - // remove all cached pages for given type - if (reset.lastValue !== null && reset.lastValue !== newParamValue) { - this.typeToComponentToHandlers.get(reset.resetType).clear(); - } - - reset.lastValue = newParamValue; - } - } + private getComponentId(component): string { + // eslint-disable-next-line + return component.id as string; } /** - * Get cache type for given component. - * - * @param route route + * Constructs full url from route snapshot, that is used as unique key + * @param route snapshot of activated route */ - private getComponentType(route: ActivatedRouteSnapshot): string { - const componentName = CacheRouteReuseStrategy.getComponentName(route.component); - for (const pages of this.allowCachePages) { - if (pages.components.includes(componentName)) { - return pages.type; - } - } + private getKey(route: ActivatedRouteSnapshot): string { + return route.pathFromRoot.map((r) => r.url.map((segment) => segment.toString())).join('/'); + } - return null; + private getCurrentTimestamp(): number { + return +Date.now(); } } diff --git a/apps/admin-gui/src/app/facilities/pages/facility-configuration-page/facility-configuration-page.component.ts b/apps/admin-gui/src/app/facilities/pages/facility-configuration-page/facility-configuration-page.component.ts index 257218cb9..d9de0da56 100644 --- a/apps/admin-gui/src/app/facilities/pages/facility-configuration-page/facility-configuration-page.component.ts +++ b/apps/admin-gui/src/app/facilities/pages/facility-configuration-page/facility-configuration-page.component.ts @@ -25,7 +25,7 @@ import { NoServiceDialogComponent } from '../../components/no-service-dialog/no- import { ConfigUnsavedDialogComponent } from '../../components/config-unsaved-dialog/config-unsaved-dialog.component'; import { CancelConfigurationDialogComponent } from '../../components/cancel-configuration-dialog/cancel-configuration-dialog.component'; import { Router } from '@angular/router'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { StepperSelectionEvent } from '@angular/cdk/stepper'; @Component({ @@ -53,8 +53,8 @@ export class FacilityConfigurationPageComponent implements OnInit, AfterViewInit availableRoles: string[] = []; filterValue = ''; ATTRIBUTES_IDX = 3; - serviceControl: FormControl = new FormControl(false, Validators.requiredTrue); - attributesControl: FormControl = new FormControl(true, Validators.requiredTrue); + serviceControl: UntypedFormControl = new UntypedFormControl(false, Validators.requiredTrue); + attributesControl: UntypedFormControl = new UntypedFormControl(true, Validators.requiredTrue); private allowNavigate = false; private attributes: Attribute[] = []; private attributeIds: Set = new Set(); diff --git a/apps/admin-gui/src/app/facilities/pages/facility-detail-page/facility-service-config/facility-service-config.component.ts b/apps/admin-gui/src/app/facilities/pages/facility-detail-page/facility-service-config/facility-service-config.component.ts index ec63df904..6f3f18bb5 100644 --- a/apps/admin-gui/src/app/facilities/pages/facility-detail-page/facility-service-config/facility-service-config.component.ts +++ b/apps/admin-gui/src/app/facilities/pages/facility-detail-page/facility-service-config/facility-service-config.component.ts @@ -12,7 +12,7 @@ import { Vo, } from '@perun-web-apps/perun/openapi'; import { MatCheckboxChange } from '@angular/material/checkbox'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; import { UserFullNamePipe } from '@perun-web-apps/perun/pipes'; @@ -27,10 +27,10 @@ export type ServiceSelectValue = 'ALL' | 'NOT_SELECTED'; styleUrls: ['./facility-service-config.component.scss'], }) export class FacilityServiceConfigComponent implements OnInit { - serviceField = new FormControl(); - resourceField = new FormControl(); - groupField = new FormControl(); - memberField = new FormControl(); + serviceField = new UntypedFormControl(); + resourceField = new UntypedFormControl(); + groupField = new UntypedFormControl(); + memberField = new UntypedFormControl(); filteredServices: Observable; filteredResources: Observable; diff --git a/apps/admin-gui/src/app/shared/components/add-owner-dialog/add-owner-dialog.component.ts b/apps/admin-gui/src/app/shared/components/add-owner-dialog/add-owner-dialog.component.ts index 6effcb00e..050f2eb75 100644 --- a/apps/admin-gui/src/app/shared/components/add-owner-dialog/add-owner-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/add-owner-dialog/add-owner-dialog.component.ts @@ -3,7 +3,7 @@ import { MatDialogRef } from '@angular/material/dialog'; import { NotificatorService } from '@perun-web-apps/perun/services'; import { InputCreateOwner, OwnersManagerService } from '@perun-web-apps/perun/openapi'; import { TranslateService } from '@ngx-translate/core'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { emailRegexString } from '@perun-web-apps/perun/utils'; import OwnerTypeEnum = InputCreateOwner.OwnerTypeEnum; @@ -15,8 +15,8 @@ import OwnerTypeEnum = InputCreateOwner.OwnerTypeEnum; export class AddOwnerDialogComponent implements OnInit { successMessage: string; loading: boolean; - nameCtrl: FormControl; - contactCtrl: FormControl; + nameCtrl: UntypedFormControl; + contactCtrl: UntypedFormControl; type = '1'; constructor( @@ -31,11 +31,11 @@ export class AddOwnerDialogComponent implements OnInit { } ngOnInit(): void { - this.nameCtrl = new FormControl(null, [ + this.nameCtrl = new UntypedFormControl(null, [ Validators.required, Validators.pattern('^[\\w.-]+( [\\w.-]+)*$'), ]); - this.contactCtrl = new FormControl(null, [ + this.contactCtrl = new UntypedFormControl(null, [ Validators.required, Validators.pattern(emailRegexString), ]); diff --git a/apps/admin-gui/src/app/shared/components/create-service-member-dialog/create-service-member-dialog.component.ts b/apps/admin-gui/src/app/shared/components/create-service-member-dialog/create-service-member-dialog.component.ts index 47b27aff7..988f2db1a 100644 --- a/apps/admin-gui/src/app/shared/components/create-service-member-dialog/create-service-member-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/create-service-member-dialog/create-service-member-dialog.component.ts @@ -22,7 +22,13 @@ import { StoreService, } from '@perun-web-apps/perun/services'; import { TranslateService } from '@ngx-translate/core'; -import { FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { + UntypedFormBuilder, + UntypedFormControl, + UntypedFormGroup, + ValidatorFn, + Validators, +} from '@angular/forms'; import { SelectionModel } from '@angular/cdk/collections'; import { TABLE_VO_MEMBERS } from '@perun-web-apps/config/table-config'; import { CustomValidators } from '@perun-web-apps/perun/utils'; @@ -40,14 +46,14 @@ export interface CreateServiceMemberDialogData { }) export class CreateServiceMemberDialogComponent implements OnInit, AfterViewInit { @ViewChild('stepper') stepper: MatStepper; - firstFormGroup: FormGroup; - secondFormGroup: FormGroup; + firstFormGroup: UntypedFormGroup; + secondFormGroup: UntypedFormGroup; parsedRules: Map = new Map(); loading: boolean; firstSearchDone = false; - searchCtrl = new FormControl(''); + searchCtrl = new UntypedFormControl(''); members: RichMember[] = []; selection = new SelectionModel(true, []); tableId = TABLE_VO_MEMBERS; @@ -66,7 +72,7 @@ export class CreateServiceMemberDialogComponent implements OnInit, AfterViewInit private translate: TranslateService, private store: StoreService, private apiRequestConfiguration: ApiRequestConfigurationService, - private _formBuilder: FormBuilder, + private _formBuilder: UntypedFormBuilder, private cd: ChangeDetectorRef ) { translate diff --git a/apps/admin-gui/src/app/shared/components/dialogs/add-application-form-item-dialog/add-application-form-item-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/add-application-form-item-dialog/add-application-form-item-dialog.component.ts index 98ecaf220..1051dc7cd 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/add-application-form-item-dialog/add-application-form-item-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/add-application-form-item-dialog/add-application-form-item-dialog.component.ts @@ -4,7 +4,7 @@ import { TranslateService } from '@ngx-translate/core'; import { StoreService } from '@perun-web-apps/perun/services'; import { ApplicationFormItem, Type } from '@perun-web-apps/perun/openapi'; import { createNewApplicationFormItem } from '@perun-web-apps/perun/utils'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; export interface AddApplicationFormItemDialogComponentData { applicationFormItems: ApplicationFormItem[]; @@ -41,7 +41,7 @@ export class AddApplicationFormItemDialogComponent implements OnInit { 'LIST_INPUT_BOX', 'MAP_INPUT_BOX', ]; - nameCtrl: FormControl; + nameCtrl: UntypedFormControl; constructor( private dialogRef: MatDialogRef, @@ -54,7 +54,7 @@ export class AddApplicationFormItemDialogComponent implements OnInit { this.translateService .get('DIALOGS.APPLICATION_FORM_ADD_ITEM.INSERT_TO_BEGINNING') .subscribe((text: string) => { - this.nameCtrl = new FormControl('', [ + this.nameCtrl = new UntypedFormControl('', [ Validators.required, Validators.pattern('.*[\\S]+.*'), Validators.maxLength(129), diff --git a/apps/admin-gui/src/app/shared/components/dialogs/add-edit-notification-dialog/add-edit-notification-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/add-edit-notification-dialog/add-edit-notification-dialog.component.ts index 98d1cfb7a..a3586a671 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/add-edit-notification-dialog/add-edit-notification-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/add-edit-notification-dialog/add-edit-notification-dialog.component.ts @@ -125,18 +125,9 @@ export class AddEditNotificationDialogComponent implements OnInit { tag: string, format: string ): void { - let place: HTMLInputElement | HTMLTextAreaElement; - if (!this.isTextFocused) { - place = - format === 'plain_text' - ? (input.children.item(0) as HTMLInputElement) - : (input.children.item(1) as HTMLInputElement); - } else { - place = - format === 'plain_text' - ? (textarea.children.item(0) as HTMLTextAreaElement) - : (textarea.children.item(1) as HTMLTextAreaElement); - } + const place: HTMLInputElement | HTMLTextAreaElement = this.isTextFocused + ? (textarea.children.item(0) as HTMLTextAreaElement) + : (input.children.item(0) as HTMLInputElement); const position: number = place.selectionStart; if (this.isTextFocused) { if (format === 'html') { diff --git a/apps/admin-gui/src/app/shared/components/dialogs/add-edit-notification-dialog/tag-bar/tag-bar.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/add-edit-notification-dialog/tag-bar/tag-bar.component.ts index e5adbe7f8..1a11dffad 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/add-edit-notification-dialog/tag-bar/tag-bar.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/add-edit-notification-dialog/tag-bar/tag-bar.component.ts @@ -35,6 +35,7 @@ export class TagBarComponent implements OnInit { tags.push(['voName', 'VONAME_DESCRIPTION']); tags.push(['groupName', 'GROUPNAME_DESCRIPTION']); tags.push(['mailFooter', 'MAILFOOTER_DESCRIPTION']); + tags.push(['htmlMailFooter', 'HTMLMAILFOOTER_DESCRIPTION']); tags.push(['errors', 'ERRORS_DESCRIPTION']); tags.push(['customMessage', 'CUSTOMMESSAGE_DESCRIPTION']); tags.push(['fromApp-itemName', 'FROMAPPITEMNAME_DESCRIPTION']); @@ -98,6 +99,7 @@ export class TagBarComponent implements OnInit { tags.push(['groupName', 'USER_INVITATIONS_GROUPNAME_DESCRIPTION']); tags.push(['displayName', 'USER_INVITATIONS_DISPLAYNAME_DESCRIPTION']); tags.push(['mailFooter', 'USER_INVITATIONS_MAILFOOTER_DESCRIPTION']); + tags.push(['htmlMailFooter', 'USER_INVITATIONS_HTMLMAILFOOTER_DESCRIPTION']); tags.push(['invitationLink', 'INVITATIONLINK_DESCRIPTION']); tags.push(['invitationLink-krb', 'INVITATIONLINKKRB_DESCRIPTION']); tags.push(['invitationLink-fed', 'INVITATIONLINKFED_DESCRIPTION']); diff --git a/apps/admin-gui/src/app/shared/components/dialogs/add-group-manager-dialog/add-group-manager-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/add-group-manager-dialog/add-group-manager-dialog.component.ts index d4ae0ce6c..5e7cc2f71 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/add-group-manager-dialog/add-group-manager-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/add-group-manager-dialog/add-group-manager-dialog.component.ts @@ -5,7 +5,7 @@ import { NotificatorService } from '@perun-web-apps/perun/services'; import { ActivatedRoute, Router } from '@angular/router'; import { SelectionModel } from '@angular/cdk/collections'; import { Observable } from 'rxjs'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; import { map, startWith } from 'rxjs/operators'; import { AuthzResolverService, @@ -45,7 +45,7 @@ export class AddGroupManagerDialogComponent implements OnInit { selectedRole: Role; filteredOptions: Observable; - myControl = new FormControl(); + myControl = new UntypedFormControl(); firstSearchDone = false; availableRoles: Role[]; diff --git a/apps/admin-gui/src/app/shared/components/dialogs/add-host-dialog/add-host-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/add-host-dialog/add-host-dialog.component.ts index 87da4f25b..e3aebe67d 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/add-host-dialog/add-host-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/add-host-dialog/add-host-dialog.component.ts @@ -3,7 +3,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { FacilitiesManagerService } from '@perun-web-apps/perun/openapi'; import { NotificatorService } from '@perun-web-apps/perun/services'; import { TranslateService } from '@ngx-translate/core'; -import { AbstractControl, FormControl, ValidatorFn, Validators } from '@angular/forms'; +import { AbstractControl, UntypedFormControl, ValidatorFn, Validators } from '@angular/forms'; export interface AddHostDialogData { theme: string; @@ -18,7 +18,7 @@ export interface AddHostDialogData { export class AddHostDialogComponent implements OnInit { theme: string; loading = false; - hostsCtrl: FormControl; + hostsCtrl: UntypedFormControl; hostPattern = new RegExp( '^(?!:\\/\\/)(?=.{1,255}$)((.{1,63}\\.){1,127}(?![0-9]*$)[a-z0-9-]+\\.?)$|^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$' @@ -43,7 +43,7 @@ export class AddHostDialogComponent implements OnInit { ngOnInit(): void { this.theme = this.data.theme; - this.hostsCtrl = new FormControl('', [Validators.required, this.hostsNameValidator()]); + this.hostsCtrl = new UntypedFormControl('', [Validators.required, this.hostsNameValidator()]); this.hostsCtrl.markAllAsTouched(); } diff --git a/apps/admin-gui/src/app/shared/components/dialogs/add-manager-dialog/add-manager-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/add-manager-dialog/add-manager-dialog.component.ts index 5e43f4263..cc8d0e10a 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/add-manager-dialog/add-manager-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/add-manager-dialog/add-manager-dialog.component.ts @@ -15,7 +15,7 @@ import { import { Role } from '@perun-web-apps/perun/models'; import { TABLE_ADD_MANAGER } from '@perun-web-apps/config/table-config'; import { Urns } from '@perun-web-apps/perun/urns'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; export interface AddManagerDialogData { complementaryObject: Vo | Group | Facility; @@ -40,7 +40,7 @@ export class AddManagerDialogComponent implements OnInit { availableRoles: Role[]; theme: string; tableId = TABLE_ADD_MANAGER; - searchCtrl: FormControl; + searchCtrl: UntypedFormControl; constructor( private dialogRef: MatDialogRef, @@ -63,7 +63,10 @@ export class AddManagerDialogComponent implements OnInit { this.theme = this.data.theme; this.availableRoles = this.data.availableRoles; this.selectedRole = this.data.selectedRole; - this.searchCtrl = new FormControl('', [Validators.required, Validators.pattern('.*[\\S]+.*')]); + this.searchCtrl = new UntypedFormControl('', [ + Validators.required, + Validators.pattern('.*[\\S]+.*'), + ]); } onCancel(): void { diff --git a/apps/admin-gui/src/app/shared/components/dialogs/add-member-dialog/add-member-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/add-member-dialog/add-member-dialog.component.ts index 3f4fc7637..7f44a6afa 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/add-member-dialog/add-member-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/add-member-dialog/add-member-dialog.component.ts @@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { SelectionModel } from '@angular/cdk/collections'; import { MemberCandidate } from '@perun-web-apps/perun/openapi'; import { TABLE_ADD_MEMBER_CANDIDATES_DIALOG } from '@perun-web-apps/config/table-config'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { FailedCandidate } from '../../../../vos/components/add-member.service'; import { MatTableDataSource } from '@angular/material/table'; @@ -26,7 +26,7 @@ export class AddMemberDialogComponent implements OnInit { @Output() search: EventEmitter = new EventEmitter(); @Output() invite: EventEmitter = new EventEmitter(); tableId = TABLE_ADD_MEMBER_CANDIDATES_DIALOG; - searchCtrl: FormControl = new FormControl('', [ + searchCtrl: UntypedFormControl = new UntypedFormControl('', [ Validators.required, Validators.pattern('.*[\\S]+.*'), ]); diff --git a/apps/admin-gui/src/app/shared/components/dialogs/add-member-to-resource-dialog/add-member-to-resource-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/add-member-to-resource-dialog/add-member-to-resource-dialog.component.ts index 6e84ba2b6..e4f6a8be1 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/add-member-to-resource-dialog/add-member-to-resource-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/add-member-to-resource-dialog/add-member-to-resource-dialog.component.ts @@ -16,7 +16,7 @@ import { RichResource, Service, } from '@perun-web-apps/perun/openapi'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; import { map, startWith } from 'rxjs/operators'; import { Observable } from 'rxjs'; import { SelectionModel } from '@angular/cdk/collections'; @@ -41,7 +41,7 @@ export class AddMemberToResourceDialogComponent implements OnInit, AfterViewInit processing = false; membersGroupsId: Set = new Set(); - facilityCtrl: FormControl = new FormControl(); + facilityCtrl: UntypedFormControl = new UntypedFormControl(); filteredFacilities: Observable; facilitiesNames: string[] = []; diff --git a/apps/admin-gui/src/app/shared/components/dialogs/add-services-destination-dialog/add-services-destination-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/add-services-destination-dialog/add-services-destination-dialog.component.ts index 479eafb06..dda05e287 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/add-services-destination-dialog/add-services-destination-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/add-services-destination-dialog/add-services-destination-dialog.component.ts @@ -9,7 +9,7 @@ import { Service, ServicesManagerService, } from '@perun-web-apps/perun/openapi'; -import { AbstractControl, FormControl, ValidatorFn, Validators } from '@angular/forms'; +import { AbstractControl, UntypedFormControl, ValidatorFn, Validators } from '@angular/forms'; import { emailRegexString } from '@perun-web-apps/perun/utils'; export interface AddServicesDestinationDialogData { @@ -27,7 +27,7 @@ export interface AddServicesDestinationDialogData { export class AddServicesDestinationDialogComponent implements OnInit { servicesOnFacility: boolean; services: Service[] = []; - serviceControl: FormControl; + serviceControl: UntypedFormControl; types: string[] = [ 'host', 'user@host', @@ -42,10 +42,10 @@ export class AddServicesDestinationDialogComponent implements OnInit { selectedType = 'host'; propagations: string[] = ['PARALLEL', 'DUMMY']; selectedPropagation = 'PARALLEL'; - destinationControl: FormControl; + destinationControl: UntypedFormControl; useFacilityHost = false; loading = false; - private emailControl: FormControl; + private emailControl: UntypedFormControl; private emailRegex = new RegExp(emailRegexString); private hostPattern = new RegExp( @@ -70,9 +70,9 @@ export class AddServicesDestinationDialogComponent implements OnInit { ) {} ngOnInit(): void { - this.serviceControl = new FormControl(undefined, Validators.required); - this.destinationControl = new FormControl('', this.getDestinationValidator()); - this.emailControl = new FormControl('', [ + this.serviceControl = new UntypedFormControl(undefined, Validators.required); + this.destinationControl = new UntypedFormControl('', this.getDestinationValidator()); + this.emailControl = new UntypedFormControl('', [ Validators.required, Validators.pattern(this.emailRegex), ]); diff --git a/apps/admin-gui/src/app/shared/components/dialogs/add-user-ext-source-dialog/add-user-ext-source-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/add-user-ext-source-dialog/add-user-ext-source-dialog.component.ts index d7f62cf1a..e4c7686c5 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/add-user-ext-source-dialog/add-user-ext-source-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/add-user-ext-source-dialog/add-user-ext-source-dialog.component.ts @@ -5,7 +5,7 @@ import { UserExtSource, UsersManagerService, } from '@perun-web-apps/perun/openapi'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { NotificatorService } from '@perun-web-apps/perun/services'; @@ -23,8 +23,8 @@ interface AddUserExtSourceDialogData { }) export class AddUserExtSourceDialogComponent implements OnInit { filteredExtSources: Observable; - loginControl: FormControl; - extSourcesControl: FormControl; + loginControl: UntypedFormControl; + extSourcesControl: UntypedFormControl; loading: boolean; private extSources: ExtSource[] = []; private successMessage: string; @@ -44,11 +44,11 @@ export class AddUserExtSourceDialogComponent implements OnInit { ngOnInit(): void { this.loading = true; - this.loginControl = new FormControl('', [ + this.loginControl = new UntypedFormControl('', [ Validators.required, Validators.pattern('.*[\\S]+.*'), ]); - this.extSourcesControl = new FormControl('', [Validators.required]); + this.extSourcesControl = new UntypedFormControl('', [Validators.required]); this.loginControl.markAllAsTouched(); this.extSourcesControl.markAllAsTouched(); this.filteredExtSources = this.extSourcesControl.valueChanges.pipe( diff --git a/apps/admin-gui/src/app/shared/components/dialogs/connect-identity-dialog/connect-identity-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/connect-identity-dialog/connect-identity-dialog.component.ts index 341082200..996258c4b 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/connect-identity-dialog/connect-identity-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/connect-identity-dialog/connect-identity-dialog.component.ts @@ -6,7 +6,7 @@ import { TranslateService } from '@ngx-translate/core'; import { TABLE_USER_SERVICE_IDENTITIES } from '@perun-web-apps/config/table-config'; import { SelectionModel } from '@angular/cdk/collections'; import { Urns } from '@perun-web-apps/perun/urns'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; export interface AddUserServiceIdentityData { userId: number; @@ -29,7 +29,7 @@ export class ConnectIdentityDialogComponent implements OnInit { firstSearchDone = false; displayedColumns = ['select', 'id', 'user', 'name', 'email', 'logins', 'organization']; tableId = TABLE_USER_SERVICE_IDENTITIES; - searchCtrl: FormControl; + searchCtrl: UntypedFormControl; private userId: number; private isService: boolean; @@ -47,7 +47,10 @@ export class ConnectIdentityDialogComponent implements OnInit { this.theme = this.data.theme; this.userId = this.data.userId; this.isService = this.data.isService; - this.searchCtrl = new FormControl('', [Validators.required, Validators.pattern('.*[\\S]+.*')]); + this.searchCtrl = new UntypedFormControl('', [ + Validators.required, + Validators.pattern('.*[\\S]+.*'), + ]); } onAdd(): void { diff --git a/apps/admin-gui/src/app/shared/components/dialogs/create-attribute-definition-dialog/create-attribute-definition-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/create-attribute-definition-dialog/create-attribute-definition-dialog.component.ts index d95ad4e27..78a409704 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/create-attribute-definition-dialog/create-attribute-definition-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/create-attribute-definition-dialog/create-attribute-definition-dialog.component.ts @@ -5,7 +5,7 @@ import { AttributePolicyCollection, AttributesManagerService, } from '@perun-web-apps/perun/openapi'; -import { FormBuilder, Validators } from '@angular/forms'; +import { UntypedFormBuilder, Validators } from '@angular/forms'; import { debounceTime, switchMap } from 'rxjs/operators'; import { BehaviorSubject, of, zip } from 'rxjs'; import { AttributeRightsService, NotificatorService } from '@perun-web-apps/perun/services'; @@ -67,7 +67,7 @@ export class CreateAttributeDefinitionDialogComponent { constructor( private dialogRef: MatDialogRef, - private formBuilder: FormBuilder, + private formBuilder: UntypedFormBuilder, private attributeService: AttributesManagerService, private attributeRightsService: AttributeRightsService, private notificator: NotificatorService, diff --git a/apps/admin-gui/src/app/shared/components/dialogs/create-edit-service-dialog/create-edit-service-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/create-edit-service-dialog/create-edit-service-dialog.component.ts index 302ec35d0..5697dfe9b 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/create-edit-service-dialog/create-edit-service-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/create-edit-service-dialog/create-edit-service-dialog.component.ts @@ -2,7 +2,7 @@ import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { NotificatorService } from '@perun-web-apps/perun/services'; import { TranslateService } from '@ngx-translate/core'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { Service, ServicesManagerService } from '@perun-web-apps/perun/openapi'; export interface CreateServiceDialogData { @@ -23,10 +23,13 @@ export class CreateEditServiceDialogComponent implements OnInit { status = true; propagateExpiredMembers = true; - nameControl = new FormControl('', [Validators.required, Validators.pattern('^[a-zA-Z0-9_]+$')]); - delayControl = new FormControl(10, [Validators.pattern('^[0-9]*$')]); - recurrenceControl = new FormControl(2, [Validators.pattern('^[0-9]*$')]); - pathControl = new FormControl('', [Validators.required]); + nameControl = new UntypedFormControl('', [ + Validators.required, + Validators.pattern('^[a-zA-Z0-9_]+$'), + ]); + delayControl = new UntypedFormControl(10, [Validators.pattern('^[0-9]*$')]); + recurrenceControl = new UntypedFormControl(2, [Validators.pattern('^[0-9]*$')]); + pathControl = new UntypedFormControl('', [Validators.required]); asEdit = false; title: string; diff --git a/apps/admin-gui/src/app/shared/components/dialogs/create-facility-dialog/create-facility-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/create-facility-dialog/create-facility-dialog.component.ts index 463e69aa3..5707904b5 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/create-facility-dialog/create-facility-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/create-facility-dialog/create-facility-dialog.component.ts @@ -3,7 +3,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { FacilitiesManagerService, Facility } from '@perun-web-apps/perun/openapi'; import { EntityStorageService, NotificatorService } from '@perun-web-apps/perun/services'; import { TranslateService } from '@ngx-translate/core'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { Router } from '@angular/router'; export interface CreateFacilityDialogData { @@ -17,8 +17,8 @@ export interface CreateFacilityDialogData { }) export class CreateFacilityDialogComponent implements OnInit { theme: string; - nameControl = new FormControl('', [Validators.required]); - descControl = new FormControl(''); + nameControl = new UntypedFormControl('', [Validators.required]); + descControl = new UntypedFormControl(''); facilities: Facility[]; srcFacility: Facility = null; loading = false; diff --git a/apps/admin-gui/src/app/shared/components/dialogs/create-group-dialog/create-group-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/create-group-dialog/create-group-dialog.component.ts index 88a87dab6..1bf944d30 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/create-group-dialog/create-group-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/create-group-dialog/create-group-dialog.component.ts @@ -3,7 +3,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { NotificatorService, StoreService } from '@perun-web-apps/perun/services'; import { Group, GroupsManagerService } from '@perun-web-apps/perun/openapi'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; export interface CreateGroupDialogData { parentGroup: Group; @@ -23,8 +23,8 @@ export class CreateGroupDialogComponent implements OnInit { isNotSubGroup: boolean; asSubgroup = false; invalidNameMessage = this.store.get('group_name_error_message') as string; - nameControl: FormControl; - descriptionControl: FormControl; + nameControl: UntypedFormControl; + descriptionControl: UntypedFormControl; selectedParent: Group; voGroups: Group[] = []; title: string; @@ -64,12 +64,12 @@ export class CreateGroupDialogComponent implements OnInit { this.theme = this.data.theme; this.invalidNameMessage = this.invalidNameMessage && this.secondaryRegex ? this.invalidNameMessage : ''; - this.nameControl = new FormControl('', [ + this.nameControl = new UntypedFormControl('', [ Validators.required, Validators.pattern(this.secondaryRegex ? this.secondaryRegex : ''), Validators.pattern('.*[\\S]+.*'), ]); - this.descriptionControl = new FormControl(''); + this.descriptionControl = new UntypedFormControl(''); this.selectedParent = null; } diff --git a/apps/admin-gui/src/app/shared/components/dialogs/create-resource-dialog/create-resource-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/create-resource-dialog/create-resource-dialog.component.ts index 738137f88..dd035dd9c 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/create-resource-dialog/create-resource-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/create-resource-dialog/create-resource-dialog.component.ts @@ -1,5 +1,5 @@ import { Component, Inject, OnInit } from '@angular/core'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { ResourcesManagerService, Vo, VosManagerService } from '@perun-web-apps/perun/openapi'; import { NotificatorService } from '@perun-web-apps/perun/services'; @@ -16,8 +16,8 @@ export interface CreateResourceDialogData { styleUrls: ['./create-resource-dialog.component.scss'], }) export class CreateResourceDialogComponent implements OnInit { - nameCtrl: FormControl; - descriptionCtrl: FormControl; + nameCtrl: UntypedFormControl; + descriptionCtrl: UntypedFormControl; vos: Vo[] = []; theme: string; @@ -49,8 +49,11 @@ export class CreateResourceDialogComponent implements OnInit { () => (this.loading = false) ); - this.nameCtrl = new FormControl(null, [Validators.required, Validators.pattern('.*[\\S]+.*')]); - this.descriptionCtrl = new FormControl(''); + this.nameCtrl = new UntypedFormControl(null, [ + Validators.required, + Validators.pattern('.*[\\S]+.*'), + ]); + this.descriptionCtrl = new UntypedFormControl(''); } onSubmit(): void { diff --git a/apps/admin-gui/src/app/shared/components/dialogs/create-sponsored-member-dialog/create-sponsored-member-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/create-sponsored-member-dialog/create-sponsored-member-dialog.component.ts index 80676a614..0cbe166ae 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/create-sponsored-member-dialog/create-sponsored-member-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/create-sponsored-member-dialog/create-sponsored-member-dialog.component.ts @@ -15,7 +15,7 @@ import { GuiAuthResolver, StoreService, } from '@perun-web-apps/perun/services'; -import { FormBuilder, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { UntypedFormBuilder, UntypedFormGroup, ValidatorFn, Validators } from '@angular/forms'; import { formatDate } from '@angular/common'; import { TranslateService } from '@ngx-translate/core'; import { Role } from '@perun-web-apps/perun/models'; @@ -47,8 +47,8 @@ export class CreateSponsoredMemberDialogComponent implements OnInit { namespaceOptions: string[] = []; selectedNamespace: string = null; - userControl: FormGroup = null; - namespaceControl: FormGroup = null; + userControl: UntypedFormGroup = null; + namespaceControl: UntypedFormGroup = null; voSponsors: RichUser[] = []; selectedSponsor: User = null; sponsorType = 'self'; @@ -71,7 +71,7 @@ export class CreateSponsoredMemberDialogComponent implements OnInit { private translator: TranslateService, private authzService: AuthzResolverService, private guiAuthResolver: GuiAuthResolver, - private formBuilder: FormBuilder, + private formBuilder: UntypedFormBuilder, private cd: ChangeDetectorRef ) {} diff --git a/apps/admin-gui/src/app/shared/components/dialogs/create-vo-dialog/create-vo-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/create-vo-dialog/create-vo-dialog.component.ts index 57e44b72e..d291da3b0 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/create-vo-dialog/create-vo-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/create-vo-dialog/create-vo-dialog.component.ts @@ -2,7 +2,7 @@ import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { NotificatorService } from '@perun-web-apps/perun/services'; import { TranslateService } from '@ngx-translate/core'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { VosManagerService } from '@perun-web-apps/perun/openapi'; import { Router } from '@angular/router'; @@ -18,8 +18,8 @@ export interface CreateVoDialogData { export class CreateVoDialogComponent implements OnInit { loading: boolean; theme: string; - shortNameCtrl: FormControl; - fullNameCtrl: FormControl; + shortNameCtrl: UntypedFormControl; + fullNameCtrl: UntypedFormControl; private successMessage: string; constructor( @@ -37,12 +37,12 @@ export class CreateVoDialogComponent implements OnInit { ngOnInit(): void { this.theme = this.data.theme; - this.shortNameCtrl = new FormControl(null, [ + this.shortNameCtrl = new UntypedFormControl(null, [ Validators.required, Validators.pattern('^[\\w.-]+$'), Validators.maxLength(33), ]); - this.fullNameCtrl = new FormControl(null, [ + this.fullNameCtrl = new UntypedFormControl(null, [ Validators.required, Validators.pattern('.*[\\S]+.*'), Validators.maxLength(129), diff --git a/apps/admin-gui/src/app/shared/components/dialogs/edit-application-form-item-data-dialog/edit-application-form-item-data-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/edit-application-form-item-data-dialog/edit-application-form-item-data-dialog.component.ts index ae3422d29..5bad94066 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/edit-application-form-item-data-dialog/edit-application-form-item-data-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/edit-application-form-item-data-dialog/edit-application-form-item-data-dialog.component.ts @@ -7,7 +7,7 @@ import { import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { NotificatorService } from '@perun-web-apps/perun/services'; import { TranslateService } from '@ngx-translate/core'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; export interface EditApplicationFormItemDataDialogData { theme: string; @@ -24,8 +24,8 @@ export class EditApplicationFormItemDataDialogComponent implements OnInit { loading = false; theme: string; itemName: string; - inputControl: FormControl = null; - emailControl: FormControl = null; + inputControl: UntypedFormControl = null; + emailControl: UntypedFormControl = null; private formItemData: ApplicationFormItemData; constructor( @@ -51,12 +51,12 @@ export class EditApplicationFormItemDataDialogComponent implements OnInit { this.itemName = EditApplicationFormItemDataDialogComponent.getLabel(this.formItemData.formItem); if (this.itemName.toLowerCase().includes('mail')) { - this.emailControl = new FormControl(this.formItemData.value, [ + this.emailControl = new UntypedFormControl(this.formItemData.value, [ Validators.required, Validators.email, ]); } else { - this.inputControl = new FormControl(this.formItemData.value, [Validators.required]); + this.inputControl = new UntypedFormControl(this.formItemData.value, [Validators.required]); } } diff --git a/apps/admin-gui/src/app/shared/components/dialogs/edit-attribute-definition-dialog/edit-attribute-definition-dialog.component.ts b/apps/admin-gui/src/app/shared/components/dialogs/edit-attribute-definition-dialog/edit-attribute-definition-dialog.component.ts index e41c79c60..ccfe2485b 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/edit-attribute-definition-dialog/edit-attribute-definition-dialog.component.ts +++ b/apps/admin-gui/src/app/shared/components/dialogs/edit-attribute-definition-dialog/edit-attribute-definition-dialog.component.ts @@ -15,7 +15,7 @@ import { TABLE_ENTITYLESS_ATTRIBUTE_KEYS } from '@perun-web-apps/config/table-co import { Clipboard } from '@angular/cdk/clipboard'; import { BehaviorSubject, Observable, of } from 'rxjs'; import { startWith, switchMap } from 'rxjs/operators'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; export interface EditAttributeDefinitionDialogData { attDef: AttributeDefinition; @@ -32,7 +32,7 @@ export class EditAttributeDefinitionDialogComponent implements OnInit { loading = false; showKeys = false; attDef: AttributeDefinition = this.data.attDef; - attributeControl: FormGroup = this.formBuilder.group({ + attributeControl: UntypedFormGroup = this.formBuilder.group({ name: [this.attDef.displayName, Validators.required], description: [this.attDef.description, Validators.required], }); @@ -49,7 +49,7 @@ export class EditAttributeDefinitionDialogComponent implements OnInit { private clipboard: Clipboard, private attributesManager: AttributesManagerService, private serviceService: ServicesManagerService, - private formBuilder: FormBuilder, + private formBuilder: UntypedFormBuilder, private attributeRightsService: AttributeRightsService ) {} diff --git a/apps/admin-gui/src/app/shared/components/dialogs/edit-email-footer-dialog/edit-email-footer-dialog.component.html b/apps/admin-gui/src/app/shared/components/dialogs/edit-email-footer-dialog/edit-email-footer-dialog.component.html index c91a39581..ea2d626fd 100644 --- a/apps/admin-gui/src/app/shared/components/dialogs/edit-email-footer-dialog/edit-email-footer-dialog.component.html +++ b/apps/admin-gui/src/app/shared/components/dialogs/edit-email-footer-dialog/edit-email-footer-dialog.component.html @@ -2,11 +2,24 @@

{{'DIALOGS.NOTIFICATIONS_EDIT_FOOTER.TITLE' | translate}}

-
{{'DIALOGS.NOTIFICATIONS_EDIT_FOOTER.LABEL' | translate}}:
- - - - + + {{'DIALOGS.NOTIFICATIONS_EDIT_FOOTER.FORMAT_HTML_NOT_AUTHORIZED' | translate}} + + + + + + {{'DIALOGS.NOTIFICATIONS_EDIT_FOOTER.FORMAT_' + format | uppercase | translate}} + + + + + + + +
{{'DIALOGS.NOTIFICATIONS_EDIT_FOOTER.DESCRIPTION' | translate}} @@ -18,12 +31,12 @@

{{'DIALOGS.NOTIFICATIONS_EDIT_FOOTER.TITLE' | translate}}
diff --git a/apps/admin-gui/src/app/vos/pages/vo-detail-page/vo-members/vo-members.component.ts b/apps/admin-gui/src/app/vos/pages/vo-detail-page/vo-members/vo-members.component.ts index ddf91c922..d164ea9f3 100644 --- a/apps/admin-gui/src/app/vos/pages/vo-detail-page/vo-members/vo-members.component.ts +++ b/apps/admin-gui/src/app/vos/pages/vo-detail-page/vo-members/vo-members.component.ts @@ -16,7 +16,7 @@ import { VoMemberStatuses, } from '@perun-web-apps/perun/openapi'; import { Urns } from '@perun-web-apps/perun/urns'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; import { TABLE_VO_MEMBERS } from '@perun-web-apps/config/table-config'; import { getDefaultDialogConfig } from '@perun-web-apps/perun/utils'; import { InviteMemberDialogComponent } from '../../../../shared/components/dialogs/invite-member-dialog/invite-member-dialog.component'; @@ -45,7 +45,7 @@ export class VoMembersComponent implements OnInit { Urns.MEMBER_DEF_EXPIRATION, Urns.MEMBER_LIFECYCLE_ALTERABLE, ]; - statuses = new FormControl(); + statuses = new UntypedFormControl(); statusList = ['VALID', 'INVALID', 'EXPIRED', 'DISABLED']; selectedStatuses: VoMemberStatuses[] = []; tableId = TABLE_VO_MEMBERS; diff --git a/apps/admin-gui/src/assets/i18n/en.json b/apps/admin-gui/src/assets/i18n/en.json index d34fbdc87..a7ebb424f 100644 --- a/apps/admin-gui/src/assets/i18n/en.json +++ b/apps/admin-gui/src/assets/i18n/en.json @@ -1328,8 +1328,10 @@ }, "NOTIFICATIONS_EDIT_FOOTER": { "TITLE": "Edit mail footer", - "DESCRIPTION": "This text will be added as a footer for all email notifications (replacing {mailFooter} tag in mail definition).", - "LABEL": "Footer text", + "FORMAT_HTML_NOT_AUTHORIZED": "You are not authorized to create HTML footer, so you can create just plain text footer.", + "FORMAT_HTML": "HTML", + "FORMAT_PLAIN_TEXT": "Plain text", + "DESCRIPTION": "This text will be added as a footer for all email notifications (plain text footer replacing {mailFooter} tag and HTML footer replacing {htmlMailFooter} tag in mail definition).", "SUBMIT_BUTTON": "Save", "CANCEL_BUTTON": "Cancel", "SUCCESS": "Email footer was successfully edited.", @@ -1378,6 +1380,7 @@ "VONAME_DESCRIPTION": "name of organization of application form", "GROUPNAME_DESCRIPTION": "name of group, if application form is for group membership", "MAILFOOTER_DESCRIPTION": "common mail footer defined by organization", + "HTMLMAILFOOTER_DESCRIPTION": "common mail HTML footer defined by organization", "ERRORS_DESCRIPTION": "errors description, what happened while processing new application. Useful for organization administrators", "CUSTOMMESSAGE_DESCRIPTION": "optional message passed by administrators when rejecting an application", "FROMAPPITEMNAME_DESCRIPTION": "value of a form item in user's application. You MUST specify the itemName, e.g. {fromApp-mail} will print value of item with short name 'mail' from user's application.", @@ -1416,6 +1419,7 @@ "USER_INVITATIONS_GROUPNAME_DESCRIPTION": "name of Group to invite user into", "USER_INVITATIONS_DISPLAYNAME_DESCRIPTION": "invited user's name", "USER_INVITATIONS_MAILFOOTER_DESCRIPTION": "common mail footer defined by organization", + "USER_INVITATIONS_HTMLMAILFOOTER_DESCRIPTION": "common mail HTML footer defined by organization", "INVITATIONLINK_DESCRIPTION": "link to registration form. Please make sure you set \"Registrar URL\" setting of your organization/group. If you don't specify authorization in \"Registrar URL\", you can use following options:", "INVITATIONLINKKRB_DESCRIPTION": "link for Kerberos authentication", "INVITATIONLINKFED_DESCRIPTION": "link for Shibboleth IdP (federation) authentication", @@ -2174,7 +2178,10 @@ "NO_FILTER_RESULTS_ALERT": "No members are matching your query", "INDIRECT_MEMBER": "Indirect member", "CHECKBOX_TOOLTIP_INDIRECT": "Indirect members cannot be removed", - "CHECKBOX_TOOLTIP_UNALTERABLE": "Members from member organizations cannot be directly removed" + "CHECKBOX_TOOLTIP_UNALTERABLE": "Members from member organizations cannot be directly removed", + "STATUS_TOOLTIP_INDIRECT": "Member status from member organization cannot be directly changed", + "STATUS_TOOLTIP_GROUP_INDIRECT": "Indirect member status cannot be changed", + "STATUS_TOOLTIP_MEMBERS_GROUP": "Group status in 'members' group cannot be directly changed" }, "MEMBERS_CANDIDATES_LIST": { "STATUS": "Status", @@ -2296,7 +2303,9 @@ "CONFIRM_DIALOG_TITLE": "Evaluate consents confirmation", "CONFIRM_DIALOG_DESCRIPTION": "Are you sure you want to evaluate consents for all selected consent hubs?", "EVALUATION_FINISH": "Consents evaluation completed", - "SEARCH": "Search by Id, Name or Facilities" + "SEARCH": "Search by Id, Name or Facilities", + "GLOBAL_DISABLED": "Global consent enforcing is disabled on this Perun instance, any following changes will have no effect.", + "TOOLTIP": "Global consent enforcing is disabled." }, "SEARCHER": { "TITLE": "Searcher", diff --git a/apps/admin-gui/src/styles.scss b/apps/admin-gui/src/styles.scss index 9a8e3c9e8..4c38bc53c 100644 --- a/apps/admin-gui/src/styles.scss +++ b/apps/admin-gui/src/styles.scss @@ -1565,3 +1565,7 @@ td.mat-cell { .align-checkbox mat-checkbox { margin-top: 7px !important; } + +mat-icon { + overflow: inherit !important; +} diff --git a/apps/admin-gui/src/tsconfig.app.json b/apps/admin-gui/src/tsconfig.app.json index f362f6d18..e821c48cc 100644 --- a/apps/admin-gui/src/tsconfig.app.json +++ b/apps/admin-gui/src/tsconfig.app.json @@ -5,12 +5,6 @@ "outDir": "../out-tsc/app", "types": [] }, - "exclude": [ - "test.ts", - "**/*.spec.ts", - "**/*.test.ts" - ], - "include": [ - "../**/*.ts" - ] + "exclude": ["test.ts", "**/*.spec.ts", "**/*.test.ts", "jest.config.ts"], + "include": ["../**/*.ts"] } diff --git a/apps/admin-gui/src/tsconfig.spec.json b/apps/admin-gui/src/tsconfig.spec.json index 7e776725f..2dc314b02 100644 --- a/apps/admin-gui/src/tsconfig.spec.json +++ b/apps/admin-gui/src/tsconfig.spec.json @@ -2,19 +2,8 @@ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/spec", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] }, - "files": [ - "test.ts", - "polyfills.ts", - "../../../node_modules/cypress/types/mocha/index.d.ts" - ], - "include": [ - "**/*.spec.ts", - "**/*.test.ts", - "**/*.d.ts" - ] + "files": ["test.ts", "polyfills.ts", "../../../node_modules/cypress/types/mocha/index.d.ts"], + "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/apps/admin-gui/tsconfig.app.json b/apps/admin-gui/tsconfig.app.json index a59a8b0f2..ae3bd7e13 100644 --- a/apps/admin-gui/tsconfig.app.json +++ b/apps/admin-gui/tsconfig.app.json @@ -4,11 +4,7 @@ "outDir": "../../dist/out-tsc", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["**/*.d.ts"], + "exclude": ["jest.config.ts"] } diff --git a/apps/admin-gui/tsconfig.editor.json b/apps/admin-gui/tsconfig.editor.json index 41d628dfc..1bf3c0a74 100644 --- a/apps/admin-gui/tsconfig.editor.json +++ b/apps/admin-gui/tsconfig.editor.json @@ -1,12 +1,8 @@ { "extends": "./tsconfig.json", - "include": [ - "**/*.ts" - ], + "include": ["**/*.ts"], "compilerOptions": { - "types": [ - "jest", - "node" - ] - } + "types": ["jest", "node"] + }, + "exclude": ["jest.config.ts"] } diff --git a/apps/admin-gui/tsconfig.json b/apps/admin-gui/tsconfig.json index cfe1aeb1f..d8351e519 100644 --- a/apps/admin-gui/tsconfig.json +++ b/apps/admin-gui/tsconfig.json @@ -1,10 +1,8 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "types": [ - "node", - "jest" - ] + "types": ["node", "jest"], + "target": "es2020" }, "include": [], "files": [], diff --git a/apps/admin-gui/tsconfig.spec.json b/apps/admin-gui/tsconfig.spec.json index f7d307101..b6347c6f6 100644 --- a/apps/admin-gui/tsconfig.spec.json +++ b/apps/admin-gui/tsconfig.spec.json @@ -3,17 +3,8 @@ "compilerOptions": { "outDir": "../../dist/out-tsc", "module": "commonjs", - "types": [ - "jest", - "node" - ] + "types": ["jest", "node"] }, - "files": [ - "src/test-setup.ts" - ], - "include": [ - "**/*.spec.ts", - "**/*.test.ts", - "**/*.d.ts" - ] + "files": ["src/test-setup.ts"], + "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/apps/consolidator-e2e/cypress.config.ts b/apps/consolidator-e2e/cypress.config.ts new file mode 100644 index 000000000..e98c8b794 --- /dev/null +++ b/apps/consolidator-e2e/cypress.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'cypress'; +import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; + +const cypressJsonConfig = { + fileServerFolder: '.', + fixturesFolder: './src/fixtures', + video: true, + videosFolder: '../../dist/cypress/apps/consolidator-e2e/videos', + screenshotsFolder: '../../dist/cypress/apps/consolidator-e2e/screenshots', + chromeWebSecurity: false, + specPattern: 'src/e2e/**/*.cy.{js,jsx,ts,tsx}', + supportFile: 'src/support/e2e.ts', +}; +export default defineConfig({ + e2e: { + ...nxE2EPreset(__dirname), + ...cypressJsonConfig, + }, +}); diff --git a/apps/consolidator-e2e/cypress.json b/apps/consolidator-e2e/cypress.json deleted file mode 100644 index aa900c061..000000000 --- a/apps/consolidator-e2e/cypress.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "fileServerFolder": ".", - "fixturesFolder": "./src/fixtures", - "integrationFolder": "./src/integration", - "modifyObstructiveCode": false, - "supportFile": "./src/support/index.ts", - "pluginsFile": false, - "video": true, - "videosFolder": "../../dist/cypress/apps/consolidator-e2e/videos", - "screenshotsFolder": "../../dist/cypress/apps/consolidator-e2e/screenshots", - "chromeWebSecurity": false -} diff --git a/apps/consolidator-e2e/src/integration/app.spec.ts b/apps/consolidator-e2e/src/e2e/app.cy.ts similarity index 100% rename from apps/consolidator-e2e/src/integration/app.spec.ts rename to apps/consolidator-e2e/src/e2e/app.cy.ts diff --git a/apps/consolidator-e2e/src/support/index.ts b/apps/consolidator-e2e/src/support/e2e.ts similarity index 100% rename from apps/consolidator-e2e/src/support/index.ts rename to apps/consolidator-e2e/src/support/e2e.ts diff --git a/apps/consolidator-e2e/tsconfig.e2e.json b/apps/consolidator-e2e/tsconfig.e2e.json index 824748ba2..54c20f01f 100644 --- a/apps/consolidator-e2e/tsconfig.e2e.json +++ b/apps/consolidator-e2e/tsconfig.e2e.json @@ -4,5 +4,5 @@ "sourceMap": false, "outDir": "../../dist/out-tsc" }, - "include": ["src/**/*.ts", "src/**/*.js"] + "include": ["src/**/*.ts", "src/**/*.js", "cypress.config.ts"] } diff --git a/apps/consolidator/jest.config.js b/apps/consolidator/jest.config.ts similarity index 94% rename from apps/consolidator/jest.config.js rename to apps/consolidator/jest.config.ts index 091e1406d..e36e44f4b 100644 --- a/apps/consolidator/jest.config.js +++ b/apps/consolidator/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { displayName: 'consolidator', preset: '../../jest.preset.js', setupFilesAfterEnv: ['/src/test-setup.ts'], diff --git a/apps/consolidator/src/app/app.module.ts b/apps/consolidator/src/app/app.module.ts index 0147bc1aa..d6419876a 100644 --- a/apps/consolidator/src/app/app.module.ts +++ b/apps/consolidator/src/app/app.module.ts @@ -29,7 +29,6 @@ import { PerunUtilsModule } from '@perun-web-apps/perun/utils'; import { GeneralModule } from '@perun-web-apps/general'; import { LibLinkerModule } from '@perun-web-apps/lib-linker'; import { ListOfIdentitiesComponent } from './components/list-of-identities/list-of-identities.component'; -import { ConnectIdentitySectionComponent } from './components/connect-identity-section/connect-identity-section.component'; import { ShowResultPageComponent } from './components/show-result-page/show-result-page.component'; export const API_INTERCEPTOR_PROVIDER: Provider = { @@ -58,7 +57,6 @@ const loadConfigs = (appConfig: ConsolidatorConfigService) => (): Promise HeaderComponent, MainWindowComponent, ListOfIdentitiesComponent, - ConnectIdentitySectionComponent, ShowResultPageComponent, ], imports: [ diff --git a/apps/consolidator/src/app/components/connect-identity-section/connect-identity-section.component.css b/apps/consolidator/src/app/components/connect-identity-section/connect-identity-section.component.css deleted file mode 100644 index fb7b3270b..000000000 --- a/apps/consolidator/src/app/components/connect-identity-section/connect-identity-section.component.css +++ /dev/null @@ -1,15 +0,0 @@ -.color { - background-color: #f1f1f1; -} - -.perun-icon-similar { - transform: scale(2); - margin-left: 1rem; - margin-top: 1rem; - color: black; -} - -.identity-card { - background-color: whitesmoke; - max-width: 450px; -} diff --git a/apps/consolidator/src/app/components/connect-identity-section/connect-identity-section.component.html b/apps/consolidator/src/app/components/connect-identity-section/connect-identity-section.component.html deleted file mode 100644 index 90b5051fd..000000000 --- a/apps/consolidator/src/app/components/connect-identity-section/connect-identity-section.component.html +++ /dev/null @@ -1,37 +0,0 @@ -
-
-

- {{'CONNECT_IDENTITY_SECTION.TITLE_' + titleHelpTranslatePath | translate}} -

-

- {{'CONNECT_IDENTITY_SECTION.' + titleHelpTranslatePath + '_HELP' | translate}} -

- -
-
- -
-
{{ similarIdentity.email }}
-
- {{ 'CONNECT_IDENTITY_SECTION.LINKED_ACCOUNTS' | translate }}: - {{ similarIdentity.identities | similarIdentityFriendlyNamesString }} -
-
-
- -
- - -
- -
diff --git a/apps/consolidator/src/app/components/connect-identity-section/connect-identity-section.component.ts b/apps/consolidator/src/app/components/connect-identity-section/connect-identity-section.component.ts deleted file mode 100644 index 979440def..000000000 --- a/apps/consolidator/src/app/components/connect-identity-section/connect-identity-section.component.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { LinkerResult, OpenLinkerService } from '@perun-web-apps/lib-linker'; -import { - EnrichedExtSource, - EnrichedIdentity, - RegistrarManagerService, -} from '@perun-web-apps/perun/openapi'; -import { Router } from '@angular/router'; - -@Component({ - selector: 'perun-web-apps-connect-identity-section', - templateUrl: './connect-identity-section.component.html', - styleUrls: ['./connect-identity-section.component.css'], -}) -export class ConnectIdentitySectionComponent implements OnInit { - similarIdentities: EnrichedIdentity[] = []; - loading = false; - titleHelpTranslatePath = 'SIMILAR_FOUND'; - - constructor( - private registrarService: RegistrarManagerService, - private router: Router, - private openLinkerService: OpenLinkerService - ) {} - - ngOnInit(): void { - this.loading = true; - this.registrarService.checkForSimilarRichIdentities().subscribe((similarIdentities) => { - this.similarIdentities = similarIdentities.slice(0, 2); - if (this.similarIdentities.length === 0) { - this.titleHelpTranslatePath = 'NO_SIMILAR_FOUND'; - } - this.loading = false; - }); - } - - openPopUp(extSources: EnrichedExtSource[]): void { - const idpFilter: string[] = []; - extSources.forEach((extSource) => { - if (extSource.attributes['sourceIdPName']) { - idpFilter.push(extSource.extSource.name); - } - }); - this.openLinkerService.openLinkerWindow((result: LinkerResult) => { - if (result === 'TOKEN_EXPIRED') { - location.reload(); - } else if (result === 'OK' || result === 'MESSAGE_SENT_TO_SUPPORT') { - void this.router.navigate(['/result', result]); - } - }, idpFilter); - } -} diff --git a/apps/consolidator/src/app/components/header/header.component.css b/apps/consolidator/src/app/components/header/header.component.css index ff639d35e..567e5d49b 100644 --- a/apps/consolidator/src/app/components/header/header.component.css +++ b/apps/consolidator/src/app/components/header/header.component.css @@ -1,4 +1,5 @@ #nav-devel-info { + margin-left: auto; font-weight: 500; font-size: 1.4rem; display: flex; @@ -16,6 +17,15 @@ top: 0; } +#nav-menu-user-info { + display: flex; + flex-direction: row; + align-items: center; + padding-right: 16px; + margin-left: auto; + margin-right: 0; +} + .logo-container { padding: 0 8px 0 8px; } diff --git a/apps/consolidator/src/app/components/header/header.component.html b/apps/consolidator/src/app/components/header/header.component.html index ee065eb3c..d88dbc6b2 100644 --- a/apps/consolidator/src/app/components/header/header.component.html +++ b/apps/consolidator/src/app/components/header/header.component.html @@ -1,7 +1,7 @@
-
+
-
+

{{ 'HEADER.TITLE' | translate }}

@@ -11,4 +11,14 @@ DEVEL  🗲 ~
+ + +

diff --git a/apps/consolidator/src/app/components/header/header.component.ts b/apps/consolidator/src/app/components/header/header.component.ts index 11907e3bb..f96840fe4 100644 --- a/apps/consolidator/src/app/components/header/header.component.ts +++ b/apps/consolidator/src/app/components/header/header.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { StoreService } from '@perun-web-apps/perun/services'; +import { OtherApplicationsService, StoreService } from '@perun-web-apps/perun/services'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; @Component({ @@ -12,7 +12,15 @@ export class HeaderComponent { textColor = this.storeService.getProperty('theme').nav_text_color; iconColor = this.storeService.getProperty('theme').nav_icon_color; isDevel = this.storeService.getProperty('is_devel'); + logoutEnabled = this.storeService.getProperty('log_out_enabled'); + profileLabel = this.storeService.getProperty('profile_label_en'); + principal = this.storeService.getPerunPrincipal(); + profileUrl = this.otherApplicationService.getUrlForOtherApplication('profile'); logo: SafeHtml = this.sanitizer.bypassSecurityTrustHtml(this.storeService.getProperty('logo')); - constructor(private storeService: StoreService, private sanitizer: DomSanitizer) {} + constructor( + private storeService: StoreService, + private sanitizer: DomSanitizer, + private otherApplicationService: OtherApplicationsService + ) {} } diff --git a/apps/consolidator/src/app/components/list-of-identities/list-of-identities.component.html b/apps/consolidator/src/app/components/list-of-identities/list-of-identities.component.html index f015cc36c..f7c5f35fd 100644 --- a/apps/consolidator/src/app/components/list-of-identities/list-of-identities.component.html +++ b/apps/consolidator/src/app/components/list-of-identities/list-of-identities.component.html @@ -1,4 +1,4 @@ -
+
{{ @@ -40,7 +40,24 @@

{{ this.idpProvider }}

- {{attribute.value}} + {{attribute.value}} + + + {{account}} + + + +
+
+
diff --git a/apps/consolidator/src/app/components/list-of-identities/list-of-identities.component.ts b/apps/consolidator/src/app/components/list-of-identities/list-of-identities.component.ts index 5282623d5..453621732 100644 --- a/apps/consolidator/src/app/components/list-of-identities/list-of-identities.component.ts +++ b/apps/consolidator/src/app/components/list-of-identities/list-of-identities.component.ts @@ -1,14 +1,16 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, Input, OnChanges, OnInit } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; import { InitAuthService, StoreService } from '@perun-web-apps/perun/services'; -import { Attribute, UsersManagerService } from '@perun-web-apps/perun/openapi'; +import { Attribute, RichUserExtSource, UsersManagerService } from '@perun-web-apps/perun/openapi'; import { MatTableDataSource } from '@angular/material/table'; -import { getAttribute } from '@perun-web-apps/perun/utils'; +import { getAttribute, getDefaultDialogConfig } from '@perun-web-apps/perun/utils'; import { Urns } from '@perun-web-apps/perun/urns'; +import { RemoveUserExtSourceDialogComponent } from '@perun-web-apps/perun/dialogs'; +import { MatDialog } from '@angular/material/dialog'; export interface TableInfo { name: string; - value: string; + value: string | string[]; } interface ProfileInfo { @@ -28,7 +30,8 @@ interface UserProfile { templateUrl: './list-of-identities.component.html', styleUrls: ['./list-of-identities.component.css'], }) -export class ListOfIdentitiesComponent implements OnInit { +export class ListOfIdentitiesComponent implements OnInit, OnChanges { + @Input() reloadData: number; idpProvider = ''; logo: string; width: string; @@ -36,49 +39,71 @@ export class ListOfIdentitiesComponent implements OnInit { unknownIdentity: boolean; dataSource = new MatTableDataSource(); info: TableInfo[] = []; + userId: number; + userExtSources: RichUserExtSource[]; loading = false; constructor( private oauthService: OAuthService, private userService: UsersManagerService, private storeService: StoreService, - private initService: InitAuthService + private initService: InitAuthService, + private dialog: MatDialog ) {} ngOnInit(): void { this.loading = true; + this.initProfileAndPrincipal(); + } + + ngOnChanges(): void { + if (this.reloadData !== 0) { + this.info = []; + this.initProfileAndPrincipal(); + } + } + + initProfileAndPrincipal(): void { void this.oauthService.loadUserProfile().then((userProfile: UserProfile) => { this.setIdpInfo(userProfile); void this.initService.simpleLoadPrincipal().then(() => { - this.unknownIdentity = this.storeService.getPerunPrincipal().userId === -1; + this.userId = this.storeService.getPerunPrincipal().userId; + this.unknownIdentity = this.userId === -1; + this.reloadAccounts(); + }); + }); + } - if (!this.unknownIdentity) { - let linkedIdentities = ''; - this.userService - .getRichUserExtSources(this.storeService.getPerunPrincipal().userId) - .subscribe((userExtSources) => { - userExtSources.forEach((ues) => { - if (ues.attributes.length !== 0) { - const sourceIdpName: Attribute = getAttribute( - ues.attributes, - Urns.UES_SOURCE_IDP_NAME - ); - if (sourceIdpName?.value) { - linkedIdentities += (sourceIdpName.value as string) + ', '; - } - } - }); - linkedIdentities = linkedIdentities.slice(0, -2); - this.info.push({ name: 'Linked accounts', value: linkedIdentities }); - this.dataSource = new MatTableDataSource(this.info); - this.loading = false; - }); - } else { - this.dataSource = new MatTableDataSource(this.info); - this.loading = false; + reloadAccounts(): void { + this.loading = true; + if (!this.unknownIdentity) { + const linkedIdentities: string[] = []; + this.userService.getRichUserExtSources(this.userId).subscribe((userExtSources) => { + this.userExtSources = userExtSources; + userExtSources.forEach((ues) => { + if (ues.attributes.length !== 0) { + const sourceIdpName: Attribute = getAttribute(ues.attributes, Urns.UES_SOURCE_IDP_NAME); + const email: Attribute = getAttribute(ues.attributes, Urns.UES_DEF_MAIL); + if (sourceIdpName?.value) { + linkedIdentities.push( + `${sourceIdpName.value as string}${ + email?.value ? ' (' + (email.value as string) + ')' : '' + }` + ); + } + } + }); + if (this.info.length !== 0) { + this.info = this.info.filter((tabInfo) => tabInfo.name !== 'Linked accounts'); } + this.info.push({ name: 'Linked accounts', value: linkedIdentities }); + this.dataSource = new MatTableDataSource(this.info); + this.loading = false; }); - }); + } else { + this.dataSource = new MatTableDataSource(this.info); + this.loading = false; + } } setIdpInfo(userProfile: UserProfile): void { @@ -153,4 +178,28 @@ export class ListOfIdentitiesComponent implements OnInit { } return ''; } + + openDeleteDialog(account: string): void { + const extSourceToDelete: RichUserExtSource[] = []; + this.userExtSources.filter((ues) => + ues.attributes.forEach((attr) => { + if (attr.baseFriendlyName === 'sourceIdPName' && account.includes(attr.value as string)) { + extSourceToDelete.push(ues); + } + }) + ); + const config = getDefaultDialogConfig(); + config.width = '450px'; + config.data = { + theme: 'user-theme', + userId: this.userId, + extSources: extSourceToDelete, + }; + const dialogRef = this.dialog.open(RemoveUserExtSourceDialogComponent, config); + dialogRef.afterClosed().subscribe((success) => { + if (success) { + this.reloadAccounts(); + } + }); + } } diff --git a/apps/consolidator/src/app/components/main-window/main-window.component.css b/apps/consolidator/src/app/components/main-window/main-window.component.css index 3c036a8b4..b4d4c813f 100644 --- a/apps/consolidator/src/app/components/main-window/main-window.component.css +++ b/apps/consolidator/src/app/components/main-window/main-window.component.css @@ -8,3 +8,15 @@ flex-wrap: wrap; gap: 1.5rem; } + +.perun-icon-similar { + transform: scale(2); + margin-left: 1rem; + margin-top: 1rem; + color: black; +} + +.identity-card { + background-color: whitesmoke; + max-width: 450px; +} diff --git a/apps/consolidator/src/app/components/main-window/main-window.component.html b/apps/consolidator/src/app/components/main-window/main-window.component.html index d5d892876..f929fee24 100644 --- a/apps/consolidator/src/app/components/main-window/main-window.component.html +++ b/apps/consolidator/src/app/components/main-window/main-window.component.html @@ -1,12 +1,50 @@
{{ - 'LIST_OF_IDENTITIES.IS_NOT_KNOWN_IDENTITY' | translate + 'MAIN_WINDOW.IS_NOT_KNOWN_IDENTITY' | translate }} -
- +
+ - +
+
+
+

+ {{'MAIN_WINDOW.TITLE_' + titleHelpTranslatePath | translate}} +

+

+ {{'MAIN_WINDOW.' + titleHelpTranslatePath + '_HELP' | translate}} +

+ +
+
+ + +
+
{{ similarIdentity.email }}
+
+ {{ 'MAIN_WINDOW.LINKED_ACCOUNTS' | translate }}: + {{ similarIdentity.identities | similarIdentityFriendlyNamesString }} +
+
+
+ +
+ + +
+ +
diff --git a/apps/consolidator/src/app/components/main-window/main-window.component.ts b/apps/consolidator/src/app/components/main-window/main-window.component.ts index 650ff3438..d89e56e68 100644 --- a/apps/consolidator/src/app/components/main-window/main-window.component.ts +++ b/apps/consolidator/src/app/components/main-window/main-window.component.ts @@ -1,5 +1,12 @@ import { Component, OnInit } from '@angular/core'; import { InitAuthService, StoreService } from '@perun-web-apps/perun/services'; +import { + EnrichedExtSource, + EnrichedIdentity, + RegistrarManagerService, +} from '@perun-web-apps/perun/openapi'; +import { LinkerResult, OpenLinkerService } from '@perun-web-apps/lib-linker'; +import { Router } from '@angular/router'; @Component({ selector: 'perun-web-apps-main-window', @@ -7,13 +14,58 @@ import { InitAuthService, StoreService } from '@perun-web-apps/perun/services'; styleUrls: ['./main-window.component.css'], }) export class MainWindowComponent implements OnInit { + loading = false; unknownIdentity: boolean; + similarIdentities: EnrichedIdentity[] = []; + titleHelpTranslatePath = 'SIMILAR_FOUND'; + reloadData = 0; - constructor(private storeService: StoreService, private initService: InitAuthService) {} + constructor( + private storeService: StoreService, + private initService: InitAuthService, + private registrarService: RegistrarManagerService, + private router: Router, + private openLinkerService: OpenLinkerService + ) {} ngOnInit(): void { + this.initData(); + } + + initData(): void { + this.loading = true; void this.initService.simpleLoadPrincipal().then(() => { this.unknownIdentity = this.storeService.getPerunPrincipal().userId === -1; + this.reloadSimilarIdentities(); + }); + } + + reloadSimilarIdentities(): void { + this.registrarService.checkForSimilarRichIdentities().subscribe((similarIdentities) => { + this.similarIdentities = similarIdentities.slice(0, 2); + if (this.similarIdentities.length === 0) { + this.titleHelpTranslatePath = 'NO_SIMILAR_FOUND'; + } + this.loading = false; + }); + } + + openPopUp(extSources: EnrichedExtSource[]): void { + const idpFilter: string[] = []; + extSources.forEach((extSource) => { + if (extSource.attributes['sourceIdPName']) { + idpFilter.push(extSource.extSource.name); + } }); + this.openLinkerService.openLinkerWindow((result: LinkerResult) => { + if (result === 'TOKEN_EXPIRED') { + location.reload(); + } else if (result === 'OK') { + this.reloadData++; + this.initData(); + } else if (result === 'MESSAGE_SENT_TO_SUPPORT') { + void this.router.navigate(['/result', result]); + } + }, idpFilter); } } diff --git a/apps/consolidator/src/app/components/show-result-page/show-result-page.component.html b/apps/consolidator/src/app/components/show-result-page/show-result-page.component.html index 3541cd670..94f715dc1 100644 --- a/apps/consolidator/src/app/components/show-result-page/show-result-page.component.html +++ b/apps/consolidator/src/app/components/show-result-page/show-result-page.component.html @@ -2,7 +2,7 @@
diff --git a/apps/consolidator/src/assets/config/defaultConfig.json b/apps/consolidator/src/assets/config/defaultConfig.json index 291a7686b..ed46cd4b4 100644 --- a/apps/consolidator/src/assets/config/defaultConfig.json +++ b/apps/consolidator/src/assets/config/defaultConfig.json @@ -22,6 +22,7 @@ "path_to_idp_logo_height_userinfo": ["target_backend", "logo", "height"], "instance_favicon": false, "auto_auth_redirect": true, + "is_devel": false, "footer": { "columns": [ { @@ -65,6 +66,8 @@ ], "github_releases": "https://www.github.com/CESNET/perun-web-apps/releases/" }, + "log_out_enabled": true, + "profile_label_en": "Profile", "logo": "\n\n\n\n", "theme": { "content_bg_color": "", diff --git a/apps/consolidator/src/assets/i18n/en.json b/apps/consolidator/src/assets/i18n/en.json index 7095163c5..a4cb3ab5a 100644 --- a/apps/consolidator/src/assets/i18n/en.json +++ b/apps/consolidator/src/assets/i18n/en.json @@ -2,13 +2,18 @@ "HEADER": { "TITLE": "Account linking" }, + "NAV": { + "LOGOUT": "Log out", + "OTHER_APPLICATIONS": "Other applications" + }, "LIST_OF_IDENTITIES": { - "IS_NOT_KNOWN_IDENTITY": "The account is not registered in the system", "SIGN_NOT_KNOW": "You are trying to sign in with", "SIGN_KNOW": "You are signed in with", - "LINKED_ACCOUNTS": "Linked accounts" + "LINKED_ACCOUNTS": "Linked accounts", + "DELETE_DISABLED_TOOLTIP": "You are logged in by this account" }, - "CONNECT_IDENTITY_SECTION": { + "MAIN_WINDOW": { + "IS_NOT_KNOWN_IDENTITY": "The account is not registered in the system", "TITLE_NO_SIMILAR_FOUND": "We didn't find any similar account", "NO_SIMILAR_FOUND_HELP": "Please prove your account by logging in using one of the registered accounts.", "CONNECT_OTHER_ACCOUNT": "Connect another account", @@ -19,7 +24,7 @@ }, "SHOW_RESULT": { "TRY_AGAIN": "Try it again", - "ADD_ANOTHER": "Add another account" + "BACK_HOME": "Back to home page" }, "SHARED_LIB": { "PERUN": { @@ -32,6 +37,25 @@ "TITLE": "Session expiration", "DESCRIPTION": "Your session has expired. Please sign in to continue.", "SIGN_IN": "Sign in" + }, + "REPORT_ISSUE": { + "TITLE": "Report an issue", + "SUBJECT": "Subject", + "SUBJECT_ERROR": "Subject cannot be empty.", + "MESSAGE": "Message", + "MESSAGE_PLACEHOLDER": "Please describe the issue", + "MESSAGE_HINT": "Please try to describe in detail the problem.", + "CANCEL": "Cancel", + "SEND": "Send", + "SUCCESS": "Issue report was sent and got ticket number: " + }, + "REMOVE_USER_EXT_SOURCE": { + "TITLE": "Remove account", + "DESCRIPTION": "Following account will be removed", + "ASK": "Are you sure you want to continue?", + "CANCEL": "Cancel", + "REMOVE": "Remove", + "SUCCESS": "User account successfully removed" } } }, diff --git a/apps/consolidator/src/styles.scss b/apps/consolidator/src/styles.scss index dda1f998d..924319557 100644 --- a/apps/consolidator/src/styles.scss +++ b/apps/consolidator/src/styles.scss @@ -215,3 +215,7 @@ button:focus { mat-chip-list { pointer-events: none; } + +mat-icon { + overflow: inherit !important; +} diff --git a/apps/consolidator/tsconfig.app.json b/apps/consolidator/tsconfig.app.json index 9f439121f..c50286012 100644 --- a/apps/consolidator/tsconfig.app.json +++ b/apps/consolidator/tsconfig.app.json @@ -3,9 +3,9 @@ "compilerOptions": { "outDir": "../../dist/out-tsc", "types": [], - "target": "ES2017" + "target": "es2020" }, "files": ["src/main.ts", "src/polyfills.ts"], "include": ["src/**/*.d.ts"], - "exclude": ["**/*.test.ts", "**/*.spec.ts"] + "exclude": ["**/*.test.ts", "**/*.spec.ts", "jest.config.ts"] } diff --git a/apps/consolidator/tsconfig.editor.json b/apps/consolidator/tsconfig.editor.json index 20c4afdbf..1bf3c0a74 100644 --- a/apps/consolidator/tsconfig.editor.json +++ b/apps/consolidator/tsconfig.editor.json @@ -3,5 +3,6 @@ "include": ["**/*.ts"], "compilerOptions": { "types": ["jest", "node"] - } + }, + "exclude": ["jest.config.ts"] } diff --git a/apps/consolidator/tsconfig.json b/apps/consolidator/tsconfig.json index 4ef4491ed..0eb8182de 100644 --- a/apps/consolidator/tsconfig.json +++ b/apps/consolidator/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "types": ["node", "jest"] + "types": ["node", "jest"], + "target": "es2020" }, "include": [], "files": [], diff --git a/apps/consolidator/tsconfig.spec.json b/apps/consolidator/tsconfig.spec.json index e70b1ea78..b2cc6087b 100644 --- a/apps/consolidator/tsconfig.spec.json +++ b/apps/consolidator/tsconfig.spec.json @@ -6,5 +6,5 @@ "types": ["jest", "node"] }, "files": ["src/test-setup.ts"], - "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] + "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/apps/linker-e2e/cypress.config.ts b/apps/linker-e2e/cypress.config.ts new file mode 100644 index 000000000..5b281cb38 --- /dev/null +++ b/apps/linker-e2e/cypress.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'cypress'; +import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; + +const cypressJsonConfig = { + fileServerFolder: '.', + fixturesFolder: './src/fixtures', + video: true, + videosFolder: '../../dist/cypress/apps/linker-e2e/videos', + screenshotsFolder: '../../dist/cypress/apps/linker-e2e/screenshots', + chromeWebSecurity: false, + specPattern: 'src/e2e/**/*.cy.{js,jsx,ts,tsx}', + supportFile: 'src/support/e2e.ts', +}; +export default defineConfig({ + e2e: { + ...nxE2EPreset(__dirname), + ...cypressJsonConfig, + }, +}); diff --git a/apps/linker-e2e/cypress.json b/apps/linker-e2e/cypress.json deleted file mode 100644 index ec6f77cd0..000000000 --- a/apps/linker-e2e/cypress.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "fileServerFolder": ".", - "fixturesFolder": "./src/fixtures", - "integrationFolder": "./src/integration", - "modifyObstructiveCode": false, - "supportFile": "./src/support/index.ts", - "pluginsFile": false, - "video": true, - "videosFolder": "../../dist/cypress/apps/linker-e2e/videos", - "screenshotsFolder": "../../dist/cypress/apps/linker-e2e/screenshots", - "chromeWebSecurity": false -} diff --git a/apps/linker-e2e/src/integration/app.spec.ts b/apps/linker-e2e/src/e2e/app.cy.ts similarity index 100% rename from apps/linker-e2e/src/integration/app.spec.ts rename to apps/linker-e2e/src/e2e/app.cy.ts diff --git a/apps/linker-e2e/src/support/index.ts b/apps/linker-e2e/src/support/e2e.ts similarity index 100% rename from apps/linker-e2e/src/support/index.ts rename to apps/linker-e2e/src/support/e2e.ts diff --git a/apps/linker-e2e/tsconfig.e2e.json b/apps/linker-e2e/tsconfig.e2e.json index 824748ba2..54c20f01f 100644 --- a/apps/linker-e2e/tsconfig.e2e.json +++ b/apps/linker-e2e/tsconfig.e2e.json @@ -4,5 +4,5 @@ "sourceMap": false, "outDir": "../../dist/out-tsc" }, - "include": ["src/**/*.ts", "src/**/*.js"] + "include": ["src/**/*.ts", "src/**/*.js", "cypress.config.ts"] } diff --git a/apps/linker/jest.config.js b/apps/linker/jest.config.ts similarity index 94% rename from apps/linker/jest.config.js rename to apps/linker/jest.config.ts index 3ae688575..50c5cb4cc 100644 --- a/apps/linker/jest.config.js +++ b/apps/linker/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { displayName: 'linker', preset: '../../jest.preset.js', setupFilesAfterEnv: ['/src/test-setup.ts'], diff --git a/apps/linker/src/app/app.module.ts b/apps/linker/src/app/app.module.ts index 2f2216648..6bb36df80 100644 --- a/apps/linker/src/app/app.module.ts +++ b/apps/linker/src/app/app.module.ts @@ -27,6 +27,7 @@ import { OAuthModule } from 'angular-oauth2-oidc'; import { LibLinkerModule } from '@perun-web-apps/lib-linker'; import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { SendMessageDialogComponent } from './components/send-message-dialog/send-message-dialog.component'; export const API_INTERCEPTOR_PROVIDER: Provider = { provide: HTTP_INTERCEPTORS, @@ -49,7 +50,7 @@ const loadConfigs = (appConfig: LinkerConfigService) => (): Promise => appConfig.loadConfigs(); @NgModule({ - declarations: [AppComponent, ShowResultComponent], + declarations: [AppComponent, ShowResultComponent, SendMessageDialogComponent], imports: [ BrowserModule, BrowserAnimationsModule, diff --git a/apps/linker/src/app/components/send-message-dialog/send-message-dialog.component.html b/apps/linker/src/app/components/send-message-dialog/send-message-dialog.component.html new file mode 100644 index 000000000..53ccbabd7 --- /dev/null +++ b/apps/linker/src/app/components/send-message-dialog/send-message-dialog.component.html @@ -0,0 +1,30 @@ +
+
+

+ {{'SHARED_LIB.CONSOLIDATOR.SEND_MESSAGE_TO_SUPPORT_DIALOG.TITLE' | translate}} +

+
+ +
+ + {{'SHARED_LIB.CONSOLIDATOR.SEND_MESSAGE_TO_SUPPORT_DIALOG.SUBTITLE' | translate}} + + + + +
+ +
+ + + +
+
diff --git a/apps/linker/src/app/components/send-message-dialog/send-message-dialog.component.scss b/apps/linker/src/app/components/send-message-dialog/send-message-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/linker/src/app/components/send-message-dialog/send-message-dialog.component.ts b/apps/linker/src/app/components/send-message-dialog/send-message-dialog.component.ts new file mode 100644 index 000000000..4319d03b6 --- /dev/null +++ b/apps/linker/src/app/components/send-message-dialog/send-message-dialog.component.ts @@ -0,0 +1,105 @@ +import { Component } from '@angular/core'; +import { MatDialogRef } from '@angular/material/dialog'; +import { parseQueryParams } from '@perun-web-apps/perun/utils'; +import { StoreService } from '@perun-web-apps/perun/services'; +import { OAuthStorage } from 'angular-oauth2-oidc'; +import { + AuthzResolverService, + RTMessagesManagerService, + User, +} from '@perun-web-apps/perun/openapi'; +import { UserFullNamePipe } from '@perun-web-apps/perun/pipes'; + +// eslint-disable-next-line +declare let require: any; + +@Component({ + selector: 'perun-web-apps-send-message-dialog', + templateUrl: './send-message-dialog.component.html', + styleUrls: ['./send-message-dialog.component.scss'], +}) +export class SendMessageDialogComponent { + loading = false; + message = + 'Hello, during the linking of my accounts I encountered a situation where ' + + 'the system cannot automatically link these accounts. Therefore I want to ask you ' + + 'for help with linking my accounts.'; + + constructor( + private dialogRef: MatDialogRef, + private storeService: StoreService, + private authzService: AuthzResolverService, + private oAuthStorage: OAuthStorage, + private rtMessages: RTMessagesManagerService, + private userFullNamePipe: UserFullNamePipe + ) {} + + onCancel(): void { + this.dialogRef.close(null); + } + + onSend(): void { + this.loading = true; + const currentUser = this.storeService.getPerunPrincipal().user; + + const queryParams = location.search.substring(1); + this.oAuthStorage.setItem('access_token', parseQueryParams('formerToken', queryParams)); + this.authzService.getPerunPrincipal().subscribe((principal) => { + const formerUser = principal.user; + this.rtMessages + .sentMessageToRTWithQueue( + 'perun', + 'Account linking: The accounts could not be automatically linked.', + this.getFullEmailBody(currentUser, formerUser) + ) + .subscribe({ + next: () => { + this.loading = false; + this.dialogRef.close(true); + }, + error: () => { + this.loading = false; + this.dialogRef.close(false); + }, + }); + }); + } + + getFullEmailBody(currentUser: User, formerUser: User): string { + const instance = this.storeService.getProperty('config'); + let text = + this.message + + '\n________________________________________________________________________\n\n' + + 'Account linking: The accounts could not be automatically linked.\n' + + 'The user proved his identities, but they were connected to different users.\n' + + 'By this message the user is asking for help with identity consolidation.\n'; + + text = text.concat('\n\n'); + text = text.concat('Information about users: \n\n'); + + text = text.concat( + 'First user: \nid=' + + formerUser.id.toString() + + '\nName: ' + + this.userFullNamePipe.transform(formerUser) + + '\n\n' + ); + + text = text.concat( + 'Second user: \n' + + 'id=' + + currentUser.id.toString() + + '\nName: ' + + this.userFullNamePipe.transform(currentUser) + + '\n\n' + ); + + text = text.concat('Perun instance: ' + instance + '\n'); + text = text.concat( + 'Sended from new Consolidator Gui, version: ', + // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access + require('../../../../../../package.json').version as string + ); + return text.split('\n').join('\n '); //add space after each new line + } +} diff --git a/apps/linker/src/app/components/show-result/show-result.component.ts b/apps/linker/src/app/components/show-result/show-result.component.ts index 003e9acf9..dd33e5f59 100644 --- a/apps/linker/src/app/components/show-result/show-result.component.ts +++ b/apps/linker/src/app/components/show-result/show-result.component.ts @@ -1,20 +1,10 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { LinkerResult } from '@perun-web-apps/lib-linker'; -import { OAuthService, OAuthStorage } from 'angular-oauth2-oidc'; +import { OAuthService } from 'angular-oauth2-oidc'; import { MatDialog } from '@angular/material/dialog'; -import { - AttributesManagerService, - AuthzResolverService, - RTMessagesManagerService, - User, -} from '@perun-web-apps/perun/openapi'; -import { StoreService } from '@perun-web-apps/perun/services'; -import { UserFullNamePipe } from '@perun-web-apps/perun/pipes'; -import { parseQueryParams } from '@perun-web-apps/perun/utils'; - -// eslint-disable-next-line -declare let require: any; +import { getDefaultDialogConfig, parseQueryParams } from '@perun-web-apps/perun/utils'; +import { SendMessageDialogComponent } from '../send-message-dialog/send-message-dialog.component'; @Component({ selector: 'perun-web-apps-show-result', @@ -29,13 +19,7 @@ export class ShowResultComponent implements OnInit { constructor( private route: ActivatedRoute, private dialog: MatDialog, - private oauthService: OAuthService, - private attributeService: AttributesManagerService, - private storeService: StoreService, - private authzService: AuthzResolverService, - private rtMessages: RTMessagesManagerService, - private userFullNamePipe: UserFullNamePipe, - private oAuthStorage: OAuthStorage + private oauthService: OAuthService ) {} ngOnInit(): void { @@ -65,67 +49,18 @@ export class ShowResultComponent implements OnInit { } sendMessageToSupport(): void { - this.loading = true; - const currentUser = this.storeService.getPerunPrincipal().user; + const config = getDefaultDialogConfig(); + config.width = '1000px'; - const queryParams = location.search.substring(1); - this.oAuthStorage.setItem('access_token', parseQueryParams('formerToken', queryParams)); - this.authzService.getPerunPrincipal().subscribe((principal) => { - const formerUser = principal.user; - this.rtMessages - .sentMessageToRTWithQueue( - 'perun', - 'Account linking: The accounts could not be automatically linked.', - this.getFullEmailBody(currentUser, formerUser) - ) - .subscribe( - () => { - this.linkerResult = 'MESSAGE_SENT_TO_SUPPORT'; - this.openerWindow.postMessage(this.linkerResult, '*'); - this.loading = false; - }, - () => { - this.loading = false; - this.linkerResult = 'UNKNOWN_ERROR'; - this.openerWindow.postMessage(this.linkerResult, '*'); - } - ); + const dialogRef = this.dialog.open(SendMessageDialogComponent, config); + dialogRef.afterClosed().subscribe((success) => { + if (success === true) { + this.linkerResult = 'MESSAGE_SENT_TO_SUPPORT'; + this.openerWindow.postMessage(this.linkerResult, '*'); + } else if (success === false) { + this.linkerResult = 'UNKNOWN_ERROR'; + this.openerWindow.postMessage(this.linkerResult, '*'); + } }); } - - getFullEmailBody(currentUser: User, formerUser: User): string { - const instance = this.storeService.getProperty('config'); - let text = - 'Account linking: The accounts could not be automatically linked.\n' + - 'The user proved his identities, but they were connected to different users.\n' + - 'By this message the user is asking for help with identity consolidation.\n'; - - text = text.concat('\n\n'); - text = text.concat('Information about users: \n\n'); - - text = text.concat( - 'First user: \nid=' + - formerUser.id.toString() + - '\nName: ' + - this.userFullNamePipe.transform(formerUser) + - '\n\n' - ); - - text = text.concat( - 'Second user: \n' + - 'id=' + - currentUser.id.toString() + - '\nName: ' + - this.userFullNamePipe.transform(currentUser) + - '\n\n' - ); - - text = text.concat('Perun instance: ' + instance + '\n'); - text = text.concat( - 'Sended from new Consolidator Gui, version: ', - // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access - require('../../../../../../package.json').version as string - ); - return text.split('\n').join('\n '); //add space after each new line - } } diff --git a/apps/linker/src/assets/i18n/en.json b/apps/linker/src/assets/i18n/en.json index 3dceacdba..c016d9efe 100644 --- a/apps/linker/src/assets/i18n/en.json +++ b/apps/linker/src/assets/i18n/en.json @@ -22,7 +22,9 @@ "CONSOLIDATOR": { "OK_TITLE": "Success!", "OK_SUBTITLE": "Accounts successfully linked.", - "IDENTITY_REGISTERED_ALREADY_TITLE": "This account is linked to another user. The account could not be automatically linked.", + "OK_SUBTITLE_WITH_MAIL_1": "Account ", + "OK_SUBTITLE_WITH_MAIL_2": " successfully linked.", + "IDENTITY_REGISTERED_ALREADY_TITLE": "We cannot automatically link these accounts.", "IDENTITY_REGISTERED_ALREADY_SUBTITLE": "Please contact the user support.", "IDENTITY_IDENTICAL_TITLE": "You logged in with the same account.", "IDENTITY_IDENTICAL_SUBTITLE": "", @@ -33,13 +35,13 @@ "TOKEN_EXPIRED_TITLE": "Some logins are expired!", "TOKEN_EXPIRED_SUBTITLE": "Please close this window and refresh the web application you came from.", "MESSAGE_SENT_TO_SUPPORT_TITLE": "Email was sent to user support.", - "MESSAGE_SENT_TO_SUPPORT_SUBTITLE": "Our user support will answer your email as soon as possible.", + "MESSAGE_SENT_TO_SUPPORT_SUBTITLE": "Our user support will answer you as soon as possible to your email", "UNKNOWN_ERROR_TITLE": "Something went wrong.", "UNKNOWN_ERROR_SUBTITLE": "Please try again later or contact the user support at", "SEND_MESSAGE_TO_SUPPORT_DIALOG": { "TITLE": "Send message to User Support", - "SUBTITLE": "Technical info will be sent automatically", - "SELECT_PREFERRED_EMAIL": "Select your preferable contact email", + "SUBTITLE": "You can send this message or you can write your own text. Technical info will be sent automatically.", + "PLACEHOLDER": "Message for support", "CANCEL": "Cancel", "SUBMIT": "Send" } diff --git a/apps/linker/src/styles.scss b/apps/linker/src/styles.scss index 605ae5235..e76794824 100644 --- a/apps/linker/src/styles.scss +++ b/apps/linker/src/styles.scss @@ -181,3 +181,12 @@ button { button:focus { outline: none !important; } + +mat-icon { + overflow: inherit !important; +} + +.page-subtitle { + margin-bottom: 1rem; + font-size: 1.5rem; +} diff --git a/apps/linker/tsconfig.app.json b/apps/linker/tsconfig.app.json index 9f439121f..c50286012 100644 --- a/apps/linker/tsconfig.app.json +++ b/apps/linker/tsconfig.app.json @@ -3,9 +3,9 @@ "compilerOptions": { "outDir": "../../dist/out-tsc", "types": [], - "target": "ES2017" + "target": "es2020" }, "files": ["src/main.ts", "src/polyfills.ts"], "include": ["src/**/*.d.ts"], - "exclude": ["**/*.test.ts", "**/*.spec.ts"] + "exclude": ["**/*.test.ts", "**/*.spec.ts", "jest.config.ts"] } diff --git a/apps/linker/tsconfig.editor.json b/apps/linker/tsconfig.editor.json index 20c4afdbf..1bf3c0a74 100644 --- a/apps/linker/tsconfig.editor.json +++ b/apps/linker/tsconfig.editor.json @@ -3,5 +3,6 @@ "include": ["**/*.ts"], "compilerOptions": { "types": ["jest", "node"] - } + }, + "exclude": ["jest.config.ts"] } diff --git a/apps/linker/tsconfig.json b/apps/linker/tsconfig.json index 1f616d619..f199f7458 100644 --- a/apps/linker/tsconfig.json +++ b/apps/linker/tsconfig.json @@ -14,6 +14,7 @@ } ], "compilerOptions": { - "types": ["node", "jest"] + "types": ["node", "jest"], + "target": "es2020" } } diff --git a/apps/linker/tsconfig.spec.json b/apps/linker/tsconfig.spec.json index e70b1ea78..b2cc6087b 100644 --- a/apps/linker/tsconfig.spec.json +++ b/apps/linker/tsconfig.spec.json @@ -6,5 +6,5 @@ "types": ["jest", "node"] }, "files": ["src/test-setup.ts"], - "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] + "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/apps/password-reset-e2e/cypress.config.ts b/apps/password-reset-e2e/cypress.config.ts new file mode 100644 index 000000000..3719f9761 --- /dev/null +++ b/apps/password-reset-e2e/cypress.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'cypress'; +import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; + +const cypressJsonConfig = { + fileServerFolder: '.', + fixturesFolder: './src/fixtures', + video: true, + videosFolder: '../../dist/cypress/apps/password-reset-e2e/videos', + screenshotsFolder: '../../dist/cypress/apps/password-reset-e2e/screenshots', + chromeWebSecurity: false, + specPattern: './src/integration/**/*.cy.{js,jsx,ts,tsx}', + supportFile: 'src/support/e2e.ts', +}; +export default defineConfig({ + e2e: { + ...nxE2EPreset(__dirname), + ...cypressJsonConfig, + }, +}); diff --git a/apps/password-reset-e2e/cypress.json b/apps/password-reset-e2e/cypress.json deleted file mode 100644 index 2ba1d0d71..000000000 --- a/apps/password-reset-e2e/cypress.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "fileServerFolder": ".", - "fixturesFolder": "./src/fixtures", - "integrationFolder": "./src/integration", - "modifyObstructiveCode": false, - "pluginsFile": "./src/plugins/index", - "supportFile": "./src/support/index.ts", - "video": true, - "videosFolder": "../../dist/cypress/apps/password-reset-e2e/videos", - "screenshotsFolder": "../../dist/cypress/apps/password-reset-e2e/screenshots", - "chromeWebSecurity": false -} diff --git a/apps/password-reset-e2e/src/support/index.ts b/apps/password-reset-e2e/src/support/e2e.ts similarity index 100% rename from apps/password-reset-e2e/src/support/index.ts rename to apps/password-reset-e2e/src/support/e2e.ts diff --git a/apps/password-reset-e2e/tsconfig.e2e.json b/apps/password-reset-e2e/tsconfig.e2e.json index 9dc3660a7..57e5b7cf3 100644 --- a/apps/password-reset-e2e/tsconfig.e2e.json +++ b/apps/password-reset-e2e/tsconfig.e2e.json @@ -6,5 +6,5 @@ "allowJs": true, "types": ["cypress", "node"] }, - "include": ["src/**/*.ts", "src/**/*.js"] + "include": ["src/**/*.ts", "src/**/*.js", "cypress.config.ts"] } diff --git a/apps/password-reset/jest.config.js b/apps/password-reset/jest.config.ts similarity index 94% rename from apps/password-reset/jest.config.js rename to apps/password-reset/jest.config.ts index c5486eec6..5fd7b9ea9 100644 --- a/apps/password-reset/jest.config.js +++ b/apps/password-reset/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { displayName: 'password-reset', preset: '../../jest.preset.js', setupFilesAfterEnv: ['/src/test-setup.ts'], diff --git a/apps/password-reset/src/app/components/password-reset-form/password-reset-form.component.ts b/apps/password-reset/src/app/components/password-reset-form/password-reset-form.component.ts index 598aa5c7b..840a5bd17 100644 --- a/apps/password-reset/src/app/components/password-reset-form/password-reset-form.component.ts +++ b/apps/password-reset/src/app/components/password-reset-form/password-reset-form.component.ts @@ -3,7 +3,12 @@ import { TranslateService } from '@ngx-translate/core'; import { ApiRequestConfigurationService, StoreService } from '@perun-web-apps/perun/services'; import { UsersManagerService } from '@perun-web-apps/perun/openapi'; import { loginAsyncValidator } from '@perun-web-apps/perun/namespace-password-form'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { + UntypedFormBuilder, + UntypedFormControl, + UntypedFormGroup, + Validators, +} from '@angular/forms'; import { CustomValidators } from '@perun-web-apps/perun/utils'; @Component({ @@ -30,14 +35,14 @@ export class PasswordResetFormComponent implements OnInit { loading = false; success = false; language = 'en'; - newPasswdForm: FormGroup; + newPasswdForm: UntypedFormGroup; constructor( private storeService: StoreService, private translate: TranslateService, private apiRequestConfiguration: ApiRequestConfigurationService, private usersService: UsersManagerService, - private _formBuilder: FormBuilder + private _formBuilder: UntypedFormBuilder ) {} ngOnInit(): void { @@ -47,10 +52,10 @@ export class PasswordResetFormComponent implements OnInit { }); this.newPasswdForm = this._formBuilder.group( { - passwordCtrl: new FormControl('', Validators.required, [ + passwordCtrl: new UntypedFormControl('', Validators.required, [ loginAsyncValidator(this.namespace, this.usersService, this.apiRequestConfiguration), ]), - passwordAgainCtrl: new FormControl('', Validators.required), + passwordAgainCtrl: new UntypedFormControl('', Validators.required), }, { validators: CustomValidators.passwordMatchValidator, diff --git a/apps/password-reset/src/styles.scss b/apps/password-reset/src/styles.scss index f86be4117..20a847bcc 100644 --- a/apps/password-reset/src/styles.scss +++ b/apps/password-reset/src/styles.scss @@ -90,3 +90,7 @@ $password-reset-theme: mat.define-light-theme( .mat-tooltip { font-size: 13px !important; } + +mat-icon { + overflow: inherit !important; +} diff --git a/apps/password-reset/tsconfig.app.json b/apps/password-reset/tsconfig.app.json index e9fa6dfd9..52299bd89 100644 --- a/apps/password-reset/tsconfig.app.json +++ b/apps/password-reset/tsconfig.app.json @@ -4,5 +4,6 @@ "outDir": "../../dist/out-tsc", "types": [] }, - "files": ["src/main.ts", "src/polyfills.ts"] + "files": ["src/main.ts", "src/polyfills.ts"], + "exclude": ["jest.config.ts"] } diff --git a/apps/password-reset/tsconfig.editor.json b/apps/password-reset/tsconfig.editor.json index 20c4afdbf..1bf3c0a74 100644 --- a/apps/password-reset/tsconfig.editor.json +++ b/apps/password-reset/tsconfig.editor.json @@ -3,5 +3,6 @@ "include": ["**/*.ts"], "compilerOptions": { "types": ["jest", "node"] - } + }, + "exclude": ["jest.config.ts"] } diff --git a/apps/password-reset/tsconfig.json b/apps/password-reset/tsconfig.json index 81cb95e9d..7dcba4076 100644 --- a/apps/password-reset/tsconfig.json +++ b/apps/password-reset/tsconfig.json @@ -12,5 +12,8 @@ { "path": "./tsconfig.editor.json" } - ] + ], + "compilerOptions": { + "target": "es2020" + } } diff --git a/apps/password-reset/tsconfig.spec.json b/apps/password-reset/tsconfig.spec.json index bc90aab09..b6347c6f6 100644 --- a/apps/password-reset/tsconfig.spec.json +++ b/apps/password-reset/tsconfig.spec.json @@ -6,5 +6,5 @@ "types": ["jest", "node"] }, "files": ["src/test-setup.ts"], - "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/apps/publications-e2e/cypress.config.ts b/apps/publications-e2e/cypress.config.ts new file mode 100644 index 000000000..493f133a2 --- /dev/null +++ b/apps/publications-e2e/cypress.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'cypress'; +import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; + +const cypressJsonConfig = { + fileServerFolder: '.', + fixturesFolder: './src/fixtures', + video: true, + videosFolder: '../../dist/cypress/apps/publications-e2e/videos', + screenshotsFolder: '../../dist/cypress/apps/publications-e2e/screenshots', + chromeWebSecurity: false, + specPattern: './src/integration/**/*.cy.{js,jsx,ts,tsx}', + supportFile: 'src/support/e2e.ts', +}; +export default defineConfig({ + e2e: { + ...nxE2EPreset(__dirname), + ...cypressJsonConfig, + }, +}); diff --git a/apps/publications-e2e/cypress.json b/apps/publications-e2e/cypress.json deleted file mode 100644 index 0242cd53a..000000000 --- a/apps/publications-e2e/cypress.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "fileServerFolder": ".", - "fixturesFolder": "./src/fixtures", - "integrationFolder": "./src/integration", - "modifyObstructiveCode": false, - "pluginsFile": "./src/plugins/index", - "supportFile": "./src/support/index.ts", - "video": true, - "videosFolder": "../../dist/cypress/apps/publications-e2e/videos", - "screenshotsFolder": "../../dist/cypress/apps/publications-e2e/screenshots", - "chromeWebSecurity": false -} diff --git a/apps/publications-e2e/src/support/index.ts b/apps/publications-e2e/src/support/e2e.ts similarity index 100% rename from apps/publications-e2e/src/support/index.ts rename to apps/publications-e2e/src/support/e2e.ts diff --git a/apps/publications-e2e/tsconfig.e2e.json b/apps/publications-e2e/tsconfig.e2e.json index 824748ba2..54c20f01f 100644 --- a/apps/publications-e2e/tsconfig.e2e.json +++ b/apps/publications-e2e/tsconfig.e2e.json @@ -4,5 +4,5 @@ "sourceMap": false, "outDir": "../../dist/out-tsc" }, - "include": ["src/**/*.ts", "src/**/*.js"] + "include": ["src/**/*.ts", "src/**/*.js", "cypress.config.ts"] } diff --git a/apps/publications/jest.config.js b/apps/publications/jest.config.ts similarity index 94% rename from apps/publications/jest.config.js rename to apps/publications/jest.config.ts index 39b8a9035..daab3411c 100644 --- a/apps/publications/jest.config.js +++ b/apps/publications/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { displayName: 'publications', preset: '../../jest.preset.js', setupFilesAfterEnv: ['/src/test-setup.ts'], diff --git a/apps/publications/src/app/components/publication-detail-list/publication-detail-list.component.ts b/apps/publications/src/app/components/publication-detail-list/publication-detail-list.component.ts index 83e6d2cde..bf005c83a 100644 --- a/apps/publications/src/app/components/publication-detail-list/publication-detail-list.component.ts +++ b/apps/publications/src/app/components/publication-detail-list/publication-detail-list.component.ts @@ -8,7 +8,7 @@ import { } from '@perun-web-apps/perun/openapi'; import { SelectionModel } from '@angular/cdk/collections'; import { Moment } from 'moment'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core'; import { MomentDateAdapter } from '@angular/material-moment-adapter'; import * as _moment from 'moment'; @@ -54,10 +54,10 @@ export class PublicationDetailListComponent implements OnInit { keys: string[]; values: string[]; map: { key: string; value: string }[] = []; - yearControl: FormControl; - categoryControl: FormControl; - rankControl: FormControl; - titleControl: FormControl; + yearControl: UntypedFormControl; + categoryControl: UntypedFormControl; + rankControl: UntypedFormControl; + titleControl: UntypedFormControl; editing = false; maxYear: Moment; @@ -97,10 +97,10 @@ export class PublicationDetailListComponent implements OnInit { } this.dataSource = new MatTableDataSource<{ key; value }>(this.map); - this.titleControl = new FormControl(this.publication.title, Validators.required); - this.yearControl = new FormControl(moment().year(this.publication.year)); - this.categoryControl = new FormControl(this.publication.categoryName); - this.rankControl = new FormControl(this.publication.rank, [ + this.titleControl = new UntypedFormControl(this.publication.title, Validators.required); + this.yearControl = new UntypedFormControl(moment().year(this.publication.year)); + this.categoryControl = new UntypedFormControl(this.publication.categoryName); + this.rankControl = new UntypedFormControl(this.publication.rank, [ Validators.pattern(/^[0-9]+(\.[0-9])?$/), Validators.required, ]); diff --git a/apps/publications/src/app/components/publication-filter/publication-filter.component.ts b/apps/publications/src/app/components/publication-filter/publication-filter.component.ts index 7046c7cfc..4522462c9 100644 --- a/apps/publications/src/app/components/publication-filter/publication-filter.component.ts +++ b/apps/publications/src/app/components/publication-filter/publication-filter.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, OnInit, Output } from '@angular/core'; import { CabinetManagerService, Category } from '@perun-web-apps/perun/openapi'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; import * as _moment from 'moment'; import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core'; import { MomentDateAdapter } from '@angular/material-moment-adapter'; @@ -46,12 +46,12 @@ export class PublicationFilterComponent implements OnInit { @Output() filteredPublication: EventEmitter = new EventEmitter(); categories: Category[]; - title = new FormControl(); - code = new FormControl(); + title = new UntypedFormControl(); + code = new UntypedFormControl(); selectedMode: string; selectedCategory: Category | 'no_value'; - startYear = new FormControl(moment()); - endYear = new FormControl(moment()); + startYear = new UntypedFormControl(moment()); + endYear = new UntypedFormControl(moment()); constructor(private cabinetService: CabinetManagerService) {} @@ -83,8 +83,8 @@ export class PublicationFilterComponent implements OnInit { this.code.setValue(''); this.selectedMode = 'isbn/issn'; this.selectedCategory = 'no_value'; - this.startYear = new FormControl(moment()); - this.endYear = new FormControl(moment()); + this.startYear = new UntypedFormControl(moment()); + this.endYear = new UntypedFormControl(moment()); const filter = { title: null, isbnissn: null, diff --git a/apps/publications/src/app/components/year-range/year-range.component.ts b/apps/publications/src/app/components/year-range/year-range.component.ts index 7faaa24f6..fc2d208c1 100644 --- a/apps/publications/src/app/components/year-range/year-range.component.ts +++ b/apps/publications/src/app/components/year-range/year-range.component.ts @@ -1,5 +1,5 @@ import { Component, Input, OnInit } from '@angular/core'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; import { MatDatepicker } from '@angular/material/datepicker'; @Component({ @@ -8,8 +8,8 @@ import { MatDatepicker } from '@angular/material/datepicker'; styleUrls: ['./year-range.component.scss'], }) export class YearRangeComponent implements OnInit { - @Input() startYear: FormControl; - @Input() endYear: FormControl; + @Input() startYear: UntypedFormControl; + @Input() endYear: UntypedFormControl; startMaxYear: Date; endMinYear: Date; endMaxYear: Date; @@ -21,8 +21,8 @@ export class YearRangeComponent implements OnInit { } chosenYearHandler( - dateFormControl: FormControl, - event: FormControl, + dateFormControl: UntypedFormControl, + event: UntypedFormControl, datepicker: MatDatepicker ): void { dateFormControl.setValue(event); diff --git a/apps/publications/src/app/dialogs/add-authors-dialog/add-authors-dialog.component.ts b/apps/publications/src/app/dialogs/add-authors-dialog/add-authors-dialog.component.ts index 88b447202..2e8f0100f 100644 --- a/apps/publications/src/app/dialogs/add-authors-dialog/add-authors-dialog.component.ts +++ b/apps/publications/src/app/dialogs/add-authors-dialog/add-authors-dialog.component.ts @@ -1,6 +1,6 @@ import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { Author, CabinetManagerService } from '@perun-web-apps/perun/openapi'; import { TABLE_PUBLICATION_AUTHORS } from '@perun-web-apps/config/table-config'; import { SelectionModel } from '@angular/cdk/collections'; @@ -18,7 +18,7 @@ export interface AddAuthorsDialogData { styleUrls: ['./add-authors-dialog.component.scss'], }) export class AddAuthorsDialogComponent implements OnInit { - searchControl: FormControl; + searchControl: UntypedFormControl; successMessage: string; loading = false; searchLoading = false; @@ -46,7 +46,7 @@ export class AddAuthorsDialogComponent implements OnInit { } ngOnInit(): void { - this.searchControl = new FormControl('', [ + this.searchControl = new UntypedFormControl('', [ Validators.required, Validators.pattern('.*[\\S]+.*'), ]); diff --git a/apps/publications/src/app/dialogs/add-category-dialog/add-category-dialog.component.ts b/apps/publications/src/app/dialogs/add-category-dialog/add-category-dialog.component.ts index 11222b9d8..25219716f 100644 --- a/apps/publications/src/app/dialogs/add-category-dialog/add-category-dialog.component.ts +++ b/apps/publications/src/app/dialogs/add-category-dialog/add-category-dialog.component.ts @@ -3,7 +3,7 @@ import { MatDialogRef } from '@angular/material/dialog'; import { NotificatorService } from '@perun-web-apps/perun/services'; import { CabinetManagerService } from '@perun-web-apps/perun/openapi'; import { TranslateService } from '@ngx-translate/core'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; @Component({ selector: 'perun-web-apps-add-category-dialog', @@ -14,8 +14,8 @@ export class AddCategoryDialogComponent implements OnInit { successMessage: string; loading: boolean; - nameCtrl: FormControl; - rankCtrl: FormControl; + nameCtrl: UntypedFormControl; + rankCtrl: UntypedFormControl; constructor( private dialogRef: MatDialogRef, @@ -29,12 +29,12 @@ export class AddCategoryDialogComponent implements OnInit { } ngOnInit(): void { - this.nameCtrl = new FormControl(null, [ + this.nameCtrl = new UntypedFormControl(null, [ Validators.required, Validators.pattern('^[\\w.-]+( [\\w.-]+)*$'), Validators.maxLength(128), ]); - this.rankCtrl = new FormControl(null, [ + this.rankCtrl = new UntypedFormControl(null, [ Validators.required, Validators.pattern('^[0-9]+(\\.[0-9])?$'), ]); diff --git a/apps/publications/src/app/dialogs/update-rank-dialog/update-rank-dialog.component.ts b/apps/publications/src/app/dialogs/update-rank-dialog/update-rank-dialog.component.ts index 1ba2018bd..0869f0399 100644 --- a/apps/publications/src/app/dialogs/update-rank-dialog/update-rank-dialog.component.ts +++ b/apps/publications/src/app/dialogs/update-rank-dialog/update-rank-dialog.component.ts @@ -3,7 +3,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { NotificatorService } from '@perun-web-apps/perun/services'; import { CabinetManagerService, Category } from '@perun-web-apps/perun/openapi'; import { TranslateService } from '@ngx-translate/core'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; @Component({ selector: 'perun-web-apps-update-rank-dialog', @@ -14,7 +14,7 @@ export class UpdateRankDialogComponent implements OnInit { successMessage: string; loading: boolean; categoryName = ''; - rankCtrl: FormControl; + rankCtrl: UntypedFormControl; constructor( private dialogRef: MatDialogRef, @@ -30,7 +30,7 @@ export class UpdateRankDialogComponent implements OnInit { ngOnInit(): void { this.categoryName = this.data.name; - this.rankCtrl = new FormControl(this.data.rank, [ + this.rankCtrl = new UntypedFormControl(this.data.rank, [ Validators.required, Validators.pattern('^[0-9]+(\\.[0-9])?$'), ]); diff --git a/apps/publications/src/app/pages/create-publication-page/create-single-publication-page/create-single-publication-page.component.ts b/apps/publications/src/app/pages/create-publication-page/create-single-publication-page/create-single-publication-page.component.ts index e442d6d14..49625256b 100644 --- a/apps/publications/src/app/pages/create-publication-page/create-single-publication-page/create-single-publication-page.component.ts +++ b/apps/publications/src/app/pages/create-publication-page/create-single-publication-page/create-single-publication-page.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { Author, CabinetManagerService, @@ -50,7 +50,7 @@ export const YEAR_MODE_FORMATS = { ], }) export class CreateSinglePublicationPageComponent implements OnInit { - publicationControl: FormGroup; + publicationControl: UntypedFormGroup; similarPublications: PublicationForGUI[] = []; filteredPublications: PublicationForGUI[] = []; categories: Category[] = []; @@ -71,7 +71,7 @@ export class CreateSinglePublicationPageComponent implements OnInit { selectedPubTitle = ''; constructor( - private formBuilder: FormBuilder, + private formBuilder: UntypedFormBuilder, private cabinetService: CabinetManagerService, private dialog: MatDialog, private router: Router, diff --git a/apps/publications/src/app/pages/create-publication-page/import-publications-page/import-publications-page.component.ts b/apps/publications/src/app/pages/create-publication-page/import-publications-page/import-publications-page.component.ts index f3c65c399..d52179c06 100644 --- a/apps/publications/src/app/pages/create-publication-page/import-publications-page/import-publications-page.component.ts +++ b/apps/publications/src/app/pages/create-publication-page/import-publications-page/import-publications-page.component.ts @@ -6,7 +6,7 @@ import { PublicationForGUI, PublicationSystem, } from '@perun-web-apps/perun/openapi'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core'; import { MomentDateAdapter } from '@angular/material-moment-adapter'; import * as _moment from 'moment'; @@ -50,7 +50,7 @@ export const YEAR_MODE_FORMATS = { export class ImportPublicationsPageComponent implements OnInit { loading = false; publicationSystems: PublicationSystem[] = []; - pubSystem = new FormControl(); + pubSystem = new UntypedFormControl(); pubSystemNamespace: string; publications: PublicationForGUI[] = []; @@ -59,8 +59,8 @@ export class ImportPublicationsPageComponent implements OnInit { displayedColumns = ['select', 'id', 'lock', 'title', 'reportedBy', 'year', 'category']; firstSearchDone: boolean; - startYear: FormControl; - endYear: FormControl; + startYear: UntypedFormControl; + endYear: UntypedFormControl; userId: number; userAsAuthor = true; @@ -84,8 +84,8 @@ export class ImportPublicationsPageComponent implements OnInit { this.firstSearchDone = false; this.userId = this.storeService.getPerunPrincipal().user.id; - this.startYear = new FormControl(moment().subtract(1, 'year')); - this.endYear = new FormControl(moment()); + this.startYear = new UntypedFormControl(moment().subtract(1, 'year')); + this.endYear = new UntypedFormControl(moment()); this.cabinetService.getPublicationSystems().subscribe((publicationSystems) => { this.publicationSystems = publicationSystems.filter((ps) => ps.friendlyName !== 'INTERNAL'); diff --git a/apps/publications/src/styles.scss b/apps/publications/src/styles.scss index 35856b6d9..f09a0f20b 100644 --- a/apps/publications/src/styles.scss +++ b/apps/publications/src/styles.scss @@ -320,3 +320,7 @@ $i: 0; fill: currentColor; } } + +mat-icon { + overflow: inherit !important; +} diff --git a/apps/publications/tsconfig.app.json b/apps/publications/tsconfig.app.json index e9fa6dfd9..52299bd89 100644 --- a/apps/publications/tsconfig.app.json +++ b/apps/publications/tsconfig.app.json @@ -4,5 +4,6 @@ "outDir": "../../dist/out-tsc", "types": [] }, - "files": ["src/main.ts", "src/polyfills.ts"] + "files": ["src/main.ts", "src/polyfills.ts"], + "exclude": ["jest.config.ts"] } diff --git a/apps/publications/tsconfig.editor.json b/apps/publications/tsconfig.editor.json index 20c4afdbf..1bf3c0a74 100644 --- a/apps/publications/tsconfig.editor.json +++ b/apps/publications/tsconfig.editor.json @@ -3,5 +3,6 @@ "include": ["**/*.ts"], "compilerOptions": { "types": ["jest", "node"] - } + }, + "exclude": ["jest.config.ts"] } diff --git a/apps/publications/tsconfig.json b/apps/publications/tsconfig.json index 81cb95e9d..7dcba4076 100644 --- a/apps/publications/tsconfig.json +++ b/apps/publications/tsconfig.json @@ -12,5 +12,8 @@ { "path": "./tsconfig.editor.json" } - ] + ], + "compilerOptions": { + "target": "es2020" + } } diff --git a/apps/publications/tsconfig.spec.json b/apps/publications/tsconfig.spec.json index bc90aab09..b6347c6f6 100644 --- a/apps/publications/tsconfig.spec.json +++ b/apps/publications/tsconfig.spec.json @@ -6,5 +6,5 @@ "types": ["jest", "node"] }, "files": ["src/test-setup.ts"], - "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/apps/user-profile-e2e/cypress.config.ts b/apps/user-profile-e2e/cypress.config.ts new file mode 100644 index 000000000..025453a70 --- /dev/null +++ b/apps/user-profile-e2e/cypress.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'cypress'; +import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; + +const cypressJsonConfig = { + fileServerFolder: '.', + fixturesFolder: './src/fixtures', + video: true, + videosFolder: '../../dist/cypress/apps/user-profile-e2e/videos', + screenshotsFolder: '../../dist/cypress/apps/user-profile-e2e/screenshots', + chromeWebSecurity: false, + specPattern: './src/integration/**/*.cy.{js,jsx,ts,tsx}', + supportFile: 'src/support/e2e.ts', +}; +export default defineConfig({ + e2e: { + ...nxE2EPreset(__dirname), + ...cypressJsonConfig, + }, +}); diff --git a/apps/user-profile-e2e/cypress.json b/apps/user-profile-e2e/cypress.json deleted file mode 100644 index 4d4eafe64..000000000 --- a/apps/user-profile-e2e/cypress.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "fileServerFolder": ".", - "fixturesFolder": "./src/fixtures", - "integrationFolder": "./src/integration", - "modifyObstructiveCode": false, - "pluginsFile": "./src/plugins/index", - "supportFile": "./src/support/index.ts", - "video": true, - "videosFolder": "../../dist/cypress/apps/user-profile-e2e/videos", - "screenshotsFolder": "../../dist/cypress/apps/user-profile-e2e/screenshots", - "chromeWebSecurity": false -} diff --git a/apps/user-profile-e2e/src/support/index.ts b/apps/user-profile-e2e/src/support/e2e.ts similarity index 100% rename from apps/user-profile-e2e/src/support/index.ts rename to apps/user-profile-e2e/src/support/e2e.ts diff --git a/apps/user-profile-e2e/tsconfig.e2e.json b/apps/user-profile-e2e/tsconfig.e2e.json index 824748ba2..54c20f01f 100644 --- a/apps/user-profile-e2e/tsconfig.e2e.json +++ b/apps/user-profile-e2e/tsconfig.e2e.json @@ -4,5 +4,5 @@ "sourceMap": false, "outDir": "../../dist/out-tsc" }, - "include": ["src/**/*.ts", "src/**/*.js"] + "include": ["src/**/*.ts", "src/**/*.js", "cypress.config.ts"] } diff --git a/apps/user-profile/jest.config.js b/apps/user-profile/jest.config.ts similarity index 93% rename from apps/user-profile/jest.config.js rename to apps/user-profile/jest.config.ts index ef7df218e..993ca3acd 100644 --- a/apps/user-profile/jest.config.js +++ b/apps/user-profile/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { preset: '../../jest.preset.js', coverageDirectory: '../../coverage/apps/users-page', diff --git a/apps/user-profile/src/app/components/dialogs/activate-local-account-dialog/activate-local-account-dialog.component.ts b/apps/user-profile/src/app/components/dialogs/activate-local-account-dialog/activate-local-account-dialog.component.ts index 8451cf028..dcee78e8b 100644 --- a/apps/user-profile/src/app/components/dialogs/activate-local-account-dialog/activate-local-account-dialog.component.ts +++ b/apps/user-profile/src/app/components/dialogs/activate-local-account-dialog/activate-local-account-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; -import { FormBuilder, ValidatorFn, Validators } from '@angular/forms'; +import { UntypedFormBuilder, ValidatorFn, Validators } from '@angular/forms'; import { CustomValidators } from '@perun-web-apps/perun/utils'; import { UsersManagerService } from '@perun-web-apps/perun/openapi'; import { ApiRequestConfigurationService, NotificatorService } from '@perun-web-apps/perun/services'; @@ -41,7 +41,7 @@ export class ActivateLocalAccountDialogComponent { private userManager: UsersManagerService, private notificator: NotificatorService, private translate: TranslateService, - private formBuilder: FormBuilder, + private formBuilder: UntypedFormBuilder, private apiRequestConfiguration: ApiRequestConfigurationService ) {} diff --git a/apps/user-profile/src/app/components/dialogs/add-ssh-dialog/add-ssh-dialog.component.ts b/apps/user-profile/src/app/components/dialogs/add-ssh-dialog/add-ssh-dialog.component.ts index af44c0019..aafc271ce 100644 --- a/apps/user-profile/src/app/components/dialogs/add-ssh-dialog/add-ssh-dialog.component.ts +++ b/apps/user-profile/src/app/components/dialogs/add-ssh-dialog/add-ssh-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Attribute, AttributesManagerService } from '@perun-web-apps/perun/openapi'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; export interface AddSshDialogData { attribute: Attribute; @@ -34,7 +34,7 @@ export class AddSshDialogComponent implements OnInit { 'sk-ecdsa-sha2-nistp256-cert-v01@openssh.com', ]; static readonly sshKeyPattern = '^(' + AddSshDialogComponent.allowedSshKeys.join('|') + ').+$'; - sshControl: FormControl; + sshControl: UntypedFormControl; constructor( private dialogRef: MatDialogRef, @@ -43,7 +43,7 @@ export class AddSshDialogComponent implements OnInit { ) {} ngOnInit(): void { - this.sshControl = new FormControl(null, [ + this.sshControl = new UntypedFormControl(null, [ Validators.required, Validators.pattern(AddSshDialogComponent.sshKeyPattern), ]); diff --git a/apps/user-profile/src/app/components/dialogs/add-unix-group-dialog/add-unix-group-dialog.component.ts b/apps/user-profile/src/app/components/dialogs/add-unix-group-dialog/add-unix-group-dialog.component.ts index a8b913c25..93892bf9a 100644 --- a/apps/user-profile/src/app/components/dialogs/add-unix-group-dialog/add-unix-group-dialog.component.ts +++ b/apps/user-profile/src/app/components/dialogs/add-unix-group-dialog/add-unix-group-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { AttributesManagerService } from '@perun-web-apps/perun/openapi'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; export interface AddUnixGroupDialogData { userId: number; @@ -15,7 +15,7 @@ export interface AddUnixGroupDialogData { styleUrls: ['./add-unix-group-dialog.component.scss'], }) export class AddUnixGroupDialogComponent implements OnInit { - inputControl: FormControl; + inputControl: UntypedFormControl; loading: boolean; groups: string[] = []; @@ -26,7 +26,7 @@ export class AddUnixGroupDialogComponent implements OnInit { ) {} ngOnInit(): void { - this.inputControl = new FormControl(null, Validators.required); + this.inputControl = new UntypedFormControl(null, Validators.required); this.groups = this.data.groups; } diff --git a/apps/user-profile/src/app/components/dialogs/request-change-data-quota-dialog/request-change-data-quota-dialog.component.ts b/apps/user-profile/src/app/components/dialogs/request-change-data-quota-dialog/request-change-data-quota-dialog.component.ts index 051625e0a..7f5b1db6f 100644 --- a/apps/user-profile/src/app/components/dialogs/request-change-data-quota-dialog/request-change-data-quota-dialog.component.ts +++ b/apps/user-profile/src/app/components/dialogs/request-change-data-quota-dialog/request-change-data-quota-dialog.component.ts @@ -1,6 +1,6 @@ import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { RichResource, RTMessagesManagerService, User, Vo } from '@perun-web-apps/perun/openapi'; import { UserFullNamePipe } from '@perun-web-apps/perun/pipes'; import { NotificatorService } from '@perun-web-apps/perun/services'; @@ -21,8 +21,8 @@ export interface RequestChangeDataQuotaDialogData { export class RequestChangeDataQuotaDialogComponent implements OnInit { resource = ''; currentQuota = ''; - reasonControl: FormControl; - newValueControl: FormControl; + reasonControl: UntypedFormControl; + newValueControl: UntypedFormControl; units: string[] = ['MiB', 'GiB', 'TiB']; selectedUnit = 'GiB'; successMessage: string; @@ -42,8 +42,8 @@ export class RequestChangeDataQuotaDialogComponent implements OnInit { ngOnInit(): void { this.resource = this.data.resource.name; this.currentQuota = this.data.currentQuota; - this.reasonControl = new FormControl(null, [Validators.required]); - this.newValueControl = new FormControl(null, [ + this.reasonControl = new UntypedFormControl(null, [Validators.required]); + this.newValueControl = new UntypedFormControl(null, [ Validators.required, Validators.pattern('[1-9][0-9]*'), ]); diff --git a/apps/user-profile/src/app/pages/groups-page/groups-page.component.ts b/apps/user-profile/src/app/pages/groups-page/groups-page.component.ts index 17cc16a23..20f1214b1 100644 --- a/apps/user-profile/src/app/pages/groups-page/groups-page.component.ts +++ b/apps/user-profile/src/app/pages/groups-page/groups-page.component.ts @@ -9,7 +9,7 @@ import { VosManagerService, } from '@perun-web-apps/perun/openapi'; import { StoreService } from '@perun-web-apps/perun/services'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; import { map, startWith } from 'rxjs/operators'; import { Observable } from 'rxjs'; @@ -25,7 +25,7 @@ export class GroupsPageComponent implements OnInit { loading = false; userId: number; vos: Vo[] = []; - myControl = new FormControl(); + myControl = new UntypedFormControl(); filteredVos: Observable; selection = new SelectionModel(false, []); diff --git a/apps/user-profile/src/app/pages/identities-page/identities-page.component.ts b/apps/user-profile/src/app/pages/identities-page/identities-page.component.ts index 27079f0d6..b0e0dcb17 100644 --- a/apps/user-profile/src/app/pages/identities-page/identities-page.component.ts +++ b/apps/user-profile/src/app/pages/identities-page/identities-page.component.ts @@ -13,6 +13,7 @@ import { getDefaultDialogConfig } from '@perun-web-apps/perun/utils'; import { RemoveUserExtSourceDialogComponent } from '@perun-web-apps/perun/dialogs'; import { LinkerResult, OpenLinkerService } from '@perun-web-apps/lib-linker'; import { TranslateService } from '@ngx-translate/core'; +import { Urns } from '@perun-web-apps/perun/urns'; @Component({ selector: 'perun-web-apps-identities-page', @@ -36,7 +37,7 @@ export class IdentitiesPageComponent implements OnInit { loading: boolean; displayCertificates: boolean; - displayedColumnsIdp = ['select', 'extSourceName', 'login', 'lastAccess']; + displayedColumnsIdp = ['select', 'extSourceName', 'login', 'mail', 'lastAccess']; displayedColumnsCert = ['select', 'extSourceName', 'login', 'lastAccess']; displayedColumnsOther = ['extSourceName', 'login', 'lastAccess']; @@ -66,13 +67,20 @@ export class IdentitiesPageComponent implements OnInit { let count = userExtSources.length; userExtSources.forEach((ues) => { this.attributesManagerService - .getUserExtSourceAttributeByName( - ues.userExtSource.id, - 'urn:perun:ues:attribute-def:def:sourceIdPName' - ) - .subscribe((sourceName) => { - if (sourceName?.value) { - ues.userExtSource.extSource.name = sourceName.value as string; + .getUserExtSourceAttributesByNames(ues.userExtSource.id, [ + Urns.UES_SOURCE_IDP_NAME, + Urns.UES_DEF_MAIL, + ]) + .subscribe((attributes) => { + attributes + .filter((attr) => attr.baseFriendlyName === 'mail' && attr.value === null) + .map((attr) => ues.attributes.push(attr)); + let sourceName: string; + attributes + .filter((attr) => attr.baseFriendlyName === 'sourceIdPName' && attr?.value) + .map((attr) => (sourceName = attr.value as string)); + if (sourceName) { + ues.userExtSource.extSource.name = sourceName; count--; this.loading = count !== 0; this.addToList(ues); @@ -80,7 +88,7 @@ export class IdentitiesPageComponent implements OnInit { this.attributesManagerService .getUserExtSourceAttributeByName( ues.userExtSource.id, - 'urn:perun:ues:attribute-def:def:IdPOrganizationName' + Urns.UES_IDP_ORGANIZATION_NAME ) .subscribe((orgName) => { count--; diff --git a/apps/user-profile/src/app/pages/settings-page/settings-alternative-passwords/settings-alternative-passwords.component.ts b/apps/user-profile/src/app/pages/settings-page/settings-alternative-passwords/settings-alternative-passwords.component.ts index 20dbba57b..46851d5b3 100644 --- a/apps/user-profile/src/app/pages/settings-page/settings-alternative-passwords/settings-alternative-passwords.component.ts +++ b/apps/user-profile/src/app/pages/settings-page/settings-alternative-passwords/settings-alternative-passwords.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { StoreService } from '@perun-web-apps/perun/services'; import { AttributesManagerService, UsersManagerService } from '@perun-web-apps/perun/openapi'; import { MatDialog } from '@angular/material/dialog'; @@ -15,7 +15,7 @@ import { getDefaultDialogConfig } from '@perun-web-apps/perun/utils'; styleUrls: ['./settings-alternative-passwords.component.scss'], }) export class SettingsAlternativePasswordsComponent implements OnInit { - altPasswordCtrl = new FormControl(null, [Validators.required]); + altPasswordCtrl = new UntypedFormControl(null, [Validators.required]); userId = this.store.getPerunPrincipal().userId; removeDialogTitle: string; removeDialogDescription: string; diff --git a/apps/user-profile/src/app/pages/settings-page/settings-authorization/mfa-settings/mfa-settings.component.html b/apps/user-profile/src/app/pages/settings-page/settings-authorization/mfa-settings/mfa-settings.component.html index 8eb217cb6..54fee5822 100644 --- a/apps/user-profile/src/app/pages/settings-page/settings-authorization/mfa-settings/mfa-settings.component.html +++ b/apps/user-profile/src/app/pages/settings-page/settings-authorization/mfa-settings/mfa-settings.component.html @@ -1,14 +1,19 @@
- {{'AUTHENTICATION.MFA_TOGGLE' | customTranslate | translate}}
- - {{category.value.label[this.translate.currentLang]}} - - +
{ + this.mfaApiService.isMfaAvailable().subscribe({ + next: (isAvailable) => { this.mfaAvailable = isAvailable; if (isAvailable) { this.loadMfa(); @@ -58,11 +58,11 @@ export class MfaSettingsComponent implements OnInit { this.loadingMfa = false; } }, - (err) => { + error: (err) => { console.error(err); this.loadingMfa = false; - } - ); + }, + }); } /** @@ -86,8 +86,8 @@ export class MfaSettingsComponent implements OnInit { const enforceMfaAttributeName = this.store.get('mfa', 'enforce_mfa_attribute') as string; this.attributesManagerService .getUserAttributeByName(this.store.getPerunPrincipal().userId, enforceMfaAttributeName) - .subscribe( - (attr) => { + .subscribe({ + next: (attr) => { if (attr.value) { this.enforceMfa = true; this.toggle.toggle(); @@ -96,11 +96,11 @@ export class MfaSettingsComponent implements OnInit { } this.loadingMfa = false; }, - (e) => { + error: (e) => { console.error(e); this.loadingMfa = false; - } - ); + }, + }); } } @@ -109,16 +109,16 @@ export class MfaSettingsComponent implements OnInit { */ getCategoriesAndSettings(): void { this.loadingCategories = true; - this.mfaApiService.getCategories().subscribe( - (categories) => { + this.mfaApiService.getCategories().subscribe({ + next: (categories) => { this.categories = categories; this.getSettings(); }, - (err) => { + error: (err) => { console.error(err); this.loadingCategories = false; - } - ); + }, + }); } /** @@ -133,8 +133,8 @@ export class MfaSettingsComponent implements OnInit { this.showDetail = !this.showDetail; this.loadingCategories = false; } else { - this.mfaApiService.getSettings().subscribe( - (settings) => { + this.mfaApiService.getSettings().subscribe({ + next: (settings) => { if (settings.length !== 0) { if (settings.all) { this.allCategories = true; @@ -149,11 +149,11 @@ export class MfaSettingsComponent implements OnInit { this.showDetail = !this.showDetail; this.loadingCategories = false; }, - (err) => { + error: (err) => { console.error(err); this.loadingCategories = false; - } - ); + }, + }); } } @@ -380,8 +380,8 @@ export class MfaSettingsComponent implements OnInit { * @param enforceMfa turn on/off mfa for all services according to toggle */ changeEnforceMfa(enforceMfa: boolean): void { - this.mfaApiService.enforceMfaForAllServices(enforceMfa).subscribe( - () => { + this.mfaApiService.enforceMfaForAllServices(enforceMfa).subscribe({ + next: () => { if (enforceMfa) { this.enforceMfa = true; if (!this.toggle.checked) { @@ -396,13 +396,15 @@ export class MfaSettingsComponent implements OnInit { sessionStorage.removeItem('mfa_route'); this.loadingMfa = false; }, - (err) => { + error: (err) => { // when token is valid, but user is logged in without MFA -> enforce MFA if (err.error.error === 'MFA is required') { this.saveSettings(true); + } else { + this.loadingMfa = false; } - } - ); + }, + }); } /** @@ -411,20 +413,22 @@ export class MfaSettingsComponent implements OnInit { updateDetailSettings(): void { const body = sessionStorage.getItem('settings_mfa'); - this.mfaApiService.updateDetailSettings(body).subscribe( - () => { + this.mfaApiService.updateDetailSettings(body).subscribe({ + next: () => { this.unchangedSettings = true; this.unchangedEnforce = true; sessionStorage.removeItem('settings_mfa'); sessionStorage.removeItem('mfa_route'); this.loadingMfa = false; }, - (err) => { + error: (err) => { // when token is valid, but user is logged in without MFA -> enforce MFA if (err.error.error === 'MFA is required') { this.saveSettings(true); + } else { + this.loadingMfa = false; } - } - ); + }, + }); } } diff --git a/apps/user-profile/src/app/pages/settings-page/settings-samba-password/settings-samba-password.component.ts b/apps/user-profile/src/app/pages/settings-page/settings-samba-password/settings-samba-password.component.ts index 28e5d2a07..49e367f25 100644 --- a/apps/user-profile/src/app/pages/settings-page/settings-samba-password/settings-samba-password.component.ts +++ b/apps/user-profile/src/app/pages/settings-page/settings-samba-password/settings-samba-password.component.ts @@ -5,7 +5,7 @@ import { UsersManagerService, } from '@perun-web-apps/perun/openapi'; import { NotificatorService, StoreService } from '@perun-web-apps/perun/services'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { TranslateService } from '@ngx-translate/core'; @Component({ @@ -17,7 +17,7 @@ export class SettingsSambaPasswordComponent implements OnInit { showPassword: boolean; sambaExists: boolean; sambaAttribute: Attribute; - sambaControl: FormControl; + sambaControl: UntypedFormControl; userId: number; showPwdTooltip: string; hidePwdTooltip: string; @@ -43,7 +43,7 @@ export class SettingsSambaPasswordComponent implements OnInit { ngOnInit(): void { this.userId = this.store.getPerunPrincipal().userId; - this.sambaControl = new FormControl('', [ + this.sambaControl = new UntypedFormControl('', [ Validators.pattern( '((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%&/=?_.,:;\\-])|(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%&/=?_.,:;\\-])|(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%&/=?_.,:;\\-])).{3,}' ), diff --git a/apps/user-profile/src/assets/i18n/cs.json b/apps/user-profile/src/assets/i18n/cs.json index 9c4535c15..0e7087476 100644 --- a/apps/user-profile/src/assets/i18n/cs.json +++ b/apps/user-profile/src/assets/i18n/cs.json @@ -5,7 +5,7 @@ }, "MENU_ITEMS": { "PROFILE": "Profil", - "IDENTITIES": "Spojené identity", + "IDENTITIES": "Spojené účty", "SERVICES": "Služby", "GROUPS": "Skupiny", "VOS": "Organizace", @@ -51,7 +51,7 @@ "MAIL_CHANGE_SUCCESS": "Preferovaný email byl změněn" }, "IDENTITIES": { - "IDP": "Vaše spojené identity", + "IDP": "Vaše spojené účty", "CERT": "Vaše certifikáty", "OTHER": "Ostatní", "ADD": "Přidat", @@ -59,8 +59,10 @@ "EXT_SOURCE_NAME_CERT": "Poskytovatel certifikátu", "EXT_SOURCE_NAME_OTHER": "Jméno externího zdroje", "LOGIN_CERT": "DN", - "LOGIN_IDP": "Připojená identita", - "OTHER_TOOLTIP": "Identity, které nebyly získány přes Konsolidátor identit" + "LOGIN_IDP": "Připojený účet", + "OTHER_TOOLTIP": "Účty, které nebyly získány přes Spojování účtů", + "SUCCESSFULLY_ADDED": "Účet byl úspěšně přidán", + "MESSAGE_SENT_TO_SUPPORT": "Email byl odeslán support týmu" }, "PRIVACY": { "TITLE": "Soukromí", @@ -332,12 +334,12 @@ }, "USER_EXT_SOURCES_LIST": { "MAIL": "Email", - "EXT_SOURCE_NAME": "Původ připojené identity", + "EXT_SOURCE_NAME": "Původ připojeného účtu", "LOGIN": "Jméno", "LAST_ACCESS": "Poslední použití", - "NO_IDENTITIES": "Nenalezeny žádné identity", + "NO_IDENTITIES": "Nenalezeny žádné účty", "ID": "Id", - "CANNOT_BE_DELETED_TOOLTIP": "Tato identita je trvalá, takže nemůže být odstraněna", + "CANNOT_BE_DELETED_TOOLTIP": "Tento účet je trvalý, takže nemůže být odstraněn", "LOA": "Úroveň důvěry" }, "BUG_REPORT": { @@ -353,12 +355,12 @@ "SUCCESS": "Nahlášená chyba byla odoslána" }, "REMOVE_USER_EXT_SOURCE": { - "TITLE": "Odstranit uživateli externi identitu", - "DESCRIPTION": "Následující externí identita bude odstraněna", + "TITLE": "Odstranit účet", + "DESCRIPTION": "Následující účet bude odstraněn", "ASK": "Jste si jistí, že chcete pokračovat?", "CANCEL": "Zrušit", "REMOVE": "Odstranit", - "SUCCESS": "Uživatelova externí identita byla odstraněna" + "SUCCESS": "Účet byl odstraněn" }, "PASSWORD_RESET": { "TITLE": "Změna hesla", diff --git a/apps/user-profile/src/assets/i18n/en.json b/apps/user-profile/src/assets/i18n/en.json index be16b8ba4..aa99db5f8 100644 --- a/apps/user-profile/src/assets/i18n/en.json +++ b/apps/user-profile/src/assets/i18n/en.json @@ -5,7 +5,7 @@ }, "MENU_ITEMS": { "PROFILE": "Profile", - "IDENTITIES": "Linked identities", + "IDENTITIES": "Linked accounts", "SERVICES": "Services", "GROUPS": "Groups", "VOS": "Organizations", @@ -51,7 +51,7 @@ "MAIL_CHANGE_SUCCESS": "Preferred mail has been changed" }, "IDENTITIES": { - "IDP": "Your linked identities", + "IDP": "Your linked accounts", "CERT": "Your certificates", "OTHER": "Other", "ADD": "Add", @@ -59,9 +59,9 @@ "EXT_SOURCE_NAME_CERT": "Certificate issuer", "EXT_SOURCE_NAME_OTHER": "External source name", "LOGIN_CERT": "DN", - "LOGIN_IDP": "Linked identity", - "OTHER_TOOLTIP": "Identities that were not acquired through Identity consolidator", - "SUCCESSFULLY_ADDED": "Identity was successfully added", + "LOGIN_IDP": "Linked account", + "OTHER_TOOLTIP": "Accounts that were not acquired through Account linking", + "SUCCESSFULLY_ADDED": "Account was successfully added", "MESSAGE_SENT_TO_SUPPORT": "Email was sent to support team" }, "PRIVACY": { @@ -381,12 +381,12 @@ }, "USER_EXT_SOURCES_LIST": { "MAIL": "Email", - "EXT_SOURCE_NAME": "Source of linked identity", + "EXT_SOURCE_NAME": "Source of linked account", "LOGIN": "Login", "LAST_ACCESS": "Last login", - "NO_IDENTITIES": "No external identities found", + "NO_IDENTITIES": "No external account found", "ID": "Id", - "CANNOT_BE_DELETED_TOOLTIP": "This identity is persistent, so it cannot be deleted", + "CANNOT_BE_DELETED_TOOLTIP": "This account is persistent, so it cannot be deleted", "LOA": "Level of assurance" }, "BUG_REPORT": { @@ -403,12 +403,12 @@ "SUCCESS2": " was created." }, "REMOVE_USER_EXT_SOURCE": { - "TITLE": "Remove user's external identity", - "DESCRIPTION": "Following external identity will be removed", + "TITLE": "Remove account", + "DESCRIPTION": "Following account will be removed", "ASK": "Are you sure you want to continue?", "CANCEL": "Cancel", "REMOVE": "Remove", - "SUCCESS": "User external source successfully removed" + "SUCCESS": "Account successfully removed" }, "PASSWORD_RESET": { "TITLE": "Change password", diff --git a/apps/user-profile/src/styles.scss b/apps/user-profile/src/styles.scss index 70135d695..5b7fbd3fa 100644 --- a/apps/user-profile/src/styles.scss +++ b/apps/user-profile/src/styles.scss @@ -212,3 +212,7 @@ td.mat-cell { .noBorderDialog .mat-dialog-container { background-color: black; } + +mat-icon { + overflow: inherit !important; +} diff --git a/apps/user-profile/tsconfig.app.json b/apps/user-profile/tsconfig.app.json index 2c67e323f..e03e801a8 100644 --- a/apps/user-profile/tsconfig.app.json +++ b/apps/user-profile/tsconfig.app.json @@ -6,5 +6,5 @@ }, "files": ["src/main.ts", "src/polyfills.ts"], "include": ["**/*.ts"], - "exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts"] + "exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts", "jest.config.ts"] } diff --git a/apps/user-profile/tsconfig.editor.json b/apps/user-profile/tsconfig.editor.json index 20c4afdbf..1bf3c0a74 100644 --- a/apps/user-profile/tsconfig.editor.json +++ b/apps/user-profile/tsconfig.editor.json @@ -3,5 +3,6 @@ "include": ["**/*.ts"], "compilerOptions": { "types": ["jest", "node"] - } + }, + "exclude": ["jest.config.ts"] } diff --git a/apps/user-profile/tsconfig.json b/apps/user-profile/tsconfig.json index 4ef4491ed..0eb8182de 100644 --- a/apps/user-profile/tsconfig.json +++ b/apps/user-profile/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "types": ["node", "jest"] + "types": ["node", "jest"], + "target": "es2020" }, "include": [], "files": [], diff --git a/apps/user-profile/tsconfig.spec.json b/apps/user-profile/tsconfig.spec.json index bc90aab09..b6347c6f6 100644 --- a/apps/user-profile/tsconfig.spec.json +++ b/apps/user-profile/tsconfig.spec.json @@ -6,5 +6,5 @@ "types": ["jest", "node"] }, "files": ["src/test-setup.ts"], - "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 6325310ed..000000000 --- a/jest.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getJestProjects } = require('@nrwl/jest'); - -module.exports = { projects: [...getJestProjects(), '/libs/dialogs'] }; diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 000000000..a371edf30 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,3 @@ +const { getJestProjects } = require('@nrwl/jest'); + +export default { projects: [...getJestProjects(), '/libs/dialogs'] }; diff --git a/jest.preset.js b/jest.preset.js index ecb0b0990..9f55bea46 100644 --- a/jest.preset.js +++ b/jest.preset.js @@ -1,4 +1,4 @@ -const nxPreset = require('@nrwl/jest/preset'); +const nxPreset = require('@nrwl/jest/preset').default; module.exports = { ...nxPreset, testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], diff --git a/libs/config/jest.config.js b/libs/config/jest.config.ts similarity index 94% rename from libs/config/jest.config.js rename to libs/config/jest.config.ts index 5b534eeaa..18d78723a 100644 --- a/libs/config/jest.config.js +++ b/libs/config/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { preset: '../../jest.preset.js', coverageDirectory: '../../coverage/libs/config', diff --git a/libs/config/table-config/jest.config.js b/libs/config/table-config/jest.config.ts similarity index 94% rename from libs/config/table-config/jest.config.js rename to libs/config/table-config/jest.config.ts index 549dd0e22..b44011824 100644 --- a/libs/config/table-config/jest.config.js +++ b/libs/config/table-config/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { preset: '../../../jest.preset.js', coverageDirectory: '../../../coverage/libs/config/table-config', diff --git a/libs/config/table-config/tsconfig.json b/libs/config/table-config/tsconfig.json index 1b6ee0bf6..5602461b1 100644 --- a/libs/config/table-config/tsconfig.json +++ b/libs/config/table-config/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../../tsconfig.base.json", "compilerOptions": { - "types": ["node", "jest"] + "types": ["node", "jest"], + "target": "es2020" }, "include": [], "files": [], diff --git a/libs/config/table-config/tsconfig.lib.json b/libs/config/table-config/tsconfig.lib.json index 9310f6c13..80ce5e870 100644 --- a/libs/config/table-config/tsconfig.lib.json +++ b/libs/config/table-config/tsconfig.lib.json @@ -13,6 +13,6 @@ "strictMetadataEmit": true, "enableResourceInlining": true }, - "exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts"], + "exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts", "jest.config.ts"], "include": ["**/*.ts"] } diff --git a/libs/config/table-config/tsconfig.spec.json b/libs/config/table-config/tsconfig.spec.json index 1f8e7f6c3..34c38b0ec 100644 --- a/libs/config/table-config/tsconfig.spec.json +++ b/libs/config/table-config/tsconfig.spec.json @@ -6,5 +6,5 @@ "types": ["jest", "node"] }, "files": ["src/test-setup.ts"], - "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/libs/config/tsconfig.json b/libs/config/tsconfig.json index 58bd2c97a..66284f305 100644 --- a/libs/config/tsconfig.json +++ b/libs/config/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "types": ["node", "jest"] + "types": ["node", "jest"], + "target": "es2020" }, "include": [], "files": [], diff --git a/libs/config/tsconfig.lib.json b/libs/config/tsconfig.lib.json index a2b675b7a..6e583ed3a 100644 --- a/libs/config/tsconfig.lib.json +++ b/libs/config/tsconfig.lib.json @@ -16,6 +16,6 @@ "strictInjectionParameters": true, "enableResourceInlining": true }, - "exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts"], + "exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts", "jest.config.ts"], "include": ["**/*.ts"] } diff --git a/libs/config/tsconfig.spec.json b/libs/config/tsconfig.spec.json index bc90aab09..b6347c6f6 100644 --- a/libs/config/tsconfig.spec.json +++ b/libs/config/tsconfig.spec.json @@ -6,5 +6,5 @@ "types": ["jest", "node"] }, "files": ["src/test-setup.ts"], - "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/libs/general/jest.config.js b/libs/general/jest.config.ts similarity index 94% rename from libs/general/jest.config.js rename to libs/general/jest.config.ts index eb6929892..e111bdb54 100644 --- a/libs/general/jest.config.js +++ b/libs/general/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { preset: '../../jest.preset.js', coverageDirectory: '../../coverage/libs/general', diff --git a/libs/general/tsconfig.json b/libs/general/tsconfig.json index 58bd2c97a..66284f305 100644 --- a/libs/general/tsconfig.json +++ b/libs/general/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "types": ["node", "jest"] + "types": ["node", "jest"], + "target": "es2020" }, "include": [], "files": [], diff --git a/libs/general/tsconfig.lib.json b/libs/general/tsconfig.lib.json index a2b675b7a..6e583ed3a 100644 --- a/libs/general/tsconfig.lib.json +++ b/libs/general/tsconfig.lib.json @@ -16,6 +16,6 @@ "strictInjectionParameters": true, "enableResourceInlining": true }, - "exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts"], + "exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts", "jest.config.ts"], "include": ["**/*.ts"] } diff --git a/libs/general/tsconfig.spec.json b/libs/general/tsconfig.spec.json index bc90aab09..b6347c6f6 100644 --- a/libs/general/tsconfig.spec.json +++ b/libs/general/tsconfig.spec.json @@ -6,5 +6,5 @@ "types": ["jest", "node"] }, "files": ["src/test-setup.ts"], - "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/libs/lib-linker/jest.config.js b/libs/lib-linker/jest.config.ts similarity index 93% rename from libs/lib-linker/jest.config.js rename to libs/lib-linker/jest.config.ts index 90bb7788f..99eea02b9 100644 --- a/libs/lib-linker/jest.config.js +++ b/libs/lib-linker/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { displayName: 'lib-linker', preset: '../../jest.preset.js', setupFilesAfterEnv: ['/src/test-setup.ts'], diff --git a/libs/lib-linker/src/lib/consolidation-result/consolidation-result.component.html b/libs/lib-linker/src/lib/consolidation-result/consolidation-result.component.html index d9dd3a8cf..20b8c17f8 100644 --- a/libs/lib-linker/src/lib/consolidation-result/consolidation-result.component.html +++ b/libs/lib-linker/src/lib/consolidation-result/consolidation-result.component.html @@ -12,9 +12,19 @@

{{('SHARED_LIB.CONSOLIDATOR.' + result + '_TITLE') | translate}}

-
+
{{('SHARED_LIB.CONSOLIDATOR.' + result + '_SUBTITLE') | translate}} - {{supportMail}} + + {{supportMail}} + + + {{userMail}} + +
+
+ {{'SHARED_LIB.CONSOLIDATOR.OK_SUBTITLE_WITH_MAIL_1' | translate}} + {{userMail}} + {{'SHARED_LIB.CONSOLIDATOR.OK_SUBTITLE_WITH_MAIL_2' | translate}}
diff --git a/libs/lib-linker/src/lib/consolidation-result/consolidation-result.component.ts b/libs/lib-linker/src/lib/consolidation-result/consolidation-result.component.ts index f4295f32c..2558106cf 100644 --- a/libs/lib-linker/src/lib/consolidation-result/consolidation-result.component.ts +++ b/libs/lib-linker/src/lib/consolidation-result/consolidation-result.component.ts @@ -11,6 +11,7 @@ export class ConsolidationResultComponent implements OnChanges { @Input() result: LinkerResult; supportMail = this.store.getProperty('support_mail'); + userMail: string = this.store.getPerunPrincipal().additionalInformations.mail; color = ''; icon = ''; diff --git a/libs/lib-linker/src/lib/open-linker.service.ts b/libs/lib-linker/src/lib/open-linker.service.ts index 81c716f65..82bcaaec7 100644 --- a/libs/lib-linker/src/lib/open-linker.service.ts +++ b/libs/lib-linker/src/lib/open-linker.service.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; import { OtherApplicationsService, StoreService } from '@perun-web-apps/perun/services'; import { OAuthService } from 'angular-oauth2-oidc'; -import { MatDialog } from '@angular/material/dialog'; -import { MatDialogRef } from '@angular/material/dialog/dialog-ref'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { FocusOnLinkerDialogComponent } from './focus-on-linker-dialog/focus-on-linker-dialog.component'; import { LinkerResult } from './models/LinkerResult'; import { getDefaultDialogConfig } from '@perun-web-apps/perun/utils'; diff --git a/libs/lib-linker/tsconfig.json b/libs/lib-linker/tsconfig.json index e568cf6bd..81233e316 100644 --- a/libs/lib-linker/tsconfig.json +++ b/libs/lib-linker/tsconfig.json @@ -11,6 +11,7 @@ } ], "compilerOptions": { - "types": ["node", "jest"] + "types": ["node", "jest"], + "target": "es2020" } } diff --git a/libs/lib-linker/tsconfig.lib.json b/libs/lib-linker/tsconfig.lib.json index bbcc12b1c..1cc2d08ae 100644 --- a/libs/lib-linker/tsconfig.lib.json +++ b/libs/lib-linker/tsconfig.lib.json @@ -9,6 +9,6 @@ "types": [], "lib": ["dom", "es2018"] }, - "exclude": ["src/test-setup.ts", "**/*.spec.ts"], + "exclude": ["src/test-setup.ts", "**/*.spec.ts", "jest.config.ts"], "include": ["**/*.ts"] } diff --git a/libs/lib-linker/tsconfig.spec.json b/libs/lib-linker/tsconfig.spec.json index cfff29a54..7cc1d7b96 100644 --- a/libs/lib-linker/tsconfig.spec.json +++ b/libs/lib-linker/tsconfig.spec.json @@ -6,5 +6,5 @@ "types": ["jest", "node"] }, "files": ["src/test-setup.ts"], - "include": ["**/*.spec.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/libs/perun/animations/jest.config.js b/libs/perun/animations/jest.config.ts similarity index 92% rename from libs/perun/animations/jest.config.js rename to libs/perun/animations/jest.config.ts index c353cbce2..509e3ab5b 100644 --- a/libs/perun/animations/jest.config.js +++ b/libs/perun/animations/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { preset: '../../../jest.preset.js', coverageDirectory: '../../../coverage/libs/perun/animations', diff --git a/libs/perun/animations/tsconfig.lib.json b/libs/perun/animations/tsconfig.lib.json index 63d67cbe0..e096f76e8 100644 --- a/libs/perun/animations/tsconfig.lib.json +++ b/libs/perun/animations/tsconfig.lib.json @@ -13,6 +13,6 @@ "strictMetadataEmit": true, "enableResourceInlining": true }, - "exclude": ["**/*.spec.ts", "**/*.test.ts"], + "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"], "include": ["**/*.ts"] } diff --git a/libs/perun/animations/tsconfig.spec.json b/libs/perun/animations/tsconfig.spec.json index e88d9bf39..67f758196 100644 --- a/libs/perun/animations/tsconfig.spec.json +++ b/libs/perun/animations/tsconfig.spec.json @@ -6,5 +6,5 @@ "types": ["jest", "node"] }, "files": [], - "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "jest.config.ts"] } diff --git a/libs/perun/components/jest.config.js b/libs/perun/components/jest.config.ts similarity index 94% rename from libs/perun/components/jest.config.js rename to libs/perun/components/jest.config.ts index cabf6451e..36f828857 100644 --- a/libs/perun/components/jest.config.js +++ b/libs/perun/components/jest.config.ts @@ -1,4 +1,5 @@ -module.exports = { +/* eslint-disable */ +export default { preset: '../../../jest.preset.js', coverageDirectory: '../../../coverage/libs/perun/components', diff --git a/libs/perun/components/src/lib/create-group-form/create-group-form.component.ts b/libs/perun/components/src/lib/create-group-form/create-group-form.component.ts index c40592866..9d12bb502 100644 --- a/libs/perun/components/src/lib/create-group-form/create-group-form.component.ts +++ b/libs/perun/components/src/lib/create-group-form/create-group-form.component.ts @@ -1,5 +1,5 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { FormControl, Validators } from '@angular/forms'; +import { UntypedFormControl, Validators } from '@angular/forms'; import { StoreService } from '@perun-web-apps/perun/services'; import { Group } from '@perun-web-apps/perun/openapi'; @@ -20,20 +20,23 @@ export class CreateGroupFormComponent implements OnInit { asSubgroup = false; invalidNameMessage: string = this.store.get('group_name_error_message') as string; secondaryRegex: string = this.store.get('group_name_secondary_regex') as string; - nameControl: FormControl; - descriptionControl: FormControl; + nameControl: UntypedFormControl; + descriptionControl: UntypedFormControl; selectedParent: Group; constructor(private store: StoreService) {} ngOnInit(): void { this.isNotSubGroup = this.parentGroup === null; - this.nameControl = new FormControl('', [ + this.nameControl = new UntypedFormControl('', [ Validators.required, Validators.pattern(this.secondaryRegex ? this.secondaryRegex : ''), Validators.pattern('.*[\\S]+.*'), ]); - this.descriptionControl = new FormControl('', [Validators.required, Validators.maxLength(129)]); + this.descriptionControl = new UntypedFormControl('', [ + Validators.required, + Validators.maxLength(129), + ]); this.selectedParent = null; this.voGroups = this.voGroups.filter((grp) => grp.name !== 'members'); } diff --git a/libs/perun/components/src/lib/date-range/date-range.component.ts b/libs/perun/components/src/lib/date-range/date-range.component.ts index 3d9f971a1..5341b3b1f 100644 --- a/libs/perun/components/src/lib/date-range/date-range.component.ts +++ b/libs/perun/components/src/lib/date-range/date-range.component.ts @@ -1,5 +1,5 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; @Component({ selector: 'perun-web-apps-date-range', @@ -7,8 +7,8 @@ import { FormControl } from '@angular/forms'; styleUrls: ['./date-range.component.scss'], }) export class DateRangeComponent implements OnInit { - @Input() startDate: FormControl; - @Input() endDate: FormControl; + @Input() startDate: UntypedFormControl; + @Input() endDate: UntypedFormControl; @Output() datePicker: EventEmitter = new EventEmitter(); startMinDate: Date; startMaxDate: Date; diff --git a/libs/perun/components/src/lib/debounce-filter/debounce-filter.component.ts b/libs/perun/components/src/lib/debounce-filter/debounce-filter.component.ts index 8bce56e5a..2c00aca0b 100644 --- a/libs/perun/components/src/lib/debounce-filter/debounce-filter.component.ts +++ b/libs/perun/components/src/lib/debounce-filter/debounce-filter.component.ts @@ -10,7 +10,7 @@ import { import { fromEvent } from 'rxjs'; import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'; import { MatInput } from '@angular/material/input'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; @Component({ selector: 'perun-web-apps-debounce-filter', @@ -20,7 +20,7 @@ import { FormControl } from '@angular/forms'; export class DebounceFilterComponent implements OnInit { @Input() placeholder: string; @Input() autoFocus = false; - @Input() control: FormControl = new FormControl(); + @Input() control: UntypedFormControl = new UntypedFormControl(); @Input() error: string; @Output() filter = new EventEmitter(); @ViewChild('input', { static: true }) input: ElementRef; diff --git a/libs/perun/components/src/lib/entity-search-select/entity-search-select.component.ts b/libs/perun/components/src/lib/entity-search-select/entity-search-select.component.ts index 19e92e5c6..a58400c19 100644 --- a/libs/perun/components/src/lib/entity-search-select/entity-search-select.component.ts +++ b/libs/perun/components/src/lib/entity-search-select/entity-search-select.component.ts @@ -11,7 +11,7 @@ import { ViewChild, } from '@angular/core'; import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; import { ReplaySubject, Subject } from 'rxjs'; import { distinctUntilChanged, takeUntil } from 'rxjs/operators'; import { GroupResourceStatus, PerunBean } from '@perun-web-apps/perun/openapi'; @@ -38,8 +38,8 @@ export class EntitySearchSelectComponent @ViewChild('scrollViewport', { static: false }) scrollViewport: CdkVirtualScrollViewport; @Input() searchFunction: (entity: T) => string; - entitiesCtrl: FormControl = new FormControl(); - entityFilterCtrl: FormControl = new FormControl(); + entitiesCtrl: UntypedFormControl = new UntypedFormControl(); + entityFilterCtrl: UntypedFormControl = new UntypedFormControl(); filteredEntities = new ReplaySubject(1); protected _onDestroy = new Subject(); private entitiesLen = 0; diff --git a/libs/perun/components/src/lib/expiration-select/expiration-select.component.ts b/libs/perun/components/src/lib/expiration-select/expiration-select.component.ts index 6ff54baee..fc5978f76 100644 --- a/libs/perun/components/src/lib/expiration-select/expiration-select.component.ts +++ b/libs/perun/components/src/lib/expiration-select/expiration-select.component.ts @@ -1,5 +1,5 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { FormControl } from '@angular/forms'; +import { UntypedFormControl } from '@angular/forms'; import { formatDate } from '@angular/common'; @Component({ @@ -10,7 +10,7 @@ import { formatDate } from '@angular/common'; export class ExpirationSelectComponent implements OnInit { @Input() expiration = 'never'; @Output() datePicker: EventEmitter = new EventEmitter(); - expirationControl = new FormControl(null); + expirationControl = new UntypedFormControl(null); minDate: Date; ngOnInit(): void { diff --git a/libs/perun/components/src/lib/groups-list/groups-list.component.html b/libs/perun/components/src/lib/groups-list/groups-list.component.html index ecf1b86b5..c43785d75 100644 --- a/libs/perun/components/src/lib/groups-list/groups-list.component.html +++ b/libs/perun/components/src/lib/groups-list/groups-list.component.html @@ -111,7 +111,7 @@ diff --git a/libs/perun/components/src/lib/header-menu/header-menu.component.html b/libs/perun/components/src/lib/header-menu/header-menu.component.html index 7c5983f49..159a2a03b 100644 --- a/libs/perun/components/src/lib/header-menu/header-menu.component.html +++ b/libs/perun/components/src/lib/header-menu/header-menu.component.html @@ -13,7 +13,7 @@