Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Improved flyout demo & show iterator #2239

Merged
merged 13 commits into from
Jan 10, 2019
121 changes: 116 additions & 5 deletions src/demos/flyout/flyout-demo.component.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@

import {
Component
AfterViewChecked,
Component,
ElementRef,
Renderer2,
ViewChild
} from '@angular/core';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';

import {
Subject
} from 'rxjs';

import {
SkyFlyoutInstance,
SkyFlyoutService
} from '../../core';

import { FlyoutDemoContext } from './flyout-demo-context';
import { SkyFlyoutDemoInternalComponent } from './flyout-demo-internal.component';
import { ListItemModel, SkyListViewGridComponent } from '../../../dist/core';

@Component({
selector: 'sky-flyout-demo',
templateUrl: './flyout-demo.component.html'
templateUrl: './flyout-demo.component.html',
styles: [`
::ng-deep .sky-grid-row.highlighted {
border-top: 1px solid #007ca6;
box-shadow: 0px 0px 0px 3px inset #007ca6; // TODO: add this class somewhere more appropriate & use $sky-text-color-action-primary
}
}
`]
})
export class SkyFlyoutDemoComponent {
export class SkyFlyoutDemoComponent implements AfterViewChecked {
public users = Observable.of([
{ id: '1', name: 'Sally' },
{ id: '2', name: 'John' },
Expand All @@ -28,11 +44,32 @@ export class SkyFlyoutDemoComponent {

public flyout: SkyFlyoutInstance<SkyFlyoutDemoInternalComponent>;

// FLYOUT ITERATOR STUFF
@ViewChild('grid', { read: ElementRef })
public gridRef: ElementRef;
@ViewChild(SkyListViewGridComponent)
public listViewGridComponent: SkyListViewGridComponent;
private listState: ListItemModel[];
private selectedRowId: string;
private openFlyoutStream = new Subject<boolean>();

constructor(
private flyoutService: SkyFlyoutService
private flyoutService: SkyFlyoutService,
private renderer: Renderer2
) { }

public ngAfterViewChecked(): void {
Blackbaud-AlexKingman marked this conversation as resolved.
Show resolved Hide resolved
// TODO: unsubscribe on destroy
this.listViewGridComponent.items.subscribe(s => {
this.listState = s;
});
}

public openRecord(record: FlyoutDemoContext) {

// Prevent highlight from being prematurely removed.
this.openFlyoutStream.next(true);

this.flyout = this.flyoutService.open(SkyFlyoutDemoInternalComponent, {
providers: [{
provide: FlyoutDemoContext,
Expand All @@ -54,12 +91,15 @@ export class SkyFlyoutDemoComponent {
}
}
}
}
},
showIterator: true // TODO: create different demo to showcase this separately.
});

this.flyout.closed.subscribe(() => {
this.flyout = undefined;
});

this.initIterators(record, this.flyout);
}

public closeFlyout() {
Expand Down Expand Up @@ -111,4 +151,75 @@ export class SkyFlyoutDemoComponent {
}
});
}

private initIterators(record: any, flyout: SkyFlyoutInstance<any>) {
this.removeAllRowHighlights();
this.highlightRow(record.id);
this.selectedRowId = record.id;

// Remove highlights when flyout is closed.
flyout.closed
.takeUntil(this.openFlyoutStream)
.subscribe(() => {
this.removeAllRowHighlights();
});

flyout.iteratorPreviousButtonClick
.takeUntil(this.openFlyoutStream)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use takeWhile in conjunction with a simple boolean property to reduce complexity.

.takeWhile(() => this.isFlyoutOpen)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if I can do this because isFlyoutOpen becomes false before the animation finishes. It causes some weird issues where the flyout won't ever fully open.

Is using .takeUntil() causing performance issues or is it just the complexity you're worried about?

.subscribe(() => {
let previous = this.stepToItemInArray(this.listState, this.selectedRowId, -1);
Blackbaud-AlexKingman marked this conversation as resolved.
Show resolved Hide resolved
this.openRecord(previous.data);
});

flyout.iteratorNextButtonClick
.takeUntil(this.openFlyoutStream)
.subscribe(() => {
let next = this.stepToItemInArray(this.listState, this.selectedRowId, 1);
this.openRecord(next.data);
});

if (this.isFirstElementInArray(this.selectedRowId, this.listState)) {
flyout.iteratorPreviousButtonDisabled = true;
}

if (this.isLastElementInArray(this.selectedRowId, this.listState)) {
flyout.iteratorNextButtonDisabled = true;
}
}

private stepToItemInArray(array: Array<any>, currentId: string, step: number) {
for (let i = 0; i < array.length; i++) {
if (array[i].id === currentId) {
return array[i + step];
}
}
}

private isFirstElementInArray(id: any, array: any[]) {
let element = array.find(x => x.id === id);
Blackbaud-AlexKingman marked this conversation as resolved.
Show resolved Hide resolved
if (array[0] === element) {
return true;
}
return false;
}

private isLastElementInArray(id: any, array: any[]) {
let element = array.find(x => x.id === id);
Blackbaud-AlexKingman marked this conversation as resolved.
Show resolved Hide resolved
if (array[array.length - 1] === element) {
return true;
}
return false;
}

private highlightRow(id: string) {
let row = this.gridRef.nativeElement.querySelector(`tbody tr[sky-cmp-id="${id}"]`);
this.renderer.addClass(row, 'highlighted');
}

private removeAllRowHighlights() {
let rows = this.gridRef.nativeElement.querySelectorAll('tbody tr');
rows.forEach((row: HTMLElement) => {
this.renderer.removeClass(row, 'highlighted');
});
}
}