mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-04-30 12:03:12 +00:00
205 lines
6.0 KiB
TypeScript
205 lines
6.0 KiB
TypeScript
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Inject, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
|
import { DOCUMENT } from '@angular/common';
|
|
import { MatTabGroup } from '@angular/material/tabs';
|
|
import { Subject } from 'rxjs';
|
|
import { takeUntil } from 'rxjs/operators';
|
|
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
|
import { Category, Course } from 'app/modules/admin/apps/academy/academy.types';
|
|
import { AcademyService } from 'app/modules/admin/apps/academy/academy.service';
|
|
|
|
@Component({
|
|
selector : 'academy-details',
|
|
templateUrl : './details.component.html',
|
|
encapsulation : ViewEncapsulation.None,
|
|
changeDetection: ChangeDetectionStrategy.OnPush
|
|
})
|
|
export class AcademyDetailsComponent implements OnInit, OnDestroy
|
|
{
|
|
@ViewChild('courseSteps', {static: true}) courseSteps: MatTabGroup;
|
|
categories: Category[];
|
|
course: Course;
|
|
currentStep: number = 0;
|
|
drawerMode: 'over' | 'side' = 'side';
|
|
drawerOpened: boolean = true;
|
|
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
constructor(
|
|
@Inject(DOCUMENT) private _document: Document,
|
|
private _academyService: AcademyService,
|
|
private _changeDetectorRef: ChangeDetectorRef,
|
|
private _elementRef: ElementRef,
|
|
private _fuseMediaWatcherService: FuseMediaWatcherService
|
|
)
|
|
{
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------------
|
|
// @ Lifecycle hooks
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* On init
|
|
*/
|
|
ngOnInit(): void
|
|
{
|
|
// Get the categories
|
|
this._academyService.categories$
|
|
.pipe(takeUntil(this._unsubscribeAll))
|
|
.subscribe((categories: Category[]) => {
|
|
|
|
// Get the categories
|
|
this.categories = categories;
|
|
|
|
// Mark for check
|
|
this._changeDetectorRef.markForCheck();
|
|
});
|
|
|
|
// Get the course
|
|
this._academyService.course$
|
|
.pipe(takeUntil(this._unsubscribeAll))
|
|
.subscribe((course: Course) => {
|
|
|
|
// Get the course
|
|
this.course = course;
|
|
|
|
// Go to step
|
|
this.goToStep(course.progress.currentStep);
|
|
|
|
// Mark for check
|
|
this._changeDetectorRef.markForCheck();
|
|
});
|
|
|
|
// Subscribe to media changes
|
|
this._fuseMediaWatcherService.onMediaChange$
|
|
.pipe(takeUntil(this._unsubscribeAll))
|
|
.subscribe(({matchingAliases}) => {
|
|
|
|
// Set the drawerMode and drawerOpened
|
|
if ( matchingAliases.includes('lg') )
|
|
{
|
|
this.drawerMode = 'side';
|
|
this.drawerOpened = true;
|
|
}
|
|
else
|
|
{
|
|
this.drawerMode = 'over';
|
|
this.drawerOpened = false;
|
|
}
|
|
|
|
// Mark for check
|
|
this._changeDetectorRef.markForCheck();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* On destroy
|
|
*/
|
|
ngOnDestroy(): void
|
|
{
|
|
// Unsubscribe from all subscriptions
|
|
this._unsubscribeAll.next();
|
|
this._unsubscribeAll.complete();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------------
|
|
// @ Public methods
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Go to given step
|
|
*
|
|
* @param step
|
|
*/
|
|
goToStep(step: number): void
|
|
{
|
|
// Set the current step
|
|
this.currentStep = step;
|
|
|
|
// Go to the step
|
|
this.courseSteps.selectedIndex = this.currentStep;
|
|
|
|
// Mark for check
|
|
this._changeDetectorRef.markForCheck();
|
|
}
|
|
|
|
/**
|
|
* Go to previous step
|
|
*/
|
|
goToPreviousStep(): void
|
|
{
|
|
// Return if we already on the first step
|
|
if ( this.currentStep === 0 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Go to step
|
|
this.goToStep(this.currentStep - 1);
|
|
|
|
// Scroll the current step selector from sidenav into view
|
|
this._scrollCurrentStepElementIntoView();
|
|
}
|
|
|
|
/**
|
|
* Go to next step
|
|
*/
|
|
goToNextStep(): void
|
|
{
|
|
// Return if we already on the last step
|
|
if ( this.currentStep === this.course.totalSteps - 1 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Go to step
|
|
this.goToStep(this.currentStep + 1);
|
|
|
|
// Scroll the current step selector from sidenav into view
|
|
this._scrollCurrentStepElementIntoView();
|
|
}
|
|
|
|
/**
|
|
* Track by function for ngFor loops
|
|
*
|
|
* @param index
|
|
* @param item
|
|
*/
|
|
trackByFn(index: number, item: any): any
|
|
{
|
|
return item.id || index;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------------
|
|
// @ Private methods
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Scrolls the current step element from
|
|
* sidenav into the view. This only happens when
|
|
* previous/next buttons pressed as we don't want
|
|
* to change the scroll position of the sidebar
|
|
* when the user actually clicks around the sidebar.
|
|
*
|
|
* @private
|
|
*/
|
|
private _scrollCurrentStepElementIntoView(): void
|
|
{
|
|
// Wrap everything into setTimeout so we can make sure that the 'current-step' class points to correct element
|
|
setTimeout(() => {
|
|
|
|
// Get the current step element and scroll it into view
|
|
const currentStepElement = this._document.getElementsByClassName('current-step')[0];
|
|
if ( currentStepElement )
|
|
{
|
|
currentStepElement.scrollIntoView({
|
|
behavior: 'smooth',
|
|
block : 'start'
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|