diff --git a/package-lock.json b/package-lock.json index fb687eb3d1..9f460144d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@denbi/cloud-portal-webapp", - "version": "4.899.0", + "version": "4.900.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@denbi/cloud-portal-webapp", - "version": "4.899.0", + "version": "4.900.0", "dependencies": { "@angular-eslint/eslint-plugin": "^18.3.0", "@angular/animations": "18.2.8", @@ -99,7 +99,7 @@ "less-loader": "12.2.0", "lint-staged": "15.2.10", "ngx-spec": "2.1.6", - "npm-run-all2": "6.2.6", + "npm-run-all2": "7.0.1", "prettier": "3.3.3", "raw-loader": "4.0.2", "sass-loader": "16.0.2", @@ -13661,9 +13661,9 @@ } }, "node_modules/npm-run-all2": { - "version": "6.2.6", - "resolved": "https://registry.npmjs.org/npm-run-all2/-/npm-run-all2-6.2.6.tgz", - "integrity": "sha512-tkyb4pc0Zb0oOswCb5tORPk9MvVL6gcDq1cMItQHmsbVk1skk7YF6cH+UU2GxeNLHMuk6wFEOSmEmJ2cnAK1jg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/npm-run-all2/-/npm-run-all2-7.0.1.tgz", + "integrity": "sha512-Adbv+bJQ8UTAM03rRODqrO5cx0YU5KCG2CvHtSURiadvdTjjgGJXdbc1oQ9CXBh9dnGfHSoSB1Web/0Dzp6kOQ==", "dev": true, "license": "MIT", "dependencies": { @@ -13672,9 +13672,9 @@ "memorystream": "^0.3.1", "minimatch": "^9.0.0", "pidtree": "^0.6.0", - "read-package-json-fast": "^3.0.2", + "read-package-json-fast": "^4.0.0", "shell-quote": "^1.7.3", - "which": "^3.0.1" + "which": "^5.0.0" }, "bin": { "npm-run-all": "bin/npm-run-all/index.js", @@ -13683,8 +13683,8 @@ "run-s": "bin/run-s/index.js" }, "engines": { - "node": "^14.18.0 || ^16.13.0 || >=18.0.0", - "npm": ">= 8" + "node": "^18.17.0 || >=20.5.0", + "npm": ">= 9" } }, "node_modules/npm-run-all2/node_modules/ansi-styles": { @@ -13700,20 +13700,30 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/npm-run-all2/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, "node_modules/npm-run-all2/node_modules/which": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", - "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, "license": "ISC", "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm-run-path": { @@ -15434,16 +15444,37 @@ } }, "node_modules/read-package-json-fast": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", - "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz", + "integrity": "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==", "dev": true, + "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/read-package-json-fast/node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/readable-stream": { diff --git a/package.json b/package.json index e9f35a7b8b..600e7b1bd6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@denbi/cloud-portal-webapp", - "version": "4.899.0", + "version": "4.900.0", "description": "de.NBI Cloud Portal", "scripts": { "ng": "ng serve", @@ -109,7 +109,7 @@ "less-loader": "12.2.0", "lint-staged": "15.2.10", "ngx-spec": "2.1.6", - "npm-run-all2": "6.2.6", + "npm-run-all2": "7.0.1", "prettier": "3.3.3", "raw-loader": "4.0.2", "sass-loader": "16.0.2", diff --git a/src/app/api-connector/applications.service.ts b/src/app/api-connector/applications.service.ts index c004fca888..876e3fed58 100644 --- a/src/app/api-connector/applications.service.ts +++ b/src/app/api-connector/applications.service.ts @@ -336,4 +336,12 @@ export class ApplicationsService { withCredentials: true }) } + + checkForTakenShortname(shortname: string): Observable { + return this.http.get(`${ApiSettings.getApiBaseURL()}project_applications/shortname/`, { + params: { shortname: shortname }, + withCredentials: true + }); + + } } diff --git a/src/app/applications/application-formular/application-formular.component.html b/src/app/applications/application-formular/application-formular.component.html index 14e60fcaa6..692b9fa040 100644 --- a/src/app/applications/application-formular/application-formular.component.html +++ b/src/app/applications/application-formular/application-formular.component.html @@ -145,6 +145,11 @@
General Information
Umlauts and special characters are prohibited in the shortname. +
+ + Please choose another shortname + +
General Information pattern="[a-zA-Z0-9]+" [ngClass]="{ 'is-invalid': - form.controls.project_application_shortname?.invalid && + (form.controls.project_application_shortname?.invalid || shortNameTaken) && (form.controls.project_application_shortname?.dirty || - form.controls.project_application_shortname?.touched), + form.controls.project_application_shortname?.touched) + , 'is-valid': - form.controls.project_application_shortname?.valid && + form.controls.project_application_shortname?.valid && !shortNameTaken && (form.controls.project_application_shortname?.dirty || form.controls.project_application_shortname?.touched), }" /> Enter a short name (between 5 and 15 characters). + @@ -490,7 +497,7 @@
Resources
/>
GB
- How much total extra storage do you need for your VMs? + How much total storage do you need for your VMs in form of Volumes?
@@ -1792,6 +1799,7 @@
Platforms
data-test-id="submit_application_btn" [disabled]=" submitting || + shortNameTaken || form.invalid || (!unknownPiAffiliationsConfirmation && !valid_pi_affiliations && diff --git a/src/app/applications/application-formular/application-formular.component.ts b/src/app/applications/application-formular/application-formular.component.ts index 8beeb64cd6..a1f2ae3525 100644 --- a/src/app/applications/application-formular/application-formular.component.ts +++ b/src/app/applications/application-formular/application-formular.component.ts @@ -33,6 +33,9 @@ import { UserService } from '../../api-connector/user.service' import { Userinfo } from '../../userinfo/userinfo.model' import { User } from '../application.model/user.model' import { NotificationModalComponent } from '../../shared/modal/notification-modal' +import { Subject, Subscription } from 'rxjs'; +import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; +import { thresholdScott } from 'd3' /** * Application formular component. @@ -87,6 +90,9 @@ export class ApplicationFormularComponent extends ApplicationBaseClassComponent WIKI_BACKUP_LINK: string = WIKI_BACKUP_LINK GDPR_LINK: string = GDPR_LINK survey_link_visible: boolean = false + private nameCheckPipe = new Subject(); + shortnameChecking: boolean = false; + shortNameTaken: boolean = false; MAX_LIFETIME_DEFAULT: number = 6 max_lifetime: number = this.MAX_LIFETIME_DEFAULT @@ -119,6 +125,7 @@ export class ApplicationFormularComponent extends ApplicationBaseClassComponent this.getListOfFlavors() this.getListOfTypes() this.is_vo_admin = is_vo + this.nameCheckPipe.pipe(debounceTime(600), distinctUntilChanged()).subscribe(value => {this.checkIfNameIsTaken(value)}); if (this.openstack_project) { this.simple_vm_min_vm = true @@ -138,6 +145,16 @@ export class ApplicationFormularComponent extends ApplicationBaseClassComponent } } + checkIfNameIsTaken(shortname: string): void { + this.shortnameChecking = true; + this.applicationsService.checkForTakenShortname(shortname).subscribe((result: boolean): void => { + let nameExists: boolean = result['exists']; + this.shortnameChecking = false; + this.shortNameTaken = nameExists; + }); + + } + checkValidityComment(): boolean { if (this.extraResourceCommentRequired) { if (this.application.project_application_comment?.length < 50) { @@ -238,6 +255,11 @@ export class ApplicationFormularComponent extends ApplicationBaseClassComponent */ public checkShortname(shortname: string): void { this.invalid_shortname = !/^[a-zA-Z0-9\s]*$/.test(shortname) + if (!this.invalid_shortname) { + this.shortnameChecking = true; + this.nameCheckPipe.next(shortname); + } + } public checkLongname(longname: string): void { diff --git a/src/app/projectmanagement/modals/adjust-application/adjust-application.component.html b/src/app/projectmanagement/modals/adjust-application/adjust-application.component.html index 4106c18141..b0b772fdb3 100644 --- a/src/app/projectmanagement/modals/adjust-application/adjust-application.component.html +++ b/src/app/projectmanagement/modals/adjust-application/adjust-application.component.html @@ -27,7 +27,7 @@

