[U] standup.service, huddle.comp: CRUD standups
This commit is contained in:
parent
e1aa1342c2
commit
8509578c74
7 changed files with 186 additions and 11 deletions
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue