[U] standup.service, huddle.comp: CRUD standups

This commit is contained in:
Jan 2020-10-29 23:13:22 +01:00
parent e1aa1342c2
commit 8509578c74
7 changed files with 186 additions and 11 deletions

View file

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
import { StandUp } from './standup'; import { StandUp } from './standup';
import { SupaService } from './supa.service'; import { SupaService } from './supa.service';
@ -10,11 +10,17 @@ export class StandupService {
// standupMap: Map<number, StandUp> = new Map(); // standupMap: Map<number, StandUp> = new Map();
standupMap = {}; standupMap = {};
standups: BehaviorSubject<any> = new BehaviorSubject([]); standups: BehaviorSubject<any> = new BehaviorSubject([]);
isListening: boolean = false;
constructor( constructor(
private supa: SupaService, private supa: SupaService,
) { } ) { }
/**
* Get StandUps from local store.
* Requests data if store is emtpy.
* @returns Observable<StandUp[]>
*/
getStandUps(): Observable<StandUp[]> { getStandUps(): Observable<StandUp[]> {
if (Object.values(this.standupMap).length === 0) { if (Object.values(this.standupMap).length === 0) {
console.log('getStandUps - REFRESH') 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>('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<StandUp>
*/
refreshStandUps(): Observable<StandUp[]> { refreshStandUps(): Observable<StandUp[]> {
this.supa.client.from<StandUp>('standup').select('id, name, description') this.subscribeToStandups();
this.supa.client.from<StandUp>('standup').select()
.then(standups => this.updateStore(standups.body)) .then(standups => this.updateStore(standups.body))
.catch(error => console.log('Error: ', error)); .catch(error => console.log('Error: ', error));
return this.standups.asObservable(); return this.standups.asObservable();
} }
/**
* Update the local store with provided standups
* @param standups
*/
updateStore(standups: StandUp[]) { updateStore(standups: StandUp[]) {
standups.forEach(e => { standups.forEach(e => {
// this.standupMap.set(e.id, e); // this.standupMap.set(e.id, e);
this.standupMap[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<StandUp> = new Subject();
this.supa.client.from<StandUp>('standup').select('id, name, description')
.filter(<never>'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<StandUp> {
const subject: Subject<StandUp> = new Subject();
this.supa.client.from<StandUp>('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<StandUp> {
const subject: Subject<StandUp> = new Subject();
this.supa.client.from<StandUp>('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<StandUp> {
const subject: Subject<StandUp> = new Subject();
this.supa.client.from<StandUp>('standup').insert(standup)
.then(data => {
subject.next(data.body[0]);
subject.complete();
})
.catch(error => {
subject.error(error);
subject.complete();
});
return subject.asObservable();
} }
} }

View file

@ -2,4 +2,9 @@ export class StandUp {
id: number; id: number;
name: string; name: string;
description: string; description: string;
constructor(name: string, description: string) {
this.name = name;
this.description = description;
}
} }

View file

@ -4,7 +4,7 @@
</nav> </nav>
<div class="container-fluid p-0"> <div class="container-fluid p-0">
<div class="myContainer d-flex"> <div class="myContainer d-flex">
<div class="menu"> <div *ngIf="supa.user | async" class="menu">
<app-channel-list></app-channel-list> <app-channel-list></app-channel-list>
</div> </div>
<div class="container content"> <div class="container content">

View file

@ -1,5 +1,5 @@
<div class="list bg-dark text-white p-3"> <div class="list bg-dark text-white p-3">
<p><strong>Standup</strong> <strong class="newBtn">+</strong></p> <p><strong>Standup</strong> <strong class="newBtn" (click)="createStandUp()">+</strong></p>
<ul class="list-unstyled"> <ul class="list-unstyled">
<li *ngFor="let s of standups" [title]="s.description" [routerLink]="'/huddle/'+s.id">{{s.name}}</li> <li *ngFor="let s of standups" [title]="s.description" [routerLink]="'/huddle/'+s.id">{{s.name}}</li>
</ul> </ul>

View file

@ -26,4 +26,11 @@ export class ChannelListComponent implements OnInit {
return this.standupSevice.getStandUps(); return this.standupSevice.getStandUps();
} }
createStandUp() {
this.standupSevice.addOne(new StandUp('test', 'test')).subscribe(
data => console.log(data),
error => console.error(error)
)
}
} }

View file

@ -1,4 +1,14 @@
<div class="row"> <div *ngIf="standup" class="row">
<div class="col-12 col-sm-9">
<legend #name contenteditable="true" (click)="dataUpdated=true">{{ standup.name }}</legend>
<p #desc contenteditable="true" (click)="dataUpdated=true">{{ standup.description }}</p>
</div>
<div class="col-12 col-sm-3">
<div class="float-right">
<button class="btn btn-primary ml-1 mr-1" [disabled]="!dataUpdated" (click)="updateStandUp(name.innerText, desc.innerText)">Save</button>
<button class="btn btn-danger ml-1 mr-1" (click)="deleteStandUp()">Delete</button>
</div>
</div>
<div class="col-12"> <div class="col-12">
<ah-recorder></ah-recorder> <ah-recorder></ah-recorder>
</div> </div>

View file

@ -1,5 +1,8 @@
import { Component, OnInit, ViewChild } from "@angular/core"; import { Component, OnInit, ViewChild } from "@angular/core";
import { ActivatedRoute } from '@angular/router';
import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap"; import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap";
import { StandUp } from '../api/supabase/standup';
import { StandupService } from '../api/supabase/standup.service';
import { SupaService } from '../api/supabase/supa.service'; import { SupaService } from '../api/supabase/supa.service';
@Component({ @Component({
@ -33,13 +36,30 @@ export class HuddleComponent implements OnInit {
} }
]; ];
selectedUser; selectedUser;
standup: StandUp;
constructor( constructor(
private modalService: NgbModal, private modalService: NgbModal,
public supa: SupaService, private standupService: StandupService,
private route: ActivatedRoute,
) {} ) {}
ngOnInit() { ngOnInit() {
this.route.params.subscribe(
params => {
if (params.id) {
this.standupService.getOne(params.id).subscribe(
data => {
console.log(data);
this.standup = data;
},
error => {
console.error(error);
}
)
}
}
)
} }
playStory(user) { playStory(user) {
@ -91,4 +111,29 @@ export class HuddleComponent implements OnInit {
} }
this.selectedUser = this.users[index + 1]; this.selectedUser = this.users[index + 1];
} }
updateStandUp(name:string, desc:string) {
this.standup.name = name;
this.standup.description = desc;
this.standupService.updateOne(this.standup).subscribe(
data => {
console.log('Success', data);
},
error => {
console.error('Failed', error);
}
)
}
deleteStandUp() {
this.standupService.deleteOne(this.standup).subscribe(
data => {
console.log('Success', data);
},
error => {
console.error('Failed', error);
}
)
}
} }