Dependency Day + Basic Setup #11

Merged
it-as merged 13 commits from dependency-day-basic-setup into main 2024-03-12 17:40:21 +01:00
50 changed files with 4669 additions and 587 deletions
Showing only changes of commit d318a4b50e - Show all commits

41
frontend/.eslintrc.json Normal file
View File

@ -0,0 +1,41 @@
{
"root": true,
"ignorePatterns": ["projects/**/*"],
"overrides": [
{
"files": ["*.ts"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "li",
"style": "camelCase"
}
],
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "li",
"style": "kebab-case"
}
]
}
},
{
"files": ["*.html"],
"extends": [
"plugin:@angular-eslint/template/recommended",
"plugin:@angular-eslint/template/accessibility"
],
"rules": {}
}
]
}

0
frontend/.prettierignore Normal file
View File

11
frontend/.prettierrc.json Normal file
View File

@ -0,0 +1,11 @@
{
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"semi": true,
"bracketSpacing": true,
"arrowParens": "avoid",
"trailingComma": "es5",
"bracketSameLine": true,
"printWidth": 80
}

View File

@ -26,13 +26,8 @@
"polyfills": "src/polyfills.ts", "polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json", "tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss", "inlineStyleLanguage": "scss",
"assets": [ "assets": ["src/favicon.ico", "src/assets"],
"src/favicon.ico", "styles": ["src/styles.scss"],
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": [] "scripts": []
}, },
"configurations": { "configurations": {
@ -85,8 +80,17 @@
"options": { "options": {
"buildTarget": "li-dance-backoffice:build" "buildTarget": "li-dance-backoffice:build"
} }
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
} }
} }
} }
} }
},
"cli": {
"schematicCollections": ["@angular-eslint/schematics"]
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,8 @@
"watch": "ng build --watch --configuration development", "watch": "ng build --watch --configuration development",
"test": "jest", "test": "jest",
"test:watch": "jest --watch", "test:watch": "jest --watch",
"test:coverage": "jest --coverage" "test:coverage": "jest --coverage",
"lint": "ng lint"
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
@ -30,12 +31,24 @@
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "^17.2.3", "@angular-devkit/build-angular": "^17.2.3",
"@angular-eslint/builder": "17.2.1",
"@angular-eslint/eslint-plugin": "17.2.1",
"@angular-eslint/eslint-plugin-template": "17.2.1",
"@angular-eslint/schematics": "17.2.1",
"@angular-eslint/template-parser": "17.2.1",
"@angular/cli": "^17.2.3", "@angular/cli": "^17.2.3",
"@angular/compiler-cli": "^17.2.4", "@angular/compiler-cli": "^17.2.4",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/node": "^12.11.1", "@types/node": "^12.11.1",
"@typescript-eslint/eslint-plugin": "6.19.0",
"@typescript-eslint/parser": "6.19.0",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-preset-angular": "^14.0.3", "jest-preset-angular": "^14.0.3",
"prettier": "^3.2.5",
"prettier-eslint": "^16.3.0",
"typescript": "~5.3.3" "typescript": "~5.3.3"
}, },
"jest": { "jest": {

View File

@ -9,11 +9,11 @@ const routes: Routes = [
{ path: 'visits', component: VisitsComponent }, { path: 'visits', component: VisitsComponent },
{ path: 'select', component: VisitsDatetimeComponent }, { path: 'select', component: VisitsDatetimeComponent },
{ path: 'visits/:date/:time', component: VisitsComponent }, { path: 'visits/:date/:time', component: VisitsComponent },
{ path: '**', redirectTo: 'students' } { path: '**', redirectTo: 'students' },
]; ];
@NgModule({ @NgModule({
imports: [RouterModule.forRoot(routes)], imports: [RouterModule.forRoot(routes)],
exports: [RouterModule] exports: [RouterModule],
}) })
export class AppRoutingModule { } export class AppRoutingModule {}

View File

@ -5,12 +5,8 @@ import { AppComponent } from './app.component';
describe('AppComponent', () => { describe('AppComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
imports: [ imports: [RouterTestingModule],
RouterTestingModule declarations: [AppComponent],
],
declarations: [
AppComponent
],
}).compileComponents(); }).compileComponents();
}); });
@ -30,6 +26,8 @@ describe('AppComponent', () => {
const fixture = TestBed.createComponent(AppComponent); const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges(); fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement; const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('.content span')?.textContent).toContain('li-dance-backoffice app is running!'); expect(compiled.querySelector('.content span')?.textContent).toContain(
'li-dance-backoffice app is running!'
);
}); });
}); });

View File

@ -3,7 +3,7 @@ import { Component } from '@angular/core';
@Component({ @Component({
selector: 'li-root', selector: 'li-root',
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'] styleUrls: ['./app.component.scss'],
}) })
export class AppComponent { export class AppComponent {
title = 'li-dance-backoffice'; title = 'li-dance-backoffice';

View File

@ -32,7 +32,7 @@ import { MatNativeDateModule, MatRippleModule } from '@angular/material/core';
EnrollPipe, EnrollPipe,
VisitsComponent, VisitsComponent,
StudentEnrollComponent, StudentEnrollComponent,
VisitsDatetimeComponent VisitsDatetimeComponent,
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
@ -49,6 +49,6 @@ import { MatNativeDateModule, MatRippleModule } from '@angular/material/core';
MatNativeDateModule, MatNativeDateModule,
], ],
providers: [], providers: [],
bootstrap: [AppComponent] bootstrap: [AppComponent],
}) })
export class AppModule { } export class AppModule {}

View File

