mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-29 21:54:13 +01:00
commit
2092387e18
@ -18,8 +18,8 @@
|
|||||||
<clr-icon shape="caret down"></clr-icon>
|
<clr-icon shape="caret down"></clr-icon>
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<a href="javascript:void(0)" clrDropdownItem (click)='switchLanguage("en-us")' [class.lang-selected]='matchLang("en")'>English</a>
|
<a href="javascript:void(0)" clrDropdownItem (click)='switchLanguage("en-us")' [class.lang-selected]='matchLang("en-us")'>English</a>
|
||||||
<a href="javascript:void(0)" clrDropdownItem (click)='switchLanguage("zh-cn")' [class.lang-selected]='matchLang("zh")'>中文简体</a>
|
<a href="javascript:void(0)" clrDropdownItem (click)='switchLanguage("zh-cn")' [class.lang-selected]='matchLang("zh-cn")'>中文简体</a>
|
||||||
</div>
|
</div>
|
||||||
</clr-dropdown>
|
</clr-dropdown>
|
||||||
<clr-dropdown [clrMenuPosition]="'bottom-right'" class="dropdown" *ngIf="isSessionValid">
|
<clr-dropdown [clrMenuPosition]="'bottom-right'" class="dropdown" *ngIf="isSessionValid">
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<clr-modal [(clrModalOpen)]="createProjectOpened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
|
<clr-modal [(clrModalOpen)]="createProjectOpened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
|
||||||
<h3 class="modal-title">{{'PROJECT.NEW_PROJECT' | translate}}</h3>
|
<h3 class="modal-title">{{'PROJECT.NEW_PROJECT' | translate}}</h3>
|
||||||
<inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></inline-alert>
|
<inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></inline-alert>
|
||||||
<div class="modal-body">
|
<div class="modal-body" style="height: 12.8em; overflow-y: hidden;">
|
||||||
<form #projectForm="ngForm">
|
<form #projectForm="ngForm">
|
||||||
<section class="form-block">
|
<section class="form-block">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="create_project_name" class="col-md-4 form-group-label-override">{{'PROJECT.NAME' | translate}}</label>
|
<label for="create_project_name" class="col-md-4 form-group-label-override">{{'PROJECT.NAME' | translate}}</label>
|
||||||
<label for="create_project_name" aria-haspopup="true" role="tooltip" [class.invalid]="projectName.invalid && (projectName.dirty || projectName.touched)" [class.valid]="projectName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-right">
|
<label for="create_project_name" aria-haspopup="true" role="tooltip" [class.invalid]="projectName.invalid && (projectName.dirty || projectName.touched)" [class.valid]="projectName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
||||||
<input type="text" id="create_project_name" [(ngModel)]="project.name" name="name" size="20" required minlength="2" #projectName="ngModel" targetExists="PROJECT_NAME">
|
<input type="text" id="create_project_name" [(ngModel)]="project.name" name="name" size="20" required minlength="2" #projectName="ngModel" targetExists="PROJECT_NAME">
|
||||||
<span class="tooltip-content" *ngIf="projectName.errors && projectName.errors.required && (projectName.dirty || projectName.touched)">
|
<span class="tooltip-content" *ngIf="projectName.errors && projectName.errors.required && (projectName.dirty || projectName.touched)">
|
||||||
{{'PROJECT.NAME_IS_REQUIRED' | translate}}
|
{{'PROJECT.NAME_IS_REQUIRED' | translate}}
|
||||||
@ -26,6 +26,9 @@
|
|||||||
<label for="create_project_public"></label>
|
<label for="create_project_public"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<p class="inline-help-public">
|
||||||
|
{{'PROJECT.INLINE_HELP_PUBLIC' | translate }}
|
||||||
|
</p>
|
||||||
</section>
|
</section>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
.inline-help-public {
|
||||||
|
color: #CCCCCC;
|
||||||
|
font-size: 12px;
|
||||||
|
letter-spacing: 0.01em;
|
||||||
|
margin-top: 0;
|
||||||
|
padding: 0 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group-label-override {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
.form-group-label-override {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
@ -6,7 +6,7 @@
|
|||||||
<section class="form-block">
|
<section class="form-block">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="member_name" class="col-md-4 form-group-label-override">{{'MEMBER.NAME' | translate}}</label>
|
<label for="member_name" class="col-md-4 form-group-label-override">{{'MEMBER.NAME' | translate}}</label>
|
||||||
<label for="member_name" aria-haspopup="true" role="tooltip" [class.invalid]="memberName.invalid && (memberName.dirty || memberName.touched)" [class.valid]="memberName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-right">
|
<label for="member_name" aria-haspopup="true" role="tooltip" [class.invalid]="memberName.invalid && (memberName.dirty || memberName.touched)" [class.valid]="memberName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
||||||
<input type="text" id="member_name" [(ngModel)]="member.username" name="name" size="20" #memberName="ngModel" required targetExists="MEMBER_NAME" [projectId]="projectId">
|
<input type="text" id="member_name" [(ngModel)]="member.username" name="name" size="20" #memberName="ngModel" required targetExists="MEMBER_NAME" [projectId]="projectId">
|
||||||
<span class="tooltip-content" *ngIf="memberName.errors && memberName.errors.required && (memberName.dirty || memberName.touched)">
|
<span class="tooltip-content" *ngIf="memberName.errors && memberName.errors.required && (memberName.dirty || memberName.touched)">
|
||||||
{{ 'MEMBER.USERNAME_IS_REQUIRED' | translate }}
|
{{ 'MEMBER.USERNAME_IS_REQUIRED' | translate }}
|
||||||
|
@ -13,7 +13,8 @@ import { Member } from '../member';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'add-member',
|
selector: 'add-member',
|
||||||
templateUrl: 'add-member.component.html'
|
templateUrl: 'add-member.component.html',
|
||||||
|
styleUrls: [ 'add-member.component.css' ]
|
||||||
})
|
})
|
||||||
export class AddMemberComponent implements AfterViewChecked {
|
export class AddMemberComponent implements AfterViewChecked {
|
||||||
|
|
||||||
|
@ -6,3 +6,10 @@
|
|||||||
.sub-nav-bg-color {
|
.sub-nav-bg-color {
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.role-label {
|
||||||
|
color: #CCCCCC;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: italic;
|
||||||
|
letter-spacing: 0.01em;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<a *ngIf="hasSignedIn" [routerLink]="['/harbor', 'projects']">< {{'PROJECT_DETAIL.PROJECTS' | translate}}</a>
|
<a *ngIf="hasSignedIn" [routerLink]="['/harbor', 'projects']">< {{'PROJECT_DETAIL.PROJECTS' | translate}}</a>
|
||||||
<a *ngIf="!hasSignedIn" [routerLink]="['/harbor', 'sign-in']">< {{'SEARCH.BACK' | translate}}</a>
|
<a *ngIf="!hasSignedIn" [routerLink]="['/harbor', 'sign-in']">< {{'SEARCH.BACK' | translate}}</a>
|
||||||
|
|
||||||
<h1 class="sub-header-title">{{currentProject.name}} <span class="badge badge-light-blue" *ngIf="isMember">{{roleName | translate}}</span> <span class="badge badge-purple" *ngIf="isSystemAdmin">{{ 'MEMBER.SYS_ADMIN' | translate}}</span></h1>
|
<h1 class="sub-header-title">{{currentProject.name}} <span class="role-label" *ngIf="isMember">{{roleName | translate}}</span> <span class="role-label" *ngIf="isSystemAdmin">{{ 'MEMBER.SYS_ADMIN' | translate}}</span></h1>
|
||||||
<nav class="subnav sub-nav-bg-color">
|
<nav class="subnav sub-nav-bg-color">
|
||||||
<ul class="nav">
|
<ul class="nav">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
|
@ -75,7 +75,13 @@ export class ProjectComponent implements OnInit, OnDestroy {
|
|||||||
console.log('Successful delete project with ID:' + projectId);
|
console.log('Successful delete project with ID:' + projectId);
|
||||||
this.retrieve();
|
this.retrieve();
|
||||||
},
|
},
|
||||||
error =>this.messageHandlerService.handleError(error)
|
error =>{
|
||||||
|
if(error && error.status === 412) {
|
||||||
|
this.messageHandlerService.showError('PROJECT.FAILED_TO_DELETE_PROJECT', '');
|
||||||
|
} else {
|
||||||
|
this.messageHandlerService.handleError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
.form-group-label-override {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
<h3 class="modal-title">{{modalTitle}}</h3>
|
<h3 class="modal-title">{{modalTitle}}</h3>
|
||||||
<inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></inline-alert>
|
<inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></inline-alert>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="alert alert-danger" *ngIf="!editable">
|
<div class="alert alert-warning" *ngIf="!editable">
|
||||||
<div class="alert-item">
|
<div class="alert-item">
|
||||||
<span class="alert-text">
|
<span class="alert-text">
|
||||||
{{'DESTINATION.CANNOT_EDIT' | translate}}
|
{{'DESTINATION.CANNOT_EDIT' | translate}}
|
||||||
@ -13,8 +13,8 @@
|
|||||||
<section class="form-block">
|
<section class="form-block">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="destination_name" class="col-md-4 form-group-label-override">{{ 'DESTINATION.NAME' | translate }}<span style="color: red">*</span></label>
|
<label for="destination_name" class="col-md-4 form-group-label-override">{{ 'DESTINATION.NAME' | translate }}<span style="color: red">*</span></label>
|
||||||
<label class="col-md-8" for="destination_name" aria-haspopup="true" role="tooltip" [class.invalid]="targetName.errors && (targetName.dirty || targetName.touched)" [class.valid]="targetName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-right">
|
<label class="col-md-8" for="destination_name" aria-haspopup="true" role="tooltip" [class.invalid]="targetName.errors && (targetName.dirty || targetName.touched)" [class.valid]="targetName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
||||||
<input type="text" id="destination_name" [disabled]="testOngoing || !editable" [(ngModel)]="target.name" name="targetName" size="20" #targetName="ngModel" value="" required>
|
<input type="text" id="destination_name" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.name" name="targetName" size="20" #targetName="ngModel" value="" required>
|
||||||
<span class="tooltip-content" *ngIf="targetName.errors && targetName.errors.required && (targetName.dirty || targetName.touched)">
|
<span class="tooltip-content" *ngIf="targetName.errors && targetName.errors.required && (targetName.dirty || targetName.touched)">
|
||||||
{{ 'DESTINATION.NAME_IS_REQUIRED' | translate }}
|
{{ 'DESTINATION.NAME_IS_REQUIRED' | translate }}
|
||||||
</span>
|
</span>
|
||||||
@ -22,8 +22,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="destination_url" class="col-md-4 form-group-label-override">{{ 'DESTINATION.URL' | translate }}<span style="color: red">*</span></label>
|
<label for="destination_url" class="col-md-4 form-group-label-override">{{ 'DESTINATION.URL' | translate }}<span style="color: red">*</span></label>
|
||||||
<label class="col-md-8" for="destination_url" aria-haspopup="true" role="tooltip" [class.invalid]="targetEndpoint.errors && (targetEndpoint.dirty || targetEndpoint.touched)" [class.valid]="targetEndpoint.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-right">
|
<label class="col-md-8" for="destination_url" aria-haspopup="true" role="tooltip" [class.invalid]="targetEndpoint.errors && (targetEndpoint.dirty || targetEndpoint.touched)" [class.valid]="targetEndpoint.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
||||||
<input type="text" id="destination_url" [disabled]="testOngoing || !editable" [(ngModel)]="target.endpoint" size="20" name="endpointUrl" #targetEndpoint="ngModel" required>
|
<input type="text" id="destination_url" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.endpoint" size="20" name="endpointUrl" #targetEndpoint="ngModel" required>
|
||||||
<span class="tooltip-content" *ngIf="targetEndpoint.errors && targetEndpoint.errors.required && (targetEndpoint.dirty || targetEndpoint.touched)">
|
<span class="tooltip-content" *ngIf="targetEndpoint.errors && targetEndpoint.errors.required && (targetEndpoint.dirty || targetEndpoint.touched)">
|
||||||
{{ 'DESTINATION.URL_IS_REQUIRED' | translate }}
|
{{ 'DESTINATION.URL_IS_REQUIRED' | translate }}
|
||||||
</span>
|
</span>
|
||||||
@ -31,11 +31,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="destination_username" class="col-md-4 form-group-label-override">{{ 'DESTINATION.USERNAME' | translate }}</label>
|
<label for="destination_username" class="col-md-4 form-group-label-override">{{ 'DESTINATION.USERNAME' | translate }}</label>
|
||||||
<input type="text" class="col-md-8" id="destination_username" [disabled]="testOngoing || !editable" [(ngModel)]="target.username" size="20" name="username" #username="ngModel">
|
<input type="text" class="col-md-8" id="destination_username" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.username" size="20" name="username" #username="ngModel">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="destination_password" class="col-md-4 form-group-label-override">{{ 'DESTINATION.PASSWORD' | translate }}</label>
|
<label for="destination_password" class="col-md-4 form-group-label-override">{{ 'DESTINATION.PASSWORD' | translate }}</label>
|
||||||
<input type="password" class="col-md-8" id="destination_password" [disabled]="testOngoing || !editable" [(ngModel)]="target.password" size="20" name="password" #password="ngModel">
|
<input type="password" class="col-md-8" id="destination_password" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.password" size="20" name="password" #password="ngModel">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="spin" class="col-md-4"></label>
|
<label for="spin" class="col-md-4"></label>
|
||||||
|
@ -13,7 +13,8 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'create-edit-destination',
|
selector: 'create-edit-destination',
|
||||||
templateUrl: './create-edit-destination.component.html'
|
templateUrl: './create-edit-destination.component.html',
|
||||||
|
styleUrls: [ 'create-edit-destination.component.css' ]
|
||||||
})
|
})
|
||||||
export class CreateEditDestinationComponent implements AfterViewChecked {
|
export class CreateEditDestinationComponent implements AfterViewChecked {
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||||
import { Job } from '../job';
|
import { Job } from '../job';
|
||||||
import { State } from 'clarity-angular';
|
import { State } from 'clarity-angular';
|
||||||
|
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'list-job',
|
selector: 'list-job',
|
||||||
@ -12,10 +13,18 @@ export class ListJobComponent {
|
|||||||
@Input() totalPage: number;
|
@Input() totalPage: number;
|
||||||
@Output() paginate = new EventEmitter<State>();
|
@Output() paginate = new EventEmitter<State>();
|
||||||
|
|
||||||
|
constructor(private messageHandlerService: MessageHandlerService) {}
|
||||||
|
|
||||||
pageOffset: number = 1;
|
pageOffset: number = 1;
|
||||||
|
|
||||||
refresh(state: State) {
|
refresh(state: State) {
|
||||||
if(this.jobs) {
|
if(this.jobs) {
|
||||||
|
for(let i = 0; i < this.jobs.length; i++) {
|
||||||
|
let j = this.jobs[i];
|
||||||
|
if(j.status === 'retrying' || j.status === 'error') {
|
||||||
|
this.messageHandlerService.showError('REPLICATION.FOUND_ERROR_IN_JOBS', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
this.paginate.emit(state);
|
this.paginate.emit(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
<h5 class="flex-items-xs-bottom option-left-down" style="margin-left: 14px;">{{'REPLICATION.REPLICATION_JOBS' | translate}}</h5>
|
<h5 class="flex-items-xs-bottom option-left-down" style="margin-left: 14px;">{{'REPLICATION.REPLICATION_JOBS' | translate}}</h5>
|
||||||
<div class="flex-items-xs-bottom option-right-down">
|
<div class="flex-items-xs-bottom option-right-down">
|
||||||
<button class="btn btn-link" (click)="toggleSearchJobOptionalName(currentJobSearchOption)">{{toggleJobSearchOption[currentJobSearchOption] | translate}}</button>
|
<button class="btn btn-link" (click)="toggleSearchJobOptionalName(currentJobSearchOption)">{{toggleJobSearchOption[currentJobSearchOption] | translate}}</button>
|
||||||
<grid-filter filterPlaceholder='{{"REPLICATION.FILTER_POLICIES_PLACEHOLDER" | translate}}' (filter)="doSearchJobs($event)"></grid-filter>
|
<grid-filter filterPlaceholder='{{"REPLICATION.FILTER_JOBS_PLACEHOLDER" | translate}}' (filter)="doSearchJobs($event)"></grid-filter>
|
||||||
<a href="javascript:void(0)" (click)="refreshJobs()">
|
<a href="javascript:void(0)" (click)="refreshJobs()">
|
||||||
<clr-icon shape="refresh"></clr-icon>
|
<clr-icon shape="refresh"></clr-icon>
|
||||||
</a>
|
</a>
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
.form-group-label-override {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
<clr-modal [(clrModalOpen)]="createEditPolicyOpened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
|
<clr-modal [(clrModalOpen)]="createEditPolicyOpened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
|
||||||
<h3 class="modal-title">{{modalTitle}}</h3>
|
<h3 class="modal-title">{{modalTitle}}</h3>
|
||||||
<inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></inline-alert>
|
<inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></inline-alert>
|
||||||
<div class="modal-body">
|
<div class="modal-body" style="max-height: 85vh;">
|
||||||
<form #policyForm="ngForm">
|
<form #policyForm="ngForm">
|
||||||
<section class="form-block">
|
<section class="form-block">
|
||||||
<div class="alert alert-danger" *ngIf="readonly">
|
<div class="alert alert-warning" *ngIf="readonly">
|
||||||
<div class="alert-item">
|
<div class="alert-item">
|
||||||
<span class="alert-text">
|
<span class="alert-text">
|
||||||
{{'REPLICATION.CANNOT_EDIT' | translate}}
|
{{'REPLICATION.CANNOT_EDIT' | translate}}
|
||||||
@ -13,8 +13,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="policy_name" class="col-md-4 form-group-label-override">{{'REPLICATION.NAME' | translate}}<span style="color: red">*</span></label>
|
<label for="policy_name" class="col-md-4 form-group-label-override">{{'REPLICATION.NAME' | translate}}<span style="color: red">*</span></label>
|
||||||
<label for="policy_name" class="col-md-8" aria-haspopup="true" role="tooltip" [class.invalid]="name.errors && (name.dirty || name.touched)" [class.valid]="name.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-right">
|
<label for="policy_name" class="col-md-8" aria-haspopup="true" role="tooltip" [class.invalid]="name.errors && (name.dirty || name.touched)" [class.valid]="name.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
||||||
<input type="text" id="policy_name" [(ngModel)]="createEditPolicy.name" name="name" #name="ngModel" required [disabled]="readonly">
|
<input type="text" id="policy_name" [(ngModel)]="createEditPolicy.name" name="name" size="20" #name="ngModel" required [readonly]="readonly">
|
||||||
<span class="tooltip-content" *ngIf="name.errors && name.errors.required && (name.dirty || name.touched)">
|
<span class="tooltip-content" *ngIf="name.errors && name.errors.required && (name.dirty || name.touched)">
|
||||||
{{'REPLICATION.NAME_IS_REQUIRED' | translate}}
|
{{'REPLICATION.NAME_IS_REQUIRED' | translate}}
|
||||||
</span>
|
</span>
|
||||||
@ -22,7 +22,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="policy_description" class="col-md-4 form-group-label-override">{{'REPLICATION.DESCRIPTION' | translate}}</label>
|
<label for="policy_description" class="col-md-4 form-group-label-override">{{'REPLICATION.DESCRIPTION' | translate}}</label>
|
||||||
<input type="text" class="col-md-8" id="policy_description" [(ngModel)]="createEditPolicy.description" name="description" size="20" #description="ngModel" [disabled]="readonly">
|
<textarea class="col-md-8" id="policy_description" row="3" [(ngModel)]="createEditPolicy.description" name="description" size="20" #description="ngModel" [readonly]="readonly"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-4 form-group-label-override">{{'REPLICATION.ENABLE' | translate}}</label>
|
<label class="col-md-4 form-group-label-override">{{'REPLICATION.ENABLE' | translate}}</label>
|
||||||
@ -38,7 +38,7 @@
|
|||||||
<option *ngFor="let t of targets" [value]="t.id" [selected]="t.id == createEditPolicy.targetId">{{t.name}}</option>
|
<option *ngFor="let t of targets" [value]="t.id" [selected]="t.id == createEditPolicy.targetId">{{t.name}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<label class="col-md-8" *ngIf="isCreateDestination" for="destination_name" aria-haspopup="true" role="tooltip" [class.invalid]="targetName.errors && (targetName.dirty || targetName.touched)" [class.valid]="targetName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-right">
|
<label class="col-md-8" *ngIf="isCreateDestination" for="destination_name" aria-haspopup="true" role="tooltip" [class.invalid]="targetName.errors && (targetName.dirty || targetName.touched)" [class.valid]="targetName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
||||||
<input type="text" id="destination_name" [(ngModel)]="createEditPolicy.targetName" name="targetName" size="8" #targetName="ngModel" value="" required>
|
<input type="text" id="destination_name" [(ngModel)]="createEditPolicy.targetName" name="targetName" size="8" #targetName="ngModel" value="" required>
|
||||||
<span class="tooltip-content" *ngIf="targetName.errors && targetName.errors.required && (targetName.dirty || targetName.touched)">
|
<span class="tooltip-content" *ngIf="targetName.errors && targetName.errors.required && (targetName.dirty || targetName.touched)">
|
||||||
{{'REPLICATION.DESTINATION_NAME_IS_REQUIRED' | translate}}
|
{{'REPLICATION.DESTINATION_NAME_IS_REQUIRED' | translate}}
|
||||||
@ -51,8 +51,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="destination_url" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_URL' | translate}}<span style="color: red">*</span></label>
|
<label for="destination_url" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_URL' | translate}}<span style="color: red">*</span></label>
|
||||||
<label for="destination_url" class="col-md-8" aria-haspopup="true" role="tooltip" [class.invalid]="endpointUrl.errors && (endpointUrl.dirty || endpointUrl.touched)" [class.valid]="endpointUrl.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-right">
|
<label for="destination_url" class="col-md-8" aria-haspopup="true" role="tooltip" [class.invalid]="endpointUrl.errors && (endpointUrl.dirty || endpointUrl.touched)" [class.valid]="endpointUrl.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
||||||
<input type="text" id="destination_url" [disabled]="testOngoing || readonly" [(ngModel)]="createEditPolicy.endpointUrl" size="20" name="endpointUrl" required #endpointUrl="ngModel">
|
<input type="text" id="destination_url" [disabled]="testOngoing" [readonly]="readonly || !isCreateDestination" [(ngModel)]="createEditPolicy.endpointUrl" size="20" name="endpointUrl" required #endpointUrl="ngModel">
|
||||||
<span class="tooltip-content" *ngIf="endpointUrl.errors && endpointUrl.errors.required && (endpointUrl.dirty || endpointUrl.touched)">
|
<span class="tooltip-content" *ngIf="endpointUrl.errors && endpointUrl.errors.required && (endpointUrl.dirty || endpointUrl.touched)">
|
||||||
{{'REPLICATION.DESTINATION_URL_IS_REQUIRED' | translate}}
|
{{'REPLICATION.DESTINATION_URL_IS_REQUIRED' | translate}}
|
||||||
</span>
|
</span>
|
||||||
@ -60,11 +60,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="destination_username" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_USERNAME' | translate}}</label>
|
<label for="destination_username" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_USERNAME' | translate}}</label>
|
||||||
<input type="text" class="col-md-8" id="destination_username" [disabled]="testOngoing || readonly" [(ngModel)]="createEditPolicy.username" size="20" name="username" #username="ngModel">
|
<input type="text" class="col-md-8" id="destination_username" [disabled]="testOngoing" [readonly]="readonly || !isCreateDestination" [(ngModel)]="createEditPolicy.username" size="20" name="username" #username="ngModel">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="destination_password" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_PASSWORD' | translate}}</label>
|
<label for="destination_password" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_PASSWORD' | translate}}</label>
|
||||||
<input type="password" class="col-md-8" id="destination_password" [disabled]="testOngoing || readonly" [(ngModel)]="createEditPolicy.password" size="20" name="password" #password="ngModel">
|
<input type="password" class="col-md-8" id="destination_password" [disabled]="testOngoing" [readonly]="readonly || !isCreateDestination" [(ngModel)]="createEditPolicy.password" size="20" name="password" #password="ngModel">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="spin" class="col-md-4"></label>
|
<label for="spin" class="col-md-4"></label>
|
||||||
@ -77,6 +77,6 @@
|
|||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-outline" (click)="testConnection()" [disabled]="testOngoing">{{'REPLICATION.TEST_CONNECTION' | translate}}</button>
|
<button type="button" class="btn btn-outline" (click)="testConnection()" [disabled]="testOngoing">{{'REPLICATION.TEST_CONNECTION' | translate}}</button>
|
||||||
<button type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL' | translate }}</button>
|
<button type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL' | translate }}</button>
|
||||||
<button type="submit" class="btn btn-primary" [disabled]="!policyForm.form.valid" (click)="onSubmit()">{{'BUTTON.OK' | translate}}</button>
|
<button type="submit" class="btn btn-primary" [disabled]="!policyForm.form.valid || testOngoing || readonly" (click)="onSubmit()">{{'BUTTON.OK' | translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
</clr-modal>
|
</clr-modal>
|
@ -17,7 +17,8 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'create-edit-policy',
|
selector: 'create-edit-policy',
|
||||||
templateUrl: 'create-edit-policy.component.html'
|
templateUrl: 'create-edit-policy.component.html',
|
||||||
|
styleUrls: [ 'create-edit-policy.component.css' ]
|
||||||
})
|
})
|
||||||
export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
||||||
|
|
||||||
@ -195,6 +196,8 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
if(this.messageHandlerService.isAppLevel(error)) {
|
if(this.messageHandlerService.isAppLevel(error)) {
|
||||||
this.messageHandlerService.handleError(error);
|
this.messageHandlerService.handleError(error);
|
||||||
this.createEditPolicyOpened = false;
|
this.createEditPolicyOpened = false;
|
||||||
|
} else if (error.status === 409) {
|
||||||
|
this.inlineAlert.showInlineError('REPLICATION.POLICY_ALREADY_EXISTS');
|
||||||
} else {
|
} else {
|
||||||
this.inlineAlert.showInlineError(error);
|
this.inlineAlert.showInlineError(error);
|
||||||
}
|
}
|
||||||
@ -217,6 +220,8 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
if(this.messageHandlerService.isAppLevel(error)) {
|
if(this.messageHandlerService.isAppLevel(error)) {
|
||||||
this.messageHandlerService.handleError(error);
|
this.messageHandlerService.handleError(error);
|
||||||
this.createEditPolicyOpened = false;
|
this.createEditPolicyOpened = false;
|
||||||
|
} else if (error.status === 409) {
|
||||||
|
this.inlineAlert.showInlineError('REPLICATION.POLICY_ALREADY_EXISTS');
|
||||||
} else {
|
} else {
|
||||||
this.inlineAlert.showInlineError(error);
|
this.inlineAlert.showInlineError(error);
|
||||||
}
|
}
|
||||||
@ -240,6 +245,8 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
if(this.messageHandlerService.isAppLevel(error)) {
|
if(this.messageHandlerService.isAppLevel(error)) {
|
||||||
this.messageHandlerService.handleError(error);
|
this.messageHandlerService.handleError(error);
|
||||||
this.createEditPolicyOpened = false;
|
this.createEditPolicyOpened = false;
|
||||||
|
} else if (error.status === 409) {
|
||||||
|
this.inlineAlert.showInlineError('REPLICATION.POLICY_ALREADY_EXISTS');
|
||||||
} else {
|
} else {
|
||||||
this.inlineAlert.showInlineError(error);
|
this.inlineAlert.showInlineError(error);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,13 @@ export class ListPolicyComponent implements OnDestroy {
|
|||||||
console.log('Successful delete policy with ID:' + message.data);
|
console.log('Successful delete policy with ID:' + message.data);
|
||||||
this.reload.emit(true);
|
this.reload.emit(true);
|
||||||
},
|
},
|
||||||
error => this.messageHandlerService.handleError(error)
|
error => {
|
||||||
|
if(error && error.status === 412) {
|
||||||
|
this.messageHandlerService.handleError('REPLICATION.FAILED_TO_DELETE_POLICY_ENABLED');
|
||||||
|
} else {
|
||||||
|
this.messageHandlerService.handleError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,9 @@
|
|||||||
"REPLICATION_RULE": "Replication Rule",
|
"REPLICATION_RULE": "Replication Rule",
|
||||||
"CREATED_SUCCESS": "Created project successfully.",
|
"CREATED_SUCCESS": "Created project successfully.",
|
||||||
"DELETED_SUCCESS": "Deleted project successfully.",
|
"DELETED_SUCCESS": "Deleted project successfully.",
|
||||||
"TOGGLED_SUCCESS": "Toggled project successfully."
|
"TOGGLED_SUCCESS": "Toggled project successfully.",
|
||||||
|
"FAILED_TO_DELETE_PROJECT": "Project contains repositories or replication rules can not be deleted.",
|
||||||
|
"INLINE_HELP_PUBLIC": "When a project is set to public, anyone has read permission to the repositories under this project, and the user does not need to run \"docker login\" before pulling images under this project."
|
||||||
},
|
},
|
||||||
"PROJECT_DETAIL": {
|
"PROJECT_DETAIL": {
|
||||||
"REPOSITORIES": "Repositories",
|
"REPOSITORIES": "Repositories",
|
||||||
@ -204,7 +206,7 @@
|
|||||||
"FILTER_JOBS_PLACEHOLDER": "Filter Jobs",
|
"FILTER_JOBS_PLACEHOLDER": "Filter Jobs",
|
||||||
"DELETION_TITLE": "Confirm Rule Deletion",
|
"DELETION_TITLE": "Confirm Rule Deletion",
|
||||||
"DELETION_SUMMARY": "Do you want to delete rule {{param}}?",
|
"DELETION_SUMMARY": "Do you want to delete rule {{param}}?",
|
||||||
"FILTER_TARGETS_PLACEHOLDER": "Filter Targets",
|
"FILTER_TARGETS_PLACEHOLDER": "Filter Endpoints",
|
||||||
"DELETION_TITLE_TARGET": "Confirm Endpoint Deletion",
|
"DELETION_TITLE_TARGET": "Confirm Endpoint Deletion",
|
||||||
"DELETION_SUMMARY_TARGET": "Do you want to delete the endpoint {{param}}?",
|
"DELETION_SUMMARY_TARGET": "Do you want to delete the endpoint {{param}}?",
|
||||||
"ADD_POLICY": "New Replication Rule",
|
"ADD_POLICY": "New Replication Rule",
|
||||||
@ -250,15 +252,18 @@
|
|||||||
"LOGS": "Logs",
|
"LOGS": "Logs",
|
||||||
"ITEMS": "item(s)",
|
"ITEMS": "item(s)",
|
||||||
"TOGGLE_ENABLE_TITLE": "Enable Rule",
|
"TOGGLE_ENABLE_TITLE": "Enable Rule",
|
||||||
"CONFIRM_TOGGLE_ENABLE_POLICY": "After enabling the replication rule, all repositories under the project will be replicated to the destination registry. Please confirm to continue.",
|
"CONFIRM_TOGGLE_ENABLE_POLICY": "After enabling the replication rule, all repositories under the project \nwill be replicated to the destination registry. \nPlease confirm to continue.",
|
||||||
"TOGGLE_DISABLE_TITLE": "Disable Rule",
|
"TOGGLE_DISABLE_TITLE": "Disable Rule",
|
||||||
"CONFIRM_TOGGLE_DISABLE_POLICY": "After disabling the rule, all unfinished replication jobs of this rule will be stopped and canceled. Please confirm to continue.",
|
"CONFIRM_TOGGLE_DISABLE_POLICY": "After disabling the rule, all unfinished replication jobs of this rule \nwill be stopped and canceled. \nPlease confirm to continue.",
|
||||||
"CREATED_SUCCESS": "Created replication rule successfully.",
|
"CREATED_SUCCESS": "Created replication rule successfully.",
|
||||||
"UPDATED_SUCCESS": "Updated replication rule successfully.",
|
"UPDATED_SUCCESS": "Updated replication rule successfully.",
|
||||||
"DELETED_SUCCESS": "Deleted replication rule successfully.",
|
"DELETED_SUCCESS": "Deleted replication rule successfully.",
|
||||||
"DELETED_FAILED": "Deleted replication rule failed.",
|
"DELETED_FAILED": "Deleted replication rule failed.",
|
||||||
"TOGGLED_SUCCESS": "Toggled replication rule status successfully.",
|
"TOGGLED_SUCCESS": "Toggled replication rule status successfully.",
|
||||||
"CANNOT_EDIT": "Replication rule cannot be changed while it is enabled."
|
"CANNOT_EDIT": "Replication rule cannot be changed while it is enabled.",
|
||||||
|
"POLICY_ALREADY_EXISTS": "Replication rule already exists.",
|
||||||
|
"FAILED_TO_DELETE_POLICY_ENABLED": "Cannot delete rule: rule has unfinished job(s) or rule is enabled.",
|
||||||
|
"FOUND_ERROR_IN_JOBS": "Found errors in the replication job(s), please check."
|
||||||
},
|
},
|
||||||
"DESTINATION": {
|
"DESTINATION": {
|
||||||
"NEW_ENDPOINT": "New Endpoint",
|
"NEW_ENDPOINT": "New Endpoint",
|
||||||
|
@ -128,7 +128,7 @@
|
|||||||
"PUBLIC": "公开",
|
"PUBLIC": "公开",
|
||||||
"PRIVATE": "私有",
|
"PRIVATE": "私有",
|
||||||
"MAKE": "设为",
|
"MAKE": "设为",
|
||||||
"NEW_POLICY": "新建策略",
|
"NEW_POLICY": "新建规则",
|
||||||
"DELETE": "删除",
|
"DELETE": "删除",
|
||||||
"MY_PROJECTS": "所有项目",
|
"MY_PROJECTS": "所有项目",
|
||||||
"PUBLIC_PROJECTS": "公开项目",
|
"PUBLIC_PROJECTS": "公开项目",
|
||||||
@ -143,10 +143,12 @@
|
|||||||
"DELETION_TITLE": "删除项目确认",
|
"DELETION_TITLE": "删除项目确认",
|
||||||
"DELETION_SUMMARY": "你确认删除项目 {{param}}?",
|
"DELETION_SUMMARY": "你确认删除项目 {{param}}?",
|
||||||
"FILTER_PLACEHOLDER": "过滤项目",
|
"FILTER_PLACEHOLDER": "过滤项目",
|
||||||
"REPLICATION_RULE": "复制策略",
|
"REPLICATION_RULE": "复制规则",
|
||||||
"CREATED_SUCCESS": "创建项目成功。",
|
"CREATED_SUCCESS": "创建项目成功。",
|
||||||
"DELETED_SUCCESS": "删除项目成功。",
|
"DELETED_SUCCESS": "删除项目成功。",
|
||||||
"TOGGLED_SUCCESS": "切换状态成功。"
|
"TOGGLED_SUCCESS": "切换状态成功。",
|
||||||
|
"FAILED_TO_DELETE_PROJECT": "项目包含镜像仓库或复制规则,无法删除。",
|
||||||
|
"INLINE_HELP_PUBLIC": "当项目设为公开后,任何人都有此项目下镜像的读权限。命令行用户不需要“docker login”就可以拉取此项目下的镜像。"
|
||||||
},
|
},
|
||||||
"PROJECT_DETAIL": {
|
"PROJECT_DETAIL": {
|
||||||
"REPOSITORIES": "镜像仓库",
|
"REPOSITORIES": "镜像仓库",
|
||||||
@ -197,19 +199,19 @@
|
|||||||
"FILTER_PLACEHOLDER": "过滤日志"
|
"FILTER_PLACEHOLDER": "过滤日志"
|
||||||
},
|
},
|
||||||
"REPLICATION": {
|
"REPLICATION": {
|
||||||
"REPLICATION_RULE": "复制策略",
|
"REPLICATION_RULE": "复制规则",
|
||||||
"NEW_REPLICATION_RULE": "新建策略",
|
"NEW_REPLICATION_RULE": "新建规则",
|
||||||
"ENDPOINTS": "目标",
|
"ENDPOINTS": "目标",
|
||||||
"FILTER_POLICIES_PLACEHOLDER": "过滤策略",
|
"FILTER_POLICIES_PLACEHOLDER": "过滤规则",
|
||||||
"FILTER_JOBS_PLACEHOLDER": "过滤任务",
|
"FILTER_JOBS_PLACEHOLDER": "过滤任务",
|
||||||
"DELETION_TITLE": "删除策略确认",
|
"DELETION_TITLE": "删除规则确认",
|
||||||
"DELETION_SUMMARY": "确认删除策略 {{param}}?",
|
"DELETION_SUMMARY": "确认删除规则 {{param}}?",
|
||||||
"FILTER_TARGETS_PLACEHOLDER": "过滤目标",
|
"FILTER_TARGETS_PLACEHOLDER": "过滤目标",
|
||||||
"DELETION_TITLE_TARGET": "删除目标确认",
|
"DELETION_TITLE_TARGET": "删除目标确认",
|
||||||
"DELETION_SUMMARY_TARGET": "确认删除目标 {{param}}?",
|
"DELETION_SUMMARY_TARGET": "确认删除目标 {{param}}?",
|
||||||
"ADD_POLICY": "新建策略",
|
"ADD_POLICY": "新建规则",
|
||||||
"EDIT_POLICY": "修改策略",
|
"EDIT_POLICY": "修改规则",
|
||||||
"DELETE_POLICY": "删除策略",
|
"DELETE_POLICY": "删除规则",
|
||||||
"TEST_CONNECTION": "测试连接",
|
"TEST_CONNECTION": "测试连接",
|
||||||
"TESTING_CONNECTION": "正在测试连接...",
|
"TESTING_CONNECTION": "正在测试连接...",
|
||||||
"TEST_CONNECTION_SUCCESS": "测试连接成功。",
|
"TEST_CONNECTION_SUCCESS": "测试连接成功。",
|
||||||
@ -249,16 +251,19 @@
|
|||||||
"END_TIME": "结束时间",
|
"END_TIME": "结束时间",
|
||||||
"LOGS": "日志",
|
"LOGS": "日志",
|
||||||
"ITEMS": "条记录",
|
"ITEMS": "条记录",
|
||||||
"TOGGLE_ENABLE_TITLE": "启用策略",
|
"TOGGLE_ENABLE_TITLE": "启用规则",
|
||||||
"CONFIRM_TOGGLE_ENABLE_POLICY": "启用策略后,该项目下的所有镜像仓库将复制到目标实例。请确认继续。",
|
"CONFIRM_TOGGLE_ENABLE_POLICY": "启用规则后,该项目下的所有镜像仓库将复制到目标实例。请确认继续。",
|
||||||
"TOGGLE_DISABLE_TITLE": "停用策略",
|
"TOGGLE_DISABLE_TITLE": "停用规则",
|
||||||
"CONFIRM_TOGGLE_DISABLE_POLICY": "停用策略后,所有未完成的复制任务将被终止和取消。请确认继续。",
|
"CONFIRM_TOGGLE_DISABLE_POLICY": "停用规则后,所有未完成的复制任务将被终止和取消。请确认继续。",
|
||||||
"CREATED_SUCCESS": "创建复制策略成功。",
|
"CREATED_SUCCESS": "创建复制规则成功。",
|
||||||
"UPDATED_SUCCESS": "更新复制策略成功。",
|
"UPDATED_SUCCESS": "更新复制规则成功。",
|
||||||
"DELETED_SUCCESS": "删除复制策略成功。",
|
"DELETED_SUCCESS": "删除复制规则成功。",
|
||||||
"DELETED_FAILED": "删除复制策略失败。",
|
"DELETED_FAILED": "删除复制规则失败。",
|
||||||
"TOGGLED_SUCCESS": "切换复制策略状态成功。",
|
"TOGGLED_SUCCESS": "切换复制规则状态成功。",
|
||||||
"CANNOT_EDIT": "当复制规则启用时无法修改。"
|
"CANNOT_EDIT": "当复制规则启用时无法修改。",
|
||||||
|
"POLICY_ALREADY_EXISTS": "规则已存在。",
|
||||||
|
"FAILED_TO_DELETE_POLICY_ENABLED": "删除复制规则失败: 仍有未完成的任务或规则未停用。",
|
||||||
|
"FOUND_ERROR_IN_JOBS": "复制任务中包含错误,请检查。"
|
||||||
},
|
},
|
||||||
"DESTINATION": {
|
"DESTINATION": {
|
||||||
"NEW_ENDPOINT": "新建目标",
|
"NEW_ENDPOINT": "新建目标",
|
||||||
|
Loading…
Reference in New Issue
Block a user