mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-28 11:37:42 +01:00
Support searching quota by project name (#14881)
Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
7fb1bc538c
commit
ba68f16b8d
@ -22,8 +22,11 @@
|
||||
{{'QUOTA.EDIT' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="clr-col-1">
|
||||
<div class="action-head-pos">
|
||||
<div class="clr-col">
|
||||
<div class="clr-row search">
|
||||
<hbr-filter [withDivider]="true"
|
||||
filterPlaceholder='{{"QUOTA.FILTER_PLACEHOLDER" | translate}}'
|
||||
(filterEvt)="doSearch($event)"></hbr-filter>
|
||||
<span class="refresh-btn" (click)="refresh()">
|
||||
<clr-icon shape="refresh"></clr-icon>
|
||||
</span>
|
||||
|
@ -51,7 +51,7 @@
|
||||
margin-bottom: .35rem;
|
||||
}
|
||||
|
||||
::ng-deep {
|
||||
:host::ng-deep {
|
||||
.progress {
|
||||
&.warning>progress {
|
||||
color: orange;
|
||||
@ -76,4 +76,15 @@
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.search {
|
||||
align-items: baseline;
|
||||
padding-top: 0.2rem;
|
||||
justify-content: flex-end;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
:host::ng-deep {
|
||||
.filter-input {
|
||||
width: 210px;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import { APP_BASE_HREF } from '@angular/common';
|
||||
import { SharedTestingModule } from "../../../../shared/shared.module";
|
||||
import { EditProjectQuotasComponent } from "./edit-project-quotas/edit-project-quotas.component";
|
||||
import { QuotaService } from "../../../../../../ng-swagger-gen/services/quota.service";
|
||||
import { ProjectService } from "../../../../../../ng-swagger-gen/services/project.service";
|
||||
|
||||
|
||||
describe('ProjectQuotasComponent', () => {
|
||||
@ -53,6 +54,11 @@ describe('ProjectQuotasComponent', () => {
|
||||
const timeout = (ms: number) => {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
};
|
||||
const fakedProjectService = {
|
||||
listProjects() {
|
||||
return of([]);
|
||||
}
|
||||
}
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
@ -63,6 +69,7 @@ describe('ProjectQuotasComponent', () => {
|
||||
EditProjectQuotasComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: ProjectService, useValue: fakedProjectService },
|
||||
{ provide: ErrorHandler, useValue: fakedErrorHandler },
|
||||
{ provide: APP_BASE_HREF, useValue : '/' },
|
||||
{ provide: Router, useValue: fakedRouter }
|
||||
@ -120,4 +127,22 @@ describe('ProjectQuotasComponent', () => {
|
||||
a.dispatchEvent(new Event("click"));
|
||||
expect(spyRoute.calls.count()).toEqual(1);
|
||||
});
|
||||
it('should refresh', async () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
component.doSearch(null);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
expect(spy.calls.count()).toEqual(2);
|
||||
});
|
||||
it('should get no quota', async () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
component.doSearch('test');
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
expect(component.quotaList.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
@ -1,27 +1,27 @@
|
||||
import { Component, Input, Output, EventEmitter, ViewChild, SimpleChanges, OnChanges } from '@angular/core';
|
||||
import { Configuration } from '../../config/config';
|
||||
import {
|
||||
Quota, State, QuotaHardLimitInterface,
|
||||
State, QuotaHardLimitInterface,
|
||||
} from '../../../../shared/services';
|
||||
import {
|
||||
clone, isEmpty, getChanges, getSuitableUnit, calculatePage, CustomComparator
|
||||
clone, isEmpty, getChanges, getSuitableUnit, calculatePage
|
||||
, getByte, GetIntegerAndUnit
|
||||
} from '../../../../shared/units/utils';
|
||||
import { ErrorHandler } from '../../../../shared/units/error-handler';
|
||||
import { QuotaUnits, QuotaUnlimited, QUOTA_DANGER_COEFFICIENT, QUOTA_WARNING_COEFFICIENT } from '../../../../shared/entities/shared.const';
|
||||
import { EditProjectQuotasComponent } from './edit-project-quotas/edit-project-quotas.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { forkJoin } from 'rxjs';
|
||||
import { forkJoin, of } from 'rxjs';
|
||||
import { Router } from '@angular/router';
|
||||
import { finalize } from 'rxjs/operators';
|
||||
import { finalize, mergeMap } from 'rxjs/operators';
|
||||
import { ClrDatagridStateInterface } from '@clr/angular';
|
||||
import { ConfigurationService } from "../../../../services/config.service";
|
||||
import { QuotaService } from "../../../../../../ng-swagger-gen/services/quota.service";
|
||||
import { QuotaUpdateReq } from "../../../../../../ng-swagger-gen/models/quota-update-req";
|
||||
const quotaSort = {
|
||||
storage: "used.storage",
|
||||
sortType: 'string'
|
||||
};
|
||||
import { ProjectService } from "../../../../../../ng-swagger-gen/services/project.service";
|
||||
import { Quota } from "../../../../../../ng-swagger-gen/models/quota";
|
||||
import { FilterComponent } from "../../../../shared/components/filter/filter.component";
|
||||
|
||||
const QuotaType = 'project';
|
||||
|
||||
@Component({
|
||||
@ -56,13 +56,15 @@ export class ProjectQuotasComponent implements OnChanges {
|
||||
this.configChange.emit(this.config);
|
||||
}
|
||||
selectedRow: Quota[] = [];
|
||||
|
||||
@ViewChild(FilterComponent)
|
||||
filterComponent: FilterComponent;
|
||||
constructor(
|
||||
private configService: ConfigurationService,
|
||||
private quotaService: QuotaService,
|
||||
private translate: TranslateService,
|
||||
private router: Router,
|
||||
private errorHandler: ErrorHandler) { }
|
||||
private errorHandler: ErrorHandler,
|
||||
private projectService: ProjectService) { }
|
||||
|
||||
editQuota() {
|
||||
if (this.selectedRow && this.selectedRow.length === 1) {
|
||||
@ -221,14 +223,31 @@ export class ProjectQuotasComponent implements OnChanges {
|
||||
this.router.navigate(linkUrl);
|
||||
}
|
||||
refresh() {
|
||||
const state: State = {
|
||||
page: {
|
||||
from: 0,
|
||||
to: 14,
|
||||
size: 15
|
||||
},
|
||||
};
|
||||
this.getQuotaList(state);
|
||||
if (this.filterComponent) {
|
||||
this.filterComponent.currentValue = null;
|
||||
}
|
||||
this.currentPage = 1;
|
||||
this.selectedRow = [];
|
||||
this.getQuotaList(this.currentState);
|
||||
}
|
||||
doSearch(name: string) {
|
||||
if (name) {
|
||||
// should query project by name first, then query quota by referenceId(project_id)
|
||||
this.projectService.listProjects({
|
||||
withDetail: false,
|
||||
q: encodeURIComponent(`name=${name}`)
|
||||
}).pipe(mergeMap(projects => {
|
||||
if (projects && projects.length) {
|
||||
return this.quotaService.listQuotas({
|
||||
referenceId: projects[0].project_id.toString()
|
||||
});
|
||||
}
|
||||
return of([]);
|
||||
})).subscribe(res => {
|
||||
this.quotaList = res;
|
||||
});
|
||||
} else {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1158,7 +1158,8 @@
|
||||
"SAVE_SUCCESS": "Ändern der Begrenzung erfolgreich",
|
||||
"UNLIMITED": "unlimitiert",
|
||||
"INVALID_INPUT": "ungültige Eingabe",
|
||||
"PLACEHOLDER": "Es konnten keine Begrenzungen gefunden werden"
|
||||
"PLACEHOLDER": "Es konnten keine Begrenzungen gefunden werden",
|
||||
"FILTER_PLACEHOLDER": "Search by name(exact match)"
|
||||
},
|
||||
"WEEKLY": {
|
||||
"MONDAY": "Montag",
|
||||
|
@ -1158,7 +1158,8 @@
|
||||
"SAVE_SUCCESS": "Quota edit success",
|
||||
"UNLIMITED": "unlimited",
|
||||
"INVALID_INPUT": "invalid input",
|
||||
"PLACEHOLDER": "We couldn't find any project quotas"
|
||||
"PLACEHOLDER": "We couldn't find any project quotas",
|
||||
"FILTER_PLACEHOLDER": "Search by name(exact match)"
|
||||
},
|
||||
"WEEKLY": {
|
||||
"MONDAY": "Monday",
|
||||
|
@ -1159,7 +1159,8 @@
|
||||
"SAVE_SUCCESS": "Quota edit success",
|
||||
"UNLIMITED": "unlimited",
|
||||
"INVALID_INPUT": "invalid input",
|
||||
"PLACEHOLDER": "We couldn't find any project quotas"
|
||||
"PLACEHOLDER": "We couldn't find any project quotas",
|
||||
"FILTER_PLACEHOLDER": "Search by name(exact match)"
|
||||
},
|
||||
"WEEKLY": {
|
||||
"MONDAY": "Monday",
|
||||
|
@ -1130,7 +1130,8 @@
|
||||
"SAVE_SUCCESS": "Quota edit success",
|
||||
"UNLIMITED": "unlimited",
|
||||
"INVALID_INPUT": "invalid input",
|
||||
"PLACEHOLDER": "We couldn't find any project quotas"
|
||||
"PLACEHOLDER": "We couldn't find any project quotas",
|
||||
"FILTER_PLACEHOLDER": "Search by name(exact match)"
|
||||
},
|
||||
"WEEKLY": {
|
||||
"MONDAY": "Monday",
|
||||
|
@ -1151,7 +1151,8 @@
|
||||
"SAVE_SUCCESS": "Quota edit success",
|
||||
"UNLIMITED": "unlimited",
|
||||
"INVALID_INPUT": "invalid input",
|
||||
"PLACEHOLDER": "We couldn't find any project quotas"
|
||||
"PLACEHOLDER": "We couldn't find any project quotas",
|
||||
"FILTER_PLACEHOLDER": "Search by name(exact match)"
|
||||
},
|
||||
"WEEKLY": {
|
||||
"MONDAY": "Segunda Feira",
|
||||
|
@ -1158,7 +1158,8 @@
|
||||
"SAVE_SUCCESS": "Kota düzenleme başarısı",
|
||||
"UNLIMITED": "sınırsız",
|
||||
"INVALID_INPUT": "geçersiz giriş",
|
||||
"PLACEHOLDER": "We couldn't find any project quotas"
|
||||
"PLACEHOLDER": "We couldn't find any project quotas",
|
||||
"FILTER_PLACEHOLDER": "Search by name(exact match)"
|
||||
},
|
||||
"WEEKLY": {
|
||||
"MONDAY": "Pazartesi",
|
||||
|
@ -1159,7 +1159,8 @@
|
||||
"SAVE_SUCCESS": "项目容量修改成功",
|
||||
"UNLIMITED": "不设限",
|
||||
"INVALID_INPUT": "输入错误",
|
||||
"PLACEHOLDER": "我们找不到任何可以配置定额的项目"
|
||||
"PLACEHOLDER": "我们找不到任何可以配置定额的项目",
|
||||
"FILTER_PLACEHOLDER": "按名称查找(完全匹配)"
|
||||
},
|
||||
"WEEKLY": {
|
||||
"MONDAY": "周一",
|
||||
|
@ -1148,7 +1148,8 @@
|
||||
"SAVE_SUCCESS": "項目容量修改成功",
|
||||
"UNLIMITED": "不設限",
|
||||
"INVALID_INPUT": "輸入錯誤",
|
||||
"PLACEHOLDER": "我們找不到任何可以配置定額的項目"
|
||||
"PLACEHOLDER": "我們找不到任何可以配置定額的項目",
|
||||
"FILTER_PLACEHOLDER": "Search by name(exact match)"
|
||||
},
|
||||
"WEEKLY":{
|
||||
"MONDAY": "週一",
|
||||
|
Loading…
Reference in New Issue
Block a user