/* * Copyright (C) 2023 StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ import { AfterViewInit, Component, DestroyRef, ElementRef, inject, NgZone, OnDestroy, OnInit, ViewChild, } from '@angular/core'; import {Router} from '@angular/router'; import {Location} from '@angular/common'; import moment from 'moment'; import {SCDateSeries, SCUuid} from '@openstapps/core'; import {DataRoutingService} from '../data/data-routing.service'; import {ScheduleProvider} from '../calendar/schedule.provider'; import {AnimationController, IonContent} from '@ionic/angular'; import {DashboardCollapse} from './dashboard-collapse'; import {BreakpointObserver} from '@angular/cdk/layout'; import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; @Component({ selector: 'app-dashboard', templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.scss', '/dashboard.collapse.component.scss'], }) export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { @ViewChild('toolbar', {read: ElementRef}) toolbarRef: ElementRef; @ViewChild('schedule', {read: ElementRef}) scheduleRef: ElementRef; @ViewChild('ionContent') ionContentRef: IonContent; collapseAnimation: DashboardCollapse; /** * The events to display */ private eventUuids: SCUuid[]; /** * Next event in calendar */ nextEvent: SCDateSeries | undefined; destroy$ = inject(DestroyRef); constructor( private readonly dataRoutingService: DataRoutingService, private scheduleProvider: ScheduleProvider, protected router: Router, public location: Location, private animationControl: AnimationController, private breakpointObserver: BreakpointObserver, private zone: NgZone, ) { this.dataRoutingService .itemSelectListener() .pipe(takeUntilDestroyed()) .subscribe(item => { void this.router.navigate(['data-detail', item.uid], {state: {item}}); }); } async ngOnInit() { this.scheduleProvider.uuids$.pipe(takeUntilDestroyed(this.destroy$)).subscribe(async result => { this.eventUuids = result; await this.loadNextEvent(); }); } async ngAfterViewInit() { this.collapseAnimation = new DashboardCollapse( this.animationControl, this.zone, await this.ionContentRef.getScrollElement(), this.toolbarRef.nativeElement, this.scheduleRef.nativeElement, ); this.breakpointObserver .observe(['(min-width: 768px)']) .pipe(takeUntilDestroyed(this.destroy$)) .subscribe(async state => { await this.collapseAnimation.ready; this.collapseAnimation.active = !state.matches; }); } async loadNextEvent() { const dataSeries = await this.scheduleProvider.getDateSeries( this.eventUuids, undefined, moment(moment.now()).startOf('week').toISOString(), ); this.nextEvent = dataSeries.dates .map(series => ({ time: new Date( series.dates .sort((a, b) => new Date(a).getTime() - new Date(b).getTime()) .find(date => new Date(date) > new Date()) || Number.POSITIVE_INFINITY, ).getTime(), series, })) .sort(({time: a}, {time: b}) => a - b) .find(({time}) => !!time)?.series; } ngOnDestroy() { this.collapseAnimation.destroy(); } }