From 2c31a248ec1bb483b964c20d9b15887bb43ae5e8 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Mon, 14 Jan 2019 13:06:18 +0000 Subject: [PATCH] Fix double requests when single endpoint connected --- .../list-data-source.ts | 6 ++-- .../list-types/app/cf-app-config.service.ts | 19 ++++++++-- .../list-types/app/cf-apps-data-source.ts | 19 +++------- .../cf-org-space-service.service.ts | 35 ++++++++++++++----- 4 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/frontend/app/shared/components/list/data-sources-controllers/list-data-source.ts b/src/frontend/app/shared/components/list/data-sources-controllers/list-data-source.ts index 8524ff041f..e1b7bdad21 100644 --- a/src/frontend/app/shared/components/list/data-sources-controllers/list-data-source.ts +++ b/src/frontend/app/shared/components/list/data-sources-controllers/list-data-source.ts @@ -1,4 +1,5 @@ import { DataSource } from '@angular/cdk/table'; +import { SortDirection } from '@angular/material'; import { Store } from '@ngrx/store'; import { schema } from 'normalizr'; import { @@ -11,8 +12,9 @@ import { Subscription, } from 'rxjs'; import { tag } from 'rxjs-spy/operators'; -import { first, publishReplay, refCount, tap, distinctUntilChanged, map, filter } from 'rxjs/operators'; +import { distinctUntilChanged, filter, first, map, publishReplay, refCount, tap } from 'rxjs/operators'; +import { ListFilter, ListSort } from '../../../../store/actions/list.actions'; import { MetricsAction } from '../../../../store/actions/metrics.actions'; import { SetResultCount } from '../../../../store/actions/pagination.actions'; import { AppState } from '../../../../store/app-state'; @@ -29,8 +31,6 @@ import { } from './list-data-source-types'; import { getDataFunctionList } from './local-filtering-sorting'; import { LocalListController } from './local-list-controller'; -import { SortDirection } from '@angular/material'; -import { ListSort, ListFilter } from '../../../../store/actions/list.actions'; export class DataFunctionDefinition { diff --git a/src/frontend/app/shared/components/list/list-types/app/cf-app-config.service.ts b/src/frontend/app/shared/components/list/list-types/app/cf-app-config.service.ts index 1d3bb3547e..1cc7d3351d 100644 --- a/src/frontend/app/shared/components/list/list-types/app/cf-app-config.service.ts +++ b/src/frontend/app/shared/components/list/list-types/app/cf-app-config.service.ts @@ -1,6 +1,8 @@ import { DatePipe } from '@angular/common'; import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs'; +import { filter, first, map, switchMap } from 'rxjs/operators'; import { UtilsService } from '../../../../../core/utils.service'; import { ListView } from '../../../../../store/actions/list.actions'; @@ -23,6 +25,7 @@ import { TableCellAppStatusComponent } from './table-cell-app-status/table-cell- export class CfAppConfigService extends ListConfig implements IListConfig { multiFilterConfigs: IListMultiFilterConfig[]; + initialised$: Observable; constructor( private datePipe: DatePipe, @@ -32,13 +35,25 @@ export class CfAppConfigService extends ListConfig implements IList ) { super(); - this.appsDataSource = new CfAppsDataSource(this.store, this); + // Apply the initial cf guid to the data source. Normally this is done via applying the selection to the filter... however this is too + // late for maxedResult world + this.initialised$ = this.cfOrgSpaceService.cf.loading$.pipe( + filter(isLoading => !isLoading), + switchMap(() => this.cfOrgSpaceService.cf.list$), + first(), + map(cfs => { + const cfGuid = cfs.length === 1 ? cfs[0].guid : null; + this.appsDataSource = new CfAppsDataSource(this.store, this, undefined, undefined, undefined, cfGuid); + return true; + }) + ); this.multiFilterConfigs = [ createCfOrgSpaceFilterConfig('cf', 'Cloud Foundry', this.cfOrgSpaceService.cf), createCfOrgSpaceFilterConfig('org', 'Organization', this.cfOrgSpaceService.org), createCfOrgSpaceFilterConfig('space', 'Space', this.cfOrgSpaceService.space), ]; + } appsDataSource: CfAppsDataSource; columns: Array> = [ @@ -117,6 +132,6 @@ export class CfAppConfigService extends ListConfig implements IList getColumns = () => this.columns; getDataSource = () => this.appsDataSource; getMultiFiltersConfigs = () => this.multiFilterConfigs; - getInitialised = () => this.appsDataSource.initialised$; + getInitialised = () => this.initialised$; } diff --git a/src/frontend/app/shared/components/list/list-types/app/cf-apps-data-source.ts b/src/frontend/app/shared/components/list/list-types/app/cf-apps-data-source.ts index 2398514b3d..ffa7e156cc 100644 --- a/src/frontend/app/shared/components/list/list-types/app/cf-apps-data-source.ts +++ b/src/frontend/app/shared/components/list/list-types/app/cf-apps-data-source.ts @@ -1,7 +1,7 @@ import { Store } from '@ngrx/store'; -import { Observable, Subscription } from 'rxjs'; +import { Subscription } from 'rxjs'; import { tag } from 'rxjs-spy/operators/tag'; -import { debounceTime, distinctUntilChanged, map, withLatestFrom, filter, switchMap } from 'rxjs/operators'; +import { debounceTime, distinctUntilChanged, filter, map, switchMap, withLatestFrom } from 'rxjs/operators'; import { DispatchSequencer, DispatchSequencerAction } from '../../../../../core/dispatch-sequencer'; import { cfOrgSpaceFilter, getRowMetadata } from '../../../../../features/cloud-foundry/cf.helpers'; @@ -17,7 +17,6 @@ import { spaceSchemaKey, } from '../../../../../store/helpers/entity-factory'; import { createEntityRelationKey } from '../../../../../store/helpers/entity-relations/entity-relations.types'; -import { selectPaginationState } from '../../../../../store/selectors/pagination.selectors'; import { APIResource } from '../../../../../store/types/api.types'; import { PaginationParam } from '../../../../../store/types/pagination.types'; import { createCfOrSpaceMultipleFilterFn } from '../../../../data-services/cf-org-space-service.service'; @@ -38,7 +37,6 @@ export class CfAppsDataSource extends ListDataSource { public static paginationKey = 'applicationWall'; private subs: Subscription[]; public action: GetAllApplications; - public initialised$: Observable; constructor( @@ -47,9 +45,11 @@ export class CfAppsDataSource extends ListDataSource { transformEntities?: any[], paginationKey = CfAppsDataSource.paginationKey, seedPaginationKey = CfAppsDataSource.paginationKey, + startingCfGuid?: string ) { const syncNeeded = paginationKey !== seedPaginationKey; const action = createGetAllAppAction(paginationKey); + action.endpointGuid = startingCfGuid; const dispatchSequencer = new DispatchSequencer(store); @@ -78,17 +78,6 @@ export class CfAppsDataSource extends ListDataSource { destroy: () => this.subs.forEach(sub => sub.unsubscribe()) }); - // Reapply the cf guid to the action. Normally this is done via reapplying the selection to the filter... however this is too slow - // for maxedResult world - this.initialised$ = store.select(selectPaginationState(action.entityKey, action.paginationKey)).pipe( - map(pagination => { - if (pagination && pagination.clientPagination) { - action.endpointGuid = pagination.clientPagination.filter.items.cf; - } - return true; - }) - ); - this.action = action; const statsSub = this.maxedResults$.pipe( diff --git a/src/frontend/app/shared/data-services/cf-org-space-service.service.ts b/src/frontend/app/shared/data-services/cf-org-space-service.service.ts index b745581a77..14fdb29466 100644 --- a/src/frontend/app/shared/data-services/cf-org-space-service.service.ts +++ b/src/frontend/app/shared/data-services/cf-org-space-service.service.ts @@ -1,10 +1,22 @@ import { Injectable, OnDestroy } from '@angular/core'; import { Store } from '@ngrx/store'; import { BehaviorSubject, combineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; -import { distinctUntilChanged, filter, first, map, startWith, switchMap, tap, withLatestFrom } from 'rxjs/operators'; +import { + distinctUntilChanged, + filter, + first, + map, + publishReplay, + refCount, + startWith, + switchMap, + tap, + withLatestFrom, +} from 'rxjs/operators'; import { IOrganization, ISpace } from '../../core/cf-api.types'; import { GetAllOrganizations } from '../../store/actions/organization.actions'; +import { ResetPagination, SetParams } from '../../store/actions/pagination.actions'; import { AppState } from '../../store/app-state'; import { entityFactory, organizationSchemaKey, spaceSchemaKey } from '../../store/helpers/entity-factory'; import { createEntityRelationKey } from '../../store/helpers/entity-relations/entity-relations.types'; @@ -17,11 +29,10 @@ import { endpointsRegisteredEntitiesSelector } from '../../store/selectors/endpo import { selectPaginationState } from '../../store/selectors/pagination.selectors'; import { APIResource } from '../../store/types/api.types'; import { EndpointModel } from '../../store/types/endpoint.types'; -import { PaginationMonitorFactory } from '../monitors/pagination-monitor.factory'; +import { PaginatedAction, PaginationParam, QParam } from '../../store/types/pagination.types'; import { ListPaginationMultiFilterChange } from '../components/list/data-sources-controllers/list-data-source-types'; -import { PaginationParam, QParam, PaginatedAction } from '../../store/types/pagination.types'; import { valueOrCommonFalsy } from '../components/list/data-sources-controllers/list-pagination-controller'; -import { SetParams, ResetPagination } from '../../store/actions/pagination.actions'; +import { PaginationMonitorFactory } from '../monitors/pagination-monitor.factory'; export function createCfOrgSpaceFilterConfig(key: string, label: string, cfOrgSpaceItem: CfOrgSpaceItem) { return { @@ -200,10 +211,14 @@ export class CfOrgSpaceDataService implements OnDestroy { } private createCf() { + const list$ = this.store.select(endpointsRegisteredEntitiesSelector).pipe( + // Ensure we have endpoints + filter(endpoints => endpoints && !!Object.keys(endpoints).length), + publishReplay(1), + refCount(), + ); this.cf = { - list$: this.store.select(endpointsRegisteredEntitiesSelector).pipe( - // Ensure we have endpoints - filter(endpoints => endpoints && !!Object.keys(endpoints).length), + list$: list$.pipe( // Filter out non-cf endpoints map(endpoints => Object.values(endpoints).filter(e => e.cnsi_type === 'cf')), // Ensure we have at least one connected cf @@ -218,9 +233,11 @@ export class CfOrgSpaceDataService implements OnDestroy { first(), map((endpoints: EndpointModel[]) => { return Object.values(endpoints).sort((a: EndpointModel, b: EndpointModel) => a.name.localeCompare(b.name)); - }) + }), + ), + loading$: list$.pipe( + map(cfs => !cfs) ), - loading$: this.allOrgsLoading$, select: new BehaviorSubject(undefined) }; }