From 19a9561ffaf5b56a6b2dd7eb2fd6aa269f1fbccd Mon Sep 17 00:00:00 2001 From: Will Sun <30999793+AllForNothing@users.noreply.github.com> Date: Wed, 7 Apr 2021 14:34:29 +0800 Subject: [PATCH] Improve grid view for repos page (#14500) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: AllForNothing Co-authored-by: 孙世军 --- .../gridview/grid-view.component.scss | 10 +-- .../repository-gridview.component.html | 4 ++ .../repository-gridview.component.scss | 7 ++ .../repository-gridview.component.spec.ts | 32 ++++++++- .../repository-gridview.component.ts | 66 ++++++++++++------- .../src/app/shared/entities/shared.const.ts | 2 + src/portal/src/css/common.scss | 6 +- src/portal/src/css/dark-theme.scss | 1 + src/portal/src/css/light-theme.scss | 1 + 9 files changed, 98 insertions(+), 31 deletions(-) diff --git a/src/portal/src/app/base/project/repository/gridview/grid-view.component.scss b/src/portal/src/app/base/project/repository/gridview/grid-view.component.scss index fe8eca862..ac9816fb8 100644 --- a/src/portal/src/app/base/project/repository/gridview/grid-view.component.scss +++ b/src/portal/src/app/base/project/repository/gridview/grid-view.component.scss @@ -31,18 +31,18 @@ right: 0; bottom: 0; text-align: center; - background-color: rgba(255, 255, 255, 0.5); } .central-block-loading-more { - position: relative; - z-index: 10; top: 0; left: 0; right: 0; bottom: 0; text-align: center; - background-color: rgba(255, 255, 255, 0.5); + .spinner { + width: 1rem; + height: 1rem; + } } .vertical-helper { @@ -55,4 +55,4 @@ width: 100px; height: 100px; vertical-align: middle; -} \ No newline at end of file +} diff --git a/src/portal/src/app/base/project/repository/repository-gridview.component.html b/src/portal/src/app/base/project/repository/repository-gridview.component.html index b75c63e96..833757d03 100644 --- a/src/portal/src/app/base/project/repository/repository-gridview.component.html +++ b/src/portal/src/app/base/project/repository/repository-gridview.component.html @@ -107,5 +107,9 @@ +
+
+
+ diff --git a/src/portal/src/app/base/project/repository/repository-gridview.component.scss b/src/portal/src/app/base/project/repository/repository-gridview.component.scss index 4ef3d00bf..7532fd17d 100644 --- a/src/portal/src/app/base/project/repository/repository-gridview.component.scss +++ b/src/portal/src/app/base/project/repository/repository-gridview.component.scss @@ -131,3 +131,10 @@ .repository-box { margin-top: 5px; } +.first-loading { + width: 100%; + height: 65vh; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/src/portal/src/app/base/project/repository/repository-gridview.component.spec.ts b/src/portal/src/app/base/project/repository/repository-gridview.component.spec.ts index 31f38fa4e..44981f134 100644 --- a/src/portal/src/app/base/project/repository/repository-gridview.component.spec.ts +++ b/src/portal/src/app/base/project/repository/repository-gridview.component.spec.ts @@ -13,6 +13,7 @@ import { ErrorHandler } from "../../../shared/units/error-handler"; import { ActivatedRoute } from "@angular/router"; import { Repository as NewRepository } from "../../../../../ng-swagger-gen/models/repository"; import { SharedTestingModule } from "../../../shared/shared.module"; +import {GridViewComponent} from "./gridview/grid-view.component"; describe('RepositoryComponentGridview (inline template)', () => { @@ -95,12 +96,23 @@ describe('RepositoryComponentGridview (inline template)', () => { } }; beforeEach(waitForAsync(() => { + let store = {}; + spyOn(localStorage, 'getItem').and.callFake( key => { + return store[key]; + }); + spyOn(localStorage, 'setItem').and.callFake((key, value) => { + return store[key] = value + ''; + }); + spyOn(localStorage, 'clear').and.callFake( () => { + store = {}; + }); TestBed.configureTestingModule({ imports: [ SharedTestingModule, ], declarations: [ - RepositoryGridviewComponent + RepositoryGridviewComponent, + GridViewComponent ], providers: [ { provide: ActivatedRoute, useValue: fakedActivatedRoute }, @@ -134,4 +146,22 @@ describe('RepositoryComponentGridview (inline template)', () => { it('should create', waitForAsync(() => { expect(compRepo).toBeTruthy(); })); + it('should be card view', async () => { + const cardViewButton = fixtureRepo.nativeElement.querySelector('.card-btn'); + cardViewButton.click(); + cardViewButton.dispatchEvent(new Event('click')); + fixtureRepo.detectChanges(); + await fixtureRepo.whenStable(); + const cordView = fixtureRepo.nativeElement.querySelector('hbr-gridview'); + expect(cordView).toBeTruthy(); + }); + it('should be list view', async () => { + const listViewButton = fixtureRepo.nativeElement.querySelector('.list-btn'); + listViewButton.click(); + listViewButton.dispatchEvent(new Event('click')); + fixtureRepo.detectChanges(); + await fixtureRepo.whenStable(); + const listView = fixtureRepo.nativeElement.querySelector('clr-datagrid'); + expect(listView).toBeTruthy(); + }); }); diff --git a/src/portal/src/app/base/project/repository/repository-gridview.component.ts b/src/portal/src/app/base/project/repository/repository-gridview.component.ts index c534799d6..6cdd0f304 100644 --- a/src/portal/src/app/base/project/repository/repository-gridview.component.ts +++ b/src/portal/src/app/base/project/repository/repository-gridview.component.ts @@ -10,7 +10,7 @@ import { OnDestroy } from "@angular/core"; import {forkJoin, of, Subscription} from "rxjs"; -import { debounceTime, distinctUntilChanged, switchMap } from "rxjs/operators"; +import {debounceTime, distinctUntilChanged, finalize, switchMap} from "rxjs/operators"; import { TranslateService } from "@ngx-translate/core"; import { map, catchError } from "rxjs/operators"; import { Observable } from "rxjs"; @@ -29,11 +29,15 @@ import { clone, DEFAULT_PAGE_SIZE, dbEncodeURIComponent, - doFiltering, - doSorting, CURRENT_BASE_HREF, getSortingString + doFiltering, CURRENT_BASE_HREF, getSortingString } from "../../../shared/units/utils"; import { ErrorHandler } from "../../../shared/units/error-handler"; -import { ConfirmationButtons, ConfirmationState, ConfirmationTargets } from "../../../shared/entities/shared.const"; +import { + CARD_VIEW_LOCALSTORAGE_KEY, + ConfirmationButtons, + ConfirmationState, + ConfirmationTargets +} from "../../../shared/entities/shared.const"; import { operateChanges, OperateInfo, OperationState } from "../../../shared/components/operation/operate"; import { ConfirmationDialogComponent, @@ -45,18 +49,20 @@ import { SessionService } from "../../../shared/services/session.service"; import { GridViewComponent } from "./gridview/grid-view.component"; import { Repository as NewRepository } from "../../../../../ng-swagger-gen/models/repository"; import { StrictHttpResponse as __StrictHttpResponse } from '../../../../../ng-swagger-gen/strict-http-response'; -import {HttpErrorResponse} from "@angular/common/http"; +import { HttpErrorResponse } from "@angular/common/http"; import { errorHandler } from "../../../shared/units/shared.utils"; import { ConfirmationAcknowledgement } from "../../global-confirmation-dialog/confirmation-state-message"; import { ConfirmationMessage } from "../../global-confirmation-dialog/confirmation-message"; - +const TRUE_STR: string = 'true'; +const FALSE_STR: string = 'false'; @Component({ selector: "hbr-repository-gridview", templateUrl: "./repository-gridview.component.html", styleUrls: ["./repository-gridview.component.scss"], }) export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy { + isFirstLoadingGridView: boolean = false; signedCon: { [key: string]: any | string[] } = {}; downloadLink: string; @Input() urlPrefix: string; @@ -106,6 +112,9 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy private session: SessionService, private router: Router, ) { + if (localStorage) { + this.isCardView = localStorage.getItem(CARD_VIEW_LOCALSTORAGE_KEY) === TRUE_STR; + } this.downloadLink = CURRENT_BASE_HREF + "/systeminfo/getcert"; } @@ -145,7 +154,9 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy this.hasSignedIn = this.session.getCurrentUser() !== null; // Get system info for tag views this.getSystemInfo(); - this.isCardView = this.mode === "admiral"; + if (this.isCardView) { + this.doSearchRepoNames('', true); + } this.lastFilteredRepoName = ""; this.getHelmChartVersionPermission(this.projectId); if (!this.searchSub) { @@ -153,7 +164,7 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy debounceTime(500), distinctUntilChanged(), switchMap(repoName => { - this.lastFilteredRepoName = repoName; + this.lastFilteredRepoName = repoName as string; this.currentPage = 1; // Pagination let params: NewRepositoryService.ListRepositoriesParams = { @@ -167,12 +178,11 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy this.loading = true; return this.newRepoService.listRepositoriesResponse(params); }) - ).subscribe((repo: __StrictHttpResponse>) => { + ).pipe(finalize(() => this.loading = false)) + .subscribe((repo: __StrictHttpResponse>) => { this.totalCount = +repo.headers.get('x-total-count'); this.repositories = repo.body; - this.loading = false; }, error => { - this.loading = false; this.errorHandlerService.error(error); }); } @@ -256,7 +266,7 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy })); } - doSearchRepoNames(repoName: string) { + doSearchRepoNames(repoName: string, isFirstLoadingGridView?: boolean) { this.lastFilteredRepoName = repoName; this.currentPage = 1; let st: ClrDatagridStateInterface = this.currentState; @@ -266,7 +276,7 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy st.page.size = this.pageSize; st.page.from = 0; st.page.to = this.pageSize - 1; - this.clrLoad(st); + this.clrLoad(st, isFirstLoadingGridView); } deleteRepos(repoLists: NewRepository[]) { @@ -334,23 +344,20 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy if (this.lastFilteredRepoName) { params.q = encodeURIComponent(`name=~${this.lastFilteredRepoName}`); } - this.loading = true; this.newRepoService.listRepositoriesResponse( params - ) + ).pipe(finalize(() => this.loading = false)) .subscribe((repo: __StrictHttpResponse>) => { this.totalCount = +repo.headers.get('x-total-count'); this.repositoriesCopy = repo.body; this.repositories = this.repositories.concat(this.repositoriesCopy); - this.loading = false; }, error => { - this.loading = false; this.errorHandlerService.error(error); }); } - clrLoad(state: ClrDatagridStateInterface): void { + clrLoad(state: ClrDatagridStateInterface, isFirstLoadingGridView?: boolean): void { if (!state || !state.page) { return; } @@ -382,20 +389,22 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy params.sort = getSortingString(state); } this.loading = true; - + if (isFirstLoadingGridView) { + this.isFirstLoadingGridView = true; + } this.newRepoService.listRepositoriesResponse( params - ) - .subscribe((repo: __StrictHttpResponse>) => { + ).pipe(finalize(() => { + this.loading = false; + this.isFirstLoadingGridView = false; + })).subscribe((repo: __StrictHttpResponse>) => { this.totalCount = +repo.headers.get('x-total-count'); this.repositories = repo.body; // Do customising filtering and sorting this.repositories = doFiltering(this.repositories, state); this.signedCon = {}; - this.loading = false; }, error => { - this.loading = false; this.errorHandlerService.error(error); }); } @@ -432,7 +441,16 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy return; } this.isCardView = cardView; - this.refresh(); + if (localStorage) { + if (this.isCardView) { + localStorage.setItem(CARD_VIEW_LOCALSTORAGE_KEY, TRUE_STR); + } else { + localStorage.setItem(CARD_VIEW_LOCALSTORAGE_KEY, FALSE_STR); + } + } + if (this.isCardView) { + this.refresh(); + } } mouseEnter(itemName: string) { diff --git a/src/portal/src/app/shared/entities/shared.const.ts b/src/portal/src/app/shared/entities/shared.const.ts index e78b5a406..b2f7e153e 100644 --- a/src/portal/src/app/shared/entities/shared.const.ts +++ b/src/portal/src/app/shared/entities/shared.const.ts @@ -240,3 +240,5 @@ export enum ResourceType { CHART_VERSION = 2, REPOSITORY_TAG = 3, } + +export const CARD_VIEW_LOCALSTORAGE_KEY = 'card-view'; diff --git a/src/portal/src/css/common.scss b/src/portal/src/css/common.scss index 4bc025508..8894c3c35 100644 --- a/src/portal/src/css/common.scss +++ b/src/portal/src/css/common.scss @@ -250,4 +250,8 @@ artifact-list-tab { .label-color-input { color: $label-color-input !important; -} \ No newline at end of file +} +// for repos page grid view +.central-block-loading { + background-color: $central-block-loading-bg-color; +} diff --git a/src/portal/src/css/dark-theme.scss b/src/portal/src/css/dark-theme.scss index 20898aca4..5688167e0 100644 --- a/src/portal/src/css/dark-theme.scss +++ b/src/portal/src/css/dark-theme.scss @@ -40,4 +40,5 @@ $command-input-bg-color: #2e4757; $label-hover-bg-color: #28404d; $nav-divider-bg-color: #fafafa; $label-color-input: #ddd; +$central-block-loading-bg-color: rgba(0, 0, 0, 0.5); @import "./common.scss"; diff --git a/src/portal/src/css/light-theme.scss b/src/portal/src/css/light-theme.scss index e1a40b482..8aab96c90 100644 --- a/src/portal/src/css/light-theme.scss +++ b/src/portal/src/css/light-theme.scss @@ -42,4 +42,5 @@ $command-input-bg-color: #ededed; $label-hover-bg-color: #eee; $nav-divider-bg-color: #000; $label-color-input: #5d5d5d; +$central-block-loading-bg-color: rgba(255, 255, 255, 0.5); @import "./common.scss";