mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-14 10:51:25 +01:00
Merge master and modify package version
This commit is contained in:
parent
31c3063783
commit
bdd0664134
@ -1,38 +1,28 @@
|
||||
export const LIST_REPLICATION_RULE_TEMPLATE: string = `
|
||||
<div style="margin-top: -24px;">
|
||||
<div>
|
||||
<clr-datagrid [clrDgLoading]="loading" [(clrDgSingleSelected)]="selectedRow" (clrDgSingleSelectedChange)="selectedChange()">
|
||||
<clr-dg-action-bar>
|
||||
<div class="btn-group">
|
||||
<button type="button" *ngIf="creationAvailable" class="btn btn-sm btn-secondary" (click)="openModal()">{{'REPLICATION.NEW_REPLICATION_RULE' | translate}}</button>
|
||||
<button type="button" *ngIf="!creationAvailable" class="btn btn-sm btn-secondary" [disabled]="!selectedRow" (click)="editRule(selectedRow)">{{'REPLICATION.EDIT_POLICY' | translate}}</button>
|
||||
<button type="button" *ngIf="!creationAvailable" class="btn btn-sm btn-secondary" [disabled]="!selectedRow" (click)="deleteRule(selectedRow)">{{'REPLICATION.DELETE_POLICY' | translate}}</button>
|
||||
<button type="button" *ngIf="creationAvailable" class="btn btn-sm btn-secondary" (click)="openModal()">{{'REPLICATION.NEW_REPLICATION_RULE' | translate}}</button>
|
||||
<button type="button" *ngIf="creationAvailable" class="btn btn-sm btn-secondary" [disabled]="!selectedRow" (click)="editRule(selectedRow)">{{'REPLICATION.EDIT_POLICY' | translate}}</button>
|
||||
<button type="button" *ngIf="creationAvailable" class="btn btn-sm btn-secondary" [disabled]="!selectedRow" (click)="deleteRule(selectedRow)">{{'REPLICATION.DELETE_POLICY' | translate}}</button>
|
||||
<button type="button" *ngIf="creationAvailable" class="btn btn-sm btn-secondary" [disabled]="!selectedRow" (click)="replicateRule(selectedRow)">{{'REPLICATION.REPLICATE' | translate}}</button>
|
||||
</div>
|
||||
</clr-dg-action-bar>
|
||||
<clr-dg-column [clrDgField]="'name'">{{'REPLICATION.NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'projects'" *ngIf="!projectScope">{{'REPLICATION.PROJECT' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'description'">{{'REPLICATION.DESCRIPTION' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'targets'">{{'REPLICATION.DESTINATION_NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="startTimeComparator">{{'REPLICATION.LAST_START_TIME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="enabledComparator">{{'REPLICATION.ACTIVATION' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'trigger'">{{'REPLICATION.SCHEDULE' | translate}}</clr-dg-column>
|
||||
<clr-dg-placeholder>{{'REPLICATION.PLACEHOLDER' | translate }}</clr-dg-placeholder>
|
||||
<clr-dg-row *clrDgItems="let p of changedRules" [clrDgItem]="p" (click)="selectRule(p)" [style.backgroundColor]="(projectScope && withReplicationJob && selectedId === p.id) ? '#eee' : ''">
|
||||
<clr-dg-cell>
|
||||
<ng-template [ngIf]="!projectScope">
|
||||
<a href="javascript:void(0)" (click)="redirectTo(p)">{{p.name}}</a>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="projectScope">
|
||||
{{p.name}}
|
||||
</ng-template>
|
||||
<clr-dg-cell>{{p.name}}</clr-dg-cell>
|
||||
<clr-dg-cell *ngIf="!projectScope">
|
||||
<a href="javascript:void(0)" (click)="redirectTo(p)">{{p.projects?.length>0 ? p.projects[0].name : ''}}</a>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>{{p.description ? p.description : '-'}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{p.targets?.length>0 ? p.targets[0].name : ''}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
<ng-template [ngIf]="p.start_time === nullTime">-</ng-template>
|
||||
<ng-template [ngIf]="p.start_time !== nullTime">{{p.start_time | date: 'short'}}</ng-template>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
{{ (p.enabled === 1 ? 'REPLICATION.ENABLED' : 'REPLICATION.DISABLED') | translate}}
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>{{p.trigger ? p.trigger.kind : ''}}</clr-dg-cell>
|
||||
</clr-dg-row>
|
||||
<clr-dg-footer>
|
||||
<span *ngIf="pagination.totalItems">{{pagination.firstItem + 1}} - {{pagination.lastItem +1 }} {{'REPLICATION.OF' | translate}} </span>{{pagination.totalItems }} {{'REPLICATION.ITEMS' | translate}}
|
||||
|
@ -67,6 +67,7 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
||||
@Output() toggleOne = new EventEmitter<ReplicationRule>();
|
||||
@Output() redirect = new EventEmitter<ReplicationRule>();
|
||||
@Output() openNewRule = new EventEmitter<any>();
|
||||
@Output() replicateManual = new EventEmitter<ReplicationRule>();
|
||||
|
||||
projectScope: boolean = false;
|
||||
|
||||
@ -96,7 +97,7 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
public get creationAvailable(): boolean {
|
||||
return !this.readonly && this.projectId ? true : false;
|
||||
return !this.readonly && !this.projectId ? true : false;
|
||||
}
|
||||
|
||||
|
||||
@ -221,6 +222,10 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
||||
this.editOne.emit(rules);
|
||||
}
|
||||
|
||||
replicateRule(rule: ReplicationRule) {
|
||||
this.replicateManual.emit(rule);
|
||||
}
|
||||
|
||||
toggleRule(rule: ReplicationRule) {
|
||||
let toggleConfirmMessage: ConfirmationMessage = new ConfirmationMessage(
|
||||
rule.enabled === 1 ? 'REPLICATION.TOGGLE_DISABLE_TITLE' : 'REPLICATION.TOGGLE_ENABLE_TITLE',
|
||||
|
@ -21,4 +21,11 @@ export const REPLICATION_STYLE: string = `
|
||||
.option-right-down {
|
||||
padding-right: 16px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
.rightPos{
|
||||
position: absolute;
|
||||
right: 35px;
|
||||
margin-top: 5px;
|
||||
z-index: 100;
|
||||
height: 32px;
|
||||
}`;
|
@ -1,13 +1,8 @@
|
||||
export const REPLICATION_TEMPLATE: string = `
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="row flex-items-xs-between" style="height:32px; float:right">
|
||||
<div>
|
||||
<div class="row flex-items-xs-between rightPos">
|
||||
<div class="flex-xs-middle option-right">
|
||||
<div class="select" style="float: left; top: 8px;">
|
||||
<select (change)="doFilterRuleStatus($event)">
|
||||
<option *ngFor="let r of ruleStatus" value="{{r.key}}">{{r.description | translate}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<hbr-filter [withDivider]="true" filterPlaceholder='{{"REPLICATION.FILTER_POLICIES_PLACEHOLDER" | translate}}' (filter)="doSearchRules($event)" [currentValue]="search.ruleName"></hbr-filter>
|
||||
<span class="refresh-btn" (click)="refreshRules()">
|
||||
<clr-icon shape="refresh"></clr-icon>
|
||||
@ -16,7 +11,7 @@ export const REPLICATION_TEMPLATE: string = `
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<hbr-list-replication-rule #listReplicationRule [readonly]="readonly" [projectId]="projectId" (selectOne)="selectOneRule($event)" (openNewRule)="openModal()" (editOne)="openEditRule($event)" (reload)="reloadRules($event)" [loading]="loading" [withReplicationJob]="withReplicationJob" (redirect)="customRedirect($event)"></hbr-list-replication-rule>
|
||||
<hbr-list-replication-rule #listReplicationRule [readonly]="readonly" [projectId]="projectId" (replicateManual)=replicateManualRule($event) (selectOne)="selectOneRule($event)" (openNewRule)="openModal()" (editOne)="openEditRule($event)" (reload)="reloadRules($event)" [loading]="loading" [withReplicationJob]="withReplicationJob" (redirect)="customRedirect($event)"></hbr-list-replication-rule>
|
||||
</div>
|
||||
<div *ngIf="withReplicationJob" class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="row flex-items-xs-between" style="height:60px;">
|
||||
@ -72,5 +67,4 @@ export const REPLICATION_TEMPLATE: string = `
|
||||
</clr-datagrid>
|
||||
</div>
|
||||
<job-log-viewer #replicationLogViewer></job-log-viewer>
|
||||
<create-edit-rule [projectId]="projectId" (reload)="reloadRules($event)"></create-edit-rule>
|
||||
</div>`;
|
@ -148,7 +148,6 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
||||
this.currentRuleStatus = this.ruleStatus[0];
|
||||
this.currentJobStatus = this.jobStatus[0];
|
||||
this.currentJobSearchOption = 0;
|
||||
console.log('readonly', this.readonly);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@ -265,6 +264,14 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
replicateManualRule(rule: ReplicationRule): void {
|
||||
toPromise<any>(this.replicationService.replicateRule(rule.id))
|
||||
.then(response => {
|
||||
this.refreshJobs();
|
||||
})
|
||||
.catch(error => this.errorHandler.error(error));
|
||||
}
|
||||
|
||||
customRedirect(rule: ReplicationRule) {
|
||||
this.redirect.emit(rule);
|
||||
}
|
||||
@ -274,14 +281,6 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
||||
this.listReplicationRule.retrieveRules(ruleName);
|
||||
}
|
||||
|
||||
/*doFilterRuleStatus($event: any) {
|
||||
if ($event && $event.target && $event.target["value"]) {
|
||||
let status = $event.target["value"];
|
||||
this.currentRuleStatus = this.ruleStatus.find((r: any) => r.key === status);
|
||||
this.listReplicationRule.filterRuleStatus(this.currentRuleStatus.key);
|
||||
}
|
||||
}*/
|
||||
|
||||
doFilterJobStatus($event: any) {
|
||||
if ($event && $event.target && $event.target["value"]) {
|
||||
let status = $event.target["value"];
|
||||
|
@ -226,8 +226,8 @@ export class ReplicationDefaultService extends ReplicationService {
|
||||
return Promise.reject("Bad argument");
|
||||
}
|
||||
|
||||
let url: string = `${this._replicateUrl}/${ruleId}`;
|
||||
return this.http.post(url, HTTP_JSON_OPTIONS).toPromise()
|
||||
let url: string = `${this._replicateUrl}`;
|
||||
return this.http.post(url, {policy_id: ruleId}, HTTP_JSON_OPTIONS).toPromise()
|
||||
.then(response => response)
|
||||
.catch(error => Promise.reject(error));
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
"clarity-icons": "^0.10.17",
|
||||
"clarity-ui": "^0.10.17",
|
||||
"core-js": "^2.4.1",
|
||||
"harbor-ui": "0.6.5",
|
||||
"harbor-ui": "^0.6.0-test-5",
|
||||
"intl": "^1.2.5",
|
||||
"mutationobserver-shim": "^0.3.2",
|
||||
"ngx-cookie": "^1.0.0",
|
||||
|
@ -86,13 +86,13 @@ const harborRoutes: Routes = [
|
||||
canActivate: [SystemAdminGuard],
|
||||
canActivateChild: [SystemAdminGuard],
|
||||
},
|
||||
{
|
||||
path: 'replications/:id/rule',
|
||||
component: ReplicationRuleComponent,
|
||||
canActivate: [SystemAdminGuard],
|
||||
canActivateChild: [SystemAdminGuard],
|
||||
canDeactivate: [LeavingNewRuleRouteDeactivate]
|
||||
},
|
||||
{
|
||||
path: 'replications/:id/rule',
|
||||
component: ReplicationRuleComponent,
|
||||
canActivate: [SystemAdminGuard],
|
||||
canActivateChild: [SystemAdminGuard],
|
||||
canDeactivate: [LeavingNewRuleRouteDeactivate]
|
||||
},
|
||||
{
|
||||
path: 'replications/new-rule',
|
||||
component: ReplicationRuleComponent,
|
||||
|
@ -121,14 +121,6 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro
|
||||
this.inNameChecking = false;
|
||||
});
|
||||
});
|
||||
/*this.confirmSub = this.confirmService.confirmationConfirm$.subscribe(confirmation => {
|
||||
if (confirmation &&
|
||||
confirmation.state === ConfirmationState.CONFIRMED) {
|
||||
if (confirmation.source === ConfirmationTargets.CONFIG) {
|
||||
this.router.navigate(['/harbor/replications']);
|
||||
}
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
@ -180,38 +172,11 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro
|
||||
this.updateFilter(rule.filters);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Force refresh view
|
||||
let hnd = setInterval(() => this.ref.markForCheck(), 100);
|
||||
setTimeout(() => clearInterval(hnd), 2000);
|
||||
}
|
||||
|
||||
/* initFom(): void {
|
||||
this.ruleForm.reset({
|
||||
name: '',
|
||||
description: '',
|
||||
trigger: {kind: this.triggerNames[0], schedule_param: {
|
||||
type: this.scheduleNames[0],
|
||||
weekday: 1,
|
||||
offtime: '08:00'
|
||||
}},
|
||||
replicate_existing_image_now: true,
|
||||
replicate_deletion: false
|
||||
});
|
||||
this.setProject([]);
|
||||
this.setTarget([this.targetList[0]]);
|
||||
this.setFilter([]);
|
||||
|
||||
this.isFilterHide = false;
|
||||
this.filterListData = [];
|
||||
this.isScheduleOpt = false;
|
||||
this.weeklySchedule = false;
|
||||
this.isRuleNameExist = true;
|
||||
this.ruleNameTooltip = 'TOOLTIP.EMPTY';
|
||||
}*/
|
||||
|
||||
|
||||
get projects(): FormArray {
|
||||
return this.ruleForm.get('projects') as FormArray;
|
||||
}
|
||||
@ -277,7 +242,6 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro
|
||||
}
|
||||
|
||||
selectedProject(project: Project): void {
|
||||
console.log('project', project)
|
||||
this.setProject([project]);
|
||||
}
|
||||
|
||||
@ -469,18 +433,6 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro
|
||||
|
||||
onCancel(): void {
|
||||
this.router.navigate(['/harbor/replications']);
|
||||
|
||||
/*if (this.hasFormChange()) {
|
||||
let msg = new ConfirmationMessage(
|
||||
'CONFIG.CONFIRM_TITLE',
|
||||
'CONFIG.CONFIRM_SUMMARY',
|
||||
'',
|
||||
null,
|
||||
ConfirmationTargets.CONFIG
|
||||
);
|
||||
|
||||
this.confirmService.openComfirmDialog(msg);
|
||||
}*/
|
||||
}
|
||||
|
||||
// UTC time
|
||||
|
@ -26,7 +26,7 @@ export class TotalReplicationPageComponent {
|
||||
private activeRoute: ActivatedRoute){}
|
||||
customRedirect(rule: ReplicationRule): void {
|
||||
if (rule) {
|
||||
this.router.navigate(['../projects', rule.projects[0].project_id, "replications"], { relativeTo: this.activeRoute });
|
||||
this.router.navigate(['../projects', rule.projects[0].project_id, 'replications'], { relativeTo: this.activeRoute });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
</ng-template>
|
||||
<ng-template [ngSwitchCase]="2">
|
||||
<button type="button" class="btn btn-outline" (click)="cancel()" [hidden]="isDelete">{{'BUTTON.CANCEL' | translate}}</button>
|
||||
<button type="button" class="btn btn-danger" (click)="confirm()" [hidden]="isDelete">{{'BUTTON.DELETE' | translate}}</button>
|
||||
<button type="button" class="btn btn-danger" (click)="delete()" [hidden]="isDelete">{{'BUTTON.DELETE' | translate}}</button>
|
||||
<button type="button" class="btn btn-primary" (click)="cancel()" [disabled]="!batchOverStatus" [hidden]="!isDelete">{{'BUTTON.CLOSE' | translate}}</button>
|
||||
</ng-template>
|
||||
<ng-template [ngSwitchCase]="3">
|
||||
|
@ -112,7 +112,7 @@ export class ConfirmationDialogComponent implements OnDestroy {
|
||||
this.close();
|
||||
}
|
||||
|
||||
confirm(): void {
|
||||
delete(): void {
|
||||
if(!this.message){//Inproper condition
|
||||
this.close();
|
||||
return;
|
||||
@ -130,6 +130,21 @@ export class ConfirmationDialogComponent implements OnDestroy {
|
||||
data,
|
||||
target
|
||||
));
|
||||
}
|
||||
|
||||
confirm(): void {
|
||||
if(!this.message){//Inproper condition
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
|
||||
let data: any = this.message.data ? this.message.data : {};
|
||||
let target = this.message.targetId ? this.message.targetId : ConfirmationTargets.EMPTY;
|
||||
this.confirmationService.confirm(new ConfirmationAcknowledgement(
|
||||
ConfirmationState.CONFIRMED,
|
||||
data,
|
||||
target
|
||||
));
|
||||
this.close();
|
||||
}
|
||||
}
|
@ -36,9 +36,7 @@ export class LeavingNewRuleRouteDeactivate implements CanDeactivate<ReplicationR
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot): Promise<boolean> | boolean {
|
||||
//Confirmation before leaving config route
|
||||
console.log('ccc');
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log("ddd", replicateRule.hasFormChange());
|
||||
if (replicateRule && replicateRule.hasFormChange()) {
|
||||
let msg: ConfirmationMessage = new ConfirmationMessage(
|
||||
"CONFIG.LEAVING_CONFIRMATION_TITLE",
|
||||
|
@ -303,7 +303,17 @@
|
||||
"INVALID_DATE": "Invalid date.",
|
||||
"PLACEHOLDER": "We couldn't find any replication rules!",
|
||||
"JOB_PLACEHOLDER": "We couldn't find any replication jobs!",
|
||||
"JOB_LOG_VIEWER": "View Replication Job Log"
|
||||
"JOB_LOG_VIEWER": "View Replication Job Log",
|
||||
"BACKINFO": "Please add project and endpoint first",
|
||||
"FILTER": "Filter",
|
||||
"SCHEDULE": "Schedule",
|
||||
"SETTING":"Setting",
|
||||
"TRIGGER":"Trigger",
|
||||
"TARGETS":"Target",
|
||||
"SOURCE": "Source",
|
||||
"REPLICATE": "Replicate",
|
||||
"DELETE_REMOTE_IMAGES":"Delete remote images when locally deleted",
|
||||
"REPLICATE_IMMEDIATE":"Replicate exiting images immediately"
|
||||
},
|
||||
"DESTINATION": {
|
||||
"NEW_ENDPOINT": "New Endpoint",
|
||||
@ -317,7 +327,7 @@
|
||||
"TEST_CONNECTION": "Test Connection",
|
||||
"TITLE_EDIT": "Edit Endpoint",
|
||||
"TITLE_ADD": "Create Endpoint",
|
||||
"DELETE": "Delete",
|
||||
"DELETE": "Delete Endpoint",
|
||||
"TESTING_CONNECTION": "Testing Connection...",
|
||||
"TEST_CONNECTION_SUCCESS": "Connection tested successfully.",
|
||||
"TEST_CONNECTION_FAILURE": "Failed to ping endpoint.",
|
||||
|
@ -299,7 +299,16 @@
|
||||
"INVALID_DATE": "Fecha invalida.",
|
||||
"PLACEHOLDER": "We couldn't find any replication rules!",
|
||||
"JOB_PLACEHOLDER": "We couldn't find any replication jobs!",
|
||||
"JOB_LOG_VIEWER": "View Replication Job Log"
|
||||
"JOB_LOG_VIEWER": "View Replication Job Log",
|
||||
"BACKINFO": "Please add project and endpoint first",
|
||||
"FILTER": "Filter",
|
||||
"SCHEDULE": "Schedule",
|
||||
"SETTING":"Setting",
|
||||
"TRIGGER":"Trigger",
|
||||
"TARGETS":"Target",
|
||||
"SOURCE": "Source",
|
||||
"DELETE_REMOTE_IMAGES":"Delete remote images when locally deleted",
|
||||
"REPLICATE_IMMEDIATE":"Replicate exiting images immediately"
|
||||
},
|
||||
"DESTINATION": {
|
||||
"NEW_ENDPOINT": "Nuevo Endpoint",
|
||||
@ -313,7 +322,7 @@
|
||||
"TEST_CONNECTION": "Comprobar conexión",
|
||||
"TITLE_EDIT": "Editar Endpoint",
|
||||
"TITLE_ADD": "Crear Endpoint",
|
||||
"DELETE": "Eliminar",
|
||||
"DELETE": "Eliminar Endpoint",
|
||||
"TESTING_CONNECTION": "Comprobar conexión...",
|
||||
"TEST_CONNECTION_SUCCESS": "Conexión comprobada satisfactoriamente.",
|
||||
"TEST_CONNECTION_FAILURE": "Fallo al comprobar el endpoint.",
|
||||
|
@ -299,7 +299,16 @@
|
||||
"INVALID_DATE": "无效日期。",
|
||||
"PLACEHOLDER": "未发现任何复制规则!",
|
||||
"JOB_PLACEHOLDER": "未发现任何复制任务!",
|
||||
"JOB_LOG_VIEWER": "查看复制任务日志"
|
||||
"JOB_LOG_VIEWER": "查看复制任务日志",
|
||||
"BACKINFO": "请先添加项目名称和目标",
|
||||
"FILTER": "过滤",
|
||||
"SCHEDULE": "日程",
|
||||
"SETTING":"设置",
|
||||
"TRIGGER":"触发器",
|
||||
"TARGETS":"目标",
|
||||
"SOURCE": "资源",
|
||||
"DELETE_REMOTE_IMAGES":"删除本地镜像时同时也删除远程的镜像。",
|
||||
"REPLICATE_IMMEDIATE":"立即复制现有的镜像。"
|
||||
},
|
||||
"DESTINATION": {
|
||||
"NEW_ENDPOINT": "新建目标",
|
||||
@ -313,7 +322,7 @@
|
||||
"TEST_CONNECTION": "测试连接",
|
||||
"TITLE_EDIT": "编辑目标",
|
||||
"TITLE_ADD": "新建目标",
|
||||
"DELETE": "删除",
|
||||
"DELETE": "删除目标",
|
||||
"TESTING_CONNECTION": "正在测试连接...",
|
||||
"TEST_CONNECTION_SUCCESS": "测试连接成功。",
|
||||
"TEST_CONNECTION_FAILURE": "测试连接失败。",
|
||||
|
Loading…
Reference in New Issue
Block a user