@ -1,44 +1,117 @@
<div id="student-edit-overlay" [class]="visibility()"> <div id="student-edit-overlay" [class]="visibility()">
<div id="student-edit-container"> <div id="student-edit-container">
<form id="student-edit-form"> <form id="student-edit-form">
<label id="student-edit-firstname-label" for="student-edit-firstname-input">Vorname</label> <label
<input id="student-edit-firstname-input" name="student-edit-firstname-input" type="text" [(ngModel)]="model.firstname" /> id="student-edit-firstname-label"
for="student-edit-firstname-input"
>Vorname</label
>
<input
id="student-edit-firstname-input"
name="student-edit-firstname-input"
type="text"
[(ngModel)]="model.firstname" />
<label id="student-edit-lastname-label" for="student-edit-lastname-input">Nachname</label> <label id="student-edit-lastname-label" for="student-edit-lastname-input"
<input id="student-edit-lastname-input" name="student-edit-lastname-input" type="text" [(ngModel)]="model.lastname" /> >Nachname</label
>
<input
id="student-edit-lastname-input"
name="student-edit-lastname-input"
type="text"
[(ngModel)]="model.lastname" />
<ng-container *ngIf="!simple"> <ng-container *ngIf="!simple">
<label id="student-edit-birthday-label" for="student-edit-birthday-input">Geburtsdatum</label> <label
<input id="student-edit-birthday-input" name="student-edit-birthday-input" type="date" [(ngModel)]="model.birthday" /> id="student-edit-birthday-label"
for="student-edit-birthday-input"
>Geburtsdatum</label
>
<input
id="student-edit-birthday-input"
name="student-edit-birthday-input"
type="date"
[(ngModel)]="model.birthday" />
<label id="student-edit-gender-label" for="student-edit-gender-input">Geschlecht</label> <label id="student-edit-gender-label" for="student-edit-gender-input"
<select id="student-edit-gender-input" name="student-edit-gender-input" [(ngModel)]="model.gender" > >Geschlecht</label
<option [value]="gender.id" *ngFor="let gender of genders">{{gender.text}}</option> >
<select
id="student-edit-gender-input"
name="student-edit-gender-input"
[(ngModel)]="model.gender">
<option [value]="gender.id" *ngFor="let gender of genders">
{{ gender.text }}
</option>
</select> </select>
<label id="student-edit-street-label" for="student-edit-street-input">Strasse</label> <label id="student-edit-street-label" for="student-edit-street-input"
<input id="student-edit-street-input" name="student-edit-street-input" type="text" [(ngModel)]="model.street" /> >Strasse</label
>
<input
id="student-edit-street-input"
name="student-edit-street-input"
type="text"
[(ngModel)]="model.street" />
<label id="student-edit-house-label" for="student-edit-house-input">Hausnummer</label> <label id="student-edit-house-label" for="student-edit-house-input"
<input id="student-edit-house-input" name="student-edit-house-input" type="text" [(ngModel)]="model.house" /> >Hausnummer</label
>
<input
id="student-edit-house-input"
name="student-edit-house-input"
type="text"
[(ngModel)]="model.house" />
<label id="student-edit-housesuffix-label" for="student-edit-housesuffix-input">Suffix</label> <label
<input id="student-edit-housesuffix-input" name="student-edit-housesuffix-input" type="text" [(ngModel)]="model.house_suffix" /> id="student-edit-housesuffix-label"
for="student-edit-housesuffix-input"
>Suffix</label
>
<input
id="student-edit-housesuffix-input"
name="student-edit-housesuffix-input"
type="text"
[(ngModel)]="model.house_suffix" />
<label id="student-edit-zip-label" for="student-edit-zip-input">PLZ</label> <label id="student-edit-zip-label" for="student-edit-zip-input"
<input id="student-edit-zip-input" name="student-edit-zip-input" type="text" [(ngModel)]="model.zip" /> >PLZ</label
>
<input
id="student-edit-zip-input"
name="student-edit-zip-input"
type="text"
[(ngModel)]="model.zip" />
<label id="student-edit-city-label" for="student-edit-city-input">Stadt</label> <label id="student-edit-city-label" for="student-edit-city-input"
<input id="student-edit-city-input" name="student-edit-city-input" type="text" [(ngModel)]="model.city" /> >Stadt</label
>
<input
id="student-edit-city-input"
name="student-edit-city-input"
type="text"
[(ngModel)]="model.city" />
<label id="student-edit-phone-label" for="student-edit-phone-input">Telefon</label> <label id="student-edit-phone-label" for="student-edit-phone-input"
<input id="student-edit-phone-input" name="student-edit-phone-input" type="text" [(ngModel)]="model.phone" /> >Telefon</label
>
<input
id="student-edit-phone-input"
name="student-edit-phone-input"
type="text"
[(ngModel)]="model.phone" />
<label id="student-edit-email-label" for="student-edit-email-input">E-Mail</label> <label id="student-edit-email-label" for="student-edit-email-input"
<input id="student-edit-email-input" name="student-edit-email-input" type="text" [(ngModel)]="model.email" /> >E-Mail</label
>
<input
id="student-edit-email-input"
name="student-edit-email-input"
type="text"
[(ngModel)]="model.email" />
</ng-container> </ng-container>
</form> </form>
<div style="text-align:center;"> <div style="text-align: center">
<button class="button-save" (click)="save()">Save</button> <button class="button-save" (click)="save()">Save</button>
<button class="button-close" (click)="close()">Close</button> <button class="button-close" (click)="close()">Close</button>
</div> </div>

View File

