mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-30 20:48:23 +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}}
|
{{'QUOTA.EDIT' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="clr-col-1">
|
<div class="clr-col">
|
||||||
<div class="action-head-pos">
|
<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()">
|
<span class="refresh-btn" (click)="refresh()">
|
||||||
<clr-icon shape="refresh"></clr-icon>
|
<clr-icon shape="refresh"></clr-icon>
|
||||||
</span>
|
</span>
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
margin-bottom: .35rem;
|
margin-bottom: .35rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
::ng-deep {
|
:host::ng-deep {
|
||||||
.progress {
|
.progress {
|
||||||
&.warning>progress {
|
&.warning>progress {
|
||||||
color: orange;
|
color: orange;
|
||||||
@ -77,3 +77,14 @@
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
align-items: center;
|
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 { SharedTestingModule } from "../../../../shared/shared.module";
|
||||||
import { EditProjectQuotasComponent } from "./edit-project-quotas/edit-project-quotas.component";
|
import { EditProjectQuotasComponent } from "./edit-project-quotas/edit-project-quotas.component";
|
||||||
import { QuotaService } from "../../../../../../ng-swagger-gen/services/quota.service";
|
import { QuotaService } from "../../../../../../ng-swagger-gen/services/quota.service";
|
||||||
|
import { ProjectService } from "../../../../../../ng-swagger-gen/services/project.service";
|
||||||
|
|
||||||
|
|
||||||
describe('ProjectQuotasComponent', () => {
|
describe('ProjectQuotasComponent', () => {
|
||||||
@ -53,6 +54,11 @@ describe('ProjectQuotasComponent', () => {
|
|||||||
const timeout = (ms: number) => {
|
const timeout = (ms: number) => {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
};
|
};
|
||||||
|
const fakedProjectService = {
|
||||||
|
listProjects() {
|
||||||
|
return of([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -63,6 +69,7 @@ describe('ProjectQuotasComponent', () => {
|
|||||||
EditProjectQuotasComponent
|
EditProjectQuotasComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
{ provide: ProjectService, useValue: fakedProjectService },
|
||||||
{ provide: ErrorHandler, useValue: fakedErrorHandler },
|
{ provide: ErrorHandler, useValue: fakedErrorHandler },
|
||||||
{ provide: APP_BASE_HREF, useValue : '/' },
|
{ provide: APP_BASE_HREF, useValue : '/' },
|
||||||
{ provide: Router, useValue: fakedRouter }
|
{ provide: Router, useValue: fakedRouter }
|
||||||
@ -120,4 +127,22 @@ describe('ProjectQuotasComponent', () => {
|
|||||||
a.dispatchEvent(new Event("click"));
|
a.dispatchEvent(new Event("click"));
|
||||||
expect(spyRoute.calls.count()).toEqual(1);
|
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 { Component, Input, Output, EventEmitter, ViewChild, SimpleChanges, OnChanges } from '@angular/core';
|
||||||
import { Configuration } from '../../config/config';
|
import { Configuration } from '../../config/config';
|
||||||
import {
|
import {
|
||||||
Quota, State, QuotaHardLimitInterface,
|
State, QuotaHardLimitInterface,
|
||||||
} from '../../../../shared/services';
|
} from '../../../../shared/services';
|
||||||
import {
|
import {
|
||||||
clone, isEmpty, getChanges, getSuitableUnit, calculatePage, CustomComparator
|
clone, isEmpty, getChanges, getSuitableUnit, calculatePage
|
||||||
, getByte, GetIntegerAndUnit
|
, getByte, GetIntegerAndUnit
|
||||||
} from '../../../../shared/units/utils';
|
} from '../../../../shared/units/utils';
|
||||||
import { ErrorHandler } from '../../../../shared/units/error-handler';
|
import { ErrorHandler } from '../../../../shared/units/error-handler';
|
||||||
import { QuotaUnits, QuotaUnlimited, QUOTA_DANGER_COEFFICIENT, QUOTA_WARNING_COEFFICIENT } from '../../../../shared/entities/shared.const';
|
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 { EditProjectQuotasComponent } from './edit-project-quotas/edit-project-quotas.component';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { forkJoin } from 'rxjs';
|
import { forkJoin, of } from 'rxjs';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { finalize } from 'rxjs/operators';
|
import { finalize, mergeMap } from 'rxjs/operators';
|
||||||
import { ClrDatagridStateInterface } from '@clr/angular';
|
import { ClrDatagridStateInterface } from '@clr/angular';
|
||||||
import { ConfigurationService } from "../../../../services/config.service";
|
import { ConfigurationService } from "../../../../services/config.service";
|
||||||
import { QuotaService } from "../../../../../../ng-swagger-gen/services/quota.service";
|
import { QuotaService } from "../../../../../../ng-swagger-gen/services/quota.service";
|
||||||
import { QuotaUpdateReq } from "../../../../../../ng-swagger-gen/models/quota-update-req";
|
import { QuotaUpdateReq } from "../../../../../../ng-swagger-gen/models/quota-update-req";
|
||||||
const quotaSort = {
|
import { ProjectService } from "../../../../../../ng-swagger-gen/services/project.service";
|
||||||
storage: "used.storage",
|
import { Quota } from "../../../../../../ng-swagger-gen/models/quota";
|
||||||
sortType: 'string'
|
import { FilterComponent } from "../../../../shared/components/filter/filter.component";
|
||||||
};
|
|
||||||
const QuotaType = 'project';
|
const QuotaType = 'project';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -56,13 +56,15 @@ export class ProjectQuotasComponent implements OnChanges {
|
|||||||
this.configChange.emit(this.config);
|
this.configChange.emit(this.config);
|
||||||
}
|
}
|
||||||
selectedRow: Quota[] = [];
|
selectedRow: Quota[] = [];
|
||||||
|
@ViewChild(FilterComponent)
|
||||||
|
filterComponent: FilterComponent;
|
||||||
constructor(
|
constructor(
|
||||||
private configService: ConfigurationService,
|
private configService: ConfigurationService,
|
||||||
private quotaService: QuotaService,
|
private quotaService: QuotaService,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private errorHandler: ErrorHandler) { }
|
private errorHandler: ErrorHandler,
|
||||||
|
private projectService: ProjectService) { }
|
||||||
|
|
||||||
editQuota() {
|
editQuota() {
|
||||||
if (this.selectedRow && this.selectedRow.length === 1) {
|
if (this.selectedRow && this.selectedRow.length === 1) {
|
||||||
@ -221,14 +223,31 @@ export class ProjectQuotasComponent implements OnChanges {
|
|||||||
this.router.navigate(linkUrl);
|
this.router.navigate(linkUrl);
|
||||||
}
|
}
|
||||||
refresh() {
|
refresh() {
|
||||||
const state: State = {
|
if (this.filterComponent) {
|
||||||
page: {
|
this.filterComponent.currentValue = null;
|
||||||
from: 0,
|
}
|
||||||
to: 14,
|
this.currentPage = 1;
|
||||||
size: 15
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this.getQuotaList(state);
|
|
||||||
this.selectedRow = [];
|
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",
|
"SAVE_SUCCESS": "Ändern der Begrenzung erfolgreich",
|
||||||
"UNLIMITED": "unlimitiert",
|
"UNLIMITED": "unlimitiert",
|
||||||
"INVALID_INPUT": "ungültige Eingabe",
|
"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": {
|
"WEEKLY": {
|
||||||
"MONDAY": "Montag",
|
"MONDAY": "Montag",
|
||||||
|
@ -1158,7 +1158,8 @@
|
|||||||
"SAVE_SUCCESS": "Quota edit success",
|
"SAVE_SUCCESS": "Quota edit success",
|
||||||
"UNLIMITED": "unlimited",
|
"UNLIMITED": "unlimited",
|
||||||
"INVALID_INPUT": "invalid input",
|
"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": {
|
"WEEKLY": {
|
||||||
"MONDAY": "Monday",
|
"MONDAY": "Monday",
|
||||||
|
@ -1159,7 +1159,8 @@
|
|||||||
"SAVE_SUCCESS": "Quota edit success",
|
"SAVE_SUCCESS": "Quota edit success",
|
||||||
"UNLIMITED": "unlimited",
|
"UNLIMITED": "unlimited",
|
||||||
"INVALID_INPUT": "invalid input",
|
"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": {
|
"WEEKLY": {
|
||||||
"MONDAY": "Monday",
|
"MONDAY": "Monday",
|
||||||
|
@ -1130,7 +1130,8 @@
|
|||||||
"SAVE_SUCCESS": "Quota edit success",
|
"SAVE_SUCCESS": "Quota edit success",
|
||||||
"UNLIMITED": "unlimited",
|
"UNLIMITED": "unlimited",
|
||||||
"INVALID_INPUT": "invalid input",
|
"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": {
|
"WEEKLY": {
|
||||||
"MONDAY": "Monday",
|
"MONDAY": "Monday",
|
||||||
|
@ -1151,7 +1151,8 @@
|
|||||||
"SAVE_SUCCESS": "Quota edit success",
|
"SAVE_SUCCESS": "Quota edit success",
|
||||||
"UNLIMITED": "unlimited",
|
"UNLIMITED": "unlimited",
|
||||||
"INVALID_INPUT": "invalid input",
|
"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": {
|
"WEEKLY": {
|
||||||
"MONDAY": "Segunda Feira",
|
"MONDAY": "Segunda Feira",
|
||||||
|
@ -1158,7 +1158,8 @@
|
|||||||
"SAVE_SUCCESS": "Kota düzenleme başarısı",
|
"SAVE_SUCCESS": "Kota düzenleme başarısı",
|
||||||
"UNLIMITED": "sınırsız",
|
"UNLIMITED": "sınırsız",
|
||||||
"INVALID_INPUT": "geçersiz giriş",
|
"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": {
|
"WEEKLY": {
|
||||||
"MONDAY": "Pazartesi",
|
"MONDAY": "Pazartesi",
|
||||||
|
@ -1159,7 +1159,8 @@
|
|||||||
"SAVE_SUCCESS": "项目容量修改成功",
|
"SAVE_SUCCESS": "项目容量修改成功",
|
||||||
"UNLIMITED": "不设限",
|
"UNLIMITED": "不设限",
|
||||||
"INVALID_INPUT": "输入错误",
|
"INVALID_INPUT": "输入错误",
|
||||||
"PLACEHOLDER": "我们找不到任何可以配置定额的项目"
|
"PLACEHOLDER": "我们找不到任何可以配置定额的项目",
|
||||||
|
"FILTER_PLACEHOLDER": "按名称查找(完全匹配)"
|
||||||
},
|
},
|
||||||
"WEEKLY": {
|
"WEEKLY": {
|
||||||
"MONDAY": "周一",
|
"MONDAY": "周一",
|
||||||
|
@ -1148,7 +1148,8 @@
|
|||||||
"SAVE_SUCCESS": "項目容量修改成功",
|
"SAVE_SUCCESS": "項目容量修改成功",
|
||||||
"UNLIMITED": "不設限",
|
"UNLIMITED": "不設限",
|
||||||
"INVALID_INPUT": "輸入錯誤",
|
"INVALID_INPUT": "輸入錯誤",
|
||||||
"PLACEHOLDER": "我們找不到任何可以配置定額的項目"
|
"PLACEHOLDER": "我們找不到任何可以配置定額的項目",
|
||||||
|
"FILTER_PLACEHOLDER": "Search by name(exact match)"
|
||||||
},
|
},
|
||||||
"WEEKLY":{
|
"WEEKLY":{
|
||||||
"MONDAY": "週一",
|
"MONDAY": "週一",
|
||||||
|
Loading…
Reference in New Issue
Block a user