funky-framadate-front/src/app/core/services/poll.service.ts

128 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
import { BehaviorSubject, Observable } from 'rxjs';
import { Answer } from '../enums/answer.enum';
import { Choice } from '../models/choice.model';
import { Poll } from '../models/poll.model';
import { User } from '../models/user.model';
import { ApiService } from './api.service';
import { ToastService } from './toast.service';
import { UserService } from './user.service';
import { UuidService } from './uuid.service';
@Injectable({
providedIn: 'root',
})
export class PollService implements Resolve<Poll> {
private _poll: BehaviorSubject<Poll | undefined> = new BehaviorSubject<Poll | undefined>(undefined);
public readonly poll: Observable<Poll | undefined> = this._poll.asObservable();
constructor(
private router: Router,
private apiService: ApiService,
private userService: UserService,
private uuidService: UuidService,
private toastService: ToastService
) {}
public async resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<Poll> {
const segments: string[] = state.url.split('/');
const wantedSlug: string = segments.includes('poll') ? segments[segments.indexOf('poll') + 1] : '';
if (!wantedSlug && state.url.includes('administration')) {
// creation of new poll
const poll = new Poll(this.userService.getCurrentUser(), this.uuidService.getUUID(), '');
this._poll.next(poll);
this.router.navigate(['poll/' + poll.slug + '/administration']);
}
if (!this._poll.getValue() || !this._poll.getValue().slug || this._poll.getValue().slug !== wantedSlug) {
await this.loadPollBySlug(wantedSlug);
}
if (this._poll.getValue()) {
return this._poll.getValue();
} else {
this.router.navigate(['page-not-found']);
return;
}
}
public async loadPollBySlug(slug: string): Promise<void> {
console.log('slug', slug);
if (slug) {
const poll: Poll | undefined = await this.apiService.getPollBySlug(slug);
console.log({ loadPollBySlugResponse: poll });
this.updateCurrentPoll(poll);
}
}
public updateCurrentPoll(poll: Poll): void {
this._poll.next(poll);
}
public async saveCurrentPoll(): Promise<void> {
const pollUrl: string = await this.apiService.createPoll(this._poll.getValue());
// TODO: Maybe handle the url to update currentPoll according to backend response
if (pollUrl) {
this.toastService.display('Le sondage a été enregistré.');
} else {
this.toastService.display('Le sondage na été correctement enregistré, veuillez ré-essayer.');
}
}
public saveParticipation(choice: Choice, user: User, response: Answer): void {
const currentPoll = this._poll.getValue();
currentPoll.choices.find((c) => c.label === choice.label)?.updateParticipation(user, response);
this.updateCurrentPoll(currentPoll);
this.apiService.createParticipation(currentPoll.slug, choice.label, user.pseudo, response);
this.toastService.display('Votre participation au sondage a été enregistrée.');
}
public async deleteAllAnswers(): Promise<void> {
await this.apiService.deletePollAnswers(this._poll.getValue().slug);
this.toastService.display('Les participations des votants à ce sondage ont été supprimées.');
}
public async addComment(comment: string): Promise<void> {
await this.apiService.createComment(this._poll.getValue().slug, comment);
this.toastService.display('Votre commentaire a été enregistré.');
}
public async deleteComments(): Promise<void> {
await this.apiService.deletePollComments(this._poll.getValue().slug);
this.toastService.display('Les commentaires de ce sondage ont été supprimés.');
}
public buildAnswersByChoiceLabelByPseudo(poll: Poll): Map<string, Map<string, Answer>> {
const pseudos: Set<string> = new Set();
poll.choices.forEach((choice: Choice) => {
choice.participants.forEach((users: Set<User>) => {
users.forEach((user: User) => {
pseudos.add(user.pseudo);
});
});
});
const list = new Map<string, Map<string, Answer>>();
pseudos.forEach((pseudo: string) => {
list.set(
pseudo,
new Map<string, Answer>(
poll.choices.map((choice: Choice) => {
return [choice.label, undefined];
})
)
);
});
poll.choices.forEach((choice: Choice) => {
choice.participants.forEach((users: Set<User>, answer: Answer) => {
users.forEach((user: User) => {
list.get(user.pseudo).set(choice.label, answer);
});
});
});
return list;
}
}