mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-23 09:08:26 +01:00
Merge pull request #4981 from ninjadq/change_admin_rename_style
Change the admin rename UX
This commit is contained in:
commit
e9158f2fb8
@ -43,4 +43,4 @@
|
||||
"web-animations-js": "^2.2.1",
|
||||
"zone.js": "^0.8.4"
|
||||
}
|
||||
}
|
||||
}
|
@ -7,14 +7,17 @@
|
||||
<div class="form-group form-group-override">
|
||||
<label for="account_settings_username" aria-haspopup="true" class="form-group-label-override">{{'PROFILE.USER_NAME' | translate}}</label>
|
||||
<input type="text" name="account_settings_username" [(ngModel)]="account.username" disabled id="account_settings_username" size="33">
|
||||
<clr-tooltip *ngIf="canRename">
|
||||
<button (dblclick)="openRenameAlert()" class="btn btn-link">
|
||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||
<div *ngIf="canRename" class="rename-tool">
|
||||
<button [disabled]="RenameOnGoing" (click)="onRename()" class="btn btn-outline btn-sm">
|
||||
{{'PROFILE.ADMIN_RENAME_BUTTON' | translate}}
|
||||
</button>
|
||||
<clr-tooltip-content clrPosition="bottom-left" clrSize="md" *clrIfOpen>
|
||||
<span (click)="openRenameAlert()"> {{'PROFILE.ADMIN_RENAME_TIP' | translate}}</span>
|
||||
</clr-tooltip-content>
|
||||
</clr-tooltip>
|
||||
<clr-tooltip>
|
||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||
<clr-tooltip-content clrPosition="bottom-left" clrSize="md" *clrIfOpen>
|
||||
<span> {{'PROFILE.ADMIN_RENAME_TIP' | translate}}</span>
|
||||
</clr-tooltip-content>
|
||||
</clr-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-group-override">
|
||||
<label for="account_settings_email" class="required form-group-label-override">{{'PROFILE.EMAIL' | translate}}</label>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 = "";
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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": "修改密码",
|
||||
|
Loading…
Reference in New Issue
Block a user