diff --git a/src/frontend/app/features/applications/application/application-tabs-base/application-tabs-base.component.html b/src/frontend/app/features/applications/application/application-tabs-base/application-tabs-base.component.html index a047ce67e4..f487d414a0 100644 --- a/src/frontend/app/features/applications/application/application-tabs-base/application-tabs-base.component.html +++ b/src/frontend/app/features/applications/application/application-tabs-base/application-tabs-base.component.html @@ -12,10 +12,10 @@

{{ application?.app?.entity?.name }}

delete
- - + @@ -23,13 +23,13 @@

{{ application?.app?.entity?.name }}

play_arrow
- +
- - + diff --git a/src/frontend/app/features/applications/application/application-tabs-base/application-tabs-base.component.ts b/src/frontend/app/features/applications/application/application-tabs-base/application-tabs-base.component.ts index cd683d1937..62816ee56f 100644 --- a/src/frontend/app/features/applications/application/application-tabs-base/application-tabs-base.component.ts +++ b/src/frontend/app/features/applications/application/application-tabs-base/application-tabs-base.component.ts @@ -14,7 +14,7 @@ import { AppMetadataTypes, GetAppStatsAction, GetAppSummaryAction } from '../../ import { ResetPagination } from '../../../../store/actions/pagination.actions'; import { RouterNav } from '../../../../store/actions/router.actions'; import { AppState } from '../../../../store/app-state'; -import { appStatsSchemaKey } from '../../../../store/helpers/entity-factory'; +import { appStatsSchemaKey, entityFactory, applicationSchemaKey } from '../../../../store/helpers/entity-factory'; import { endpointEntitiesSelector } from '../../../../store/selectors/endpoint.selectors'; import { APIResource } from '../../../../store/types/api.types'; import { EndpointModel } from '../../../../store/types/endpoint.types'; @@ -52,7 +52,7 @@ const appDeleteConfirmation = new ConfirmationDialogConfig( styleUrls: ['./application-tabs-base.component.scss'] }) export class ApplicationTabsBaseComponent implements OnInit, OnDestroy { - + public schema = entityFactory(applicationSchemaKey); constructor( private route: ActivatedRoute, @@ -107,7 +107,7 @@ export class ApplicationTabsBaseComponent implements OnInit, OnDestroy { appSub$: Subscription; entityServiceAppRefresh$: Subscription; autoRefreshString = 'auto-refresh'; - appActions$: Observable<{[key: string]: boolean}>; + appActions$: Observable<{ [key: string]: boolean }>; autoRefreshing$ = this.entityService.updatingSection$.pipe(map( update => update[this.autoRefreshString] || { busy: false } diff --git a/src/frontend/app/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.html b/src/frontend/app/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.html index f8fad1073a..34b3a4a260 100644 --- a/src/frontend/app/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.html +++ b/src/frontend/app/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.html @@ -16,6 +16,6 @@

{{ name$ | async }}

- + diff --git a/src/frontend/app/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts b/src/frontend/app/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts index 69793872cd..49d1bb5f70 100644 --- a/src/frontend/app/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts +++ b/src/frontend/app/features/cloud-foundry/tabs/cloud-foundry-organizations/cloud-foundry-organization-spaces/cloud-foundry-space-base/cloud-foundry-space-base.component.ts @@ -1,8 +1,8 @@ -import { Component, OnInit } from '@angular/core'; + +import { Component, OnDestroy } from '@angular/core'; import { Store } from '@ngrx/store'; import { combineLatest, Observable, of as observableOf } from 'rxjs'; -import { first, map } from 'rxjs/operators'; - +import { first, map, tap } from 'rxjs/operators'; import { environment } from '../../../../../../../environments/environment'; import { CurrentUserPermissions } from '../../../../../../core/current-user-permissions.config'; import { CurrentUserPermissionsService } from '../../../../../../core/current-user-permissions.service'; @@ -11,12 +11,14 @@ import { ConfirmationDialogService } from '../../../../../../shared/components/c import { IHeaderBreadcrumb } from '../../../../../../shared/components/page-header/page-header.types'; import { RouterNav } from '../../../../../../store/actions/router.actions'; import { AppState } from '../../../../../../store/app-state'; +import { entityFactory, spaceSchemaKey } from '../../../../../../store/helpers/entity-factory'; import { canUpdateOrgSpaceRoles, getActiveRouteCfOrgSpaceProvider } from '../../../../cf.helpers'; import { CloudFoundryEndpointService } from '../../../../services/cloud-foundry-endpoint.service'; import { CloudFoundryOrganizationService } from '../../../../services/cloud-foundry-organization.service'; import { CloudFoundrySpaceService } from '../../../../services/cloud-foundry-space.service'; + @Component({ selector: 'app-cloud-foundry-space-base', templateUrl: './cloud-foundry-space-base.component.html', @@ -27,7 +29,7 @@ import { CloudFoundrySpaceService } from '../../../../services/cloud-foundry-spa CloudFoundryOrganizationService ] }) -export class CloudFoundrySpaceBaseComponent implements OnInit { +export class CloudFoundrySpaceBaseComponent implements OnDestroy { tabLinks = [ { @@ -67,9 +69,12 @@ export class CloudFoundrySpaceBaseComponent implements OnInit { public permsSpaceDelete = CurrentUserPermissions.SPACE_DELETE; public canUpdateRoles$: Observable; + public schema = entityFactory(spaceSchemaKey); + deleteRedirectSub: any; + constructor( public cfEndpointService: CloudFoundryEndpointService, - private cfSpaceService: CloudFoundrySpaceService, + public cfSpaceService: CloudFoundrySpaceService, private cfOrgService: CloudFoundryOrganizationService, private store: Store, currentUserPermissionsService: CurrentUserPermissionsService, @@ -89,6 +94,23 @@ export class CloudFoundrySpaceBaseComponent implements OnInit { cfSpaceService.cfGuid, cfSpaceService.orgGuid, cfSpaceService.spaceGuid); + + this.deleteRedirectSub = this.cfSpaceService.spaceEntityService.entityObs$.pipe( + tap(({ entityRequestInfo }) => { + if (entityRequestInfo.deleting.deleted) { + this.store.dispatch(new RouterNav({ + path: [ + 'cloud-foundry', + this.cfSpaceService.cfGuid, + 'organizations', + this.cfSpaceService.orgGuid, + 'spaces'] + })); + } + }) + ).subscribe(); + + } private setUpBreadcrumbs( @@ -118,7 +140,9 @@ export class CloudFoundrySpaceBaseComponent implements OnInit { } - ngOnInit() { } + ngOnDestroy() { + this.deleteRedirectSub.unsubscribe(); + } deleteSpaceWarn = () => { // .first within name$ @@ -139,16 +163,6 @@ export class CloudFoundrySpaceBaseComponent implements OnInit { this.cfSpaceService.orgGuid, this.cfSpaceService.cfGuid ); - - this.store.dispatch(new RouterNav({ - path: [ - 'cloud-foundry', - this.cfSpaceService.cfGuid, - 'organizations', - this.cfSpaceService.orgGuid, - 'spaces'] - } - )); } } diff --git a/src/frontend/app/shared/components/list/list.component.spec.ts b/src/frontend/app/shared/components/list/list.component.spec.ts index 57d0736267..dc98f1eb3f 100644 --- a/src/frontend/app/shared/components/list/list.component.spec.ts +++ b/src/frontend/app/shared/components/list/list.component.spec.ts @@ -1,30 +1,16 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; - import { CoreModule } from '../../../core/core.module'; import { EntityInfo } from '../../../store/types/api.types'; import { createBasicStoreModule } from '../../../test-framework/store-test-helper'; -import { PercentagePipe } from '../../pipes/percentage.pipe'; -import { ValuesPipe } from '../../pipes/values.pipe'; -import { ApplicationStateIconComponent } from '../application-state/application-state-icon/application-state-icon.component'; -import { ApplicationStateIconPipe } from '../application-state/application-state-icon/application-state-icon.pipe'; -import { ApplicationStateComponent } from '../application-state/application-state.component'; +import { EntityMonitorFactory } from '../../monitors/entity-monitor.factory.service'; +import { PaginationMonitorFactory } from '../../monitors/pagination-monitor.factory'; +import { SharedModule } from '../../shared.module'; import { ApplicationStateService } from '../application-state/application-state.service'; -import { CardStatusComponent } from '../cards/card-status/card-status.component'; -import { RunningInstancesComponent } from '../running-instances/running-instances.component'; -import { UsageGaugeComponent } from '../usage-gauge/usage-gauge.component'; -import { CardComponent, listCards } from './list-cards/card/card.component'; -import { CardsComponent } from './list-cards/cards.component'; -import { listTableCells, TableCellComponent } from './list-table/table-cell/table-cell.component'; -import { TableRowComponent } from './list-table/table-row/table-row.component'; -import { TableComponent } from './list-table/table.component'; -import { EventTabActorIconPipe } from './list-types/app-event/table-cell-event-action/event-tab-actor-icon.pipe'; import { EndpointsListConfigService } from './list-types/endpoint/endpoints-list-config.service'; import { ListComponent } from './list.component'; import { ListConfig } from './list.component.types'; -import { SharedModule } from '../../shared.module'; -import { PaginationMonitorFactory } from '../../monitors/pagination-monitor.factory'; -import { EntityMonitorFactory } from '../../monitors/entity-monitor.factory.service'; + describe('ListComponent', () => { let component: ListComponent; diff --git a/src/frontend/app/shared/components/loading-page/loading-page.component.html b/src/frontend/app/shared/components/loading-page/loading-page.component.html index 63e03cc0cb..7e81408eba 100644 --- a/src/frontend/app/shared/components/loading-page/loading-page.component.html +++ b/src/frontend/app/shared/components/loading-page/loading-page.component.html @@ -1,8 +1,8 @@ -
+
{{ alert }}
-
{{ text }}
+
{{ text$ | async }}
diff --git a/src/frontend/app/shared/components/loading-page/loading-page.component.spec.ts b/src/frontend/app/shared/components/loading-page/loading-page.component.spec.ts index 81e5330937..b9a1779d10 100644 --- a/src/frontend/app/shared/components/loading-page/loading-page.component.spec.ts +++ b/src/frontend/app/shared/components/loading-page/loading-page.component.spec.ts @@ -2,6 +2,9 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MDAppModule } from '../../../core/md.module'; import { LoadingPageComponent } from './loading-page.component'; +import { EntityMonitorFactory } from '../../monitors/entity-monitor.factory.service'; +import { createBasicStoreModule } from '../../../test-framework/store-test-helper'; +import { SharedModule } from '../../shared.module'; describe('LoadingPageComponent', () => { let component: LoadingPageComponent; @@ -9,9 +12,13 @@ describe('LoadingPageComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [LoadingPageComponent], imports: [ - MDAppModule + MDAppModule, + SharedModule, + createBasicStoreModule() + ], + providers: [ + EntityMonitorFactory ] }) .compileComponents(); diff --git a/src/frontend/app/shared/components/loading-page/loading-page.component.ts b/src/frontend/app/shared/components/loading-page/loading-page.component.ts index d069905ace..f587e7f9ba 100644 --- a/src/frontend/app/shared/components/loading-page/loading-page.component.ts +++ b/src/frontend/app/shared/components/loading-page/loading-page.component.ts @@ -1,9 +1,11 @@ -import {of as observableOf, Observable , combineLatest } from 'rxjs'; +import { of as observableOf, Observable, combineLatest } from 'rxjs'; import { animate, style, transition, trigger } from '@angular/animations'; import { Component, Input, OnInit } from '@angular/core'; -import { RouterState, Router, RouterStateSnapshot, ActivatedRoute } from '@angular/router'; -import { filter, first } from 'rxjs/operators'; +import { filter, first, startWith, map } from 'rxjs/operators'; +import { EntityMonitorFactory } from '../../monitors/entity-monitor.factory.service'; +import { schema } from 'normalizr'; +import { EntityMonitor } from '../../monitors/entity-monitor'; @Component({ selector: 'app-loading-page', @@ -22,20 +24,31 @@ import { filter, first } from 'rxjs/operators'; }) export class LoadingPageComponent implements OnInit { - constructor() { } + + constructor(private entityMonitorFactory: EntityMonitorFactory) { } @Input('isLoading') - isLoading: Observable = observableOf(false) - .pipe( - first() - ); + isLoading: Observable; @Input('text') text = 'Retrieving your data'; + @Input('deleteText') + deleteText = 'Deleting data'; + @Input('alert') alert = ''; + @Input('entityId') + private entityId: string; + + @Input('entitySchema') + private entitySchema: schema.Entity; + + public isDeleting: Observable; + + public text$: Observable; + ngOnInit() { if (this.isLoading) { this.isLoading @@ -43,6 +56,29 @@ export class LoadingPageComponent implements OnInit { filter(loading => !loading), first() ); + this.isDeleting = observableOf(false); + } else if (this.entityId && this.entitySchema) { + this.buildFromMonitor(this.entityMonitorFactory.create(this.entityId, this.entitySchema.key, this.entitySchema)); + } else { + this.isLoading = this.isDeleting = observableOf(false); } + this.text$ = combineLatest( + this.isLoading.pipe(startWith(false)), + this.isDeleting.pipe(startWith(false)) + ).pipe( + map(([isLoading, isDeleting]) => { + if (isDeleting) { + return this.deleteText; + } else if (isLoading) { + return this.text; + } + return ''; + }) + ); + } + + private buildFromMonitor(monitor: EntityMonitor) { + this.isLoading = monitor.isFetchingEntity$; + this.isDeleting = monitor.isDeletingEntity$; } }