diff --git a/src/ui_ng/lib/package.json b/src/ui_ng/lib/package.json
index 3017d468e..f779fd0d5 100644
--- a/src/ui_ng/lib/package.json
+++ b/src/ui_ng/lib/package.json
@@ -43,4 +43,4 @@
"web-animations-js": "^2.2.1",
"zone.js": "^0.8.4"
}
-}
+}
\ No newline at end of file
diff --git a/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.html b/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.html
index 4da5773fa..7031269a7 100644
--- a/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.html
+++ b/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.html
@@ -7,14 +7,17 @@
diff --git a/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.scss b/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.scss
index e69de29bb..ff10745a9 100644
--- a/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.scss
+++ b/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.scss
@@ -0,0 +1,14 @@
+clr-modal {
+ ::ng-deep div.modal-dialog {
+ width: unset;
+ }
+ .rename-tool {
+ .btn {
+ margin-right: 6px;
+ padding-left: 3px;
+ padding-right: 3px;
+ }
+ position: relative;
+ bottom: 9px;
+ }
+}
\ No newline at end of file
diff --git a/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.ts b/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.ts
index 4f2d46fe4..34752b1a0 100644
--- a/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.ts
+++ b/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.ts
@@ -1,3 +1,4 @@
+import { ChangeDetectorRef } from '@angular/core';
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,206 +24,238 @@ import { SearchTriggerService } from "../../base/global-search/search-trigger.se
import { CommonRoutes } from "../../shared/shared.const";
@Component({
- selector: "account-settings-modal",
- templateUrl: "account-settings-modal.component.html",
- styleUrls: ["./account-settings-modal.component.scss", "../../common.scss"]
+ selector: "account-settings-modal",
+ templateUrl: "account-settings-modal.component.html",
+ styleUrls: ["./account-settings-modal.component.scss", "../../common.scss"]
})
-
export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
- opened = false;
- staticBackdrop = true;
- account: SessionUser;
- error: any = null;
- originalStaticData: SessionUser;
- emailTooltip = "TOOLTIP.EMAIL";
- mailAlreadyChecked = {};
- isOnCalling = false;
- formValueChanged = false;
- checkOnGoing = false;
- RenameOnGoing = false;
+ opened = false;
+ staticBackdrop = true;
+ originalStaticData: SessionUser;
+ account: SessionUser;
+ error: any = null;
+ emailTooltip = "TOOLTIP.EMAIL";
+ mailAlreadyChecked = {};
+ isOnCalling = false;
+ formValueChanged = false;
+ checkOnGoing = false;
+ RenameOnGoing = false;
+ originAdminName = "admin";
+ newAdminName = "admin@harbor.local";
+ renameConfirmation = false;
+// confirmRename = false;
- accountFormRef: NgForm;
- @ViewChild("accountSettingsFrom") accountForm: NgForm;
- @ViewChild(InlineAlertComponent)
- inlineAlert: InlineAlertComponent;
+ accountFormRef: NgForm;
+ @ViewChild("accountSettingsFrom") accountForm: NgForm;
+ @ViewChild(InlineAlertComponent) inlineAlert: InlineAlertComponent;
- constructor(
- private session: SessionService,
- private msgHandler: MessageHandlerService,
- private router: Router,
- private searchTrigger: SearchTriggerService
- ) { }
+ constructor(
+ private session: SessionService,
+ private msgHandler: MessageHandlerService,
+ private router: Router,
+ private searchTrigger: SearchTriggerService,
+ private ref: ChangeDetectorRef
+ ) {}
+ private validationStateMap: any = {
+ account_settings_email: true,
+ account_settings_full_name: true
+ };
+ ngOnInit(): void {
+ // Value copy
+ this.account = Object.assign({}, this.session.getCurrentUser());
+ this.originalStaticData = Object.assign({}, this.session.getCurrentUser());
+ }
- private validationStateMap: any = {
- "account_settings_email": true,
- "account_settings_full_name": true
- };
- ngOnInit(): void {
- // Value copy
- this.account = Object.assign({}, this.session.getCurrentUser());
- }
-
- getValidationState(key: string): boolean {
- return this.validationStateMap[key];
- }
-
- handleValidation(key: string, flag: boolean): void {
- if (flag) {
- // Checking
- let cont = this.accountForm.controls[key];
- if (cont) {
- this.validationStateMap[key] = cont.valid;
- // Check email existing from backend
- if (cont.valid && key === "account_settings_email") {
- if (this.formValueChanged && this.account.email !== this.originalStaticData.email) {
- if (this.mailAlreadyChecked[this.account.email]) {
- this.validationStateMap[key] = !this.mailAlreadyChecked[this.account.email].result;
- if (!this.validationStateMap[key]) {
- this.emailTooltip = "TOOLTIP.EMAIL_EXISTING";
- }
- return;
- }
-
- // Mail changed
- this.checkOnGoing = true;
- this.session.checkUserExisting("email", this.account.email)
- .then((res: boolean) => {
- this.checkOnGoing = false;
- this.validationStateMap[key] = !res;
- if (res) {
- this.emailTooltip = "TOOLTIP.EMAIL_EXISTING";
- }
- this.mailAlreadyChecked[this.account.email] = {
- result: res
- }; // Tag it checked
- })
- .catch(error => {
- this.checkOnGoing = false;
- this.validationStateMap[key] = false; // Not valid @ backend
- });
- }
- }
- }
- } else {
- // Reset
- this.validationStateMap[key] = true;
- this.emailTooltip = "TOOLTIP.EMAIL";
- }
- }
-
- isUserDataChange(): boolean {
- if (!this.originalStaticData || !this.account) {
- return false;
- }
-
- for (let prop in this.originalStaticData) {
- if (this.originalStaticData[prop] !== this.account[prop]) {
- return true;
- }
- }
-
- return false;
- }
-
- public get isValid(): boolean {
- return this.accountForm &&
- this.accountForm.valid &&
- this.error === null &&
- this.validationStateMap["account_settings_email"]; // backend check is valid as well
- }
-
- public get showProgress(): boolean {
- return this.isOnCalling;
- }
-
- public get checkProgress(): boolean {
- return this.checkOnGoing;
- }
-
- public get canRename(): boolean {
- return this.account && this.account.has_admin_role && this.account.username === "admin" && this.account.user_id === 1;
- }
-
- openRenameAlert(): void {
- this.RenameOnGoing = true;
- this.inlineAlert.showInlineConfirmation({
- message: "PROFILE.RENAME_CONFIRM_INFO"
+ ngAfterViewChecked(): void {
+ if (this.accountFormRef !== this.accountForm) {
+ this.accountFormRef = this.accountForm;
+ if (this.accountFormRef) {
+ this.accountFormRef.valueChanges.subscribe(data => {
+ if (this.error) {
+ this.error = null;
+ }
+ this.formValueChanged = true;
+ if (this.account.username === this.originAdminName) {
+ this.inlineAlert.close();
+ }
});
+ }
}
+ }
- confirmRename(): void {
- if (this.canRename) {
- this.session.renameAdmin(this.account)
- .then(() => {
- this.msgHandler.showSuccess("PROFILE.RENAME_SUCCESS");
- })
- .catch(error => {
- this.msgHandler.handleError(error);
- });
- }
- }
+ getValidationState(key: string): boolean {
+ return this.validationStateMap[key];
+ }
- ngAfterViewChecked(): void {
- if (this.accountFormRef !== this.accountForm) {
- this.accountFormRef = this.accountForm;
- if (this.accountFormRef) {
- this.accountFormRef.valueChanges.subscribe(data => {
- if (this.error) {
- this.error = null;
- }
- this.formValueChanged = true;
- this.inlineAlert.close();
- });
+ handleValidation(key: string, flag: boolean): void {
+ if (flag) {
+ // Checking
+ let cont = this.accountForm.controls[key];
+ if (cont) {
+ this.validationStateMap[key] = cont.valid;
+ // Check email existing from backend
+ if (cont.valid && key === "account_settings_email") {
+ if (
+ this.formValueChanged &&
+ this.account.email !== this.originalStaticData.email
+ ) {
+ if (this.mailAlreadyChecked[this.account.email]) {
+ this.validationStateMap[key] = !this.mailAlreadyChecked[
+ this.account.email
+ ].result;
+ if (!this.validationStateMap[key]) {
+ this.emailTooltip = "TOOLTIP.EMAIL_EXISTING";
+ }
+ return;
}
+
+ // Mail changed
+ this.checkOnGoing = true;
+ this.session
+ .checkUserExisting("email", this.account.email)
+ .then((res: boolean) => {
+ this.checkOnGoing = false;
+ this.validationStateMap[key] = !res;
+ if (res) {
+ this.emailTooltip = "TOOLTIP.EMAIL_EXISTING";
+ }
+ this.mailAlreadyChecked[this.account.email] = {
+ result: res
+ }; // Tag it checked
+ })
+ .catch(error => {
+ this.checkOnGoing = false;
+ this.validationStateMap[key] = false; // Not valid @ backend
+ });
+ }
}
+ }
+ } else {
+ // Reset
+ this.validationStateMap[key] = true;
+ this.emailTooltip = "TOOLTIP.EMAIL";
}
+ }
- // Log out system
- logOut(): void {
- // Naviagte to the sign in route
- // Appending 'signout' means destroy session cache
- let navigatorExtra: NavigationExtras = {
- queryParams: { "signout": true }
- };
- this.router.navigate([CommonRoutes.EMBEDDED_SIGN_IN], navigatorExtra);
- // Confirm search result panel is close
- this.searchTrigger.closeSearch(true);
+ isUserDataChange(): boolean {
+ if (!this.originalStaticData || !this.account) {
+ return false;
}
-
- open() {
- // Keep the initial data for future diff
- this.originalStaticData = Object.assign({}, this.session.getCurrentUser());
- this.account = Object.assign({}, this.session.getCurrentUser());
- this.formValueChanged = false;
-
- // Confirm inline alert is closed
- this.inlineAlert.close();
-
- // Clear check history
- this.mailAlreadyChecked = {};
-
- // Reset validation status
- this.validationStateMap = {
- "account_settings_email": true,
- "account_settings_full_name": true
- };
-
- this.opened = true;
+ for (let prop in this.originalStaticData) {
+ if (this.originalStaticData[prop] !== this.account[prop]) {
+ return true;
+ }
}
+ return false;
+ }
+
+ public get isValid(): boolean {
+ return (
+ this.accountForm &&
+ this.accountForm.valid &&
+ this.error === null &&
+ this.validationStateMap["account_settings_email"]
+ ); // backend check is valid as well
+ }
+
+ public get showProgress(): boolean {
+ return this.isOnCalling;
+ }
+
+ public get checkProgress(): boolean {
+ return this.checkOnGoing;
+ }
+
+ public get canRename(): boolean {
+ return (
+ this.account &&
+ this.account.has_admin_role &&
+ this.originalStaticData.username === "admin" &&
+ this.account.user_id === 1
+ );
+ }
+
+ onRename(): void {
+ this.account.username = this.newAdminName;
+ this.RenameOnGoing = true;
+ }
+
+ confirmRename(): void {
+ if (this.canRename) {
+ this.session
+ .updateAccountSettings(this.account)
+ .then(() => {
+ this.session.renameAdmin(this.account)
+ .then(() => {
+ this.msgHandler.showSuccess("PROFILE.RENAME_SUCCESS");
+ this.opened = false;
+ this.logOut();
+ })
+ .catch(error => {
+ this.msgHandler.handleError(error);
+ });
+ })
+ .catch(error => {
+ this.isOnCalling = false;
+ this.error = error;
+ if (this.msgHandler.isAppLevel(error)) {
+ this.opened = false;
+ this.msgHandler.handleError(error);
+ } else {
+ this.inlineAlert.showInlineError(error);
+ }
+ });
+ }
+ }
+
+ // Log out system
+ logOut(): void {
+ // Naviagte to the sign in route
+ // Appending 'signout' means destroy session cache
+ let navigatorExtra: NavigationExtras = {
+ queryParams: { signout: true }
+ };
+ this.router.navigate([CommonRoutes.EMBEDDED_SIGN_IN], navigatorExtra);
+ // Confirm search result panel is close
+ this.searchTrigger.closeSearch(true);
+ }
+
+ open() {
+ // Keep the initial data for future diff
+ this.originalStaticData = Object.assign({}, this.session.getCurrentUser());
+ this.account = Object.assign({}, this.session.getCurrentUser());
+ this.formValueChanged = false;
+
+ // Confirm inline alert is closed
+ this.inlineAlert.close();
+
+ // Clear check history
+ this.mailAlreadyChecked = {};
+
+ // Reset validation status
+ this.validationStateMap = {
+ account_settings_email: true,
+ account_settings_full_name: true
+ };
+
+ this.opened = true;
+ }
close() {
- if (this.RenameOnGoing) {
- this.RenameOnGoing = false;
- }
if (this.formValueChanged) {
if (!this.isUserDataChange()) {
this.opened = false;
} else {
- // Need user confirmation
- this.inlineAlert.showInlineConfirmation({
- message: "ALERT.FORM_CHANGE_CONFIRMATION"
- });
+ if (this.RenameOnGoing) {
+ this.RenameOnGoing = false;
+ this.opened = false;
+ } else {
+ // Need user confirmation
+ this.inlineAlert.showInlineConfirmation({
+ message: "ALERT.FORM_CHANGE_CONFIRMATION"
+ });
+ }
}
} else {
this.opened = false;
@@ -240,38 +273,55 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
return;
}
+ if (this.RenameOnGoing && !this.renameConfirmation) {
+ this.renameConfirmation = true;
+ this.inlineAlert.showInlineWarning({
+ message: "PROFILE.RENAME_CONFIRM_INFO"
+ });
+ return;
+ }
+
this.isOnCalling = true;
- this.session.updateAccountSettings(this.account)
- .then(() => {
- this.isOnCalling = false;
- this.opened = false;
- this.msgHandler.showSuccess("PROFILE.SAVE_SUCCESS");
- })
- .catch(error => {
- this.isOnCalling = false;
- this.error = error;
- if (this.msgHandler.isAppLevel(error)) {
+ if (this.RenameOnGoing && this.renameConfirmation) {
+ this.confirmRename();
+ } else {
+ this.session
+ .updateAccountSettings(this.account)
+ .then(() => {
+ this.isOnCalling = false;
this.opened = false;
- this.msgHandler.handleError(error);
- } else {
- this.inlineAlert.showInlineError(error);
- }
- });
+ this.msgHandler.showSuccess("PROFILE.SAVE_SUCCESS");
+ })
+ .catch(error => {
+ this.isOnCalling = false;
+ this.error = error;
+ if (this.msgHandler.isAppLevel(error)) {
+ this.opened = false;
+ this.msgHandler.handleError(error);
+ } else {
+ this.inlineAlert.showInlineError(error);
+ }
+ });
+ }
}
- confirmNo($event: any): void {
- if (this.RenameOnGoing) {
- this.RenameOnGoing = false;
- }
+ confirmNo($event: any): void {
+ if (this.RenameOnGoing) {
+ this.RenameOnGoing = false;
}
- confirmYes($event: any): void {
- if (this.RenameOnGoing) {
- this.confirmRename();
- this.RenameOnGoing = false;
- this.logOut();
- }
- this.inlineAlert.close();
- this.opened = false;
+ if (this.renameConfirmation) {
+ this.renameConfirmation = false;
}
+ }
+ confirmYes($event: any): void {
+ if (this.RenameOnGoing) {
+ this.RenameOnGoing = false;
+ }
+ if (this.renameConfirmation) {
+ this.renameConfirmation = false;
+ }
+ this.inlineAlert.close();
+ this.opened = false;
+ }
}
diff --git a/src/ui_ng/src/app/shared/inline-alert/inline-alert.component.ts b/src/ui_ng/src/app/shared/inline-alert/inline-alert.component.ts
index a96f717b1..7576f170a 100644
--- a/src/ui_ng/src/app/shared/inline-alert/inline-alert.component.ts
+++ b/src/ui_ng/src/app/shared/inline-alert/inline-alert.component.ts
@@ -69,6 +69,19 @@ export class InlineAlertComponent {
this.useAppLevelStyle = false;
}
+ // Show warning
+ public showInlineWarning(warning: any): void {
+ this.displayedText = "";
+ if (warning && warning.message) {
+ this.translate.get(warning.message).subscribe((res: string) => this.displayedText = res);
+ }
+ this.inlineAlertType = 'alert-warning';
+ this.showCancelAction = false;
+ this.inlineAlertClosable = true;
+ this.alertClose = false;
+ this.useAppLevelStyle = false;
+ }
+
// Show inline sccess info
public showInlineSuccess(info: any): void {
this.displayedText = "";
diff --git a/src/ui_ng/src/i18n/lang/en-us-lang.json b/src/ui_ng/src/i18n/lang/en-us-lang.json
index fe680f68a..b66d7c748 100644
--- a/src/ui_ng/src/i18n/lang/en-us-lang.json
+++ b/src/ui_ng/src/i18n/lang/en-us-lang.json
@@ -83,9 +83,10 @@
"COMMENT": "Comments",
"PASSWORD": "Password",
"SAVE_SUCCESS": "User profile saved successfully.",
- "ADMIN_RENAME_TIP": "Double click to change your username to \"admin@harbor.local\", but this action can NOT redo.",
+ "ADMIN_RENAME_BUTTON": "Change username",
+ "ADMIN_RENAME_TIP": "Select the button in order to change the username to \"admin@harbor.local\". This operation can not be undone.",
"RENAME_SUCCESS": "Rename success!",
- "RENAME_CONFIRM_INFO": "This action can not undo, Confirm To Rename?"
+ "RENAME_CONFIRM_INFO": "Warning, changing the name to admin@harbor.local can not be undone."
},
"CHANGE_PWD": {
"TITLE": "Change Password",
diff --git a/src/ui_ng/src/i18n/lang/es-es-lang.json b/src/ui_ng/src/i18n/lang/es-es-lang.json
index 0c6565158..c7cc7f5b8 100644
--- a/src/ui_ng/src/i18n/lang/es-es-lang.json
+++ b/src/ui_ng/src/i18n/lang/es-es-lang.json
@@ -83,9 +83,9 @@
"COMMENT": "Comentarios",
"PASSWORD": "Contraseña",
"SAVE_SUCCESS": "Perfil de usuario guardado satisfactoriamente.",
- "ADMIN_RENAME_TIP": "Double click to change your username to \"admin@harbor.local\", but this action can NOT redo.",
+ "ADMIN_RENAME_TIP": "Select the button in order to change the username to \"admin@harbor.local\". This operation can not be undone.",
"RENAME_SUCCESS": "Rename success!",
- "RENAME_CONFIRM_INFO": "This action can not undo, Confirm To Rename?"
+ "RENAME_CONFIRM_INFO": "Warning, changing the name to admin@harbor.local can not be undone."
},
"CHANGE_PWD": {
"TITLE": "Cambiar contraseña",
diff --git a/src/ui_ng/src/i18n/lang/fr-fr-lang.json b/src/ui_ng/src/i18n/lang/fr-fr-lang.json
index f4c9e2ca1..b6b40b6ac 100644
--- a/src/ui_ng/src/i18n/lang/fr-fr-lang.json
+++ b/src/ui_ng/src/i18n/lang/fr-fr-lang.json
@@ -69,7 +69,10 @@
"FULL_NAME": "Prénom et nom",
"COMMENT": "Commentaires",
"PASSWORD": "Mot de passe",
- "SAVE_SUCCESS": "Profil utilisateur sauvegardé avec succès."
+ "SAVE_SUCCESS": "Profil utilisateur sauvegardé avec succès.",
+ "ADMIN_RENAME_TIP": "Select the button in order to change the username to \"admin@harbor.local\". This operation can not be undone.",
+ "RENAME_SUCCESS": "Rename success!",
+ "RENAME_CONFIRM_INFO": "Warning, changing the name to admin@harbor.local can not be undone."
},
"CHANGE_PWD": {
"TITLE": "Modifier le mot de passe",
diff --git a/src/ui_ng/src/i18n/lang/zh-cn-lang.json b/src/ui_ng/src/i18n/lang/zh-cn-lang.json
index 48b3c2764..9b3271042 100644
--- a/src/ui_ng/src/i18n/lang/zh-cn-lang.json
+++ b/src/ui_ng/src/i18n/lang/zh-cn-lang.json
@@ -83,9 +83,9 @@
"COMMENT": "注释",
"PASSWORD": "密码",
"SAVE_SUCCESS": "成功保存用户设置。",
- "ADMIN_RENAME_TIP": "双击将用户名改为 \"admin@harbor.local\", 注意这个操作是不可逆的",
+ "ADMIN_RENAME_TIP": "单击将用户名改为 \"admin@harbor.local\", 注意这个操作是无法撤销的",
"RENAME_SUCCESS": "用户名更改成功!",
- "RENAME_CONFIRM_INFO": "更改用户名无法撤销, 你确定更改吗·?"
+ "RENAME_CONFIRM_INFO": "更改用户名为admin@harbor.local是无法撤销的, 你确定更改吗·?"
},
"CHANGE_PWD": {
"TITLE": "修改密码",