diff --git a/src/portal/src/app/distribution/distribution-instances/distribution-instances.component.scss b/src/portal/src/app/distribution/distribution-instances/distribution-instances.component.scss
index 775bcbfda8..63b7653489 100644
--- a/src/portal/src/app/distribution/distribution-instances/distribution-instances.component.scss
+++ b/src/portal/src/app/distribution/distribution-instances/distribution-instances.component.scss
@@ -16,6 +16,7 @@ $refrsh-btn-color: #007CBB;
}
.action-head-pos {
+ padding-top: 12px;
padding-right: 18px;
height: 24px;
display: flex;
diff --git a/src/portal/src/app/distribution/distribution-setup-modal/distribution-setup-modal.component.html b/src/portal/src/app/distribution/distribution-setup-modal/distribution-setup-modal.component.html
index ebb6c9722a..cd7df4b3ca 100644
--- a/src/portal/src/app/distribution/distribution-setup-modal/distribution-setup-modal.component.html
+++ b/src/portal/src/app/distribution/distribution-setup-modal/distribution-setup-modal.component.html
@@ -33,24 +33,30 @@
-
-
-
-
- {{ 'TOOLTIP.ITEM_REQUIRED' | translate }}
-
-
+
@@ -65,27 +71,32 @@
[ngModelOptions]="{ standalone: true }"
>
-
-
-
-
- {{
- 'TOOLTIP.ENDPOINT_FORMAT' | translate
- }}
-
+
@@ -232,7 +243,7 @@
diff --git a/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.spec.ts b/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.spec.ts
index d4b8f5b41e..b6d0d2cd9b 100644
--- a/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.spec.ts
+++ b/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.spec.ts
@@ -33,6 +33,9 @@ describe('AddP2pPolicyComponent', () => {
},
UpdatePolicy() {
return of(true).pipe(delay(0));
+ },
+ ListPolicies() {
+ return of([]).pipe(delay(0));
}
};
const mockActivatedRoute = {
@@ -135,7 +138,7 @@ describe('AddP2pPolicyComponent', () => {
nameInput.dispatchEvent(new Event('input'));
nameInput.blur();
const errorEle: HTMLElement = fixture.nativeElement.querySelector("clr-control-error");
- expect(errorEle.innerText).toEqual('P2P_PROVIDER.NAME_REQUIRED');
+ expect(errorEle.innerText).toEqual('PROJECT.NAME_TOOLTIP');
});
it("save button should work", async () => {
fixture.autoDetectChanges(true);
diff --git a/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.ts b/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.ts
index 120445cbf9..fdc1da6f5c 100644
--- a/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.ts
+++ b/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.ts
@@ -1,11 +1,11 @@
-import { Component, EventEmitter, Input, OnInit, Output, ViewChild, } from '@angular/core';
+import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild, } from '@angular/core';
import { PreheatPolicy } from '../../../../../ng-swagger-gen/models/preheat-policy';
import { InlineAlertComponent } from '../../../shared/inline-alert/inline-alert.component';
import { NgForm } from '@angular/forms';
import { OriginCron, ProjectService } from '../../../../lib/services';
import { CronScheduleComponent } from '../../../../lib/components/cron-schedule';
import { PreheatService } from '../../../../../ng-swagger-gen/services/preheat.service';
-import { finalize } from 'rxjs/operators';
+import { debounceTime, distinctUntilChanged, filter, finalize, switchMap } from 'rxjs/operators';
import { deleteEmptyKey } from '../../../../lib/utils/utils';
import { ClrLoadingState } from '@clr/angular';
import { SessionService } from '../../../shared/session.service';
@@ -14,6 +14,7 @@ import { ActivatedRoute } from '@angular/router';
import { FILTER_TYPE, PROJECT_SEVERITY_LEVEL_MAP, TRIGGER, TRIGGER_I18N_MAP } from '../p2p-provider.service';
import { ProviderUnderProject } from '../../../../../ng-swagger-gen/models/provider-under-project';
import { AppConfigService } from '../../../services/app-config.service';
+import { Subject, Subscription } from 'rxjs';
const SCHEDULE_TYPE = {
NONE: "None",
@@ -28,7 +29,7 @@ const TRUE: string = 'true';
templateUrl: './add-p2p-policy.component.html',
styleUrls: ['./add-p2p-policy.component.scss']
})
-export class AddP2pPolicyComponent implements OnInit {
+export class AddP2pPolicyComponent implements OnInit, OnDestroy {
severityOptions = [
{severity: 5, severityLevel: 'VULNERABILITY.SEVERITY.CRITICAL'},
{severity: 4, severityLevel: 'VULNERABILITY.SEVERITY.HIGH'},
@@ -73,7 +74,10 @@ export class AddP2pPolicyComponent implements OnInit {
projectSeverity: string;
triggers: string[] = [TRIGGER.MANUAL, TRIGGER.SCHEDULED, TRIGGER.EVENT_BASED];
enableContentTrust: boolean = false;
-
+ private _nameSubject: Subject = new Subject();
+ private _nameSubscription: Subscription;
+ isNameExisting: boolean = false;
+ checkNameOnGoing: boolean = false;
constructor(private preheatService: PreheatService,
private session: SessionService,
private route: ActivatedRoute,
@@ -90,6 +94,43 @@ export class AddP2pPolicyComponent implements OnInit {
// get latest project info
this.getProject();
}
+ this.subscribeName();
+ }
+ ngOnDestroy() {
+ if (this._nameSubscription) {
+ this._nameSubscription.unsubscribe();
+ this._nameSubscription = null;
+ }
+ }
+ subscribeName() {
+ if (!this._nameSubscription) {
+ this._nameSubscription = this._nameSubject
+ .pipe(
+ debounceTime(500),
+ distinctUntilChanged(),
+ filter(name => {
+ if (this.isEdit && this.originPolicyForEdit && this.originPolicyForEdit.name === name) {
+ return false;
+ }
+ return name.length > 0;
+ }),
+ switchMap((name) => {
+ this.isNameExisting = false;
+ this.checkNameOnGoing = true;
+ return this.preheatService.ListPolicies({
+ projectName: this.projectName,
+ q: encodeURIComponent(`name=${name}`)
+ }).pipe(finalize(() => this.checkNameOnGoing = false));
+ }))
+ .subscribe(res => {
+ if (res && res.length > 0) {
+ this.isNameExisting = true;
+ }
+ });
+ }
+ }
+ inputName() {
+ this._nameSubject.next(this.policy.name);
}
getProject() {
this.projectService.getProject(this.projectId)
@@ -115,6 +156,13 @@ export class AddP2pPolicyComponent implements OnInit {
severity: PROJECT_SEVERITY_LEVEL_MAP[this.projectSeverity],
onlySignedImages: this.enableContentTrust
});
+ if (this.providers && this.providers.length) {
+ this.providers.forEach(item => {
+ if (item.default) {
+ this.policy.provider_id = item.id;
+ }
+ });
+ }
}
setCron(event: any) {
diff --git a/src/portal/src/app/project/p2p-provider/policy/policy.component.html b/src/portal/src/app/project/p2p-provider/policy/policy.component.html
index bf80b017ec..8a42d3fbcc 100644
--- a/src/portal/src/app/project/p2p-provider/policy/policy.component.html
+++ b/src/portal/src/app/project/p2p-provider/policy/policy.component.html
@@ -77,7 +77,7 @@
{{'P2P_PROVIDER.NAME' | translate}}
{{'P2P_PROVIDER.ENABLED' | translate}}
- {{'P2P_PROVIDER.PROVIDER' | translate}}
+ {{'P2P_PROVIDER.PROVIDER' | translate}}
{{'P2P_PROVIDER.FILTERS' | translate}}
{{'P2P_PROVIDER.TRIGGER' | translate}}
{{'P2P_PROVIDER.CREATED' | translate}}
@@ -164,20 +164,19 @@
-
+
{{'REPLICATION.ID' | translate}}
{{'REPLICATION.STATUS' | translate}}
- {{'REPLICATION.REPLICATION_TRIGGER' | translate}}
+ {{'P2P_PROVIDER.TRIGGER' | translate}}
{{'REPLICATION.CREATION_TIME' | translate}}
{{'REPLICATION.DURATION' | translate}}
{{'REPLICATION.SUCCESS_RATE' | translate}}
@@ -196,7 +195,7 @@
- {{execution.trigger}}
+ {{getTriggerTypeI18nForExecution(execution.trigger) | translate}}
{{execution.start_time | date: 'short'}}
{{getDuration(execution)}}
{{getSuccessRate(execution.metrics)}}
@@ -206,7 +205,7 @@
{{pagination.firstItem + 1}}
- {{pagination.lastItem + 1}} {{'REPLICATION.OF' | translate}}
{{totalExecutionCount}} {{'REPLICATION.ITEMS' | translate}}
-
diff --git a/src/portal/src/app/project/p2p-provider/policy/policy.component.scss b/src/portal/src/app/project/p2p-provider/policy/policy.component.scss
index 178e1d39c3..b93c6c41c4 100644
--- a/src/portal/src/app/project/p2p-provider/policy/policy.component.scss
+++ b/src/portal/src/app/project/p2p-provider/policy/policy.component.scss
@@ -33,7 +33,7 @@
cursor: pointer;
}
.filter-tag {
- margin-top: 6px;
+ margin-top: 7px;
}
.filter-title {
font-weight: 400;
diff --git a/src/portal/src/app/project/p2p-provider/policy/policy.component.ts b/src/portal/src/app/project/p2p-provider/policy/policy.component.ts
index d10ab70b9d..1245c173be 100644
--- a/src/portal/src/app/project/p2p-provider/policy/policy.component.ts
+++ b/src/portal/src/app/project/p2p-provider/policy/policy.component.ts
@@ -11,7 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-import { distinctUntilChanged, finalize, switchMap } from 'rxjs/operators';
+import { debounceTime, distinctUntilChanged, finalize, switchMap } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core';
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
@@ -106,10 +106,7 @@ export class PolicyComponent implements OnInit, OnDestroy {
this._searchSubscription.unsubscribe();
this._searchSubscription = null;
}
- if (this.timeout) {
- clearTimeout(this.timeout);
- this.timeout = null;
- }
+ this.clearLoop();
}
getPermissions() {
const permissionsList: Observable[] = [];
@@ -134,7 +131,11 @@ export class PolicyComponent implements OnInit, OnDestroy {
getProviders() {
this.preheatService.ListProvidersUnderProject({projectName: this.projectName})
.subscribe(res => {
- this.providers = res;
+ if (res && res.length) {
+ this.providers = res.filter(provider => {
+ return provider.enabled;
+ });
+ }
});
}
refresh() {
@@ -358,23 +359,13 @@ export class PolicyComponent implements OnInit, OnDestroy {
}).pipe(finalize(() => this.jobsLoading = false))
.subscribe(response => {
if (response.headers) {
- let xHeader: string = response.headers.get('x-total-count');
+ let xHeader: string = response.headers.get('X-Total-Count');
if (xHeader) {
this.totalExecutionCount = parseInt(xHeader, 0);
}
}
this.executionList = response.body;
- if (this.executionList && this.executionList.length) {
- for (let i = 0; i < this.executionList.length; i++) {
- if (this.p2pProviderService.willChangStatus(this.executionList[i].status)) {
- if (!this.timeout) {
- this.timeout = setTimeout(() => {
- this.clrLoadJobs(null, false);
- }, TIME_OUT);
- }
- }
- }
- }
+ this.setLoop();
}, error => {
this.messageHandlerService.handleError(error);
});
@@ -412,6 +403,12 @@ export class PolicyComponent implements OnInit, OnDestroy {
}
return TRIGGER_I18N_MAP[TRIGGER.MANUAL];
}
+ getTriggerTypeI18nForExecution(trigger: string) {
+ if (trigger && TRIGGER_I18N_MAP[trigger]) {
+ return TRIGGER_I18N_MAP[trigger];
+ }
+ return trigger;
+ }
isScheduled(trigger: string): boolean {
return JSON.parse(trigger).type === TRIGGER.SCHEDULED;
}
@@ -459,7 +456,7 @@ export class PolicyComponent implements OnInit, OnDestroy {
subscribeSearch() {
if (!this._searchSubscription) {
this._searchSubscription = this._searchSubject.pipe(
- distinctUntilChanged(),
+ debounceTime(500),
switchMap(searchString => {
this.jobsLoading = true;
let params: string;
@@ -481,10 +478,31 @@ export class PolicyComponent implements OnInit, OnDestroy {
}
}
this.executionList = response.body;
+ this.setLoop();
});
}
}
canStop(): boolean {
return this.selectedExecutionRow && this.p2pProviderService.willChangStatus(this.selectedExecutionRow.status);
}
+ clearLoop() {
+ if (this.timeout) {
+ clearTimeout(this.timeout);
+ this.timeout = null;
+ }
+ }
+ setLoop() {
+ this.clearLoop();
+ if (this.executionList && this.executionList.length) {
+ for (let i = 0; i < this.executionList.length; i++) {
+ if (this.p2pProviderService.willChangStatus(this.executionList[i].status)) {
+ if (!this.timeout) {
+ this.timeout = setTimeout(() => {
+ this.clrLoadJobs(null, false);
+ }, TIME_OUT);
+ }
+ }
+ }
+ }
+ }
}
diff --git a/src/portal/src/app/project/p2p-provider/task-list/task-list.component.html b/src/portal/src/app/project/p2p-provider/task-list/task-list.component.html
index 020e9c364d..cd7176a457 100644
--- a/src/portal/src/app/project/p2p-provider/task-list/task-list.component.html
+++ b/src/portal/src/app/project/p2p-provider/task-list/task-list.component.html
@@ -76,25 +76,34 @@
{{'P2P_PROVIDER.TASKS' | translate}}
-
- {{'REPLICATION.TASK_ID'| translate}}
- {{'P2P_PROVIDER.ID' | translate}}
- {{'REPLICATION.STATUS' | translate}}
+
+
+
+
+
+
+
+
+
+
+
+ {{'REPLICATION.TASK_ID'| translate}}
+ {{'P2P_PROVIDER.ID' | translate}}
+ {{'REPLICATION.STATUS' | translate}}
{{'P2P_PROVIDER.ARTIFACT' | translate}}
{{'P2P_PROVIDER.DIGEST' | translate}}
{{'P2P_PROVIDER.TYPE' | translate}}
- {{'REPLICATION.CREATION_TIME' | translate}}
+ {{'REPLICATION.CREATION_TIME' | translate}}
{{'REPLICATION.DURATION' | translate}}
{{'REPLICATION.LOGS' | translate}}
{{'P2P_PROVIDER.TASKS_PLACEHOLDER' | translate }}
-
+
{{t.id}}
{{t.execution_id}}
{{t.status}}
@@ -124,8 +133,11 @@
- {{pagination.firstItem + 1}} - {{pagination.lastItem +1 }} {{'REPLICATION.OF' | translate}} {{totalCount }} {{'REPLICATION.ITEMS' | translate}}
-
+ {{pagination.firstItem + 1}}
+ - {{pagination.lastItem + 1}} {{'REPLICATION.OF' | translate}}
+ {{totalCount}} {{'REPLICATION.ITEMS' | translate}}
+
diff --git a/src/portal/src/app/project/p2p-provider/task-list/task-list.component.scss b/src/portal/src/app/project/p2p-provider/task-list/task-list.component.scss
index f4cef3a6c6..705a94789e 100644
--- a/src/portal/src/app/project/p2p-provider/task-list/task-list.component.scss
+++ b/src/portal/src/app/project/p2p-provider/task-list/task-list.component.scss
@@ -103,7 +103,6 @@
}
}
clr-datagrid {
- margin-top: 20px;
.resource-width {
width: 150px;
}
@@ -113,3 +112,16 @@
.margin-top-075 {
margin-top: 0.75rem;
}
+.flex-end {
+ align-items: center;
+ display: flex;
+ justify-content: flex-end;
+ padding-right: 1.5rem;
+}
+.refresh-btn {
+ margin-top: 6px;
+ cursor: pointer;
+}
+.filter-tag {
+ margin-top: 7px;
+}
diff --git a/src/portal/src/app/project/p2p-provider/task-list/task-list.component.spec.ts b/src/portal/src/app/project/p2p-provider/task-list/task-list.component.spec.ts
index 35e80a789d..fd95862b39 100644
--- a/src/portal/src/app/project/p2p-provider/task-list/task-list.component.spec.ts
+++ b/src/portal/src/app/project/p2p-provider/task-list/task-list.component.spec.ts
@@ -17,6 +17,7 @@ import { TaskListComponent } from './task-list.component';
import { MessageHandlerService } from '../../../shared/message-handler/message-handler.service';
import { UserPermissionService } from '../../../../lib/services';
import { Task } from '../../../../../ng-swagger-gen/models/task';
+import { HttpHeaders, HttpResponse } from '@angular/common/http';
describe('TaskListComponent', () => {
let component: TaskListComponent;
let fixture: ComponentFixture;
@@ -38,8 +39,13 @@ describe('TaskListComponent', () => {
GetExecution() {
return of(execution).pipe(delay(0));
},
- ListTasks() {
- return of([task]).pipe(delay(0));
+ ListTasksResponse() {
+ return of(new HttpResponse({
+ body: [task],
+ headers: new HttpHeaders({
+ "X-Total-Count": "1"
+ })
+ })).pipe(delay(0));
}
};
const mockActivatedRoute = {
diff --git a/src/portal/src/app/project/p2p-provider/task-list/task-list.component.ts b/src/portal/src/app/project/p2p-provider/task-list/task-list.component.ts
index 36cfbcce79..1645ab17fb 100644
--- a/src/portal/src/app/project/p2p-provider/task-list/task-list.component.ts
+++ b/src/portal/src/app/project/p2p-provider/task-list/task-list.component.ts
@@ -1,16 +1,16 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
-import { finalize } from 'rxjs/operators';
-import { clone, CustomComparator, DEFAULT_PAGE_SIZE, isEmptyObject } from '../../../../lib/utils/utils';
+import { debounceTime, finalize, switchMap } from 'rxjs/operators';
+import { clone, DEFAULT_PAGE_SIZE } from '../../../../lib/utils/utils';
import { Task } from '../../../../../ng-swagger-gen/models/task';
import { MessageHandlerService } from '../../../shared/message-handler/message-handler.service';
import { Project } from '../../project';
-import { ClrDatagridComparatorInterface, UserPermissionService, USERSTATICPERMISSION } from '../../../../lib/services';
+import { UserPermissionService, USERSTATICPERMISSION } from '../../../../lib/services';
import { Execution } from '../../../../../ng-swagger-gen/models/execution';
import { PreheatService } from '../../../../../ng-swagger-gen/services/preheat.service';
import { EXECUTION_STATUS, P2pProviderService, TIME_OUT } from '../p2p-provider.service';
-import { forkJoin, Observable } from 'rxjs';
+import { forkJoin, Observable, Subject, Subscription } from 'rxjs';
import { ClrLoadingState } from '@clr/angular';
@Component({
@@ -31,12 +31,15 @@ export class TaskListComponent implements OnInit, OnDestroy {
stopOnGoing: boolean;
executionId: string;
preheatPolicyName: string;
- startTimeComparator: ClrDatagridComparatorInterface = new CustomComparator("start_time", "date");
execution: Execution;
hasUpdatePermission: boolean = false;
btnState: ClrLoadingState = ClrLoadingState.DEFAULT;
timeout: any;
timeoutForTaskList: any;
+ searchString: string;
+ private _searchSubject: Subject = new Subject();
+ private _searchSubscription: Subscription;
+ filterKey: string = 'id';
constructor(
private translate: TranslateService,
private router: Router,
@@ -60,6 +63,37 @@ export class TaskListComponent implements OnInit, OnDestroy {
this.getExecutionDetail(true);
}
this.getPermissions();
+ this.subscribeSearch();
+ }
+ subscribeSearch() {
+ if (!this._searchSubscription) {
+ this._searchSubscription = this._searchSubject.pipe(
+ debounceTime(500),
+ switchMap(searchString => {
+ this.loading = true;
+ let params: string;
+ if (this.searchString) {
+ params = encodeURIComponent(`${this.filterKey}=~${searchString}`);
+ }
+ return this.preheatService.ListTasksResponse({
+ projectName: this.projectName,
+ preheatPolicyName: this.preheatPolicyName,
+ executionId: +this.executionId,
+ page: this.currentPage,
+ pageSize: this.pageSize,
+ q: params
+ }).pipe(finalize(() => this.loading = false));
+ })).subscribe(res => {
+ if (res.headers) {
+ let xHeader: string = res.headers.get('x-total-count');
+ if (xHeader) {
+ this.totalCount = parseInt(xHeader, 0);
+ }
+ }
+ this.tasks = res.body;
+ this.setLoop();
+ });
+ }
}
ngOnDestroy(): void {
if (this.timeout) {
@@ -70,6 +104,10 @@ export class TaskListComponent implements OnInit, OnDestroy {
clearTimeout(this.timeoutForTaskList);
this.timeoutForTaskList = null;
}
+ if (this._searchSubscription) {
+ this._searchSubscription.unsubscribe();
+ this._searchSubscription = null;
+ }
}
getPermissions() {
const permissionsList: Observable[] = [];
@@ -93,10 +131,14 @@ export class TaskListComponent implements OnInit, OnDestroy {
projectName: this.projectName,
preheatPolicyName: this.preheatPolicyName,
executionId: +this.executionId
- }).pipe(finalize(() => (this.inProgress = false)))
+ }).pipe(finalize(() => this.inProgress = false))
.subscribe(res => {
this.execution = res;
if (!this.execution || this.p2pProviderService.willChangStatus(this.execution.status)) {
+ if (this.timeout) {
+ clearTimeout(this.timeout);
+ this.timeout = null;
+ }
if (!this.timeout) {
this.timeout = setTimeout(() => {
this.getExecutionDetail(false);
@@ -182,28 +224,30 @@ export class TaskListComponent implements OnInit, OnDestroy {
if (withLoading) {
this.loading = true;
}
- this.preheatService.ListTasks({
+ let params: string;
+ if (this.searchString) {
+ params = encodeURIComponent(`${this.filterKey}=~${this.searchString}`);
+ }
+ this.preheatService.ListTasksResponse({
projectName: this.projectName,
preheatPolicyName: this.preheatPolicyName,
- executionId: +this.executionId
+ executionId: +this.executionId,
+ page: this.currentPage,
+ pageSize: this.pageSize,
+ q: params
})
.pipe(finalize(() => {
this.loading = false;
}))
.subscribe(res => {
- this.tasks = res;
- if (this.tasks && this.tasks.length) {
- this.totalCount = this.tasks.length;
- for (let i = 0; i < this.tasks.length; i++) {
- if (this.p2pProviderService.willChangStatus(this.tasks[i].status)) {
- if (!this.timeoutForTaskList) {
- this.timeoutForTaskList = setTimeout(() => {
- this.clrLoadTasks(false);
- }, TIME_OUT);
- }
- }
+ if (res.headers) {
+ let xHeader: string = res.headers.get('x-total-count');
+ if (xHeader) {
+ this.totalCount = parseInt(xHeader, 0);
}
}
+ this.tasks = res.body;
+ this.setLoop();
},
error => {
this.messageHandlerService.error(error);
@@ -233,4 +277,35 @@ export class TaskListComponent implements OnInit, OnDestroy {
canStop(): boolean {
return this.execution && this.p2pProviderService.willChangStatus(this.execution.status);
}
+ setLoop() {
+ if (this.timeoutForTaskList) {
+ clearTimeout(this.timeoutForTaskList);
+ this.timeoutForTaskList = null;
+ }
+ if (this.tasks && this.tasks.length) {
+ for (let i = 0; i < this.tasks.length; i++) {
+ if (this.p2pProviderService.willChangStatus(this.tasks[i].status)) {
+ if (!this.timeoutForTaskList) {
+ this.timeoutForTaskList = setTimeout(() => {
+ this.clrLoadTasks(false);
+ }, TIME_OUT);
+ }
+ }
+ }
+ }
+ }
+ selectFilterKey($event: any): void {
+ this.filterKey = $event['target'].value;
+ }
+ doFilter(terms: string): void {
+ this.searchString = terms;
+ if (terms.trim()) {
+ this._searchSubject.next(terms.trim());
+ } else {
+ this.clrLoadTasks(true);
+ }
+ }
+ openFilter(isOpen: boolean): void {
+ this.isOpenFilterTag = isOpen;
+ }
}
diff --git a/src/portal/src/i18n/lang/zh-cn-lang.json b/src/portal/src/i18n/lang/zh-cn-lang.json
index ddb7dfd0d9..af6a5da86b 100644
--- a/src/portal/src/i18n/lang/zh-cn-lang.json
+++ b/src/portal/src/i18n/lang/zh-cn-lang.json
@@ -175,7 +175,7 @@
"LOGS": "日志",
"TASKS": "任务",
"API_EXPLORER": "API控制中心",
- "HARBOR_API_MANAGEMENT": "Harbor Api V2.0",
+ "HARBOR_API_MANAGEMENT": "Harbor API V2.0",
"HELM_API_MANAGEMENT": "Harbor Api",
"DISTRIBUTIONS": {
"NAME": "分布式分发",
@@ -289,7 +289,7 @@
"SYS_ADMIN": "系统管理员",
"PROJECT_ADMIN": "项目管理员",
"PROJECT_MAINTAINER": "维护人员",
- "DEVELOPER": "开发人员",
+ "DEVELOPER": "开发者",
"GUEST": "访客",
"LIMITED_GUEST": "受限访客",
"DELETE": "删除",
@@ -503,7 +503,7 @@
"SOURCE": "源",
"DESTINATION": "目标",
"POLICY": "政策",
- "DURATION": "到期时间",
+ "DURATION": "持续时间",
"SUCCESS_RATE": "成功百分比",
"SUCCESS": "成功",
"FAILURE": "失败",
@@ -1446,7 +1446,7 @@
"ENDPOINT": "端点",
"STATUS": "状态",
"ENABLED": "启用",
- "SETUP_TIMESTAMP": "设置时间",
+ "SETUP_TIMESTAMP": "创建时间",
"PROVIDER": "供应商",
"DELETION_TITLE": "删除实例",
"DELETION_SUMMARY": "你确认删除实例 {{param}}?",