|
@@ -5,7 +5,8 @@ import { ChangeDetectionStrategy, Component, computed, inject, NgZone, OnDestroy
|
|
|
import { FormsModule } from '@angular/forms';
|
|
import { FormsModule } from '@angular/forms';
|
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
|
import { AlertCircle, BarChart3, BookOpen, CalendarDays, ChevronRight, GraduationCap, LoaderCircle, LucideAngularModule, Search, X } from 'lucide-angular';
|
|
import { AlertCircle, BarChart3, BookOpen, CalendarDays, ChevronRight, GraduationCap, LoaderCircle, LucideAngularModule, Search, X } from 'lucide-angular';
|
|
|
-import { finalize, Subscription } from 'rxjs';
|
|
|
|
|
|
|
+import { finalize, map, Subscription } from 'rxjs';
|
|
|
|
|
+import { HomeDailyCacheService } from '../../core/home-daily-cache.service';
|
|
|
import { ApiError, ApiService } from '../../core/api.service';
|
|
import { ApiError, ApiService } from '../../core/api.service';
|
|
|
import { canStartTeacherLedLearning } from '../../core/learning-access';
|
|
import { canStartTeacherLedLearning } from '../../core/learning-access';
|
|
|
import { LiveDataRefreshService, LiveSyncStatus } from '../../core/live-data-refresh.service';
|
|
import { LiveDataRefreshService, LiveSyncStatus } from '../../core/live-data-refresh.service';
|
|
@@ -102,6 +103,7 @@ export class CourseCenterPageComponent implements OnInit, OnDestroy {
|
|
|
readonly icons = { AlertCircle, BarChart3, BookOpen, CalendarDays, ChevronRight, GraduationCap, LoaderCircle, Search, X };
|
|
readonly icons = { AlertCircle, BarChart3, BookOpen, CalendarDays, ChevronRight, GraduationCap, LoaderCircle, Search, X };
|
|
|
|
|
|
|
|
private readonly api = inject(ApiService);
|
|
private readonly api = inject(ApiService);
|
|
|
|
|
+ private readonly dailyCache = inject(HomeDailyCacheService);
|
|
|
private readonly zone = inject(NgZone);
|
|
private readonly zone = inject(NgZone);
|
|
|
private readonly liveData = inject(LiveDataRefreshService);
|
|
private readonly liveData = inject(LiveDataRefreshService);
|
|
|
private readonly router = inject(Router);
|
|
private readonly router = inject(Router);
|
|
@@ -123,12 +125,20 @@ export class CourseCenterPageComponent implements OnInit, OnDestroy {
|
|
|
ngOnInit(): void {
|
|
ngOnInit(): void {
|
|
|
this.restoredScheduleState = this.restoreScheduleState();
|
|
this.restoredScheduleState = this.restoreScheduleState();
|
|
|
this.load();
|
|
this.load();
|
|
|
- this.stopLiveRefresh = this.liveData.watch({
|
|
|
|
|
|
|
+ this.stopLiveRefresh = this.isHistory ? this.liveData.watch({
|
|
|
scopes: ['courses', 'appointments'],
|
|
scopes: ['courses', 'appointments'],
|
|
|
studentId: () => this.isCoach && this.selectedStudent() === 'all' ? undefined : Number(this.selectedStudent() === 'all' ? this.session.user()?.userId : this.selectedStudent()) || undefined,
|
|
studentId: () => this.isCoach && this.selectedStudent() === 'all' ? undefined : Number(this.selectedStudent() === 'all' ? this.session.user()?.userId : this.selectedStudent()) || undefined,
|
|
|
appointmentPolling: true,
|
|
appointmentPolling: true,
|
|
|
onRefresh: () => this.load(true, true, true),
|
|
onRefresh: () => this.load(true, true, true),
|
|
|
onState: (state) => { this.liveChecking.set(state.checking); this.updateSyncStatus(state.syncStatus); },
|
|
onState: (state) => { this.liveChecking.set(state.checking); this.updateSyncStatus(state.syncStatus); },
|
|
|
|
|
+ }) : this.dailyCache.watchDay((today, previous) => {
|
|
|
|
|
+ this.now.set(Date.now());
|
|
|
|
|
+ if (this.selectedDate() === previous) {
|
|
|
|
|
+ this.selectedDate.set(today);
|
|
|
|
|
+ this.calendarMonth.set(this.firstOfMonth(this.parseDate(today)));
|
|
|
|
|
+ this.syncScheduleState();
|
|
|
|
|
+ }
|
|
|
|
|
+ this.load(false, true);
|
|
|
});
|
|
});
|
|
|
if (this.hasScheduleCalendar) this.nowTimer = this.zone.runOutsideAngular(() => setInterval(() => this.zone.run(() => this.now.set(Date.now())), 60_000));
|
|
if (this.hasScheduleCalendar) this.nowTimer = this.zone.runOutsideAngular(() => setInterval(() => this.zone.run(() => this.now.set(Date.now())), 60_000));
|
|
|
}
|
|
}
|
|
@@ -154,7 +164,7 @@ export class CourseCenterPageComponent implements OnInit, OnDestroy {
|
|
|
}
|
|
}
|
|
|
const today = this.today();
|
|
const today = this.today();
|
|
|
const range = this.isHistory || this.scheduleRange() === 'all' ? null : this.calendarWindow();
|
|
const range = this.isHistory || this.scheduleRange() === 'all' ? null : this.calendarWindow();
|
|
|
- this.loadRequest=this.api.post<CompanionOverview>('app_companion_overview', {
|
|
|
|
|
|
|
+ const params = {
|
|
|
uid,
|
|
uid,
|
|
|
mode: this.isCoach ? 'coach' : 'student',
|
|
mode: this.isCoach ? 'coach' : 'student',
|
|
|
history: this.isHistory,
|
|
history: this.isHistory,
|
|
@@ -163,12 +173,14 @@ export class CourseCenterPageComponent implements OnInit, OnDestroy {
|
|
|
dateEnd:this.isHistory||this.scheduleRange()==='all'?undefined:this.scheduleRange()==='week'?this.weekRange(this.selectedDate())[1]:this.selectedDate(),
|
|
dateEnd:this.isHistory||this.scheduleRange()==='all'?undefined:this.scheduleRange()==='week'?this.weekRange(this.selectedDate())[1]:this.selectedDate(),
|
|
|
rangeStart: range?.start,
|
|
rangeStart: range?.start,
|
|
|
rangeEnd: range?.end,
|
|
rangeEnd: range?.end,
|
|
|
- refresh,
|
|
|
|
|
source: 'database',
|
|
source: 'database',
|
|
|
- }).pipe(finalize(() => {
|
|
|
|
|
|
|
+ };
|
|
|
|
|
+ const fetch = () => this.api.post<CompanionOverview>('app_companion_overview', { ...params, refresh }).pipe(map(({ result }) => result));
|
|
|
|
|
+ const request = this.isHistory ? fetch() : this.dailyCache.load(`companion:${JSON.stringify(params)}`, fetch, refresh).pipe(map(({ value }) => value));
|
|
|
|
|
+ this.loadRequest = request.pipe(finalize(() => {
|
|
|
if (!background && requestId === this.loadId) this.loading.set(false);
|
|
if (!background && requestId === this.loadId) this.loading.set(false);
|
|
|
})).subscribe({
|
|
})).subscribe({
|
|
|
- next: ({ result }) => {
|
|
|
|
|
|
|
+ next: (result) => {
|
|
|
if(requestId!==this.loadId)return;this.listPages.set(result.page?.pageCount||1);this.listTotal.set(result.page?.itemCount||0);this.serverDates.set(result.dates||[]);this.serverStudents.set(result.studentOptions||[]);
|
|
if(requestId!==this.loadId)return;this.listPages.set(result.page?.pageCount||1);this.listTotal.set(result.page?.itemCount||0);this.serverDates.set(result.dates||[]);this.serverStudents.set(result.studentOptions||[]);
|
|
|
this.courses.set(Array.isArray(result?.courses) ? result.courses : []);
|
|
this.courses.set(Array.isArray(result?.courses) ? result.courses : []);
|
|
|
this.schedules.set(Array.isArray(result?.schedules) ? result.schedules : []);
|
|
this.schedules.set(Array.isArray(result?.schedules) ? result.schedules : []);
|