Adjust application for {{ application?.project_application_shortname }}

[ngStyle]="{ 'background-color': adjustedApplication.project_application_openstack_project ? '#FF0000' - : '#00adef' + : '#00adef', }" > @@ -78,7 +78,7 @@

Adjust application for {{ application?.project_application_shortname }}

appInteger [ngClass]="{ 'is-invalid': resourceAdjustmentForm.controls.granted_lifetime_counter?.invalid, - 'is-valid': resourceAdjustmentForm.controls.granted_lifetime_counter?.valid + 'is-valid': resourceAdjustmentForm.controls.granted_lifetime_counter?.valid, }" />
@@ -109,7 +109,7 @@
style="font-size: 25px" [ngClass]="{ 'icon-arrow-up': groupval.isOpen, - 'icon-arrow-down': !groupval.isOpen + 'icon-arrow-down': !groupval.isOpen, }" > @@ -163,7 +163,7 @@
appIntegerOrNull [ngClass]="{ 'is-invalid': name?.invalid, - 'is-valid': name?.valid + 'is-valid': name?.valid, }" />
VMs
@@ -217,7 +217,7 @@
appInteger [ngClass]="{ 'is-invalid': resourceAdjustmentForm.controls.granted_volume_counter?.invalid, - 'is-valid': resourceAdjustmentForm.controls.grated_volume_counter?.valid + 'is-valid': resourceAdjustmentForm.controls.grated_volume_counter?.valid, }" /> @@ -247,7 +247,7 @@
/>
GB
- Requested extra storage + Requested volume storage
@@ -264,13 +264,13 @@
appInteger [ngClass]="{ 'is-invalid': resourceAdjustmentForm.controls.granted_volume_limit?.invalid, - 'is-valid': resourceAdjustmentForm.controls.granted_volume_limit?.valid + 'is-valid': resourceAdjustmentForm.controls.granted_volume_limit?.valid, }" [disabled]="resourceAdjustmentForm.controls.granted_volume_counter?.value === 0" />
GB
- Amount of extra storage you want to grant + Amount of volume storage you want to grant
@@ -316,7 +316,7 @@
required [ngClass]="{ 'is-invalid': resourceAdjustmentForm.controls.granted_object_storage?.invalid, - 'is-valid': resourceAdjustmentForm.controls.granted_object_storage?.valid + 'is-valid': resourceAdjustmentForm.controls.granted_object_storage?.valid, }" />
GB
diff --git a/src/app/projectmanagement/modals/modification-request/modification-request.component.html b/src/app/projectmanagement/modals/modification-request/modification-request.component.html index 5551ec8d73..92d6d34293 100644 --- a/src/app/projectmanagement/modals/modification-request/modification-request.component.html +++ b/src/app/projectmanagement/modals/modification-request/modification-request.component.html @@ -126,7 +126,7 @@
aria-describedby="{{ flavor.name }}_help" [ngClass]="{ 'is-invalid': name?.invalid && !adjustment, - 'is-valid': name?.valid && !adjustment + 'is-valid': name?.valid && !adjustment, }" />
@@ -160,7 +160,7 @@
aria-describedby="adjust_{{ flavor.name }}_help" [ngClass]="{ 'is-invalid': name?.invalid, - 'is-valid': name?.valid + 'is-valid': name?.valid, }" /> @@ -220,7 +220,7 @@
appInteger [ngClass]="{ 'is-invalid': modificationForm.controls.project_application_renewal_volume_counter?.invalid, - 'is-valid': modificationForm.controls.project_application_renewal_volume_counter?.valid + 'is-valid': modificationForm.controls.project_application_renewal_volume_counter?.valid, }" />
@@ -259,7 +259,7 @@
appInteger [ngClass]="{ 'is-invalid': modificationForm.controls.project_application_renewal_volume_counter_adjusted?.invalid, - 'is-valid': modificationForm.controls.project_application_renewal_volume_counter_adjusted?.valid + 'is-valid': modificationForm.controls.project_application_renewal_volume_counter_adjusted?.valid, }" /> @@ -291,7 +291,7 @@
/>
GB
- Current extra storage + Current volume storage
@@ -310,17 +310,17 @@
appInteger [ngClass]="{ 'is-invalid': modificationForm.controls.project_application_renewal_volume_limit?.invalid, - 'is-valid': modificationForm.controls.project_application_renewal_volume_limit?.valid + 'is-valid': modificationForm.controls.project_application_renewal_volume_limit?.valid, }" [disabled]="modificationForm.controls.project_application_renewal_volume_counter?.value === 0" />
GB
What is the total amount of volume storage, that you need in the future? How much total volume storage does the user want in the future?
@@ -351,7 +351,7 @@
appInteger [ngClass]="{ 'is-invalid': modificationForm.controls.project_application_renewal_volume_limit_adjusted?.invalid, - 'is-valid': modificationForm.controls.project_application_renewal_volume_limit_adjusted?.valid + 'is-valid': modificationForm.controls.project_application_renewal_volume_limit_adjusted?.valid, }" [disabled]="modificationForm.controls.project_application_renewal_volume_counter_adjusted?.value === 0" /> @@ -407,7 +407,7 @@
required [ngClass]="{ 'is-invalid': modificationForm.controls.project_application_renewal_object_storage?.invalid, - 'is-valid': modificationForm.controls.project_application_renewal_object_storage?.valid + 'is-valid': modificationForm.controls.project_application_renewal_object_storage?.valid, }" />
GB
@@ -448,7 +448,7 @@
required [ngClass]="{ 'is-invalid': modificationForm.controls.project_application_renewal_object_storage_adjust?.invalid, - 'is-valid': modificationForm.controls.project_application_renewal_object_storage_adjust?.valid + 'is-valid': modificationForm.controls.project_application_renewal_object_storage_adjust?.valid, }" />
GB
@@ -553,7 +553,7 @@
required [ngClass]="{ 'is-invalid': modificationForm.controls.project_application_renewal_cloud_service_user_number?.invalid, - 'is-valid': modificationForm.controls.project_application_renewal_cloud_service_user_number?.valid + 'is-valid': modificationForm.controls.project_application_renewal_cloud_service_user_number?.valid, }" /> @@ -611,7 +611,7 @@
[ngClass]="{ 'is-invalid': modificationForm.controls.project_application_renewal_comment?.invalid || !checkValidityComment(), - 'is-valid': modificationForm.controls.project_application_renewal_comment?.valid && checkValidityComment() + 'is-valid': modificationForm.controls.project_application_renewal_comment?.valid && checkValidityComment(), }" >
diff --git a/src/app/projectmanagement/overview.component.html b/src/app/projectmanagement/overview.component.html index 093540ec68..76eb8253e1 100644 --- a/src/app/projectmanagement/overview.component.html +++ b/src/app/projectmanagement/overview.component.html @@ -431,7 +431,6 @@

Request termination

+ ` + ) }) } diff --git a/src/links/links.ts b/src/links/links.ts index bca5730564..f36d30c87e 100644 --- a/src/links/links.ts +++ b/src/links/links.ts @@ -37,6 +37,7 @@ export const SCALING_UP_WIKI: string = `${environment.SIMPLEVM_WIKI_PRE}simple_v export const CREDITS_WIKI: string = `${environment.WIKI_PRE}portal/credits/` export const WIKI_PERSONAL_DATA: string = `${environment.WIKI_PRE}portal/personal_data` export const SURVEY_LINK: string = 'https://cloud.denbi.de/survey/index.php/252136?lang=en' +export const TERMINATION_SURVEY_LINK: string= 'https://cloud.denbi.de/survey/index.php/823721?lang=en' export const CLOUD_PORTAL_SUPPORT_MAIL = 'cloud-helpdesk@denbi.de' export const POLICY_LINK: string = 'https://cloud.denbi.de/about/policies/' export const SIMPLE_VM_LINK: string = 'https://cloud.denbi.de/about/project-types/simplevm/'