mirror of https://github.com/goharbor/harbor.git
Add server driven sorting (#14426)
Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
85f9a49bc8
commit
68d7c91596
|
@ -18,7 +18,6 @@ import { RouterModule, Routes } from "@angular/router";
|
|||
import { ProjectQuotasContainerComponent } from "./project-quotas-container.component";
|
||||
import { ProjectQuotasComponent } from "./project-quotas/project-quotas.component";
|
||||
import { EditProjectQuotasComponent } from "./project-quotas/edit-project-quotas/edit-project-quotas.component";
|
||||
import { QuotaService } from "../../../shared/services";
|
||||
|
||||
|
||||
const routes: Routes = [
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
</clr-dg-action-bar>
|
||||
<clr-dg-column>{{'QUOTA.PROJECT' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'QUOTA.OWNER' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="storageComparator">{{'QUOTA.STORAGE' | translate }}</clr-dg-column>
|
||||
<clr-dg-column>{{'QUOTA.STORAGE' | translate }}</clr-dg-column>
|
||||
<clr-dg-placeholder>{{'QUOTA.PLACEHOLDER' | translate }}</clr-dg-placeholder>
|
||||
<clr-dg-row *ngFor="let quota of quotaList" [clrDgItem]='quota'>
|
||||
<clr-dg-cell>
|
||||
|
|
|
@ -2,8 +2,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
|||
import { ProjectQuotasComponent } from './project-quotas.component';
|
||||
import { Router } from '@angular/router';
|
||||
import {
|
||||
QuotaService
|
||||
, QuotaDefaultService, Quota, RequestQueryParams
|
||||
Quota, RequestQueryParams
|
||||
} from '../../../../shared/services';
|
||||
import { ErrorHandler } from '../../../../shared/units/error-handler';
|
||||
import { of } from 'rxjs';
|
||||
|
@ -11,6 +10,7 @@ import { delay } from 'rxjs/operators';
|
|||
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";
|
||||
|
||||
|
||||
describe('ProjectQuotasComponent', () => {
|
||||
|
@ -64,7 +64,6 @@ describe('ProjectQuotasComponent', () => {
|
|||
],
|
||||
providers: [
|
||||
{ provide: ErrorHandler, useValue: fakedErrorHandler },
|
||||
{ provide: QuotaService, useClass: QuotaDefaultService },
|
||||
{ provide: APP_BASE_HREF, useValue : '/' },
|
||||
{ provide: Router, useValue: fakedRouter }
|
||||
]
|
||||
|
@ -82,7 +81,7 @@ describe('ProjectQuotasComponent', () => {
|
|||
};
|
||||
component.loading = true;
|
||||
quotaService = fixture.debugElement.injector.get(QuotaService);
|
||||
spy = spyOn(quotaService, 'getQuotaList')
|
||||
spy = spyOn(quotaService, 'listQuotasResponse')
|
||||
.and.callFake(function (params: RequestQueryParams) {
|
||||
let header = new Map();
|
||||
header.set("X-Total-Count", 123);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, Input, Output, EventEmitter, ViewChild, SimpleChanges, OnChanges } from '@angular/core';
|
||||
import { Configuration } from '../../config/config';
|
||||
import {
|
||||
Quota, State, Comparator, ClrDatagridComparatorInterface, QuotaHardLimitInterface, QuotaHard
|
||||
Quota, State, QuotaHardLimitInterface,
|
||||
} from '../../../../shared/services';
|
||||
import {
|
||||
clone, isEmpty, getChanges, getSuitableUnit, calculatePage, CustomComparator
|
||||
|
@ -12,11 +12,12 @@ import { QuotaUnits, QuotaUnlimited, QUOTA_DANGER_COEFFICIENT, QUOTA_WARNING_COE
|
|||
import { EditProjectQuotasComponent } from './edit-project-quotas/edit-project-quotas.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { forkJoin } from 'rxjs';
|
||||
import { QuotaService } from "../../../../shared/services";
|
||||
import { Router } from '@angular/router';
|
||||
import { finalize } 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'
|
||||
|
@ -54,7 +55,6 @@ export class ProjectQuotasComponent implements OnChanges {
|
|||
this.config = cfg;
|
||||
this.configChange.emit(this.config);
|
||||
}
|
||||
storageComparator: Comparator<Quota> = new CustomComparator<Quota>(quotaSort.storage, quotaSort.sortType);
|
||||
selectedRow: Quota[] = [];
|
||||
|
||||
constructor(
|
||||
|
@ -151,9 +151,9 @@ export class ProjectQuotasComponent implements OnChanges {
|
|||
saveCurrentQuota(event) {
|
||||
let storage = +event.formValue.storage === QuotaUnlimited ?
|
||||
+event.formValue.storage : getByte(+event.formValue.storage, event.formValue.storageUnit);
|
||||
let rep: QuotaHard = { hard: { storage } };
|
||||
let rep: QuotaUpdateReq = { hard: { storage } };
|
||||
this.loading = true;
|
||||
this.quotaService.updateQuota(event.id, rep).subscribe(res => {
|
||||
this.quotaService.updateQuota({id: event.id, hard: rep}).subscribe(res => {
|
||||
this.editQuotaDialog.openEditQuota = false;
|
||||
this.getQuotaList(this.currentState);
|
||||
this.errorHandler.info('QUOTA.SAVE_SUCCESS');
|
||||
|
@ -179,15 +179,12 @@ export class ProjectQuotasComponent implements OnChanges {
|
|||
|
||||
let pageNumber: number = calculatePage(state);
|
||||
if (pageNumber <= 0) { pageNumber = 1; }
|
||||
let sortBy: any = '';
|
||||
if (state.sort) {
|
||||
sortBy = state.sort.by as string | ClrDatagridComparatorInterface<any>;
|
||||
sortBy = sortBy.fieldName ? sortBy.fieldName : sortBy;
|
||||
sortBy = state.sort.reverse ? `-${sortBy}` : sortBy;
|
||||
}
|
||||
this.loading = true;
|
||||
|
||||
this.quotaService.getQuotaList(QuotaType, pageNumber, this.pageSize, sortBy).pipe(finalize(() => {
|
||||
this.quotaService.listQuotasResponse({
|
||||
reference: QuotaType,
|
||||
page: pageNumber,
|
||||
pageSize: this.pageSize
|
||||
}).pipe(finalize(() => {
|
||||
this.loading = false;
|
||||
this.selectedRow = [];
|
||||
})).subscribe(res => {
|
||||
|
|
|
@ -1,21 +1,18 @@
|
|||
import { waitForAsync, ComponentFixture, TestBed, ComponentFixtureAutoDetect } from '@angular/core/testing';
|
||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { ListProjectComponent } from './list-project.component';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectorRef } from '@angular/core';
|
||||
import { ClarityModule } from '@clr/angular';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { SessionService } from "../../../../shared/services/session.service";
|
||||
import { AppConfigService } from "../../../../services/app-config.service";
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { SearchTriggerService } from "../../../../shared/components/global-search/search-trigger.service";
|
||||
import { MessageHandlerService } from "../../../../shared/services/message-handler.service";
|
||||
import { StatisticHandler } from "../statictics/statistic-handler.service";
|
||||
import { of } from 'rxjs';
|
||||
import { BrowserAnimationsModule, NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||
import { delay } from 'rxjs/operators';
|
||||
import { ProjectService } from "../../../../shared/services";
|
||||
import { OperationService } from "../../../../shared/components/operation/operation.service";
|
||||
import { ConfirmationDialogService } from "../../../global-confirmation-dialog/confirmation-dialog.service";
|
||||
import { SharedTestingModule } from "../../../../shared/shared.module";
|
||||
describe('ListProjectComponent', () => {
|
||||
let component: ListProjectComponent;
|
||||
let fixture: ComponentFixture<ListProjectComponent>;
|
||||
|
@ -68,12 +65,7 @@ describe('ListProjectComponent', () => {
|
|||
CUSTOM_ELEMENTS_SCHEMA
|
||||
],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
ClarityModule,
|
||||
TranslateModule.forRoot(),
|
||||
FormsModule,
|
||||
RouterTestingModule,
|
||||
NoopAnimationsModule
|
||||
SharedTestingModule
|
||||
],
|
||||
declarations: [ListProjectComponent],
|
||||
providers: [
|
||||
|
|
|
@ -27,7 +27,13 @@ import { SearchTriggerService } from "../../../../shared/components/global-searc
|
|||
import { AppConfigService } from "../../../../services/app-config.service";
|
||||
import { Project } from "../../../project/project";
|
||||
import { map, catchError, finalize } from "rxjs/operators";
|
||||
import { calculatePage, CustomComparator, doFiltering, doSorting } from "../../../../shared/units/utils";
|
||||
import {
|
||||
calculatePage,
|
||||
CustomComparator,
|
||||
doFiltering,
|
||||
doSorting,
|
||||
getSortingString
|
||||
} from "../../../../shared/units/utils";
|
||||
import { OperationService } from "../../../../shared/components/operation/operation.service";
|
||||
import { operateChanges, OperateInfo, OperationState } from "../../../../shared/components/operation/operate";
|
||||
import {HttpErrorResponse} from "@angular/common/http";
|
||||
|
@ -159,7 +165,7 @@ export class ListProjectComponent implements OnDestroy {
|
|||
if (this.filteredType > 0) {
|
||||
passInFilteredType = this.filteredType - 1;
|
||||
}
|
||||
this.proService.listProjects(this.searchKeyword, passInFilteredType, pageNumber, this.pageSize)
|
||||
this.proService.listProjects(this.searchKeyword, passInFilteredType, pageNumber, this.pageSize, getSortingString(state))
|
||||
.pipe(finalize(() => {
|
||||
this.loading = false;
|
||||
}))
|
||||
|
|
|
@ -5,7 +5,14 @@ import { finalize } from "rxjs/operators";
|
|||
import { Subscription, timer } from "rxjs";
|
||||
import { ErrorHandler } from "../../../../../shared/units/error-handler";
|
||||
import { ClrDatagridComparatorInterface, ReplicationJob, ReplicationTasks } from "../../../../../shared/services";
|
||||
import { CURRENT_BASE_HREF, CustomComparator, DEFAULT_PAGE_SIZE, doFiltering, doSorting } from "../../../../../shared/units/utils";
|
||||
import {
|
||||
CURRENT_BASE_HREF,
|
||||
CustomComparator,
|
||||
DEFAULT_PAGE_SIZE,
|
||||
doFiltering,
|
||||
doSorting,
|
||||
getSortingString
|
||||
} from "../../../../../shared/units/utils";
|
||||
import { REFRESH_TIME_DIFFERENCE } from '../../../../../shared/entities/shared.const';
|
||||
import { ClrDatagridStateInterface } from '@clr/angular';
|
||||
import { ReplicationExecution } from "../../../../../../../ng-swagger-gen/models/replication-execution";
|
||||
|
@ -163,6 +170,7 @@ export class ReplicationTasksComponent implements OnInit, OnDestroy {
|
|||
id: +this.executionId,
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize,
|
||||
sort: getSortingString(state)
|
||||
};
|
||||
if (this.searchTask && this.searchTask !== "") {
|
||||
if (this.searchTask === STATUS_MAP.Succeed && this.defaultFilter === 'status') {// convert 'Succeeded' to 'Succeed'
|
||||
|
|
|
@ -56,10 +56,10 @@
|
|||
</clr-dropdown>
|
||||
</clr-dg-action-bar>
|
||||
<clr-datagrid (clrDgRefresh)="clrLoad($event)" [clrDgLoading]="loading" [(clrDgSelected)]="selectedRows">
|
||||
<clr-dg-column>{{'ROBOT_ACCOUNT.NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'name'">{{'ROBOT_ACCOUNT.NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'ROBOT_ACCOUNT.ENABLED_STATE' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{"SYSTEM_ROBOT.PROJECTS" | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'ROBOT_ACCOUNT.CREATETION' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'creation_time'">{{'ROBOT_ACCOUNT.CREATETION' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'SYSTEM_ROBOT.EXPIRES_AT' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'ROBOT_ACCOUNT.DESCRIPTION' | translate}}</clr-dg-column>
|
||||
<clr-dg-placeholder>{{
|
||||
|
|
|
@ -3,7 +3,7 @@ import { NewRobotComponent } from './new-robot/new-robot.component';
|
|||
import { ViewTokenComponent } from '../../../shared/components/view-token/view-token.component';
|
||||
import { RobotService } from "../../../../../ng-swagger-gen/services/robot.service";
|
||||
import { Robot } from "../../../../../ng-swagger-gen/models/robot";
|
||||
import { clone, DEFAULT_PAGE_SIZE } from "../../../shared/units/utils";
|
||||
import { clone, DEFAULT_PAGE_SIZE, getSortingString } from "../../../shared/units/utils";
|
||||
import { ClrDatagridStateInterface, ClrLoadingState } from "@clr/angular";
|
||||
import { catchError, debounceTime, distinctUntilChanged, finalize, map, switchMap } from "rxjs/operators";
|
||||
import { MessageHandlerService } from "../../../shared/services/message-handler.service";
|
||||
|
@ -45,7 +45,6 @@ export class SystemRobotAccountsComponent implements OnInit, OnDestroy {
|
|||
loading: boolean = true;
|
||||
loadingData: boolean = false;
|
||||
addBtnState: ClrLoadingState = ClrLoadingState.DEFAULT;
|
||||
hasGetAllProjects: boolean = false;
|
||||
@ViewChild(NewRobotComponent, {static: true})
|
||||
newRobotComponent: NewRobotComponent;
|
||||
@ViewChild(ViewTokenComponent)
|
||||
|
@ -189,6 +188,7 @@ export class SystemRobotAccountsComponent implements OnInit, OnDestroy {
|
|||
const queryParam: RobotService.ListRobotParams = {
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize,
|
||||
sort: getSortingString(state)
|
||||
};
|
||||
if (this.searchKey) {
|
||||
queryParam.q = encodeURIComponent(`name=~${this.searchKey}`);
|
||||
|
|
|
@ -147,12 +147,12 @@
|
|||
|
||||
</clr-dg-action-bar>
|
||||
|
||||
<clr-dg-column class="flex-max-width">{{'REPOSITORY.ARTIFACTS_COUNT' | translate}}
|
||||
<clr-dg-column class="flex-max-width" [clrDgSortBy]="'digest'">{{'REPOSITORY.ARTIFACTS_COUNT' | translate}}
|
||||
</clr-dg-column>
|
||||
<clr-dg-column>{{'REPOSITORY.PULL_COMMAND' | translate}}</clr-dg-column>
|
||||
<clr-dg-column *ngIf="depth">{{'REPOSITORY.PLATFORM' | translate}}</clr-dg-column>
|
||||
<clr-dg-column class="w-rem-4">{{'REPOSITORY.TAGS' | translate}}</clr-dg-column>
|
||||
<clr-dg-column >{{'REPOSITORY.SIZE' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'size'">{{'REPOSITORY.SIZE' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPOSITORY.VULNERABILITY' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'ARTIFACT.ANNOTATION' | translate}}</clr-dg-column>
|
||||
<clr-dg-column *ngIf="!withAdmiral">{{'REPOSITORY.LABELS' | translate}}</clr-dg-column>
|
||||
|
|
|
@ -26,15 +26,20 @@ import { ClrLoadingState, ClrDatagridStateInterface, ClrDatagridComparatorInterf
|
|||
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import {
|
||||
Comparator, Label, LabelService, ScannerVo, ScanningResultService,
|
||||
UserPermissionService, USERSTATICPERMISSION, VulnerabilitySummary
|
||||
Comparator, Label, LabelService, ScanningResultService,
|
||||
UserPermissionService, USERSTATICPERMISSION,
|
||||
} from "../../../../../../../shared/services";
|
||||
import {
|
||||
calculatePage,
|
||||
clone,
|
||||
CustomComparator,
|
||||
DEFAULT_PAGE_SIZE,
|
||||
formatSize, VULNERABILITY_SCAN_STATUS, dbEncodeURIComponent, doSorting, DEFAULT_SUPPORTED_MIME_TYPES
|
||||
formatSize,
|
||||
VULNERABILITY_SCAN_STATUS,
|
||||
dbEncodeURIComponent,
|
||||
doSorting,
|
||||
DEFAULT_SUPPORTED_MIME_TYPES,
|
||||
getSortingString
|
||||
} from "../../../../../../../shared/units/utils";
|
||||
import { ImageNameInputComponent } from "../../../../../../../shared/components/image-name-input/image-name-input.component";
|
||||
import { CopyInputComponent } from "../../../../../../../shared/components/push-image/copy-input.component";
|
||||
|
@ -367,6 +372,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||
this.loading = false;
|
||||
})).subscribe(artifacts => {
|
||||
this.artifactList = artifacts;
|
||||
this.artifactList = doSorting<ArtifactFront>(this.artifactList, state);
|
||||
this.artifactList.forEach((artifact, index) => {
|
||||
artifact.platform = clone(platFormAttr[index].platform);
|
||||
});
|
||||
|
@ -387,6 +393,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||
withLabel: true,
|
||||
withScanOverview: true,
|
||||
withTag: false,
|
||||
sort: getSortingString(state),
|
||||
XAcceptVulnerabilities: DEFAULT_SUPPORTED_MIME_TYPES
|
||||
};
|
||||
Object.assign(listArtifactParams, params);
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
<clr-dg-column [clrDgField]="'name'">{{'TAG.NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column *ngIf="hasPullCommand()">{{'REPOSITORY.PULL_COMMAND' | translate}}</clr-dg-column>
|
||||
<clr-dg-column *ngIf="withNotary">{{'REPOSITORY.SIGNED' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'TAG.PULL_TIME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'TAG.PUSH_TIME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'pull_time'">{{'TAG.PULL_TIME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'push_time'">{{'TAG.PUSH_TIME' | translate}}</clr-dg-column>
|
||||
|
||||
<clr-dg-row *ngFor="let tag of currentTags" [clrDgItem]="tag">
|
||||
<clr-dg-cell>
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
calculatePage,
|
||||
dbEncodeURIComponent,
|
||||
doFiltering,
|
||||
doSorting
|
||||
doSorting, getSortingString
|
||||
} from '../../../../../shared/units/utils';
|
||||
import { AppConfigService } from "../../../../../services/app-config.service";
|
||||
import { errorHandler } from "../../../../../shared/units/shared.utils";
|
||||
|
@ -129,8 +129,10 @@ export class ArtifactTagComponent implements OnInit, OnDestroy {
|
|||
page: pageNumber,
|
||||
withSignature: true,
|
||||
withImmutableStatus: true,
|
||||
pageSize: this.pageSize
|
||||
pageSize: this.pageSize,
|
||||
sort: getSortingString(state)
|
||||
};
|
||||
this.loading = true;
|
||||
this.artifactService.listTagsResponse(params).pipe(finalize(() => {
|
||||
this.loading = false;
|
||||
})).subscribe(res => {
|
||||
|
|
|
@ -30,7 +30,7 @@ import {
|
|||
DEFAULT_PAGE_SIZE,
|
||||
dbEncodeURIComponent,
|
||||
doFiltering,
|
||||
doSorting, CURRENT_BASE_HREF
|
||||
doSorting, CURRENT_BASE_HREF, getSortingString
|
||||
} from "../../../shared/units/utils";
|
||||
import { ErrorHandler } from "../../../shared/units/error-handler";
|
||||
import { ConfirmationButtons, ConfirmationState, ConfirmationTargets } from "../../../shared/entities/shared.const";
|
||||
|
@ -379,7 +379,7 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy
|
|||
});
|
||||
}
|
||||
if (state.sort && state.sort.by) {
|
||||
// params = params.set(`sort`, `${(state.sort.reverse ? `-` : ``)}${state.sort.by as string}`);
|
||||
params.sort = getSortingString(state);
|
||||
}
|
||||
this.loading = true;
|
||||
|
||||
|
@ -392,7 +392,6 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy
|
|||
this.repositories = repo.body;
|
||||
// Do customising filtering and sorting
|
||||
this.repositories = doFiltering<NewRepository>(this.repositories, state);
|
||||
this.repositories = doSorting<NewRepository>(this.repositories, state);
|
||||
this.signedCon = {};
|
||||
this.loading = false;
|
||||
}, error => {
|
||||
|
|
|
@ -55,10 +55,10 @@
|
|||
</clr-dropdown>
|
||||
</clr-dg-action-bar>
|
||||
<clr-datagrid (clrDgRefresh)="clrLoad($event)" [clrDgLoading]="loading" [(clrDgSelected)]="selectedRows">
|
||||
<clr-dg-column>{{'ROBOT_ACCOUNT.NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'name'">{{'ROBOT_ACCOUNT.NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'ROBOT_ACCOUNT.ENABLED_STATE' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{"SYSTEM_ROBOT.PERMISSION_COLUMN" | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'ROBOT_ACCOUNT.CREATETION' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'creation_time'">{{'ROBOT_ACCOUNT.CREATETION' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'SYSTEM_ROBOT.EXPIRES_AT' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'ROBOT_ACCOUNT.DESCRIPTION' | translate}}</clr-dg-column>
|
||||
<clr-dg-placeholder>{{
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
ACTION_RESOURCE_I18N_MAP,
|
||||
PermissionsKinds
|
||||
} from "../../left-side-nav/system-robot-accounts/system-robot-util";
|
||||
import { clone, DEFAULT_PAGE_SIZE } from "../../../shared/units/utils";
|
||||
import { clone, DEFAULT_PAGE_SIZE, getSortingString } from "../../../shared/units/utils";
|
||||
import { ViewTokenComponent } from "../../../shared/components/view-token/view-token.component";
|
||||
import { FilterComponent } from "../../../shared/components/filter/filter.component";
|
||||
import { MessageHandlerService } from "../../../shared/services/message-handler.service";
|
||||
|
@ -157,6 +157,7 @@ export class RobotAccountComponent implements OnInit, OnDestroy {
|
|||
const queryParam: RobotService.ListRobotParams = {
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize,
|
||||
sort: getSortingString(state),
|
||||
q: encodeURIComponent(`Level=${PermissionsKinds.PROJECT},ProjectID=${this.projectId}`)
|
||||
};
|
||||
if (this.searchKey) {
|
||||
|
|
|
@ -8,4 +8,3 @@ export * from "./project.service";
|
|||
export * from "./label.service";
|
||||
export * from "./permission.service";
|
||||
export * from "./permission-static";
|
||||
export * from "./quota.service";
|
||||
|
|
|
@ -64,7 +64,8 @@ export abstract class ProjectService {
|
|||
name: string,
|
||||
isPublic?: number,
|
||||
page?: number,
|
||||
pageSize?: number
|
||||
pageSize?: number,
|
||||
sort?: string
|
||||
): Observable<HttpResponse<Project[]>>;
|
||||
abstract createProject(name: string, metadata: any, storageLimit: number, registryId: number): Observable<any>;
|
||||
abstract deleteProject(projectId: number): Observable<any>;
|
||||
|
@ -125,7 +126,8 @@ export class ProjectDefaultService extends ProjectService {
|
|||
)
|
||||
.pipe(catchError(error => observableThrowError(error)));
|
||||
}
|
||||
public listProjects(name: string, isPublic?: number, page?: number, pageSize?: number): Observable<HttpResponse<Project[]>> {
|
||||
public listProjects(name: string, isPublic?: number,
|
||||
page?: number, pageSize?: number, sort?: string): Observable<HttpResponse<Project[]>> {
|
||||
let params = new HttpParams();
|
||||
if (page && pageSize) {
|
||||
params = params.set('page', page + '').set('page_size', pageSize + '');
|
||||
|
@ -136,6 +138,9 @@ export class ProjectDefaultService extends ProjectService {
|
|||
if (isPublic !== undefined) {
|
||||
params = params.set('public', '' + isPublic);
|
||||
}
|
||||
if (sort) {
|
||||
params = params.set('sort', sort);
|
||||
}
|
||||
return this.http
|
||||
.get<HttpResponse<Project[]>>(`${ CURRENT_BASE_HREF }/projects`, buildHttpRequestOptionsWithObserveResponse(params)).pipe(
|
||||
catchError(error => observableThrowError(error)), );
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
import { HttpClient, HttpResponse, HttpParams } from "@angular/common/http";
|
||||
import { Injectable } from "@angular/core";
|
||||
import {
|
||||
HTTP_JSON_OPTIONS,
|
||||
buildHttpRequestOptionsWithObserveResponse, CURRENT_BASE_HREF,
|
||||
} from "../units/utils";
|
||||
import {
|
||||
QuotaHard
|
||||
} from "./interface";
|
||||
import { map, catchError } from "rxjs/operators";
|
||||
import { Observable, throwError as observableThrowError } from "rxjs";
|
||||
import { Quota } from "./interface";
|
||||
|
||||
/**
|
||||
* Define the service methods to handle the replication (rule and job) related things.
|
||||
*
|
||||
**
|
||||
* @abstract
|
||||
* class QuotaService
|
||||
*/
|
||||
export abstract class QuotaService {
|
||||
/**
|
||||
*
|
||||
* @abstract
|
||||
* returns {(Observable<ReplicationRule[]>)}
|
||||
*
|
||||
* @memberOf QuotaService
|
||||
*/
|
||||
abstract getQuotaList(quotaType, page?, pageSize?, sortBy?: any):
|
||||
any;
|
||||
|
||||
abstract updateQuota(
|
||||
id: number,
|
||||
rep: QuotaHard
|
||||
): Observable<any>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement default service for replication rule and job.
|
||||
*
|
||||
**
|
||||
* class QuotaDefaultService
|
||||
* extends {QuotaService}
|
||||
*/
|
||||
@Injectable()
|
||||
export class QuotaDefaultService extends QuotaService {
|
||||
quotaUrl: string;
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
) {
|
||||
super();
|
||||
this.quotaUrl = CURRENT_BASE_HREF + "/quotas";
|
||||
}
|
||||
|
||||
public getQuotaList(quotaType: string, page?, pageSize?, sortBy?: any):
|
||||
any {
|
||||
|
||||
let params = new HttpParams();
|
||||
if (quotaType) {
|
||||
params = params.set('reference', quotaType);
|
||||
}
|
||||
if (page && pageSize) {
|
||||
params = params.set('page', page + '').set('page_size', pageSize + '');
|
||||
}
|
||||
if (sortBy) {
|
||||
params = params.set('sort', sortBy);
|
||||
}
|
||||
|
||||
return this.http
|
||||
.get<HttpResponse<Quota[]>>(this.quotaUrl
|
||||
, buildHttpRequestOptionsWithObserveResponse(params))
|
||||
.pipe(map(response => {
|
||||
return response;
|
||||
})
|
||||
, catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
public updateQuota(
|
||||
id: number,
|
||||
quotaHardLimit: QuotaHard
|
||||
): Observable<any> {
|
||||
|
||||
let url = `${this.quotaUrl}/${id}`;
|
||||
return this.http
|
||||
.put(url, quotaHardLimit, HTTP_JSON_OPTIONS)
|
||||
.pipe(catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
}
|
|
@ -36,8 +36,6 @@ import { AboutDialogComponent } from "./components/about-dialog/about-dialog.com
|
|||
import {
|
||||
LabelDefaultService,
|
||||
LabelService, ProjectDefaultService, ProjectService,
|
||||
QuotaDefaultService,
|
||||
QuotaService,
|
||||
ReplicationDefaultService,
|
||||
ReplicationService, ScanningResultDefaultService,
|
||||
ScanningResultService,
|
||||
|
@ -199,7 +197,6 @@ ClarityIcons.add({"robot-head": `
|
|||
{provide: EndpointService, useClass: EndpointDefaultService },
|
||||
{provide: ReplicationService, useClass: ReplicationDefaultService },
|
||||
{provide: LabelService, useClass: LabelDefaultService },
|
||||
{provide: QuotaService, useClass: QuotaDefaultService },
|
||||
{provide: SystemInfoService, useClass: SystemInfoDefaultService },
|
||||
{provide: ScanningResultService, useClass: ScanningResultDefaultService },
|
||||
{provide: HelmChartService, useClass: HelmChartDefaultService },
|
||||
|
|
|
@ -6,6 +6,7 @@ import { Comparator, State, HttpOptionInterface, HttpOptionTextInterface, QuotaU
|
|||
import { QuotaUnits, StorageMultipleConstant } from '../entities/shared.const';
|
||||
import { AbstractControl } from "@angular/forms";
|
||||
import { isValidCron } from 'cron-validator';
|
||||
import { ClrDatagridStateInterface } from "@clr/angular";
|
||||
/**
|
||||
* Api levels
|
||||
*/
|
||||
|
@ -629,3 +630,19 @@ export function deleteEmptyKey(obj: Object): void {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getSortingString(state: ClrDatagridStateInterface): string {
|
||||
if (state && state.sort && state.sort.by) {
|
||||
let sortString: string;
|
||||
if (typeof state.sort.by === 'string') {
|
||||
sortString = state.sort.by;
|
||||
} else {
|
||||
sortString = (state.sort.by as any).fieldName;
|
||||
}
|
||||
if (state.sort.reverse) {
|
||||
sortString = `-${sortString}`;
|
||||
}
|
||||
return sortString;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue