Skip to content

Commit

Permalink
feat: Display component of currently activated activity
Browse files Browse the repository at this point in the history
If toggling an activity more than once, no other activity component can be displayed.

This bug is related to Angular issue: angular/angular#25313.
This commit installs a workaround until the issue is fixed.

Fixes #10
  • Loading branch information
danielwiehl committed Dec 11, 2018
1 parent 86b77f1 commit f59a74d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import { ChangeDetectorRef, ComponentFactoryResolver, Directive, Inject, ViewContainerRef } from '@angular/core';
import { ChildrenOutletContexts, RouterOutlet } from '@angular/router';
import { ROUTER_OUTLET_NAME } from '../workbench.constants';
import { OutletContext } from '@angular/router/src/router_outlet_context';

/**
* Like 'RouterOutlet' but with functionality to dynamically set the router outlet name via {ROUTER_OUTLET_NAME} injection token.
Expand All @@ -25,5 +26,19 @@ export class WbRouterOutletDirective extends RouterOutlet {
resolver: ComponentFactoryResolver,
changeDetector: ChangeDetectorRef) {
super(parentContexts, location, resolver, outlet, changeDetector);
WbRouterOutletDirective.installWorkaroundForAngularIssue25313(parentContexts.getContext(outlet));
}

/**
* Installs a workaround for Angular issue 'https://github.com/angular/angular/issues/25313'.
* TODO[Angular 7.0]: Remove if fixed.
*
* Issue #25313: Router outlet mounts wrong component if using a route reuse strategy and if the router
* outlet was not instantiated at the time the route got activated.
*/
private static installWorkaroundForAngularIssue25313(context: OutletContext): void {
if (context.attachRef && context.route.component !== context.attachRef.componentType) {
context.attachRef = null;
}
}
}
59 changes: 56 additions & 3 deletions projects/scion/workbench/src/lib/spec/activity.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ import { async, fakeAsync, inject, TestBed, tick } from '@angular/core/testing';
import { Component, NgModule, OnDestroy } from '@angular/core';
import { WorkbenchModule } from '../workbench.module';
import { RouterTestingModule } from '@angular/router/testing';
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import { ActivatedRoute, ParamMap, Router, RouteReuseStrategy } from '@angular/router';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { advance } from './util/util.spec';
import { advance, clickElement } from './util/util.spec';
import { expect, jasmineCustomMatchers } from './util/jasmine-custom-matchers.spec';
import { Subject } from 'rxjs/index';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators';
import { ActivityPartComponent } from '../activity-part/activity-part.component';

describe('Activity part', () => {

Expand Down Expand Up @@ -53,6 +54,40 @@ describe('Activity part', () => {

tick();
})));

/**
* Test for Angular issue #25313: Router outlet mounts wrong component if using a route reuse strategy and if the router outlet was not instantiated at the time the route got activated
* @see https://github.com/angular/angular/issues/25313
*/
it('should mount the correct activity if the router outlet was not instantiated at the time the route got activated (https://github.com/angular/angular/issues/25313)', fakeAsync(inject([Router, RouteReuseStrategy], (router: Router, routeReuseStrategy: RouteReuseStrategy) => {
// Setup: set workbench reuse strategy
router.routeReuseStrategy = routeReuseStrategy;

const fixture = TestBed.createComponent(AppComponent);
advance(fixture);

// Open 'activity-1'
clickElement(fixture, ActivityPartComponent, 'a.activity-1', '(1a)');
expect(fixture).toShow(Activity1Component, '(1b)');

// Close 'activity-1'
clickElement(fixture, ActivityPartComponent, 'a.activity-1', '(2a)');
expect(fixture).not.toShow(Activity1Component, '(2b)');

// Open 'activity-1'
clickElement(fixture, ActivityPartComponent, 'a.activity-1', '(3a)');
expect(fixture).toShow(Activity1Component, '(3b)');

// Close 'activity-1'
clickElement(fixture, ActivityPartComponent, 'a.activity-1', '(4a)');
expect(fixture).not.toShow(Activity1Component, '(4b)');

// Open 'activity-2'
clickElement(fixture, ActivityPartComponent, 'a.activity-2', '(5a)');
expect(fixture).toShow(Activity2Component, '(5b)');

tick();
})));
});

/****************************************************************************************************
Expand All @@ -66,6 +101,14 @@ describe('Activity part', () => {
label="activity-debug"
routerLink="activity-debug">
</wb-activity>
<wb-activity cssClass="activity-1"
label="activity-1"
routerLink="activity-1">
</wb-activity>
<wb-activity cssClass="activity-2"
label="activity-2"
routerLink="activity-2">
</wb-activity>
</wb-workbench>
`
})
Expand Down Expand Up @@ -96,15 +139,25 @@ class AppComponent implements OnDestroy {
class ActivityDebugComponent {
}

@Component({template: 'Activity-1'})
class Activity1Component {
}

@Component({template: 'Activity-2'})
class Activity2Component {
}

@NgModule({
imports: [
WorkbenchModule.forRoot(),
NoopAnimationsModule,
RouterTestingModule.withRoutes([
{path: 'activity-debug', component: ActivityDebugComponent},
{path: 'activity-1', component: Activity1Component},
{path: 'activity-2', component: Activity2Component},
]),
],
declarations: [AppComponent, ActivityDebugComponent]
declarations: [AppComponent, ActivityDebugComponent, Activity1Component, Activity2Component]
})
class AppTestModule {
}

0 comments on commit f59a74d

Please sign in to comment.