[A] channel.service functionality, create channel from sidebar
This commit is contained in:
parent
42640f113c
commit
1da9c1e81a
5 changed files with 194 additions and 8 deletions
|
|
@ -1,9 +1,160 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
|
||||||
|
import { Channel } from './channel';
|
||||||
|
import { SupaService } from './supa.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class ChannelService {
|
export class ChannelService {
|
||||||
|
channelMap = {};
|
||||||
|
channels: BehaviorSubject<any> = new BehaviorSubject([]);
|
||||||
|
isListening: boolean = false;
|
||||||
|
|
||||||
constructor() { }
|
constructor(
|
||||||
|
private supa: SupaService,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Channels from local store.
|
||||||
|
* Requests data if store is emtpy.
|
||||||
|
* @returns Observable<Channel[]>
|
||||||
|
*/
|
||||||
|
getChannels(): Observable<Channel[]> {
|
||||||
|
if (Object.values(this.channelMap).length === 0) {
|
||||||
|
console.log('getChannels - REFRESH')
|
||||||
|
return this.refreshChannels();
|
||||||
|
} else {
|
||||||
|
console.log('getChannels - LOCAL')
|
||||||
|
return this.channels.asObservable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to realtime events from channel db.
|
||||||
|
*/
|
||||||
|
subscribeToChannels() {
|
||||||
|
if (!this.isListening) {
|
||||||
|
this.isListening = true;
|
||||||
|
this.supa.client.from<Channel>('channel').on('*', payload => {
|
||||||
|
console.log('subscribeToChannels - REALTIME EVENT', payload);
|
||||||
|
if ((payload.eventType === 'INSERT') || (payload.eventType === 'UPDATE')) {
|
||||||
|
this.channelMap[payload.new.id] = payload.new;
|
||||||
|
} else {
|
||||||
|
delete this.channelMap[payload.old.id];
|
||||||
|
}
|
||||||
|
this.next();
|
||||||
|
}).subscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests up to date data from API.
|
||||||
|
* Returns the local copy.
|
||||||
|
* @returns Observable<Channel>
|
||||||
|
*/
|
||||||
|
refreshChannels(): Observable<Channel[]> {
|
||||||
|
this.subscribeToChannels();
|
||||||
|
this.supa.client.from<Channel>('channel').select()
|
||||||
|
.then(channels => this.updateStore(channels.body))
|
||||||
|
.catch(error => console.log('Error: ', error));
|
||||||
|
return this.channels.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the local store with provided channels
|
||||||
|
* @param channels
|
||||||
|
*/
|
||||||
|
updateStore(channels: Channel[]) {
|
||||||
|
channels.forEach(e => {
|
||||||
|
this.channelMap[e.id] = e;
|
||||||
|
});
|
||||||
|
this.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emits local store.
|
||||||
|
*/
|
||||||
|
next = () => this.channels.next(Object.values(this.channelMap));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve channel from local store.
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
getOne(id: number) {
|
||||||
|
if (this.channelMap[id]) {
|
||||||
|
return of(this.channelMap[id]);
|
||||||
|
} else {
|
||||||
|
const subject: Subject<Channel> = new Subject();
|
||||||
|
this.supa.client.from<Channel>('channel').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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
updateOne(channel: Channel): Observable<Channel> {
|
||||||
|
const subject: Subject<Channel> = new Subject();
|
||||||
|
this.supa.client.from<Channel>('channel').update(channel)
|
||||||
|
.match({ id: channel.id })
|
||||||
|
.then(data => {
|
||||||
|
subject.next(data.body[0]);
|
||||||
|
subject.complete();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
subject.error(error);
|
||||||
|
subject.complete();
|
||||||
|
});
|
||||||
|
return subject.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes one channel from db.
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
deleteOne(channel: Channel): Observable<Channel> {
|
||||||
|
const subject: Subject<Channel> = new Subject();
|
||||||
|
this.supa.client.from<Channel>('channel').delete()
|
||||||
|
.match({ id: channel.id })
|
||||||
|
.then(data => {
|
||||||
|
subject.next(channel);
|
||||||
|
subject.complete();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
subject.error(error);
|
||||||
|
subject.complete();
|
||||||
|
});
|
||||||
|
return subject.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a channel on the db.
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
addOne(channel: Channel): Observable<Channel> {
|
||||||
|
const subject: Subject<Channel> = new Subject();
|
||||||
|
this.supa.client.from<Channel>('channel').insert(channel)
|
||||||
|
.then(data => {
|
||||||
|
subject.next(data.body[0]);
|
||||||
|
subject.complete();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
subject.error(error);
|
||||||
|
subject.complete();
|
||||||
|
});
|
||||||
|
return subject.asObservable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
src/app/api/supabase/channel.ts
Normal file
13
src/app/api/supabase/channel.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
export class Channel {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
inserted_at: string | Date;
|
||||||
|
created_by: string;
|
||||||
|
|
||||||
|
constructor(created_by: string, name: string, description?: string) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.created_by = created_by;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,6 @@ import { SupaService } from './supa.service';
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class StandupService {
|
export class StandupService {
|
||||||
// standupMap: Map<number, StandUp> = new Map();
|
|
||||||
standupMap = {};
|
standupMap = {};
|
||||||
standups: BehaviorSubject<any> = new BehaviorSubject([]);
|
standups: BehaviorSubject<any> = new BehaviorSubject([]);
|
||||||
isListening: boolean = false;
|
isListening: boolean = false;
|
||||||
|
|
@ -68,7 +67,6 @@ export class StandupService {
|
||||||
*/
|
*/
|
||||||
updateStore(standups: StandUp[]) {
|
updateStore(standups: StandUp[]) {
|
||||||
standups.forEach(e => {
|
standups.forEach(e => {
|
||||||
// this.standupMap.set(e.id, e);
|
|
||||||
this.standupMap[e.id] = e;
|
this.standupMap[e.id] = e;
|
||||||
});
|
});
|
||||||
this.next();
|
this.next();
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,12 @@
|
||||||
<p><strong>Standup</strong> <strong class="newBtn" (click)="createStandUp()">+</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>
|
||||||
|
<li *ngIf="standups && (standups.length === 0)"><small>There are no standups yet.</small></li>
|
||||||
</ul>
|
</ul>
|
||||||
<p><strong>Channel</strong> <strong class="newBtn">+</strong></p>
|
<p><strong>Channel</strong> <strong class="newBtn" (click)="createChannel()">+</strong></p>
|
||||||
<ul class="list-unstyled">
|
<ul class="list-unstyled">
|
||||||
<li>...</li>
|
<li *ngFor="let c of channels" [title]="c.description" [routerLink]="'/channel/'+c.id">{{c.name}}</li>
|
||||||
<li>...</li>
|
<li *ngIf="channels && (channels.length === 0)"><small>There are no channels yet.</small></li>
|
||||||
<li>...</li>
|
|
||||||
<li>...</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<p><strong>Settings</strong></p>
|
<p><strong>Settings</strong></p>
|
||||||
<ul class="list-unstyled">
|
<ul class="list-unstyled">
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@ import { Observable, throwError } from 'rxjs';
|
||||||
import { StandUp } from '../api/supabase/standup';
|
import { StandUp } from '../api/supabase/standup';
|
||||||
import { StandupService } from '../api/supabase/standup.service';
|
import { StandupService } from '../api/supabase/standup.service';
|
||||||
import { environment } from '../../environments/environment';
|
import { environment } from '../../environments/environment';
|
||||||
|
import { Channel } from '../api/supabase/channel';
|
||||||
|
import { ChannelService } from '../api/supabase/channel.service';
|
||||||
|
import { SupaService } from '../api/supabase/supa.service';
|
||||||
|
import { User } from '../api/supabase/user';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-sidebar',
|
selector: 'app-sidebar',
|
||||||
|
|
@ -11,10 +15,13 @@ import { environment } from '../../environments/environment';
|
||||||
})
|
})
|
||||||
export class SidebarComponent implements OnInit {
|
export class SidebarComponent implements OnInit {
|
||||||
standups: StandUp[] = [];
|
standups: StandUp[] = [];
|
||||||
|
channels: Channel[] = [];
|
||||||
environment = environment;
|
environment = environment;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private supaService: SupaService,
|
||||||
private standupSevice: StandupService,
|
private standupSevice: StandupService,
|
||||||
|
private channelService: ChannelService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|
@ -22,12 +29,20 @@ export class SidebarComponent implements OnInit {
|
||||||
console.log('ChannelListComponent - StandUps', standups);
|
console.log('ChannelListComponent - StandUps', standups);
|
||||||
this.standups = standups;
|
this.standups = standups;
|
||||||
});
|
});
|
||||||
|
this.loadChannels().subscribe(channels => {
|
||||||
|
console.log('ChannelListComponent - Channels', channels);
|
||||||
|
this.channels = channels;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadStandUps(): Observable<StandUp[]> {
|
loadStandUps(): Observable<StandUp[]> {
|
||||||
return this.standupSevice.getStandUps();
|
return this.standupSevice.getStandUps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadChannels(): Observable<Channel[]> {
|
||||||
|
return this.channelService.getChannels();
|
||||||
|
}
|
||||||
|
|
||||||
createStandUp() {
|
createStandUp() {
|
||||||
this.standupSevice.addOne(new StandUp('test', 'test')).subscribe(
|
this.standupSevice.addOne(new StandUp('test', 'test')).subscribe(
|
||||||
data => console.log(data),
|
data => console.log(data),
|
||||||
|
|
@ -35,4 +50,14 @@ export class SidebarComponent implements OnInit {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createChannel() {
|
||||||
|
if (!this.supaService.userProfile.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.channelService.addOne(new Channel(this.supaService.userProfile.id, 'test', 'test')).subscribe(
|
||||||
|
data => console.log(data),
|
||||||
|
error => console.error(error)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue