From 8509578c7440d3f5246325a10daf612818122aed Mon Sep 17 00:00:00 2001 From: jgerstbe Date: Thu, 29 Oct 2020 23:13:22 +0100 Subject: [PATCH] [U] standup.service, huddle.comp: CRUD standups --- src/app/api/supabase/standup.service.ts | 122 +++++++++++++++++- src/app/api/supabase/standup.ts | 5 + src/app/app.component.html | 2 +- .../channel-list/channel-list.component.html | 2 +- .../channel-list/channel-list.component.ts | 7 + src/app/huddle/huddle.component.html | 12 +- src/app/huddle/huddle.component.ts | 47 ++++++- 7 files changed, 186 insertions(+), 11 deletions(-) diff --git a/src/app/api/supabase/standup.service.ts b/src/app/api/supabase/standup.service.ts index f7953e0..f67c401 100644 --- a/src/app/api/supabase/standup.service.ts +++ b/src/app/api/supabase/standup.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { BehaviorSubject, Observable, of, Subject } from 'rxjs'; import { StandUp } from './standup'; import { SupaService } from './supa.service'; @@ -10,11 +10,17 @@ export class StandupService { // standupMap: Map = new Map(); standupMap = {}; standups: BehaviorSubject = new BehaviorSubject([]); + isListening: boolean = false; constructor( private supa: SupaService, ) { } + /** + * Get StandUps from local store. + * Requests data if store is emtpy. + * @returns Observable + */ getStandUps(): Observable { if (Object.values(this.standupMap).length === 0) { console.log('getStandUps - REFRESH') @@ -25,31 +31,133 @@ export class StandupService { } } + /** + * Listen to realtime events from standup db. + */ + subscribeToStandups() { + if (!this.isListening) { + this.isListening = true; + this.supa.client.from('standup').on('*', payload => { + console.log('subscribeToStandups - REALTIME EVENT', payload); + if ((payload.eventType === 'INSERT') || (payload.eventType === 'UPDATE')) { + this.standupMap[payload.new.id] = payload.new; + } else { + delete this.standupMap[payload.old.id]; + } + this.next(); + }).subscribe(); + } + } + + /** + * Requests up to date data from API. + * Returns the local copy. + * @returns Observable + */ refreshStandUps(): Observable { - this.supa.client.from('standup').select('id, name, description') + this.subscribeToStandups(); + this.supa.client.from('standup').select() .then(standups => this.updateStore(standups.body)) .catch(error => console.log('Error: ', error)); return this.standups.asObservable(); } + /** + * Update the local store with provided standups + * @param standups + */ updateStore(standups: StandUp[]) { standups.forEach(e => { // this.standupMap.set(e.id, e); this.standupMap[e.id] = e; }); - this.standups.next(Object.values(this.standupMap)); + this.next(); } - updateOne(standup: StandUp) { + /** + * Emits local store. + */ + next = () => this.standups.next(Object.values(this.standupMap)); + /** + * Retrieve standup from local store. + * @param id + */ + getOne(id: number) { + if (this.standupMap[id]) { + return of(this.standupMap[id]); + } else { + const subject: Subject = new Subject(); + this.supa.client.from('standup').select('id, name, description') + .filter('id', 'eq', id) + .then(data => { + this.updateStore([data.body[0]]); + subject.next(data.body[0]); + subject.complete(); + }) + .catch(error => { + subject.error(error); + subject.complete(); + }); + return subject.asObservable(); + } } - deleteOne(standup: StandUp) { - + /** + * + * @param standup + */ + updateOne(standup: StandUp): Observable { + const subject: Subject = new Subject(); + this.supa.client.from('standup').update(standup) + .match({ id: standup.id }) + .then(data => { + subject.next(data.body[0]); + subject.complete(); + }) + .catch(error => { + subject.error(error); + subject.complete(); + }); + return subject.asObservable(); } - addOne(standup: StandUp) { + /** + * Removes one standup from db. + * @param standup + */ + deleteOne(standup: StandUp): Observable { + const subject: Subject = new Subject(); + this.supa.client.from('standup').delete() + .match({ id: standup.id }) + .then(data => { + subject.next(standup); + subject.complete(); + }) + .catch(error => { + subject.error(error); + subject.complete(); + }); + return subject.asObservable(); + } + + /** + * Creates a standup on the db. + * @param standup + */ + addOne(standup: StandUp): Observable { + const subject: Subject = new Subject(); + this.supa.client.from('standup').insert(standup) + .then(data => { + subject.next(data.body[0]); + subject.complete(); + }) + .catch(error => { + subject.error(error); + subject.complete(); + }); + return subject.asObservable(); } } diff --git a/src/app/api/supabase/standup.ts b/src/app/api/supabase/standup.ts index b6aa608..a529637 100644 --- a/src/app/api/supabase/standup.ts +++ b/src/app/api/supabase/standup.ts @@ -2,4 +2,9 @@ export class StandUp { id: number; name: string; description: string; + + constructor(name: string, description: string) { + this.name = name; + this.description = description; + } } \ No newline at end of file diff --git a/src/app/app.component.html b/src/app/app.component.html index 5acaf4c..72725c9 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -4,7 +4,7 @@
-