@ -1,8 +1,8 @@
.hidden{ .hidden {
display:none; display: none;
} }
.show{ .show {
display:grid; display: grid;
} }
#student-edit-container { #student-edit-container {
@ -21,7 +21,7 @@
inset: 0; inset: 0;
z-index: 99; z-index: 99;
background: rgba(0,0,0,0.8); background: rgba(0, 0, 0, 0.8);
grid-template-columns: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr;
} }
@ -59,16 +59,16 @@ button.button-close {
} }
label { label {
display:block; display: block;
width:100%; width: 100%;
margin-bottom: 0.5em; margin-bottom: 0.5em;
} }
select, select,
input[type=date], input[type='date'],
input[type=text]{ input[type='text'] {
display:block; display: block;
width:100%; width: 100%;
height: 2em; height: 2em;
margin-bottom: 1.5em; margin-bottom: 1.5em;
font-size: 1em; font-size: 1em;

View File

@ -5,10 +5,9 @@ import { StudentsService } from 'src/app/services/students/students.service';
@Component({ @Component({
selector: 'li-student-edit', selector: 'li-student-edit',
templateUrl: './student-edit.component.html', templateUrl: './student-edit.component.html',
styleUrls: ['./student-edit.component.scss'] styleUrls: ['./student-edit.component.scss'],
}) })
export class StudentEditComponent implements OnInit { export class StudentEditComponent implements OnInit {
@Input() @Input()
public student?: Student = undefined; public student?: Student = undefined;
@ -19,27 +18,28 @@ export class StudentEditComponent implements OnInit {
public closing = new EventEmitter(); public closing = new EventEmitter();
public genders = [ public genders = [
{id: 0, text: 'Männlich'}, { id: 0, text: 'Männlich' },
{id: 1, text: 'Weiblich'}, { id: 1, text: 'Weiblich' },
{id: 2, text: 'Divers'}, { id: 2, text: 'Divers' },
]; ];
public get model(): Student { public get model(): Student {
return this.student || <Student>{}; return this.student || <Student>{};
} }
constructor(private studentsService: StudentsService) { } constructor(private studentsService: StudentsService) {}
ngOnInit(): void { ngOnInit(): void {}
}
public close(): void { public close(): void {
this.closing.emit(); this.closing.emit();
} }
public save(): void { public save(): void {
if(this.student){ if (this.student) {
this.studentsService.set(this.sanitize(this.model)).subscribe(_ => this.closing.emit()); this.studentsService
.set(this.sanitize(this.model))
.subscribe(_ => this.closing.emit());
} else { } else {
this.closing.emit(); this.closing.emit();
} }
@ -50,7 +50,7 @@ export class StudentEditComponent implements OnInit {
} }
private sanitize(student: Student): Student { private sanitize(student: Student): Student {
if(student){ if (student) {
student.firstname ??= ''; student.firstname ??= '';
student.lastname ??= ''; student.lastname ??= '';
student.gender ??= 0; student.gender ??= 0;

View File

@ -1,26 +1,47 @@
<div id="student-enroll-overlay" [class]="visibility()"> <div id="student-enroll-overlay" [class]="visibility()">
<div id="student-enroll-container"> <div id="student-enroll-container">
<h1>{{model | name}}</h1> <h1>{{ model | name }}</h1>
<form id="student-enroll-form"> <form id="student-enroll-form">
<div style="display: grid; grid-template-columns: auto auto auto auto;"> <div style="display: grid; grid-template-columns: auto auto auto auto">
<ng-container *ngFor="let enrollment of student?.enrollments; index as i"> <ng-container
*ngFor="let enrollment of student?.enrollments; index as i">
<div class="enrollment-name">{{ enrollment.name }}</div> <div class="enrollment-name">{{ enrollment.name }}</div>
<div> <div>
<input *ngIf="enrollment.begin" id="student-enroll-begin-input{{i}}" name="student-enroll-begin-input{{i}}" type="date" [(ngModel)]="enrollment.begin" /> <input
<button *ngIf="!enrollment.begin" class="button-add" (click)="enroll(enrollment)">+</button> *ngIf="enrollment.begin"
id="student-enroll-begin-input{{ i }}"
name="student-enroll-begin-input{{ i }}"
type="date"
[(ngModel)]="enrollment.begin" />
<button
*ngIf="!enrollment.begin"
class="button-add"
(click)="enroll(enrollment)">
+
</button>
</div> </div>
<div> <div>
<input *ngIf="enrollment.end" id="student-enroll-end-input{{i}}" name="student-enroll-end-input{{i}}" type="date" [(ngModel)]="enrollment.end" /> <input
*ngIf="enrollment.end"
id="student-enroll-end-input{{ i }}"
name="student-enroll-end-input{{ i }}"
type="date"
[(ngModel)]="enrollment.end" />
</div> </div>
<div> <div>
<button *ngIf="enrollment.begin" class="button-remove" (click)="deroll(enrollment)">X</button> <button
*ngIf="enrollment.begin"
class="button-remove"
(click)="deroll(enrollment)">
X
</button>
</div> </div>
</ng-container> </ng-container>
</div> </div>
</form> </form>
<div style="text-align:center;"> <div style="text-align: center">
<button class="button-save" (click)="save()">Save</button> <button class="button-save" (click)="save()">Save</button>
<button class="button-close" (click)="close()">Close</button> <button class="button-close" (click)="close()">Close</button>
</div> </div>

View File

@ -1,8 +1,8 @@
.hidden{ .hidden {
display:none; display: none;
} }
.show{ .show {
display:grid; display: grid;
} }
#student-enroll-container { #student-enroll-container {
@ -21,7 +21,7 @@
inset: 0; inset: 0;
z-index: 99; z-index: 99;
background: rgba(0,0,0,0.8); background: rgba(0, 0, 0, 0.8);
grid-template-columns: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr;
} }

View File

@ -7,25 +7,22 @@ import { EnrollService } from 'src/app/services/enroll/enroll.service';
@Component({ @Component({
selector: 'li-student-enroll', selector: 'li-student-enroll',
templateUrl: './student-enroll.component.html', templateUrl: './student-enroll.component.html',
styleUrls: ['./student-enroll.component.scss'] styleUrls: ['./student-enroll.component.scss'],
}) })
export class StudentEnrollComponent implements OnInit { export class StudentEnrollComponent implements OnInit {
@Input() @Input()
public student?: Student; public student?: Student;
@Output() @Output()
public closing = new EventEmitter(); public closing = new EventEmitter();
public get model(): Student { public get model(): Student {
return this.student || <Student>{}; return this.student || <Student>{};
} }
public constructor(private enrollService: EnrollService) { } public constructor(private enrollService: EnrollService) {}
public ngOnInit() { public ngOnInit() {}
}
public enroll(enrollment: StudentEnrollment) { public enroll(enrollment: StudentEnrollment) {
enrollment.begin = formatDate(new Date(), 'yyyy-MM-dd', 'en-US'); enrollment.begin = formatDate(new Date(), 'yyyy-MM-dd', 'en-US');
@ -47,9 +44,11 @@ export class StudentEnrollComponent implements OnInit {
return; return;
} }
this.enrollService.set( this.enrollService
.set(
this.student.sid, this.student.sid,
this.student.enrollments.filter(e => e.begin)) this.student.enrollments.filter(e => e.begin)
)
.subscribe(_ => this.closing.emit()); .subscribe(_ => this.closing.emit());
} }

View File

@ -2,10 +2,9 @@
<div class="grid-item"> <div class="grid-item">
<button class="button-add" (click)="add()">Hinzufügen</button> <button class="button-add" (click)="add()">Hinzufügen</button>
</div> </div>
<div class="grid-item"> <div class="grid-item"></div>
</div>
<div class="grid-item-full"> <div class="grid-item-full">
<div *ngIf="loading;else table"> <div *ngIf="loading; else table">
<mat-spinner class="center"></mat-spinner> <mat-spinner class="center"></mat-spinner>
</div> </div>
@ -13,55 +12,101 @@
<mat-table [dataSource]="dataSource"> <mat-table [dataSource]="dataSource">
<ng-container matColumnDef="Name"> <ng-container matColumnDef="Name">
<mat-header-cell *matHeaderCellDef> Name </mat-header-cell> <mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
<mat-cell *matCellDef="let element" (click)="edit(element)">{{element | name}}</mat-cell> <mat-cell *matCellDef="let element" (click)="edit(element)">{{
element | name
}}</mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="Enroll"> <ng-container matColumnDef="Enroll">
<mat-header-cell *matHeaderCellDef> Gruppen </mat-header-cell> <mat-header-cell *matHeaderCellDef> Gruppen </mat-header-cell>
<mat-cell *matCellDef="let element" (click)="enroll(element)">{{element | enroll}}</mat-cell> <mat-cell *matCellDef="let element" (click)="enroll(element)">{{
element | enroll
}}</mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="Birthday"> <ng-container matColumnDef="Birthday">
<mat-header-cell *matHeaderCellDef> Geburtsdatum </mat-header-cell> <mat-header-cell *matHeaderCellDef> Geburtsdatum </mat-header-cell>
<mat-cell *matCellDef="let element" (click)="edit(element)">{{element.birthday | date: 'dd.MM.yyyy'}}</mat-cell> <mat-cell *matCellDef="let element" (click)="edit(element)">{{
element.birthday | date: 'dd.MM.yyyy'
}}</mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="Gender"> <ng-container matColumnDef="Gender">
<mat-header-cell *matHeaderCellDef> Geschlecht </mat-header-cell> <mat-header-cell *matHeaderCellDef> Geschlecht </mat-header-cell>
<mat-cell *matCellDef="let element" (click)="edit(element)">{{element | gender}}</mat-cell> <mat-cell *matCellDef="let element" (click)="edit(element)">{{
element | gender
}}</mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="Address"> <ng-container matColumnDef="Address">
<mat-header-cell *matHeaderCellDef> Adresse </mat-header-cell> <mat-header-cell *matHeaderCellDef> Adresse </mat-header-cell>
<mat-cell *matCellDef="let element" (click)="edit(element)">{{element | address}}</mat-cell> <mat-cell *matCellDef="let element" (click)="edit(element)">{{
element | address
}}</mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="Phone"> <ng-container matColumnDef="Phone">
<mat-header-cell *matHeaderCellDef> Telefon </mat-header-cell> <mat-header-cell *matHeaderCellDef> Telefon </mat-header-cell>
<mat-cell *matCellDef="let element" (click)="edit(element)">{{element.phone}}</mat-cell> <mat-cell *matCellDef="let element" (click)="edit(element)">{{
element.phone
}}</mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="E-Mail"> <ng-container matColumnDef="E-Mail">
<mat-header-cell *matHeaderCellDef> E-Mail </mat-header-cell> <mat-header-cell *matHeaderCellDef> E-Mail </mat-header-cell>
<mat-cell *matCellDef="let element" (click)="edit(element)">{{element.email}}</mat-cell> <mat-cell *matCellDef="let element" (click)="edit(element)">{{
element.email
}}</mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="Actions"> <ng-container matColumnDef="Actions">
<mat-header-cell *matHeaderCellDef></mat-header-cell> <mat-header-cell *matHeaderCellDef></mat-header-cell>
<mat-cell *matCellDef="let element" class="actions"><a (click)="delete(element)"><i class="bi bi-trash"></i></a></mat-cell> <mat-cell *matCellDef="let element" class="actions"
><a (click)="delete(element)"><i class="bi bi-trash"></i></a
></mat-cell>
</ng-container> </ng-container>
<mat-header-row *matHeaderRowDef="[ 'Name', 'Enroll', 'Birthday', 'Gender', 'Address', 'Phone', 'E-Mail', 'Actions' ] "></mat-header-row> <mat-header-row
<mat-row *matRowDef="let row; columns: [ 'Name', 'Enroll', 'Birthday', 'Gender', 'Address', 'Phone', 'E-Mail', 'Actions' ] "></mat-row> *matHeaderRowDef="[
'Name',
'Enroll',
'Birthday',
'Gender',
'Address',
'Phone',
'E-Mail',
'Actions'
]"></mat-header-row>
<mat-row
*matRowDef="
let row;
columns: [
'Name',
'Enroll',
'Birthday',
'Gender',
'Address',
'Phone',
'E-Mail',
'Actions'
]
"></mat-row>
</mat-table> </mat-table>
</ng-template> </ng-template>
</div> </div>
<div class="grid-item"> <div class="grid-item">
<input matInput id="pipelineFilter" (keyup)="applyFilter($event)" placeholder="Filtern"> <input
</div> matInput
<div class="grid-item"> id="pipelineFilter"
(keyup)="applyFilter($event)"
placeholder="Filtern" />
</div> </div>
<div class="grid-item"></div>
</div> </div>
<li-student-edit [student]="selectedStudent" (closing)="commit()"></li-student-edit> <li-student-edit
<li-student-enroll [student]="enrollingStudent" (closing)="commit()"></li-student-enroll> [student]="selectedStudent"
(closing)="commit()"></li-student-edit>
<li-student-enroll
[student]="enrollingStudent"
(closing)="commit()"></li-student-enroll>

View File

@ -50,7 +50,7 @@ a:hover {
.bi { .bi {
color: #411ccc; color: #411ccc;
font-size: 2em; font-size: 2em;
margin-right:0.4em; margin-right: 0.4em;
cursor: pointer; cursor: pointer;
} }
@ -62,8 +62,8 @@ a:hover {
color: white; color: white;
} }
#pipelineFilter{ #pipelineFilter {
display:block; display: block;
height: 2em; height: 2em;
margin-bottom: 1.5em; margin-bottom: 1.5em;
font-size: 1em; font-size: 1em;

View File

@ -9,10 +9,9 @@ import { StudentsService } from 'src/app/services/students/students.service';
@Component({ @Component({
selector: 'li-student-list', selector: 'li-student-list',
templateUrl: './student-list.component.html', templateUrl: './student-list.component.html',
styleUrls: ['./student-list.component.scss'] styleUrls: ['./student-list.component.scss'],
}) })
export class StudentListComponent implements OnInit { export class StudentListComponent implements OnInit {
public loading: boolean = true; public loading: boolean = true;
public students: Student[] = new Array<Student>(); public students: Student[] = new Array<Student>();
public courses: Course[] = new Array<Course>(); public courses: Course[] = new Array<Course>();
@ -23,22 +22,24 @@ export class StudentListComponent implements OnInit {
public constructor( public constructor(
private studentsService: StudentsService, private studentsService: StudentsService,
private coursesService: CoursesService) { } private coursesService: CoursesService
) {}
public ngOnInit() { public ngOnInit() {
this.dataSource.filterPredicate = function (record: any, filter: any) { this.dataSource.filterPredicate = function (record: any, filter: any) {
if(filter.length < 3) { if (filter.length < 3) {
return true; return true;
} }
const searchIn = (record.firstname?.toLocaleLowerCase() const searchIn =
+ record.lastname?.toLocaleLowerCase() record.firstname?.toLocaleLowerCase() +
+ record.street?.toLocaleLowerCase() record.lastname?.toLocaleLowerCase() +
+ record.email?.toLocaleLowerCase()) || ''; record.street?.toLocaleLowerCase() +
record.email?.toLocaleLowerCase() || '';
const searchFor = filter.toLocaleLowerCase() || ''; const searchFor = filter.toLocaleLowerCase() || '';
return searchIn.indexOf(searchFor) >= 0; return searchIn.indexOf(searchFor) >= 0;
} };
this.getData(); this.getData();
} }
@ -63,13 +64,18 @@ export class StudentListComponent implements OnInit {
public enroll(student: Student): void { public enroll(student: Student): void {
const enrollingStudent = Object.assign({}, student); const enrollingStudent = Object.assign({}, student);
enrollingStudent.enrollments = this.courses.map(c => <StudentEnrollment> { enrollingStudent.enrollments = this.courses.map(
c =>
<StudentEnrollment>{
cid: c.cid, cid: c.cid,
name: c.name, name: c.name,
diffname: c.diffname, diffname: c.diffname,
begin: student?.enrollments.find(e => e.cid === c.cid)?.begin || undefined, begin:
end: student?.enrollments.find(e => e.cid === c.cid)?.end || undefined, student?.enrollments.find(e => e.cid === c.cid)?.begin || undefined,
}); end:
student?.enrollments.find(e => e.cid === c.cid)?.end || undefined,
}
);
this.enrollingStudent = enrollingStudent; this.enrollingStudent = enrollingStudent;
} }
@ -81,16 +87,14 @@ export class StudentListComponent implements OnInit {
} }
private getData() { private getData() {
this.studentsService.get() this.studentsService.get().subscribe({
.subscribe({
next: students => { next: students => {
this.loading = false; this.loading = false;
this.students = students; this.students = students;
this.dataSource.data = this.students; this.dataSource.data = this.students;
} },
}); });
this.coursesService.get() this.coursesService.get().subscribe(c => (this.courses = c));
.subscribe(c => this.courses = c);
} }
} }

View File

@ -1,4 +1,4 @@
<div> <div>
<mat-calendar [(selected)]="selected"></mat-calendar> <mat-calendar [(selected)]="selected"></mat-calendar>
<p>Selected date: {{selected}}</p> <p>Selected date: {{ selected }}</p>
</div> </div>

View File

@ -8,9 +8,8 @@ describe('VisitsDatetimeComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ VisitsDatetimeComponent ] declarations: [VisitsDatetimeComponent],
}) }).compileComponents();
.compileComponents();
}); });
beforeEach(() => { beforeEach(() => {

View File

@ -3,15 +3,12 @@ import { Component, OnInit } from '@angular/core';
@Component({ @Component({
selector: 'li-visits-datetime', selector: 'li-visits-datetime',
templateUrl: './visits-datetime.component.html', templateUrl: './visits-datetime.component.html',
styleUrls: ['./visits-datetime.component.scss'] styleUrls: ['./visits-datetime.component.scss'],
}) })
export class VisitsDatetimeComponent implements OnInit { export class VisitsDatetimeComponent implements OnInit {
selected: Date = new Date(); selected: Date = new Date();
constructor() { } constructor() {}
ngOnInit(): void {
}
ngOnInit(): void {}
} }

View File

@ -4,37 +4,45 @@
<div *ngIf="courseVisit" id="content"> <div *ngIf="courseVisit" id="content">
<div class="grid-item"> <div class="grid-item">
<h1>{{courseVisit?.name}}</h1> <h1>{{ courseVisit?.name }}</h1>
<h2>{{courseVisit?.date | date: 'dd.MM.yyyy'}}, {{courseVisit?.begin}} - {{courseVisit?.end}}</h2> <h2>
{{ courseVisit?.date | date: 'dd.MM.yyyy' }}, {{ courseVisit?.begin }} -
{{ courseVisit?.end }}
</h2>
<button class="button-add" (click)="add()">Hinzufügen</button> <button class="button-add" (click)="add()">Hinzufügen</button>
</div> </div>
<div class="grid-item"> <div class="grid-item"></div>
</div>
<div class="grid-item-full"> <div class="grid-item-full">
<div *ngIf="loading;else table"> <div *ngIf="loading; else table">
<mat-spinner class="center"></mat-spinner> <mat-spinner class="center"></mat-spinner>
</div> </div>
<ng-template #table> <ng-template #table>
<table mat-table [dataSource]="dataSource"> <table mat-table [dataSource]="dataSource">
<ng-container matColumnDef="Name"> <ng-container matColumnDef="Name">
<th mat-header-cell *matHeaderCellDef> Name </th> <th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let element">{{element | name}}</td> <td mat-cell *matCellDef="let element">{{ element | name }}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="Visited"> <ng-container matColumnDef="Visited">
<th mat-header-cell *matHeaderCellDef> Anwesend </th> <th mat-header-cell *matHeaderCellDef>Anwesend</th>
<td mat-cell *matCellDef="let element"><input type="checkbox" [checked]="element.visited > 0" (change)="visit(element)"/></ng-container> <td mat-cell *matCellDef="let element">
<input
type="checkbox"
[checked]="element.visited > 0"
(change)="visit(element)" /></td
></ng-container>
<tr mat-header-row *matHeaderRowDef="[ 'Name', 'Visited' ] "></tr> <tr mat-header-row *matHeaderRowDef="['Name', 'Visited']"></tr>
<tr mat-row *matRowDef="let row; columns: [ 'Name', 'Visited' ] "></tr> <tr mat-row *matRowDef="let row; columns: ['Name', 'Visited']"></tr>
</table> </table>
</ng-template> </ng-template>
</div> </div>
<div class="grid-item"> <div class="grid-item"></div>
</div> <div class="grid-item"></div>
<div class="grid-item">
</div>
</div> </div>
<li-student-edit [student]="addedStudent" (closing)="commit()" [simple]="true"></li-student-edit> <li-student-edit
[student]="addedStudent"
(closing)="commit()"
[simple]="true"></li-student-edit>

View File

@ -42,9 +42,9 @@ a:hover {
color: aqua; color: aqua;
} }
input[type=checkbox] { input[type='checkbox'] {
width:2em; width: 2em;
height:2em; height: 2em;
} }
.grid-item-full { .grid-item-full {

View File

@ -14,10 +14,9 @@ import { VisitsService } from 'src/app/services/visits/visits.service';
@Component({ @Component({
selector: 'li-visits', selector: 'li-visits',
templateUrl: './visits.component.html', templateUrl: './visits.component.html',
styleUrls: ['./visits.component.scss'] styleUrls: ['./visits.component.scss'],
}) })
export class VisitsComponent implements OnInit, OnDestroy { export class VisitsComponent implements OnInit, OnDestroy {
public loading: boolean = true; public loading: boolean = true;
public courseVisit?: CourseVisit; public courseVisit?: CourseVisit;
public dataSource = new MatTableDataSource<StudentVisit>(); public dataSource = new MatTableDataSource<StudentVisit>();
@ -30,7 +29,8 @@ export class VisitsComponent implements OnInit, OnDestroy {
public constructor( public constructor(
private visitsService: VisitsService, private visitsService: VisitsService,
private enrollService: EnrollService, private enrollService: EnrollService,
private route: ActivatedRoute) { } private route: ActivatedRoute
) {}
public ngOnInit() { public ngOnInit() {
this.routerSubscription = this.route.params.subscribe(params => { this.routerSubscription = this.route.params.subscribe(params => {
@ -56,13 +56,13 @@ export class VisitsComponent implements OnInit, OnDestroy {
} }
public visit(studentVisit: StudentVisit): void { public visit(studentVisit: StudentVisit): void {
const visit = <Visit> { const visit = <Visit>{
cid: this.courseVisit?.cid, cid: this.courseVisit?.cid,
sid: studentVisit.sid, sid: studentVisit.sid,
date: this.courseVisit?.date date: this.courseVisit?.date,
} };
if(studentVisit.visited > 0) { if (studentVisit.visited > 0) {
this.visitsService.del(visit).subscribe(_ => this.getData()); this.visitsService.del(visit).subscribe(_ => this.getData());
} else { } else {
this.visitsService.set(visit).subscribe(_ => this.getData()); this.visitsService.set(visit).subscribe(_ => this.getData());
@ -70,15 +70,14 @@ export class VisitsComponent implements OnInit, OnDestroy {
} }
private getData(): void { private getData(): void {
this.visitsService.get(this.courseDate) this.visitsService.get(this.courseDate).subscribe({
.subscribe({
next: courseVisit => { next: courseVisit => {
this.loading = false; this.loading = false;
this.courseVisit = courseVisit; this.courseVisit = courseVisit;
if(this.courseVisit) { if (this.courseVisit) {
this.dataSource.data = this.courseVisit.students; this.dataSource.data = this.courseVisit.students;
} }
} },
}); });
} }
@ -87,13 +86,15 @@ export class VisitsComponent implements OnInit, OnDestroy {
} }
public commit(): void { public commit(): void {
this.enrollService.set( this.enrollService
-1, .set(-1, [
[<StudentEnrollment>{ <StudentEnrollment>{
cid: this.courseVisit?.cid, cid: this.courseVisit?.cid,
begin: formatDate(new Date(), 'yyyy-MM-dd', 'en-US'), begin: formatDate(new Date(), 'yyyy-MM-dd', 'en-US'),
end: formatDate(new Date('2100-01-01'), 'yyyy-MM-dd', 'en-US') end: formatDate(new Date('2100-01-01'), 'yyyy-MM-dd', 'en-US'),
}]).subscribe(_ => { },
])
.subscribe(_ => {
this.addedStudent = undefined; this.addedStudent = undefined;
this.getData(); this.getData();
}); });

View File

@ -1,4 +1,4 @@
import { StudentVisit } from "./student-visit"; import { StudentVisit } from './student-visit';
export interface CourseVisit { export interface CourseVisit {
cid: number; cid: number;

View File

@ -1,4 +1,4 @@
import { StudentEnrollment } from "./student-enrollment"; import { StudentEnrollment } from './student-enrollment';
export interface Student { export interface Student {
sid: number; sid: number;

View File

@ -1,10 +1,10 @@
import { Pipe, PipeTransform } from '@angular/core'; import { Pipe, PipeTransform } from '@angular/core';
import { Student } from '../models/student'; import { Student } from '../models/student';
@Pipe({name: 'address'}) @Pipe({ name: 'address' })
export class AddressPipe implements PipeTransform { export class AddressPipe implements PipeTransform {
transform(student: Student): string { transform(student: Student): string {
let result = `${student.street} ${student.house}${student.house_suffix}, ${student.zip} ${student.city}` let result = `${student.street} ${student.house}${student.house_suffix}, ${student.zip} ${student.city}`;
return result.trim() === '0,' ? '' : result; return result.trim() === '0,' ? '' : result;
} }
} }

View File

@ -2,12 +2,12 @@ import { Pipe, PipeTransform } from '@angular/core';
import { Student } from '../models/student'; import { Student } from '../models/student';
@Pipe({ @Pipe({
name: 'enroll' name: 'enroll',
}) })
export class EnrollPipe implements PipeTransform { export class EnrollPipe implements PipeTransform {
transform(student: Student): string { transform(student: Student): string {
return student.enrollments?.length > 0 ? student.enrollments?.map(e => e.name).join(', ') : '+'; return student.enrollments?.length > 0
? student.enrollments?.map(e => e.name).join(', ')
: '+';
} }
} }

View File

@ -1,13 +1,16 @@
import { Pipe, PipeTransform } from '@angular/core'; import { Pipe, PipeTransform } from '@angular/core';
import { Student } from '../models/student'; import { Student } from '../models/student';
@Pipe({name: 'gender'}) @Pipe({ name: 'gender' })
export class GenderPipe implements PipeTransform { export class GenderPipe implements PipeTransform {
transform(student: Student): string { transform(student: Student): string {
switch(Number(student.gender)) { switch (Number(student.gender)) {
case 0: return 'M'; case 0:
case 1: return 'W'; return 'M';
default: return '?'; case 1:
return 'W';
default:
return '?';
} }
} }
} }

View File

@ -2,7 +2,7 @@ import { Pipe, PipeTransform } from '@angular/core';
import { Student } from '../models/student'; import { Student } from '../models/student';
import { StudentVisit } from '../models/student-visit'; import { StudentVisit } from '../models/student-visit';
@Pipe({name: 'name'}) @Pipe({ name: 'name' })
export class NamePipe implements PipeTransform { export class NamePipe implements PipeTransform {
transform(student: Student | StudentVisit): string { transform(student: Student | StudentVisit): string {
return `${student.firstname} ${student.lastname}`; return `${student.firstname} ${student.lastname}`;

View File

@ -5,14 +5,16 @@ import { Course } from 'src/app/models/course';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class CoursesService { export class CoursesService {
private readonly serviceName = "courses"; private readonly serviceName = 'courses';
constructor(private http: HttpClient) { } constructor(private http: HttpClient) {}
public get(): Observable<Course[]> { public get(): Observable<Course[]> {
return this.http.get<Course[]>(`${environment.apiUrl}${this.serviceName}/get.php`); return this.http.get<Course[]>(
`${environment.apiUrl}${this.serviceName}/get.php`
);
} }
} }

View File

@ -7,21 +7,32 @@ import { StudentEnrollment } from 'src/app/models/student-enrollment';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class EnrollService { export class EnrollService {
private readonly serviceName = "enroll"; private readonly serviceName = 'enroll';
constructor(private http: HttpClient) { } constructor(private http: HttpClient) {}
public get(cid: number, date: Date): Observable<Enrollment> { public get(cid: number, date: Date): Observable<Enrollment> {
let params = new HttpParams().set('cid', cid).set('date', formatDate(date, 'yyyy-MM-dd', '' )); let params = new HttpParams()
return this.http.get<Enrollment>(`${environment.apiUrl}${this.serviceName}/get.php`, { params: params }); .set('cid', cid)
.set('date', formatDate(date, 'yyyy-MM-dd', ''));
return this.http.get<Enrollment>(
`${environment.apiUrl}${this.serviceName}/get.php`,
{ params: params }
);
} }
public set(sid: number, enrollments: StudentEnrollment[]): Observable<boolean> { public set(
sid: number,
enrollments: StudentEnrollment[]
): Observable<boolean> {
const payload = `sid=${sid}&enrollments=${JSON.stringify(enrollments)}`; const payload = `sid=${sid}&enrollments=${JSON.stringify(enrollments)}`;
return this.http.post<boolean>(`${environment.apiUrl}${this.serviceName}/set.php`, payload); return this.http.post<boolean>(
`${environment.apiUrl}${this.serviceName}/set.php`,
payload
);
} }
} }

View File

@ -5,15 +5,17 @@ import { Student } from 'src/app/models/student';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class StudentsService { export class StudentsService {
private readonly serviceName = "students"; private readonly serviceName = 'students';
constructor(private http: HttpClient) { } constructor(private http: HttpClient) {}
public get(): Observable<Student[]> { public get(): Observable<Student[]> {
return this.http.get<Student[]>(`${environment.apiUrl}${this.serviceName}/get.php`); return this.http.get<Student[]>(
`${environment.apiUrl}${this.serviceName}/get.php`
);
} }
public set(student: Student): Observable<void> { public set(student: Student): Observable<void> {
@ -22,12 +24,18 @@ export class StudentsService {
&house=${student.house}&house_suffix=${student.house_suffix}&zip=${student.zip} &house=${student.house}&house_suffix=${student.house_suffix}&zip=${student.zip}
&city=${student.city}&phone=${student.phone}&email=${student.email}`; &city=${student.city}&phone=${student.phone}&email=${student.email}`;
return this.http.post<void>(`${environment.apiUrl}${this.serviceName}/set.php`, payload); return this.http.post<void>(
`${environment.apiUrl}${this.serviceName}/set.php`,
payload
);
} }
public del(student: Student): Observable<void> { public del(student: Student): Observable<void> {
const payload = `sid=${student.sid}`; const payload = `sid=${student.sid}`;
return this.http.post<void>(`${environment.apiUrl}${this.serviceName}/del.php`, payload); return this.http.post<void>(
`${environment.apiUrl}${this.serviceName}/del.php`,
payload
);
} }
} }

View File

@ -7,30 +7,39 @@ import { Visit } from 'src/app/models/visit';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class VisitsService { export class VisitsService {
private readonly serviceName = "visits"; private readonly serviceName = 'visits';
constructor(private http: HttpClient) { } constructor(private http: HttpClient) {}
public get(date: Date): Observable<CourseVisit> { public get(date: Date): Observable<CourseVisit> {
const payload = `date=${formatDate(date, 'yyyy-MM-dd', 'en-US' )}&time=${formatDate(date, 'HH:mm', 'en-US' )}`; const payload = `date=${formatDate(date, 'yyyy-MM-dd', 'en-US')}&time=${formatDate(date, 'HH:mm', 'en-US')}`;
// Not easy to pass "time" over GET // Not easy to pass "time" over GET
return this.http.post<CourseVisit>(`${environment.apiUrl}${this.serviceName}/get.php`, payload); return this.http.post<CourseVisit>(
`${environment.apiUrl}${this.serviceName}/get.php`,
payload
);
} }
public set(visit: Visit): Observable<boolean> { public set(visit: Visit): Observable<boolean> {
const payload = `cid=${visit.cid}&sid=${visit.sid}&date=${formatDate(visit.date, 'yyyy-MM-dd', 'en-US' )}` const payload = `cid=${visit.cid}&sid=${visit.sid}&date=${formatDate(visit.date, 'yyyy-MM-dd', 'en-US')}`;
return this.http.post<boolean>(`${environment.apiUrl}${this.serviceName}/set.php`, payload); return this.http.post<boolean>(
`${environment.apiUrl}${this.serviceName}/set.php`,
payload
);
} }
public del(visit: Visit): Observable<boolean> { public del(visit: Visit): Observable<boolean> {
// Delete accepts no payload // Delete accepts no payload
const payload = `cid=${visit.cid}&sid=${visit.sid}&date=${formatDate(visit.date, 'yyyy-MM-dd', 'en-US' )}` const payload = `cid=${visit.cid}&sid=${visit.sid}&date=${formatDate(visit.date, 'yyyy-MM-dd', 'en-US')}`;
return this.http.post<boolean>(`${environment.apiUrl}${this.serviceName}/del.php`, payload); return this.http.post<boolean>(
`${environment.apiUrl}${this.serviceName}/del.php`,
payload
);
} }
} }

View File

@ -1,4 +1,4 @@
export const environment = { export const environment = {
production: true, production: true,
apiUrl: 'https://li-dance.de/plan/api/' apiUrl: 'https://li-dance.de/plan/api/',
}; };

View File

@ -4,7 +4,7 @@
export const environment = { export const environment = {
production: false, production: false,
apiUrl: 'https://li-dance.de/plan/api/' apiUrl: 'https://li-dance.de/plan/api/',
}; };
/* /*

View File

@ -1,16 +1,20 @@
<!doctype html> <!doctype html>
<html lang="de"> <html lang="de">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8" />
<title>Li-Dance Backoffice</title> <title>Li-Dance Backoffice</title>
<base href="/"> <base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="icon" type="image/x-icon" href="favicon.ico" />
<link rel="preconnect" href="https://fonts.gstatic.com"> <link rel="preconnect" href="https://fonts.gstatic.com" />
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet"> <link
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
</head> rel="stylesheet" />
<body class="mat-typography"> <link
href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet" />
</head>
<body class="mat-typography">
<li-root></li-root> <li-root></li-root>
</body> </body>
</html> </html>

View File

@ -8,5 +8,6 @@ if (environment.production) {
enableProdMode(); enableProdMode();
} }
platformBrowserDynamic().bootstrapModule(AppModule) platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch(err => console.error(err)); .catch(err => console.error(err));

View File

@ -47,7 +47,6 @@
*/ */
import 'zone.js'; // Included with Angular CLI. import 'zone.js'; // Included with Angular CLI.
/*************************************************************************************************** /***************************************************************************************************
* APPLICATION IMPORTS * APPLICATION IMPORTS
*/ */

View File

@ -1,6 +1,6 @@
/* Provide sufficient contrast against white background */ /* Provide sufficient contrast against white background */
@import "~bootstrap-icons/font/bootstrap-icons.css"; @import '~bootstrap-icons/font/bootstrap-icons.css';
a { a {
color: #0366d6; color: #0366d6;
} }
@ -23,7 +23,7 @@ body {
body { body {
background-color: rgb(245, 126, 32); background-color: rgb(245, 126, 32);
margin: 0; margin: 0;
font-family: Roboto, "Helvetica Neue", sans-serif; font-family: Roboto, 'Helvetica Neue', sans-serif;
} }
.mat-calendar-body-cell-content { .mat-calendar-body-cell-content {
@ -38,7 +38,6 @@ body {
} }
.mat-calendar-table-header { .mat-calendar-table-header {
tr { tr {
th { th {
padding-top: 2em; padding-top: 2em;

View File

@ -5,11 +5,6 @@
"outDir": "./out-tsc/app", "outDir": "./out-tsc/app",
"types": [] "types": []
}, },
"files": [ "files": ["src/main.ts", "src/polyfills.ts"],
"src/main.ts", "include": ["src/**/*.d.ts"]
"src/polyfills.ts"
],
"include": [
"src/**/*.d.ts"
]
} }

View File

@ -18,10 +18,7 @@
"importHelpers": true, "importHelpers": true,
"target": "ES2022", "target": "ES2022",
"module": "es2020", "module": "es2020",
"lib": [ "lib": ["es2020", "dom"],
"es2020",
"dom"
],
"useDefineForClassFields": false "useDefineForClassFields": false
}, },
"angularCompilerOptions": { "angularCompilerOptions": {

View File

@ -3,17 +3,8 @@
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"outDir": "./out-tsc/spec", "outDir": "./out-tsc/spec",
"types": [ "types": ["jest", "node"]
"jest",
"node"
]
}, },
"files": [ "files": ["src/test.ts", "src/polyfills.ts"],
"src/test.ts", "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
"src/polyfills.ts"
],
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
} }