Sign in through the admin app instead of this one #20
@@ -3,7 +3,9 @@ import {Subject} from 'rxjs';
|
|||||||
import {takeUntil} from 'rxjs/operators';
|
import {takeUntil} from 'rxjs/operators';
|
||||||
import {MatDialog} from '@angular/material/dialog';
|
import {MatDialog} from '@angular/material/dialog';
|
||||||
import {Event} from '../../models/event';
|
import {Event} from '../../models/event';
|
||||||
|
import {HttpErrorResponse} from '@angular/common/http';
|
||||||
import {ApiService} from '../../services/api.service';
|
import {ApiService} from '../../services/api.service';
|
||||||
|
import {AdminAuthService} from '../../services/admin-auth.service';
|
||||||
import {EventMovePopupComponent} from "../event-move-popup/event-move-popup.component";
|
import {EventMovePopupComponent} from "../event-move-popup/event-move-popup.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -71,20 +73,21 @@ export class EventComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(this.event.eventId === undefined) {
|
if(this.event.eventId === undefined) {
|
||||||
this.api.createEvent(this.event).pipe(takeUntil(this.destroy$)).subscribe((res: any) => {
|
this.api.createEvent(this.event).pipe(takeUntil(this.destroy$)).subscribe({
|
||||||
console.log(res);
|
next: (res: any) => {
|
||||||
|
if(res.eventId) {
|
||||||
if(res.eventId) {
|
this.event!.eventId = res.eventId;
|
||||||
this.event!.eventId = res.eventId;
|
} else {
|
||||||
} else {
|
this.showCreateError = true;
|
||||||
this.showCreateError = true;
|
}
|
||||||
return;
|
},
|
||||||
}
|
error: this.handleWriteError('The new event')
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Update existing event
|
// Update existing event
|
||||||
this.api.updateEvent(this.event).pipe(takeUntil(this.destroy$)).subscribe((res: any) => {
|
this.api.updateEvent(this.event).pipe(takeUntil(this.destroy$)).subscribe({
|
||||||
console.log(res);
|
next: () => {},
|
||||||
|
error: this.handleWriteError('Your change')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,15 +183,48 @@ export class EventComponent implements OnInit, OnDestroy {
|
|||||||
let deleteConfirmed = window.confirm(`Are you sure you want to delete "${this.event!.name}"? This action cannot be undone.`);
|
let deleteConfirmed = window.confirm(`Are you sure you want to delete "${this.event!.name}"? This action cannot be undone.`);
|
||||||
|
|
||||||
if(deleteConfirmed && this.event) {
|
if(deleteConfirmed && this.event) {
|
||||||
this.api.deleteEvent(this.event).pipe(takeUntil(this.destroy$)).subscribe((res: any) => {
|
this.api.deleteEvent(this.event).pipe(takeUntil(this.destroy$)).subscribe({
|
||||||
console.log(res);
|
next: (res: any) => {
|
||||||
if(res.message) {
|
if(res.message) {
|
||||||
this.deleteEvent.next(this.event!.eventId);
|
this.deleteEvent.next(this.event!.eventId);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
error: this.handleWriteError('The deletion')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What to do when a write fails.
|
||||||
|
*
|
||||||
|
* Before the auth cutover none of the writes here had an error callback, so
|
||||||
|
* a failure was invisible: the row closed, nothing was saved, and the user
|
||||||
|
* had every reason to think it had been. A 401 is now a routine event - the
|
||||||
|
* session expires, or is ended from another app or another tab - so silence
|
||||||
|
* is no longer survivable.
|
||||||
|
*
|
||||||
|
* A 401 means the session is gone, and nothing on this page can be saved
|
||||||
|
* until it comes back, so it goes straight to the login carrying this page
|
||||||
|
* as the return target. Everything else says what happened and leaves the
|
||||||
|
* user where they are, with their edits still on screen.
|
||||||
|
*/
|
||||||
|
private handleWriteError(action: string): (error: HttpErrorResponse) => void {
|
||||||
|
return (error: HttpErrorResponse) => {
|
||||||
|
if (error.status === 401) {
|
||||||
|
window.alert(`Your session has expired, so ${action} was not saved. Signing you in again.`);
|
||||||
|
AdminAuthService.goToLogin();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error.status === 403) {
|
||||||
|
window.alert(`${action} failed: this account no longer has access to the calendar.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.alert(`${action} failed. Please try again. (${error.status || 'no response from the server'})`);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
triggerMove() {
|
triggerMove() {
|
||||||
if(this.editActive) {
|
if(this.editActive) {
|
||||||
window.alert('Please save your changes before moving the event to a different calendar.');
|
window.alert('Please save your changes before moving the event to a different calendar.');
|
||||||
@@ -204,11 +240,13 @@ export class EventComponent implements OnInit, OnDestroy {
|
|||||||
movePopup.afterClosed().pipe(takeUntil(this.destroy$)).subscribe(result => {
|
movePopup.afterClosed().pipe(takeUntil(this.destroy$)).subscribe(result => {
|
||||||
// If popup is dismissed, undefined will be returned
|
// If popup is dismissed, undefined will be returned
|
||||||
if(result) {
|
if(result) {
|
||||||
this.api.moveEvent(result).pipe(takeUntil(this.destroy$)).subscribe((res: any) => {
|
this.api.moveEvent(result).pipe(takeUntil(this.destroy$)).subscribe({
|
||||||
console.log(res);
|
next: () => {
|
||||||
// Uses the same interface as delete as from the calendar table perspective it is the same action
|
// Uses the same interface as delete as from the calendar table perspective it is the same action
|
||||||
// as a delete
|
// as a delete
|
||||||
this.deleteEvent.next(result.eventId);
|
this.deleteEvent.next(result.eventId);
|
||||||
|
},
|
||||||
|
error: this.handleWriteError('The move')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -78,20 +78,33 @@ export class AdminComponent implements OnInit, OnDestroy {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.api.getEvents(this.selectedCalendar).pipe(takeUntil(this.destroy$)).subscribe((events: Event[]): void => {
|
this.api.getEvents(this.selectedCalendar).pipe(takeUntil(this.destroy$)).subscribe({
|
||||||
for (let event of events) {
|
next: (events: Event[]): void => {
|
||||||
if(event.status !== 'DELETED') {
|
for (let event of events) {
|
||||||
this.events.push({
|
if (event.status !== 'DELETED') {
|
||||||
...event,
|
this.events.push({
|
||||||
startDateTime: new Date(event.startDateTime),
|
...event,
|
||||||
endDateTime: new Date(event.endDateTime),
|
startDateTime: new Date(event.startDateTime),
|
||||||
createdDate: new Date(event.createdDate),
|
endDateTime: new Date(event.endDateTime),
|
||||||
lastModifiedDate: new Date(event.lastModifiedDate)
|
createdDate: new Date(event.createdDate),
|
||||||
});
|
lastModifiedDate: new Date(event.lastModifiedDate)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.filterEvents();
|
||||||
|
this.sortEvents();
|
||||||
|
},
|
||||||
|
// Without this a failed load is indistinguishable from an empty
|
||||||
|
// calendar - which is exactly what the old bundle looks like against
|
||||||
|
// the post-cutover API, and how a deploy in progress gets mistaken for
|
||||||
|
// lost data.
|
||||||
|
error: (error: HttpErrorResponse): void => {
|
||||||
|
if (error.status === 401) {
|
||||||
|
AdminAuthService.goToLogin();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.failure = error.status === 403 ? 'denied' : 'unavailable';
|
||||||
}
|
}
|
||||||
this.filterEvents();
|
|
||||||
this.sortEvents();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user