Finish edit capabilities and add adding capabilities

This commit is contained in:
Patrick Müller 2022-12-26 15:59:24 +01:00
parent 6dd89e4c69
commit 8ae121ca0c
Signed by: Paddy
GPG Key ID: 37ABC11275CAABCE
9 changed files with 228 additions and 76 deletions

View File

@ -1,3 +1,12 @@
table, th, td {
border: .05em solid black;
}
p.has-error {
color: red;
}
td.has-error {
border-color: red;
border-width: 2px;
}

View File

@ -1,67 +1,64 @@
<td>
<div *ngIf="editActive">
{{this.event?.calendarId}}
</div>
<div *ngIf="!editActive">
{{this.event?.calendarId}}
</div>
</td>
<td>
<div *ngIf="editActive">
<ng-container *ngIf="editActive">
<td>
{{event?.calendarId}}
</td>
<td class="{{requiredFieldsMissing? 'has-error' : ''}}">
<input type="text" [(ngModel)]="event!.name">
</div>
<div *ngIf="!editActive">
{{this.event?.name}}
</div>
</td>
<td>
<div *ngIf="editActive">
</div>
<div *ngIf="!editActive">
{{this.event?.description}}
</div>
</td>
<td>
<div *ngIf="editActive">
</div>
<div *ngIf="!editActive">
{{this.event?.startDateTime}}
</div>
</td>
<td>
<div *ngIf="editActive">
</div>
<div *ngIf="!editActive">
{{this.event?.endDateTime}}
</div>
</td>
<td>
<div *ngIf="editActive">
</div>
<div *ngIf="!editActive">
{{this.event?.location}}
</div>
</td>
<td>
<div *ngIf="editActive">
</div>
<div *ngIf="!editActive">
{{this.event?.createdBy}}
</div>
</td>
<td>
<div *ngIf="editActive">
</div>
<div *ngIf="!editActive">
{{this.event?.url}}
</div>
</td>
<td>
<button (click)="toggleEdit()">{{editActive ? 'Save' : 'Edit'}}</button>
</td>
</td>
<td>
<input type="text" [(ngModel)]="event!.description">
</td>
<td class="{{showDateError || requiredFieldsMissing? 'has-error' : ''}}">
<input type="date" [(ngModel)]="newStartDate" (change)="setStartDateTime()">
<input type="time" [(ngModel)]="newStartTime" (change)="setStartDateTime()">
</td>
<td class="{{showDateError || requiredFieldsMissing? 'has-error' : ''}}">
<input type="date" [(ngModel)]="newEndDate" (change)="setEndDateTime()">
<input type="time" [(ngModel)]="newEndTime" (change)="setEndDateTime()">
</td>
<td>
<input type="text" [(ngModel)]="event!.location">
</td>
<td class="{{showDateError || requiredFieldsMissing? 'has-error' : ''}}">
{{event?.createdBy}}
</td>
<td>
<input type="text" [(ngModel)]="event!.url">
</td>
<td>
<button (click)="toggleEdit()">Save</button>
<p class="has-error" *ngIf="showDateError">Start Date must not be after end date!</p>
<p class="has-error" *ngIf="requiredFieldsMissing">Required fields are missing!</p>
</td>
</ng-container>
<ng-container *ngIf="!editActive">
<td>
{{event?.calendarId}}
</td>
<td>
{{event?.name}}
</td>
<td>
{{event?.description}}
</td>
<td>
<input type="date" [value]="newStartDate" readonly>
<input type="time" [value]="newStartTime" readonly>
</td>
<td>
<input type="date" [value]="newEndDate" readonly>
<input type="time" [value]="newEndTime" readonly>
</td>
<td>
{{event?.location}}
</td>
<td>
{{event?.createdBy}}
</td>
<td>
{{event?.url}}
</td>
<td>
<button (click)="toggleEdit()">Edit</button>
</td>
</ng-container>

View File

