Added substitution date + default courses
This commit is contained in:
@@ -72,6 +72,9 @@ public class UnitsController : ControllerBase {
|
|||||||
|
|
||||||
data.Substitutions.Add(substitution);
|
data.Substitutions.Add(substitution);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var date = html.DocumentNode.SelectNodes("//body/center[1]")[0].ChildNodes[1];
|
||||||
|
data.Date = DateTime.Parse(date.InnerHtml.Split(" ")[0]);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
namespace BetterIServ.Backend.Entities;
|
namespace BetterIServ.Backend.Entities;
|
||||||
|
|
||||||
public struct UnitsData {
|
public struct UnitsData {
|
||||||
|
public DateTime Date { get; set; }
|
||||||
public IList<string> Notifications { get; set; }
|
public IList<string> Notifications { get; set; }
|
||||||
public IList<Substitution> Substitutions { get; set; }
|
public IList<Substitution> Substitutions { get; set; }
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using PuppeteerSharp;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
@@ -18,6 +20,8 @@ var app = builder.Build();
|
|||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
if (app.Environment.IsDevelopment()) {
|
if (app.Environment.IsDevelopment()) {
|
||||||
|
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultChromiumRevision);
|
||||||
|
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
app.UseSwaggerUI();
|
app.UseSwaggerUI();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ export class UnitsService {
|
|||||||
public async getSubstitutionPlan(date: "today" | "tomorrow"): Promise<UnitsData> {
|
public async getSubstitutionPlan(date: "today" | "tomorrow"): Promise<UnitsData> {
|
||||||
if (this.schools[this.iserv.userdata.domain] == undefined) return undefined;
|
if (this.schools[this.iserv.userdata.domain] == undefined) return undefined;
|
||||||
const url = this.schools[this.iserv.userdata.domain][date];
|
const url = this.schools[this.iserv.userdata.domain][date];
|
||||||
return await firstValueFrom(this.client.get<UnitsData>(this.iserv.backend + "/units/substitution?url=" + url));
|
const data = await firstValueFrom(this.client.get<UnitsData>(this.iserv.backend + "/units/substitution?url=" + url));
|
||||||
|
data.date = new Date(data.date);
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface UnitsData {
|
export interface UnitsData {
|
||||||
|
date: Date;
|
||||||
notifications: string[];
|
notifications: string[];
|
||||||
substitutions: Substitution[];
|
substitutions: Substitution[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
<ion-card>
|
<ion-card>
|
||||||
<ion-card-header>
|
<ion-card-header>
|
||||||
<ion-card-title>Vertretungsplan</ion-card-title>
|
<ion-card-title>Vertretungsplan</ion-card-title>
|
||||||
|
<ion-card-subtitle>{{subsDate?.toLocaleDateString()}}</ion-card-subtitle>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
<ion-card-content>
|
<ion-card-content>
|
||||||
<ion-card *ngIf="subs?.length == 0 && subs != undefined">
|
<ion-card *ngIf="subs?.length == 0 && subs != undefined">
|
||||||
|
|||||||
@@ -5,5 +5,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.lesson-content {
|
.lesson-content {
|
||||||
overflow-x: scroll;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export class HomePage implements OnInit {
|
|||||||
public today: Date;
|
public today: Date;
|
||||||
public dayName: string;
|
public dayName: string;
|
||||||
public subs: Substitution[];
|
public subs: Substitution[];
|
||||||
|
public subsDate: Date;
|
||||||
public classData: {class: string, courses: Course[]};
|
public classData: {class: string, courses: Course[]};
|
||||||
public lessons: Lesson[];
|
public lessons: Lesson[];
|
||||||
|
|
||||||
@@ -43,7 +44,13 @@ export class HomePage implements OnInit {
|
|||||||
|
|
||||||
this.unreadMails = (await mailPromise).filter(mail => !mail.read);
|
this.unreadMails = (await mailPromise).filter(mail => !mail.read);
|
||||||
this.classData = await classPromise;
|
this.classData = await classPromise;
|
||||||
this.subs = (await subsPromise).substitutions.filter(subs => subs.classes.includes(this.classData.class));
|
let unitsData = await subsPromise;
|
||||||
|
|
||||||
|
if (this.dateIsPast(unitsData.date, new Date())) {
|
||||||
|
unitsData = await this.units.getSubstitutionPlan("tomorrow");
|
||||||
|
}
|
||||||
|
this.subs = unitsData.substitutions?.filter(subs => subs.classes.includes(this.classData.class));
|
||||||
|
this.subsDate = unitsData.date;
|
||||||
|
|
||||||
if (this.classData.class.startsWith("Q")) {
|
if (this.classData.class.startsWith("Q")) {
|
||||||
this.subs = this.subs.filter(subs => this.classData.courses.filter(course => course.id == subs.lesson).length > 0);
|
this.subs = this.subs.filter(subs => this.classData.courses.filter(course => course.id == subs.lesson).length > 0);
|
||||||
@@ -54,4 +61,8 @@ export class HomePage implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private dateIsPast(first: Date, second: Date): boolean {
|
||||||
|
return first.setHours(0, 0, 0, 0) <= second.setHours(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
<ion-title>Stundenplan</ion-title>
|
<ion-title>Stundenplan</ion-title>
|
||||||
|
|
||||||
<ion-buttons slot="end">
|
<ion-buttons slot="end">
|
||||||
<ion-button (click)="onEditOrAdd()"><ion-icon ios="add-circle-outline" md="add-circle-sharp"></ion-icon></ion-button>
|
<ion-button *ngIf="courses?.length == 0 && showCourses" (click)="loadAllCourses(); defaultModal.present()"><ion-icon ios="arrow-down-circle-outline" md="arrow-down-circle-sharp" /></ion-button>
|
||||||
|
<ion-button (click)="onEditOrAdd()"><ion-icon ios="add-circle-outline" md="add-circle-sharp" /></ion-button>
|
||||||
|
|
||||||
<ion-modal #courseModal (willDismiss)="updateOrCreateCourse($event)">
|
<ion-modal #courseModal (willDismiss)="updateOrCreateCourse($event)">
|
||||||
<ng-template>
|
<ng-template>
|
||||||
@@ -24,7 +25,7 @@
|
|||||||
<ion-content class="ion-padding course-content">
|
<ion-content class="ion-padding course-content">
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-label position="stacked">Farbe</ion-label>
|
<ion-label position="stacked">Farbe</ion-label>
|
||||||
<ion-select aria-label="Farbe" interface="action-sheet" [value]="iserv.colors[0].val" #color>
|
<ion-select aria-label="Farbe" interface="action-sheet" [value]="currentCourse?.color || iserv.colors[0].val" #color>
|
||||||
<ion-select-option *ngFor="let color of iserv.colors" [value]="color.val">
|
<ion-select-option *ngFor="let color of iserv.colors" [value]="color.val">
|
||||||
{{color.name}}
|
{{color.name}}
|
||||||
</ion-select-option>
|
</ion-select-option>
|
||||||
@@ -107,6 +108,50 @@
|
|||||||
</ion-content>
|
</ion-content>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</ion-modal>
|
</ion-modal>
|
||||||
|
<ion-modal #defaultModal (didDismiss)="saveCourses($event)">
|
||||||
|
<ng-template>
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-buttons slot="start">
|
||||||
|
<ion-button (click)="defaultModal.dismiss(null, 'cancel')">Abbrechen</ion-button>
|
||||||
|
</ion-buttons>
|
||||||
|
<ion-title>Kurse hinzufügen</ion-title>
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
<ion-button (click)="defaultModal.dismiss(null, 'confirm')">Fertig</ion-button>
|
||||||
|
</ion-buttons>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content class="ion-padding course-content">
|
||||||
|
<ion-list>
|
||||||
|
<ion-item *ngFor="let course of allCourses; let i = index">
|
||||||
|
<ion-label>{{course.name}}</ion-label>
|
||||||
|
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
<ion-button color="danger" (click)="allCourses.splice(i, 1)"><ion-icon ios="close-outline" md="close-sharp" /></ion-button>
|
||||||
|
</ion-buttons>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<ion-input
|
||||||
|
label="Kürzel"
|
||||||
|
label-placement="floating"
|
||||||
|
maxlength="2"
|
||||||
|
style="width: 70px"
|
||||||
|
#newShort
|
||||||
|
/>
|
||||||
|
<ion-input
|
||||||
|
label="Name"
|
||||||
|
label-placement="floating"
|
||||||
|
#newName
|
||||||
|
/>
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
<ion-button (click)="addToAll(newName.value.toString(), newShort.value.toString()); newShort.value = ''; newName.value = ''"><ion-icon ios="add-outline" md="add-sharp" /></ion-button>
|
||||||
|
</ion-buttons>
|
||||||
|
</ion-item>
|
||||||
|
</ion-list>
|
||||||
|
</ion-content>
|
||||||
|
</ng-template>
|
||||||
|
</ion-modal>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export class SchedulePage implements OnInit {
|
|||||||
public currentCourse: Course;
|
public currentCourse: Course;
|
||||||
public timetable: Timetable = {mon: [], tue: [], wed: [], thu: [], fri: []};
|
public timetable: Timetable = {mon: [], tue: [], wed: [], thu: [], fri: []};
|
||||||
public currentLesson: {lesson: Lesson, day: string, time: number};
|
public currentLesson: {lesson: Lesson, day: string, time: number};
|
||||||
|
public allCourses: Course[];
|
||||||
|
|
||||||
@ViewChild('courseModal') courseModal: IonModal;
|
@ViewChild('courseModal') courseModal: IonModal;
|
||||||
@ViewChild('tableModal') tableModal: IonModal;
|
@ViewChild('tableModal') tableModal: IonModal;
|
||||||
@@ -103,4 +104,27 @@ export class SchedulePage implements OnInit {
|
|||||||
return rooms[rooms.length - 1];
|
return rooms[rooms.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public loadAllCourses() {
|
||||||
|
this.allCourses = [];
|
||||||
|
for (let short of Object.keys(this.iserv.courseNames)) {
|
||||||
|
const name = this.iserv.courseNames[short];
|
||||||
|
this.allCourses.push({short, name, id: short, color: this.getRandomColor()});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRandomColor(): string {
|
||||||
|
return this.iserv.colors[Math.floor(Math.random() * this.iserv.colors.length)].val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addToAll(name: string, short: string) {
|
||||||
|
this.allCourses.push({short, name, id: short, color: this.getRandomColor()});
|
||||||
|
}
|
||||||
|
|
||||||
|
public saveCourses(event: any) {
|
||||||
|
if (event.detail.role != "confirm") return;
|
||||||
|
this.courses = this.allCourses;
|
||||||
|
delete this.allCourses;
|
||||||
|
localStorage.setItem("courses", JSON.stringify(this.courses));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<ion-buttons slot="start">
|
<ion-buttons slot="start">
|
||||||
<ion-menu-button></ion-menu-button>
|
<ion-menu-button></ion-menu-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<ion-title>Vertretungsplan</ion-title>
|
<ion-title>Vertretungsplan {{data?.date.toLocaleDateString()}}</ion-title>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user