Merge pull request #8150 from AllForNothing/robot-account-helm-ui

UI modification for creating robot account
This commit is contained in:
Will Sun 2019-06-27 13:23:39 +08:00 committed by GitHub
commit 108b9284a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 224 additions and 206 deletions

View File

@ -1,130 +1,129 @@
<clr-modal [(clrModalOpen)]="addRobotOpened" <clr-modal [(clrModalOpen)]="addRobotOpened"
[clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable"> [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
<h3 class="modal-title">{{'ROBOT_ACCOUNT.CREAT_ROBOT_ACCOUNT' | translate}}</h3> <h3 class="modal-title">{{'ROBOT_ACCOUNT.CREAT_ROBOT_ACCOUNT' | translate}}</h3>
<inline-alert #copyAlert class="modal-title"></inline-alert> <inline-alert #copyAlert class="modal-title"></inline-alert>
<div class="modal-body"> <div class="modal-body">
<form #robotForm="ngForm"> <form #robotForm="ngForm">
<section class="form-block"> <section class="form-block">
<div class="form-group"> <div class="form-group padding-left-120">
<label class="col-md-3 <label class="col-md-3
form-group-label-override required" for="robot_name"> form-group-label-override required" for="robot_name">
{{'ROBOT_ACCOUNT.NAME' | translate}} {{'ROBOT_ACCOUNT.NAME' | translate}}
</label> </label>
<label aria-haspopup="true" role="tooltip" class="tooltip <label aria-haspopup="true" role="tooltip" class="tooltip
tooltip-validation tooltip-validation
tooltip-md tooltip-bottom-left" for="robot_name" tooltip-md tooltip-bottom-left" for="robot_name"
[class.invalid]="!isRobotNameValid"> [class.invalid]="!isRobotNameValid">
<input type="text" <input type="text"
[(ngModel)]="robot.name" [(ngModel)]="robot.name"
size="30" class="input-width" size="30" class="input-width"
name="robot_name" name="robot_name"
id="robot_name" id="robot_name"
#robotName="ngModel" #robotName="ngModel"
required required
pattern='[^" ~#$%]+' pattern='[^" ~#$%]+'
maxLengthExt="255" maxLengthExt="255"
autocomplete="off" autocomplete="off"
(keyup)='handleValidation()'> (keyup)='handleValidation()'>
<span class="tooltip-content"> <span class="tooltip-content">
{{ nameTooltipText | translate }} {{ nameTooltipText | translate }}
</span> </span>
</label> </label>
<span class="spinner spinner-inline" [hidden]="!checkOnGoing"></span> <span class="spinner spinner-inline" [hidden]="!checkOnGoing"></span>
</div> </div>
<div class="form-group"> <div class="form-group padding-left-120">
<label class="form-group-label-override">{{'REPLICATION.DESCRIPTION' | <label class="form-group-label-override">{{'REPLICATION.DESCRIPTION' |
translate}}</label> translate}}</label>
<input type="text" size="255" class="input-width" <input type="text" size="255" class="input-width"
[(ngModel)]="robot.description" [(ngModel)]="robot.description"
name="robot_desc" id="robot_desc"> name="robot_desc" id="robot_desc">
</div> </div>
<div class="form-group"> <div class="clr-row">
<label class="col-md-3"> <div class="clr-col-3 permission">
{{'ROBOT_ACCOUNT.PERMISSIONS' | translate}} <label class="col-md-3">
</label> {{'ROBOT_ACCOUNT.PERMISSIONS' | translate}}
<label class="clr-col-md-8 no-margin padding-left-0"> </label>
<clr-checkbox-wrapper> </div>
<input type="checkbox" clrCheckbox [checked]="true" <div class="clr-col">
[(ngModel)]="robot.access.isPullImage" name="isPullImage" <div class="form-group padding-left-120">
id="permission-pull" class="clr-checkbox"> <label>{{'ROBOT_ACCOUNT.PERMISSIONS_IMAGE' | translate}}</label>
<label for="permission-pull" class="clr-control-label"> <div class="radio-inline">
{{'ROBOT_ACCOUNT.PULL_PERMISSION' | translate}} <input type="radio" name="image-permission"
</label> id="image-permission-pull"
</clr-checkbox-wrapper> value="pull"
</label> [(ngModel)]="imagePermission">
<label class="clr-col-md-8 no-margin padding-left-0"> <label for="image-permission-pull">{{'ROBOT_ACCOUNT.PULL' | translate}}</label>
<clr-checkbox-wrapper> </div>
<input type="checkbox" clrCheckbox [checked]="true" <div class="radio-inline">
[(ngModel)]="robot.access.isPushOrPullImage" name="isPushOrPullImage" <input type="radio" name="image-permission"
id="permission-push" class="clr-checkbox"> id="image-permission-push-and-pull"
<label for="permission-push" class="clr-control-label"> value="push-and-pull"
{{'ROBOT_ACCOUNT.PULL_PUSH_PERMISSION' | translate}} [(ngModel)]="imagePermission">
</label> <label for="image-permission-push-and-pull">{{'ROBOT_ACCOUNT.PUSH' | translate}}
</clr-checkbox-wrapper> & {{'ROBOT_ACCOUNT.PULL' | translate}}</label>
</label> </div>
<label class="clr-col-md-8 no-margin padding-left-0"> </div>
<clr-checkbox-wrapper> <div class="form-group padding-left-120">
<input type="checkbox" clrCheckbox [checked]="true" <label>{{'ROBOT_ACCOUNT.PERMISSIONS_HELMCHART' | translate}}</label>
[(ngModel)]="robot.access.isPushChart" name="isPushChart" <div class="checkbox-inline">
id="permission-push-chart" class="clr-checkbox"> <input type="checkbox" id="helm-permission-push"
<label for="permission-push-chart" class="clr-control-label"> [checked]="robot.access.isPushChart"
{{'ROBOT_ACCOUNT.PUSH_CHART_PERMISSION' | translate}} [(ngModel)]="robot.access.isPushChart"
</label> name="helm-permission">
</clr-checkbox-wrapper> <label for="helm-permission-push">{{'ROBOT_ACCOUNT.PUSH' | translate}}</label>
</label> </div>
<label class="clr-col-md-8 no-margin padding-left-0"> <div class="checkbox-inline">
<clr-checkbox-wrapper> <input type="checkbox" id="helm-permission-pull"
<input type="checkbox" clrCheckbox [checked]="true" [checked]="robot.access.isPullChart"
[(ngModel)]="robot.access.isPullChart" name="isPullChart" [(ngModel)]="robot.access.isPullChart"
id="permission-pull-chart" class="clr-checkbox"> name="helm-permission">
<label for="permission-pull-chart" class="clr-control-label"> <label for="helm-permission-pull">{{'ROBOT_ACCOUNT.PULL' | translate}}</label>
{{'ROBOT_ACCOUNT.PULL_CHART_PERMISSION' | translate}} </div>
</label> </div>
</clr-checkbox-wrapper> </div>
</label> </div>
</div> </section>
</section> </form>
</form> </div>
</div> <div class="modal-footer">
<div class="modal-footer"> <button type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL'
<button type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL' | translate}}</button>
| translate}}</button> <button type="button" [disabled]="shouldDisable" class="btn btn-primary"
<button type="button" [disabled]="shouldDisable" class="btn btn-primary" (click)="onSubmit()">{{'BUTTON.SAVE'
(click)="onSubmit()">{{'BUTTON.SAVE' | translate}}</button>
| translate}}</button> </div>
</div>
</clr-modal> </clr-modal>
<clr-modal [(clrModalOpen)]="copyToken" class="copy-token" <clr-modal [(clrModalOpen)]="copyToken" class="copy-token"
[clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable"> [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
<div class="modal-title"> <div class="modal-title">
<h3 class="modal-title"> <h3 class="modal-title">
<clr-icon class="alert-icon success-icon" shape="check-circle" size="50"></clr-icon> <clr-icon class="alert-icon success-icon" shape="check-circle" size="50"></clr-icon>
{{ createSuccess | translate}}</h3> {{ createSuccess | translate}}</h3>
<div class="alert alert-info" role="alert"> <div class="alert alert-info" role="alert">
<div class="alert-items"> <div class="alert-items">
<div class="alert-item static"> <div class="alert-item static">
<div class="alert-icon-wrapper"> <div class="alert-icon-wrapper">
<clr-icon class="alert-icon" shape="info-circle"></clr-icon> <clr-icon class="alert-icon" shape="info-circle"></clr-icon>
</div> </div>
<span class="alert-text">{{'ROBOT_ACCOUNT.ALERT_TEXT' | translate}}</span> <span class="alert-text">{{'ROBOT_ACCOUNT.ALERT_TEXT' | translate}}</span>
</div>
</div>
</div> </div>
</div>
</div> </div>
</div> <div class="modal-body">
<div class="modal-body"> <section class="form-block show-info">
<section class="form-block show-info"> <div class="form-group robot-name">
<div class="form-group robot-name"> <label class="form-group-label-override">{{'ROBOT_ACCOUNT.NAME'
<label class="form-group-label-override">{{'ROBOT_ACCOUNT.NAME' | translate}}</label>
| translate}}</label> <span>{{robotAccount}}</span>
<span>{{robotAccount}}</span> </div>
</div> <div class="form-group robot-token">
<div class="form-group robot-token"> <label class="form-group-label-override">{{'ROBOT_ACCOUNT.TOKEN' |
<label class="form-group-label-override">{{'ROBOT_ACCOUNT.TOKEN' | translate}}</label>
translate}}</label> <hbr-copy-input (onCopySuccess)="onCpSuccess($event)"
<hbr-copy-input (onCopySuccess)="onCpSuccess($event)" (onCopyError)="onCpError($event)" inputSize="50" headerTitle=""
(onCopyError)="onCpError($event)" inputSize="50" headerTitle="" defaultValue="{{robotToken}}" class="copy-input"></hbr-copy-input>
defaultValue="{{robotToken}}" class="copy-input"></hbr-copy-input> </div>
</div> </section>
</section> </div>
</div>
</clr-modal> </clr-modal>

View File

@ -3,7 +3,7 @@
} }
.input-width { .input-width {
width: 200px; width: 300px;
} }
.copy-token { .copy-token {
@ -35,3 +35,12 @@
.no-margin { .no-margin {
margin: 0; margin: 0;
} }
.permission{
padding-top: 5px;
color: #000000;
}
.padding-left-120{
padding-left: 120px;
}

View File

@ -38,17 +38,18 @@ export class AddRobotComponent implements OnInit, OnDestroy {
robotNameChecker: Subject<string> = new Subject<string>(); robotNameChecker: Subject<string> = new Subject<string>();
nameTooltipText = "ROBOT_ACCOUNT.ROBOT_NAME"; nameTooltipText = "ROBOT_ACCOUNT.ROBOT_NAME";
robotForm: NgForm; robotForm: NgForm;
imagePermission: string = "push-and-pull";
@Input() projectId: number; @Input() projectId: number;
@Input() projectName: string; @Input() projectName: string;
@Output() create = new EventEmitter<boolean>(); @Output() create = new EventEmitter<boolean>();
@ViewChild("robotForm") currentForm: NgForm; @ViewChild("robotForm") currentForm: NgForm;
@ViewChild("copyAlert") copyAlert: InlineAlertComponent; @ViewChild("copyAlert") copyAlert: InlineAlertComponent;
constructor( constructor(
private robotService: RobotService, private robotService: RobotService,
private translate: TranslateService, private translate: TranslateService,
private errorHandler: ErrorHandler, private errorHandler: ErrorHandler,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
private messageHandlerService: MessageHandlerService private messageHandlerService: MessageHandlerService
) {} ) {}
ngOnInit(): void { ngOnInit(): void {
@ -59,31 +60,31 @@ export class AddRobotComponent implements OnInit, OnDestroy {
if (this.isRobotNameValid) { if (this.isRobotNameValid) {
this.checkOnGoing = true; this.checkOnGoing = true;
this.robotService this.robotService
.listRobotAccount(this.projectId) .listRobotAccount(this.projectId)
.pipe( .pipe(
finalize(() => { finalize(() => {
this.checkOnGoing = false; this.checkOnGoing = false;
let hnd = setInterval(() => this.cdr.markForCheck(), 100); let hnd = setInterval(() => this.cdr.markForCheck(), 100);
setTimeout(() => clearInterval(hnd), 2000); setTimeout(() => clearInterval(hnd), 2000);
}) })
) )
.subscribe( .subscribe(
response => { response => {
if (response && response.length) { if (response && response.length) {
if ( if (
response.find(target => { response.find(target => {
return target.name === "robot$" + cont.value; return target.name === "robot$" + cont.value;
}) })
) { ) {
this.isRobotNameValid = false; this.isRobotNameValid = false;
this.nameTooltipText = "ROBOT_ACCOUNT.ACCOUNT_EXISTING"; this.nameTooltipText = "ROBOT_ACCOUNT.ACCOUNT_EXISTING";
}
}
},
error => {
this.errorHandler.error(error);
} }
} );
},
error => {
this.errorHandler.error(error);
}
);
} else { } else {
this.nameTooltipText = "ROBOT_ACCOUNT.ROBOT_NAME"; this.nameTooltipText = "ROBOT_ACCOUNT.ROBOT_NAME";
} }
@ -116,49 +117,57 @@ export class AddRobotComponent implements OnInit, OnDestroy {
if (this.isSubmitOnGoing) { if (this.isSubmitOnGoing) {
return; return;
} }
// set value to robot.access.isPullImage and robot.access.isPushOrPullImage when submit
if ( this.imagePermission === 'pull' ) {
this.robot.access.isPullImage = true;
this.robot.access.isPushOrPullImage = false;
} else {
this.robot.access.isPullImage = false;
this.robot.access.isPushOrPullImage = true;
}
this.isSubmitOnGoing = true; this.isSubmitOnGoing = true;
this.robotService this.robotService
.addRobotAccount( .addRobotAccount(
this.projectId, this.projectId,
this.robot, this.robot,
this.projectName this.projectName
) )
.subscribe( .subscribe(
response => { response => {
this.isSubmitOnGoing = false; this.isSubmitOnGoing = false;
this.robotToken = response.token; this.robotToken = response.token;
this.robotAccount = response.name; this.robotAccount = response.name;
this.copyToken = true; this.copyToken = true;
this.create.emit(true); this.create.emit(true);
this.translate this.translate
.get("ROBOT_ACCOUNT.CREATED_SUCCESS", { param: this.robotAccount }) .get("ROBOT_ACCOUNT.CREATED_SUCCESS", { param: this.robotAccount })
.subscribe((res: string) => { .subscribe((res: string) => {
this.createSuccess = res; this.createSuccess = res;
}); });
this.addRobotOpened = false; this.addRobotOpened = false;
}, },
error => { error => {
this.isSubmitOnGoing = false; this.isSubmitOnGoing = false;
this.copyAlert.showInlineError(error); this.copyAlert.showInlineError(error);
} }
); );
} }
isValid(): boolean { isValid(): boolean {
return ( return (
this.currentForm && this.currentForm &&
this.currentForm.valid && this.currentForm.valid &&
!this.isSubmitOnGoing && !this.isSubmitOnGoing &&
this.isRobotNameValid && this.isRobotNameValid &&
!this.checkOnGoing !this.checkOnGoing
); );
} }
get shouldDisable(): boolean { get shouldDisable(): boolean {
if (this.robot && this.robot.access) { if (this.robot && this.robot.access) {
return ( return (
!this.isValid() || !this.isValid() ||
(!this.robot.access.isPushOrPullImage && !this.robot.access.isPullImage (!this.robot.access.isPushOrPullImage && !this.robot.access.isPullImage
&& !this.robot.access.isPullChart && !this.robot.access.isPushChart) && !this.robot.access.isPullChart && !this.robot.access.isPushChart)
); );
} }
} }
@ -180,9 +189,9 @@ export class AddRobotComponent implements OnInit, OnDestroy {
onCpSuccess($event: any): void { onCpSuccess($event: any): void {
this.copyToken = false; this.copyToken = false;
this.translate this.translate
.get("ROBOT_ACCOUNT.COPY_SUCCESS", { param: this.robotAccount }) .get("ROBOT_ACCOUNT.COPY_SUCCESS", { param: this.robotAccount })
.subscribe((res: string) => { .subscribe((res: string) => {
this.messageHandlerService.showSuccess(res); this.messageHandlerService.showSuccess(res);
}); });
} }
} }

View File

@ -16,7 +16,7 @@ export class Robot {
constructor () { constructor () {
this.access = <any>{}; this.access = <any>{};
// this.access[0].action = true; // this.access[0].action = true;
this.access.isPullImage = true; this.access.isPullImage = false;
this.access.isPushOrPullImage = true; this.access.isPushOrPullImage = true;
this.access.isPushChart = false; this.access.isPushChart = false;
this.access.isPullChart = false; this.access.isPullChart = false;

View File

@ -310,10 +310,10 @@
"ENABLE_ACCOUNT": "Enable Account", "ENABLE_ACCOUNT": "Enable Account",
"DELETE": "Delete", "DELETE": "Delete",
"CREAT_ROBOT_ACCOUNT": "Creat Robot Account", "CREAT_ROBOT_ACCOUNT": "Creat Robot Account",
"PULL_PERMISSION": "Image pull", "PERMISSIONS_IMAGE": "Image",
"PULL_PUSH_PERMISSION": "Image pull / push", "PERMISSIONS_HELMCHART": "Helm Chart",
"PUSH_CHART_PERMISSION": "Helm chart push", "PUSH": "Push",
"PULL_CHART_PERMISSION": "Helm chart pull", "PULL": "Pull",
"FILTER_PLACEHOLDER": "Filter Robot Accounts", "FILTER_PLACEHOLDER": "Filter Robot Accounts",
"ROBOT_NAME": "Cannot contain special characters(~#$%) and maximum length should be 255 characters.", "ROBOT_NAME": "Cannot contain special characters(~#$%) and maximum length should be 255 characters.",
"ACCOUNT_EXISTING": "Robot Account is already exists.", "ACCOUNT_EXISTING": "Robot Account is already exists.",

View File

@ -311,10 +311,10 @@
"ENABLE_ACCOUNT": "Enable Account", "ENABLE_ACCOUNT": "Enable Account",
"DELETE": "Delete", "DELETE": "Delete",
"CREAT_ROBOT_ACCOUNT": "Creat Robot Account", "CREAT_ROBOT_ACCOUNT": "Creat Robot Account",
"PULL_PERMISSION": "Image pull", "PERMISSIONS_IMAGE": "Image",
"PULL_PUSH_PERMISSION": "Image pull / push", "PERMISSIONS_HELMCHART": "Helm Chart",
"PUSH_CHART_PERMISSION": "Helm chart push", "PUSH": "Push",
"PULL_CHART_PERMISSION": "Helm chart pull", "PULL": "Pull",
"FILTER_PLACEHOLDER": "Filter Robot Accounts", "FILTER_PLACEHOLDER": "Filter Robot Accounts",
"ROBOT_NAME": "Cannot contain special characters(~#$%) and maximum length should be 255 characters.", "ROBOT_NAME": "Cannot contain special characters(~#$%) and maximum length should be 255 characters.",
"ACCOUNT_EXISTING": "Robot Account is already exists.", "ACCOUNT_EXISTING": "Robot Account is already exists.",

View File

@ -302,10 +302,11 @@
"ENABLE_ACCOUNT": "permettre à compte ", "ENABLE_ACCOUNT": "permettre à compte ",
"DELETE": "Supprimer", "DELETE": "Supprimer",
"CREAT_ROBOT_ACCOUNT": "créat robot compte ", "CREAT_ROBOT_ACCOUNT": "créat robot compte ",
"PULL_PERMISSION": "Image pull", "PERMISSIONS_IMAGE": "Image",
"PULL_PUSH_PERMISSION": "Image pull / push", "PERMISSIONS_HELMCHART": "Helm Chart",
"PUSH_CHART_PERMISSION": "Helm chart push", "PUSH": "Push",
"PULL_CHART_PERMISSION": "Helm chart pull", "PULL": "Pull",
"FILTER_PLACEHOLDER": "Filter Robot Accounts", "FILTER_PLACEHOLDER": "Filter Robot Accounts",
"ROBOT_NAME": "ne peut pas contenir de caractères spéciaux(~#$%) et la longueur maximale devrait être de 255 caractères.", "ROBOT_NAME": "ne peut pas contenir de caractères spéciaux(~#$%) et la longueur maximale devrait être de 255 caractères.",
"ACCOUNT_EXISTING": "le robot est existe déjà.", "ACCOUNT_EXISTING": "le robot est existe déjà.",

View File

@ -308,10 +308,10 @@
"ENABLE_ACCOUNT": "Ativar conta", "ENABLE_ACCOUNT": "Ativar conta",
"DELETE": "Remover", "DELETE": "Remover",
"CREAT_ROBOT_ACCOUNT": "CRIA robô conta", "CREAT_ROBOT_ACCOUNT": "CRIA robô conta",
"PULL_PERMISSION": "Image pull", "PERMISSIONS_IMAGE": "Image",
"PULL_PUSH_PERMISSION": "Image pull / push", "PERMISSIONS_HELMCHART": "Helm Chart",
"PUSH_CHART_PERMISSION": "Helm chart push", "PUSH": "Push",
"PULL_CHART_PERMISSION": "Helm chart pull", "PULL": "Pull",
"FILTER_PLACEHOLDER": "Filtro robot accounts", "FILTER_PLACEHOLDER": "Filtro robot accounts",
"ROBOT_NAME": "Não Pode conter caracteres especiais(~#$%) e comprimento máximo deveria ser 255 caracteres.", "ROBOT_NAME": "Não Pode conter caracteres especiais(~#$%) e comprimento máximo deveria ser 255 caracteres.",
"ACCOUNT_EXISTING": "Robô conta já existe.", "ACCOUNT_EXISTING": "Robô conta já existe.",

View File

@ -309,10 +309,10 @@
"ENABLE_ACCOUNT": "启用账户", "ENABLE_ACCOUNT": "启用账户",
"DELETE": "删除", "DELETE": "删除",
"CREAT_ROBOT_ACCOUNT": "创建机器人账户", "CREAT_ROBOT_ACCOUNT": "创建机器人账户",
"PULL_PERMISSION": "Pull 镜像", "PERMISSIONS_IMAGE": "镜像",
"PULL_PUSH_PERMISSION": "Push和Pull 镜像", "PERMISSIONS_HELMCHART": "Helm Chart",
"PUSH_CHART_PERMISSION": "推送Chart", "PUSH": "推送",
"PULL_CHART_PERMISSION": "拉取Chart", "PULL": "拉取",
"FILTER_PLACEHOLDER": "过滤机器人账户", "FILTER_PLACEHOLDER": "过滤机器人账户",
"ROBOT_NAME": "不能包含特殊字符(~#$%)且长度不能超过255.", "ROBOT_NAME": "不能包含特殊字符(~#$%)且长度不能超过255.",
"ACCOUNT_EXISTING": "机器人账户已经存在.", "ACCOUNT_EXISTING": "机器人账户已经存在.",