@ -11,20 +11,119 @@ export class EventComponent implements OnInit {
@Input() event: Event | undefined;
editActive: boolean = false;
@Input() editActive: boolean = false;
newStartDate: string | undefined;
newStartTime: string | undefined;
newEndDate: string | undefined;
newEndTime: string | undefined;
showDateError: boolean = false;
requiredFieldsMissing: boolean = false;
constructor(private api: ApiService) {
}
ngOnInit(): void {
if (this.event) {
this.newStartDate = this.serializeDate(this.event.startDateTime);
this.newStartTime = this.serializeTime(this.event.startDateTime);
this.newEndDate = this.serializeDate(this.event.endDateTime);
this.newEndTime = this.serializeTime(this.event.endDateTime);
}
}
toggleEdit() {
if(this.editActive && this.event !== undefined) {
this.api.updateEvent(this.event).subscribe((res: any) => {
console.log(res);
});
if (this.editActive && this.event !== undefined) {
// Prevent save if endDateTime is before startDateTime
if(this.event.endDateTime < this.event.startDateTime) {
this.showDateError = true;
return;
}
// Check required fields
if(
this.isNullOrBlank(this.event.name) ||
this.isNullOrBlank(this.event.createdBy) ||
this.event.startDateTime == undefined ||
this.event.endDateTime == undefined
) {
this.requiredFieldsMissing = true;
return;
}
if(this.event.eventId === undefined) {
this.api.createEvent(this.event).subscribe((res: any) => {
console.log(res);
this.event!.eventId = res.eventId;
});
} else {
// Update existing event
this.api.updateEvent(this.event).subscribe((res: any) => {
console.log(res);
});
}
}
this.editActive = !this.editActive;
}
setStartDateTime() {
if (this.newStartDate && this.event) {
let newDate: Date = this.parseDate(this.newStartDate);
this.event.startDateTime.setFullYear(newDate.getFullYear());
this.event.startDateTime.setMonth(newDate.getMonth());
this.event.startDateTime.setDate(newDate.getDate());
}
if (this.newStartTime && this.event) {
let newTime: Date = this.parseTime(this.newStartTime);
this.event.startDateTime.setHours(newTime.getHours());
this.event.startDateTime.setMinutes(newTime.getMinutes());
this.event.startDateTime.setSeconds(0);
}
}
setEndDateTime() {
if (this.newEndDate && this.event) {
let newDate: Date = this.parseDate(this.newEndDate);
this.event.endDateTime.setFullYear(newDate.getFullYear());
this.event.endDateTime.setMonth(newDate.getMonth());
this.event.endDateTime.setDate(newDate.getDate());
}
if (this.newEndTime && this.event) {
let newTime: Date = this.parseTime(this.newEndTime);
this.event.endDateTime.setHours(newTime.getHours());
this.event.endDateTime.setMinutes(newTime.getMinutes());
this.event.endDateTime.setSeconds(0);
}
}
serializeDate(date: Date): string {
let year = date.getFullYear();
let month = (date.getMonth() + 1).toString().padStart(2, '0');
let day = date.getDate().toString().padStart(2, '0');
return `${year}-${month}-${day}`;
}
serializeTime(date: Date): string {
let hours = date.getHours().toString().padStart(2, '0');
let minutes = date.getMinutes().toString().padStart(2, '0');
return `${hours}:${minutes}`;
}
parseDate(text: string): Date {
return new Date(text);
}
parseTime(text: string): Date {
return new Date(`2000-01-01T${text}:00`);
}
isNullOrBlank(str: string | null): boolean {
return str === null || str === undefined || str.trim() === '';
}
}

View File

@ -10,5 +10,6 @@
<th>URL</th>
<th>Edit</th>
</tr>
<tr app-event *ngFor="let event of events" [event]="event"></tr>
<tr app-event *ngFor="let event of events" [event]="event" [editActive]="event.eventId === undefined"></tr>
</table>
<button *ngIf="selectedCalendar !== -1" (click)="addEvent()">Add Event</button>

View File

@ -1,5 +1,6 @@
import {Component, Input, OnInit} from '@angular/core';
import {Event} from '../../models/event';
import {UtilsService} from '../../services/utils.service';
@Component({
selector: 'app-events-table',
@ -9,10 +10,20 @@ import {Event} from '../../models/event';
export class EventsTableComponent implements OnInit {
@Input() events: Event[] = [];
@Input() selectedCalendar: number = -1;
constructor() {
}
ngOnInit(): void {
}
addEvent() {
this.events.push({
calendarId: this.selectedCalendar,
startDateTime: new Date(),
endDateTime: new Date(),
createdDate: new Date(),
createdBy: UtilsService.getNameFromLocalStorage()
} as Event);
}
}

View File

@ -4,11 +4,11 @@
<input type="text" aria-label="Your Name" (keyup.enter)="login()" [(ngModel)]="name">
</div>
<div *ngIf="isLoggedIn">
<select [(ngModel)]="selectedCalendar" (change)="getEvents()">
<select [(ngModel)]="selectedCalendar" (change)="handleCalendarChange()">
<option value="" disabled selected hidden>Select calendar</option>
<option>public</option>
<option>members</option>
<option>management</option>
</select>
<app-events-table [events]="this.events"></app-events-table>
<app-events-table [events]="this.events" [selectedCalendar]="getCalendarId(selectedCalendar)"></app-events-table>
</div>

View File

@ -49,4 +49,22 @@ export class AdminComponent implements OnInit {
this.isLoggedIn = true;
this.getEvents();
}
handleCalendarChange() {
this.events = [];
this.getEvents();
}
getCalendarId(text: string): number {
switch(text) {
case 'public':
return 1;
case 'members':
return 2;
case 'management':
return 3;
default:
return -1;
}
}
}

View File

@ -37,12 +37,25 @@ export class ApiService {
updateEvent.password = password;
console.log(event);
return this.http.put(this.apiUrl + updateEvent.eventId, updateEvent);
} catch (exception) {
console.log('Error fetching events from API');
}
return new Observable<any>();
}
createEvent(event: Event): Observable<any> {
try {
let password = UtilsService.getPasswordFromLocalStorage();
let createEvent: any = event;
createEvent.password = password;
return this.http.post(this.apiUrl, createEvent);
} catch (exception) {
console.log('Error fetching events from API');
}
return new Observable<any>();
}
}

View File

@ -16,4 +16,8 @@ export class UtilsService {
static getPasswordFromLocalStorage(): string {
return localStorage.getItem('password') ?? '';
}
static getNameFromLocalStorage(): string {
return localStorage.getItem('name') ?? '';
}
}