mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-19 15:17:43 +01:00
Merge pull request #7555 from pureshine/loading-filter
Add loading if the fileter is not loaded when creating the replication rule
This commit is contained in:
commit
cceb624fc2
@ -46,7 +46,7 @@
|
|||||||
translate }}</label>
|
translate }}</label>
|
||||||
<label class="col-md-8" for="destination_url" aria-haspopup="true" role="tooltip" [class.invalid]="targetEndpoint.errors && (targetEndpoint.dirty || targetEndpoint.touched)"
|
<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">
|
[class.valid]="targetEndpoint.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
||||||
<input type="text" id="destination_url" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.url"
|
<input type="text" id="destination_url" [disabled]="testOngoing || urlDisabled" [readonly]="!editable" [(ngModel)]="target.url"
|
||||||
size="25" name="endpointUrl" #targetEndpoint="ngModel" required placeholder="http(s)://192.168.1.1">
|
size="25" name="endpointUrl" #targetEndpoint="ngModel" required placeholder="http(s)://192.168.1.1">
|
||||||
<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 }}
|
||||||
|
@ -41,6 +41,7 @@ const DOCKERHUB_URL = "https://hub.docker.com";
|
|||||||
export class CreateEditEndpointComponent
|
export class CreateEditEndpointComponent
|
||||||
implements AfterViewChecked, OnDestroy, OnInit {
|
implements AfterViewChecked, OnDestroy, OnInit {
|
||||||
modalTitle: string;
|
modalTitle: string;
|
||||||
|
urlDisabled: boolean = false;
|
||||||
editDisabled: boolean = false;
|
editDisabled: boolean = false;
|
||||||
controlEnabled: boolean = false;
|
controlEnabled: boolean = false;
|
||||||
createEditDestinationOpened: boolean;
|
createEditDestinationOpened: boolean;
|
||||||
@ -184,6 +185,7 @@ export class CreateEditEndpointComponent
|
|||||||
this.endpointService.getEndpoint(targetId).subscribe(
|
this.endpointService.getEndpoint(targetId).subscribe(
|
||||||
target => {
|
target => {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
|
this.urlDisabled = this.target.type === 'dockerHub' ? true : false;
|
||||||
// Keep data cache
|
// Keep data cache
|
||||||
this.initVal = clone(target);
|
this.initVal = clone(target);
|
||||||
this.initVal.credential.access_secret = FAKE_PASSWORD;
|
this.initVal.credential.access_secret = FAKE_PASSWORD;
|
||||||
@ -197,6 +199,7 @@ export class CreateEditEndpointComponent
|
|||||||
error => this.errorHandler.error(error)
|
error => this.errorHandler.error(error)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
this.urlDisabled = false;
|
||||||
this.endpointId = "";
|
this.endpointId = "";
|
||||||
this.translateService
|
this.translateService
|
||||||
.get("DESTINATION.TITLE_ADD")
|
.get("DESTINATION.TITLE_ADD")
|
||||||
@ -210,8 +213,10 @@ export class CreateEditEndpointComponent
|
|||||||
adapterChange($event): void {
|
adapterChange($event): void {
|
||||||
let selectValue = this.targetForm.controls.adapter.value;
|
let selectValue = this.targetForm.controls.adapter.value;
|
||||||
if (selectValue === 'dockerHub') {
|
if (selectValue === 'dockerHub') {
|
||||||
|
this.urlDisabled = true;
|
||||||
this.targetForm.controls.endpointUrl.setValue(DOCKERHUB_URL);
|
this.targetForm.controls.endpointUrl.setValue(DOCKERHUB_URL);
|
||||||
} else {
|
} else {
|
||||||
|
this.urlDisabled = false;
|
||||||
this.targetForm.controls.endpointUrl.setValue("");
|
this.targetForm.controls.endpointUrl.setValue("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
<!--images/Filter-->
|
<!--images/Filter-->
|
||||||
<div class="form-group form-group-override">
|
<div class="form-group form-group-override">
|
||||||
<label class="form-group-label-override">{{'REPLICATION.SOURCE_RESOURCE_FILTER' | translate}}</label>
|
<label class="form-group-label-override">{{'REPLICATION.SOURCE_RESOURCE_FILTER' | translate}}</label>
|
||||||
|
<span class="spinner spinner-inline spinner-position" [hidden]="onGoing === false"></span>
|
||||||
<div formArrayName="filters">
|
<div formArrayName="filters">
|
||||||
<div class="filterSelect" *ngFor="let filter of filters.controls; let i=index">
|
<div class="filterSelect" *ngFor="let filter of filters.controls; let i=index">
|
||||||
<div [formGroupName]="i">
|
<div [formGroupName]="i">
|
||||||
@ -69,12 +70,15 @@
|
|||||||
<input type="text" #filterValue required size="14" formControlName="value" id="{{'filter_'+ supportedFilters[i]?.type}}">
|
<input type="text" #filterValue required size="14" formControlName="value" id="{{'filter_'+ supportedFilters[i]?.type}}">
|
||||||
<span class="tooltip-content">{{'TOOLTIP.EMPTY' | translate}}</span>
|
<span class="tooltip-content">{{'TOOLTIP.EMPTY' | translate}}</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="select inline-block" *ngIf="supportedFilters[i]?.style==='radio'">
|
<div class="select resource-box" *ngIf="supportedFilters[i]?.style==='radio' && supportedFilters[i]?.values.length > 1">
|
||||||
<select formControlName="value" #selectedValue id="{{'select_'+ supportedFilters[i]?.type}}" name="{{supportedFilters[i]?.type}}">
|
<select formControlName="value" #selectedValue id="{{'select_'+ supportedFilters[i]?.type}}" name="{{supportedFilters[i]?.type}}">
|
||||||
<option value="">{{'REPLICATION.BOTH' | translate}}</option>
|
<option value="">{{'REPLICATION.BOTH' | translate}}</option>
|
||||||
<option *ngFor="let value of supportedFilters[i]?.values;" value="{{value}}">{{value}}</option>
|
<option *ngFor="let value of supportedFilters[i]?.values;" value="{{value}}">{{value}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="resource-box" *ngIf="supportedFilters[i]?.style==='radio' && supportedFilters[i]?.values.length <= 1">
|
||||||
|
<span>{{supportedFilters[i]?.values}}</span>
|
||||||
|
</div>
|
||||||
<clr-tooltip>
|
<clr-tooltip>
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
.select {
|
|
||||||
width: 190px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select .optionMore {
|
.select .optionMore {
|
||||||
background-color: #bfbaba;
|
background-color: #bfbaba;
|
||||||
height: 1.6em;
|
height: 1.6em;
|
||||||
@ -239,8 +235,9 @@ clr-modal {
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inline-block {
|
.resource-box {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
width: 190px;
|
||||||
}
|
}
|
||||||
.form-cron {
|
.form-cron {
|
||||||
padding-left:3.8rem;
|
padding-left:3.8rem;
|
||||||
@ -256,3 +253,7 @@ clr-modal {
|
|||||||
margin: 3px 0 0 5px;
|
margin: 3px 0 0 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.spinner-position {
|
||||||
|
left: 25%;
|
||||||
|
}
|
@ -56,6 +56,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
createEditRuleOpened: boolean;
|
createEditRuleOpened: boolean;
|
||||||
inProgress = false;
|
inProgress = false;
|
||||||
|
onGoing = false;
|
||||||
inNameChecking = false;
|
inNameChecking = false;
|
||||||
isRuleNameValid = true;
|
isRuleNameValid = true;
|
||||||
nameChecker: Subject<string> = new Subject<string>();
|
nameChecker: Subject<string> = new Subject<string>();
|
||||||
@ -84,12 +85,13 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initRegistryInfo(id: number): void {
|
initRegistryInfo(id: number): void {
|
||||||
|
this.onGoing = true;
|
||||||
this.repService.getRegistryInfo(id).subscribe(adapter => {
|
this.repService.getRegistryInfo(id).subscribe(adapter => {
|
||||||
this.supportedFilters = adapter.supported_resource_filters;
|
this.supportedFilters = adapter.supported_resource_filters;
|
||||||
this.supportedFilters.forEach(element => {
|
this.supportedFilters.forEach(element => {
|
||||||
this.filters.push(this.initFilter(element.type));
|
this.filters.push(this.initFilter(element.type));
|
||||||
});
|
});
|
||||||
|
this.onGoing = false;
|
||||||
this.supportedTriggers = adapter.supported_triggers;
|
this.supportedTriggers = adapter.supported_triggers;
|
||||||
this.ruleForm.get("trigger").get("type").setValue(this.supportedTriggers[0]);
|
this.ruleForm.get("trigger").get("type").setValue(this.supportedTriggers[0]);
|
||||||
});
|
});
|
||||||
@ -367,10 +369,12 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
this.inlineAlert.showInlineError(error);
|
this.inlineAlert.showInlineError(error);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
this.onGoing = true;
|
||||||
let registryObs = this.repService.getRegistryInfo(0);
|
let registryObs = this.repService.getRegistryInfo(0);
|
||||||
registryObs.subscribe(adapter => {
|
registryObs.subscribe(adapter => {
|
||||||
this.setFilterAndTrigger(adapter);
|
this.setFilterAndTrigger(adapter);
|
||||||
this.copyUpdateForm = clone(this.ruleForm.value);
|
this.copyUpdateForm = clone(this.ruleForm.value);
|
||||||
|
this.onGoing = false;
|
||||||
});
|
});
|
||||||
this.headerTitle = "REPLICATION.ADD_POLICY";
|
this.headerTitle = "REPLICATION.ADD_POLICY";
|
||||||
this.copyUpdateForm = clone(this.ruleForm.value);
|
this.copyUpdateForm = clone(this.ruleForm.value);
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.execution-select {
|
.execution-select {
|
||||||
padding-right: 18px;
|
padding-right: 50px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
@ -327,7 +327,13 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
catchError(error => {
|
catchError(error => {
|
||||||
if (error && error._body) {
|
if (error && error.status === 504) {
|
||||||
|
return this.translateService.get("BATCH.TIME_OUT").pipe(
|
||||||
|
map(res => {
|
||||||
|
operateChanges(operMessage, OperationState.failure, res);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else if (error && error._body) {
|
||||||
const message = JSON.parse(error._body).message;
|
const message = JSON.parse(error._body).message;
|
||||||
operateChanges(operMessage, OperationState.failure, message);
|
operateChanges(operMessage, OperationState.failure, message);
|
||||||
return observableThrowError(message);
|
return observableThrowError(message);
|
||||||
|
@ -52,7 +52,8 @@
|
|||||||
"REPLICATE_SUCCESS": "Started successfully",
|
"REPLICATE_SUCCESS": "Started successfully",
|
||||||
"REPLICATE_FAILURE": "Started failed",
|
"REPLICATE_FAILURE": "Started failed",
|
||||||
"STOP_SUCCESS": "Stop successfully",
|
"STOP_SUCCESS": "Stop successfully",
|
||||||
"STOP_FAILURE": "Stop execution failed"
|
"STOP_FAILURE": "Stop execution failed",
|
||||||
|
"TIME_OUT": "Gateway time-out"
|
||||||
},
|
},
|
||||||
"TOOLTIP": {
|
"TOOLTIP": {
|
||||||
"NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
|
"NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
|
||||||
|
@ -52,7 +52,8 @@
|
|||||||
"REPLICATE_SUCCESS": "Started successfully",
|
"REPLICATE_SUCCESS": "Started successfully",
|
||||||
"REPLICATE_FAILURE": "Started failed",
|
"REPLICATE_FAILURE": "Started failed",
|
||||||
"STOP_SUCCESS": "Stop successfully",
|
"STOP_SUCCESS": "Stop successfully",
|
||||||
"STOP_FAILURE": "Stop execution failed"
|
"STOP_FAILURE": "Stop execution failed",
|
||||||
|
"TIME_OUT": "Gateway time-out"
|
||||||
},
|
},
|
||||||
"TOOLTIP": {
|
"TOOLTIP": {
|
||||||
"NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
|
"NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
|
||||||
|
@ -49,7 +49,8 @@
|
|||||||
"REPLICATE_SUCCESS": "Started successfully",
|
"REPLICATE_SUCCESS": "Started successfully",
|
||||||
"REPLICATE_FAILURE": "Started failed",
|
"REPLICATE_FAILURE": "Started failed",
|
||||||
"STOP_SUCCESS": "Stop successfully",
|
"STOP_SUCCESS": "Stop successfully",
|
||||||
"STOP_FAILURE": "Stop execution failed"
|
"STOP_FAILURE": "Stop execution failed",
|
||||||
|
"TIME_OUT": "Gateway time-out"
|
||||||
},
|
},
|
||||||
"TOOLTIP": {
|
"TOOLTIP": {
|
||||||
"NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
|
"NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
|
||||||
|
@ -52,7 +52,8 @@
|
|||||||
"REPLICATE_SUCCESS": "Iniciado com sucesso",
|
"REPLICATE_SUCCESS": "Iniciado com sucesso",
|
||||||
"REPLICATE_FAILURE": "Falha ao iniciar",
|
"REPLICATE_FAILURE": "Falha ao iniciar",
|
||||||
"STOP_SUCCESS": "Stop successfully",
|
"STOP_SUCCESS": "Stop successfully",
|
||||||
"STOP_FAILURE": "Stop execution failed"
|
"STOP_FAILURE": "Stop execution failed",
|
||||||
|
"TIME_OUT": "Gateway time-out"
|
||||||
},
|
},
|
||||||
"TOOLTIP": {
|
"TOOLTIP": {
|
||||||
"NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
|
"NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
|
||||||
|
@ -52,7 +52,8 @@
|
|||||||
"REPLICATE_SUCCESS": "开始成功",
|
"REPLICATE_SUCCESS": "开始成功",
|
||||||
"REPLICATE_FAILURE": "开始失败",
|
"REPLICATE_FAILURE": "开始失败",
|
||||||
"STOP_SUCCESS": "停止任务成功",
|
"STOP_SUCCESS": "停止任务成功",
|
||||||
"STOP_FAILURE": "停止任务失败"
|
"STOP_FAILURE": "停止任务失败",
|
||||||
|
"TIME_OUT": "网关超时"
|
||||||
},
|
},
|
||||||
"TOOLTIP": {
|
"TOOLTIP": {
|
||||||
"NAME_FILTER": "过滤资源的名字。不填或者“”匹配所有资源;“library/”只匹配“library”下的资源。更多的匹配模式请参考用户手册。",
|
"NAME_FILTER": "过滤资源的名字。不填或者“”匹配所有资源;“library/”只匹配“library”下的资源。更多的匹配模式请参考用户手册。",
|
||||||
|
Loading…
Reference in New Issue
Block a user