fuse-angular/src/app/modules/admin/apps/scrumboard/scrumboard.service.ts
sercan 3a1a7d44b6 Updated RxJS to 7.4.0
Optimized import paths
2021-11-05 11:36:03 +03:00

608 lines
17 KiB
TypeScript

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, map, Observable, of, switchMap, take, tap, throwError } from 'rxjs';
import { Board, Card, Label, List } from 'app/modules/admin/apps/scrumboard/scrumboard.models';
@Injectable({
providedIn: 'root'
})
export class ScrumboardService
{
// Private
private _board: BehaviorSubject<Board | null>;
private _boards: BehaviorSubject<Board[] | null>;
private _card: BehaviorSubject<Card | null>;
/**
* Constructor
*/
constructor(
private _httpClient: HttpClient
)
{
// Set the private defaults
this._board = new BehaviorSubject(null);
this._boards = new BehaviorSubject(null);
this._card = new BehaviorSubject(null);
}
// -----------------------------------------------------------------------------------------------------
// @ Accessors
// -----------------------------------------------------------------------------------------------------
/**
* Getter for board
*/
get board$(): Observable<Board>
{
return this._board.asObservable();
}
/**
* Getter for boards
*/
get boards$(): Observable<Board[]>
{
return this._boards.asObservable();
}
/**
* Getter for card
*/
get card$(): Observable<Card>
{
return this._card.asObservable();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Get boards
*/
getBoards(): Observable<Board[]>
{
return this._httpClient.get<Board[]>('api/apps/scrumboard/boards').pipe(
map(response => response.map(item => new Board(item))),
tap(boards => this._boards.next(boards))
);
}
/**
* Get board
*
* @param id
*/
getBoard(id: string): Observable<Board>
{
return this._httpClient.get<Board>('api/apps/scrumboard/board', {params: {id}}).pipe(
map(response => new Board(response)),
tap(board => this._board.next(board))
);
}
/**
* Create board
*
* @param board
*/
createBoard(board: Board): Observable<Board>
{
return this.boards$.pipe(
take(1),
switchMap(boards => this._httpClient.put<Board>('api/apps/scrumboard/board', {board}).pipe(
map((newBoard) => {
// Update the boards with the new board
this._boards.next([...boards, newBoard]);
// Return new board from observable
return newBoard;
})
))
);
}
/**
* Update the board
*
* @param id
* @param board
*/
updateBoard(id: string, board: Board): Observable<Board>
{
return this.boards$.pipe(
take(1),
switchMap(boards => this._httpClient.patch<Board>('api/apps/scrumboard/board', {
id,
board
}).pipe(
map((updatedBoard) => {
// Find the index of the updated board
const index = boards.findIndex(item => item.id === id);
// Update the board
boards[index] = updatedBoard;
// Update the boards
this._boards.next(boards);
// Return the updated board
return updatedBoard;
})
))
);
}
/**
* Delete the board
*
* @param id
*/
deleteBoard(id: string): Observable<boolean>
{
return this.boards$.pipe(
take(1),
switchMap(boards => this._httpClient.delete('api/apps/scrumboard/board', {params: {id}}).pipe(
map((isDeleted: boolean) => {
// Find the index of the deleted board
const index = boards.findIndex(item => item.id === id);
// Delete the board
boards.splice(index, 1);
// Update the boards
this._boards.next(boards);
// Update the board
this._board.next(null);
// Update the card
this._card.next(null);
// Return the deleted status
return isDeleted;
})
))
);
}
/**
* Create list
*
* @param list
*/
createList(list: List): Observable<List>
{
return this._httpClient.post<List>('api/apps/scrumboard/board/list', {list}).pipe(
map(response => new List(response)),
tap((newList) => {
// Get the board value
const board = this._board.value;
// Update the board lists with the new list
board.lists = [...board.lists, newList];
// Sort the board lists
board.lists.sort((a, b) => a.position - b.position);
// Update the board
this._board.next(board);
})
);
}
/**
* Update the list
*
* @param list
*/
updateList(list: List): Observable<List>
{
return this._httpClient.patch<List>('api/apps/scrumboard/board/list', {list}).pipe(
map(response => new List(response)),
tap((updatedList) => {
// Get the board value
const board = this._board.value;
// Find the index of the updated list
const index = board.lists.findIndex(item => item.id === list.id);
// Update the list
board.lists[index] = updatedList;
// Sort the board lists
board.lists.sort((a, b) => a.position - b.position);
// Update the board
this._board.next(board);
})
);
}
/**
* Update the lists
*
* @param lists
*/
updateLists(lists: List[]): Observable<List[]>
{
return this._httpClient.patch<List[]>('api/apps/scrumboard/board/lists', {lists}).pipe(
map(response => response.map(item => new List(item))),
tap((updatedLists) => {
// Get the board value
const board = this._board.value;
// Go through the updated lists
updatedLists.forEach((updatedList) => {
// Find the index of the updated list
const index = board.lists.findIndex(item => item.id === updatedList.id);
// Update the list
board.lists[index] = updatedList;
});
// Sort the board lists
board.lists.sort((a, b) => a.position - b.position);
// Update the board
this._board.next(board);
})
);
}
/**
* Delete the list
*
* @param id
*/
deleteList(id: string): Observable<boolean>
{
return this._httpClient.delete<boolean>('api/apps/scrumboard/board/list', {params: {id}}).pipe(
tap((isDeleted) => {
// Get the board value
const board = this._board.value;
// Find the index of the deleted list
const index = board.lists.findIndex(item => item.id === id);
// Delete the list
board.lists.splice(index, 1);
// Sort the board lists
board.lists.sort((a, b) => a.position - b.position);
// Update the board
this._board.next(board);
})
);
}
/**
* Get card
*/
getCard(id: string): Observable<Card>
{
return this._board.pipe(
take(1),
map((board) => {
// Find the card
const card = board.lists.find(list => list.cards.some(item => item.id === id))
.cards.find(item => item.id === id);
// Update the card
this._card.next(card);
// Return the card
return card;
}),
switchMap((card) => {
if ( !card )
{
return throwError('Could not found the card with id of ' + id + '!');
}
return of(card);
})
);
}
/**
* Create card
*
* @param card
*/
createCard(card: Card): Observable<Card>
{
return this._httpClient.put<Card>('api/apps/scrumboard/board/card', {card}).pipe(
map(response => new Card(response)),
tap((newCard) => {
// Get the board value
const board = this._board.value;
// Find the list and push the new card in it
board.lists.forEach((listItem, index, list) => {
if ( listItem.id === newCard.listId )
{
list[index].cards.push(newCard);
}
});
// Update the board
this._board.next(board);
// Return the new card
return newCard;
})
);
}
/**
* Update the card
*
* @param id
* @param card
*/
updateCard(id: string, card: Card): Observable<Card>
{
return this.board$.pipe(
take(1),
switchMap(board => this._httpClient.patch<Card>('api/apps/scrumboard/board/card', {
id,
card
}).pipe(
map((updatedCard) => {
// Find the card and update it
board.lists.forEach((listItem) => {
listItem.cards.forEach((cardItem, index, array) => {
if ( cardItem.id === id )
{
array[index] = updatedCard;
}
});
});
// Update the board
this._board.next(board);
// Update the card
this._card.next(updatedCard);
// Return the updated card
return updatedCard;
})
))
);
}
/**
* Update the cards
*
* @param cards
*/
updateCards(cards: Card[]): Observable<Card[]>
{
return this._httpClient.patch<Card[]>('api/apps/scrumboard/board/cards', {cards}).pipe(
map(response => response.map(item => new Card(item))),
tap((updatedCards) => {
// Get the board value
const board = this._board.value;
// Go through the updated cards
updatedCards.forEach((updatedCard) => {
// Find the index of the updated card's list
const listIndex = board.lists.findIndex(list => list.id === updatedCard.listId);
// Find the index of the updated card
const cardIndex = board.lists[listIndex].cards.findIndex(item => item.id === updatedCard.id);
// Update the card
board.lists[listIndex].cards[cardIndex] = updatedCard;
// Sort the cards
board.lists[listIndex].cards.sort((a, b) => a.position - b.position);
});
// Update the board
this._board.next(board);
})
);
}
/**
* Delete the card
*
* @param id
*/
deleteCard(id: string): Observable<boolean>
{
return this.board$.pipe(
take(1),
switchMap(board => this._httpClient.delete('api/apps/scrumboard/board/card', {params: {id}}).pipe(
map((isDeleted: boolean) => {
// Find the card and delete it
board.lists.forEach((listItem) => {
listItem.cards.forEach((cardItem, index, array) => {
if ( cardItem.id === id )
{
array.splice(index, 1);
}
});
});
// Update the board
this._board.next(board);
// Update the card
this._card.next(null);
// Return the deleted status
return isDeleted;
})
))
);
}
/**
* Update card positions
*
* @param cards
*/
updateCardPositions(cards: Card[]): void // Observable<Card[]>
{
/*return this._httpClient.patch<Card[]>('api/apps/scrumboard/board/card/positions', {cards}).pipe(
map((response) => response.map((item) => new Card(item))),
tap((updatedCards) => {
// Get the board value
const board = this._board.value;
// Find the card and update it
board.lists.forEach((listItem) => {
listItem.cards.forEach((cardItem, index, array) => {
if ( cardItem.id === id )
{
array[index] = updatedCard;
}
});
});
// Update the lists
board.lists = updatedLists;
// Sort the board lists
board.lists.sort((a, b) => a.position - b.position);
// Update the board
this._board.next(board);
})
);*/
}
/**
* Create label
*
* @param label
*/
createLabel(label: Label): Observable<Label>
{
return this.board$.pipe(
take(1),
switchMap(board => this._httpClient.post<Label>('api/apps/scrumboard/board/label', {label}).pipe(
map((newLabel) => {
// Update the board labels with the new label
board.labels = [...board.labels, newLabel];
// Update the board
this._board.next(board);
// Return new label from observable
return newLabel;
})
))
);
}
/**
* Update the label
*
* @param id
* @param label
*/
updateLabel(id: string, label: Label): Observable<Label>
{
return this.board$.pipe(
take(1),
switchMap(board => this._httpClient.patch<Label>('api/apps/scrumboard/board/label', {
id,
label
}).pipe(
map((updatedLabel) => {
// Find the index of the updated label
const index = board.labels.findIndex(item => item.id === id);
// Update the label
board.labels[index] = updatedLabel;
// Update the board
this._board.next(board);
// Return the updated label
return updatedLabel;
})
))
);
}
/**
* Delete the label
*
* @param id
*/
deleteLabel(id: string): Observable<boolean>
{
return this.board$.pipe(
take(1),
switchMap(board => this._httpClient.delete('api/apps/scrumboard/board/label', {params: {id}}).pipe(
map((isDeleted: boolean) => {
// Find the index of the deleted label
const index = board.labels.findIndex(item => item.id === id);
// Delete the label
board.labels.splice(index, 1);
// If the label is deleted...
if ( isDeleted )
{
// Remove the label from any card that uses it
board.lists.forEach((list) => {
list.cards.forEach((card) => {
const labelIndex = card.labels.findIndex(label => label.id === id);
if ( labelIndex > -1 )
{
card.labels.splice(labelIndex, 1);
}
});
});
}
// Update the board
this._board.next(board);
// Return the deleted status
return isDeleted;
})
))
);
}
/**
* Search within board cards
*
* @param query
*/
search(query: string): Observable<Card[] | null>
{
// @TODO: Update the board cards based on the search results
return this._httpClient.get<Card[] | null>('api/apps/scrumboard/board/search', {params: {query}});
}
}