You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.7 KiB
172 lines
5.7 KiB
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'; |
|
import { Form } from '@angular/forms'; |
|
import { PollConfig } from '../../features/old-stuff/config/PollConfig'; |
|
|
|
@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); |
|
} |
|
|
|
/** |
|
* make a uniq slug for the current poll creation |
|
* @param config |
|
*/ |
|
makeSlug(config: Poll): string { |
|
let str = ''; |
|
str = |
|
config.configuration.dateCreated.getFullYear() + |
|
'_' + |
|
(config.configuration.dateCreated.getMonth() + 1) + |
|
'_' + |
|
config.configuration.dateCreated.getDate() + |
|
'_' + |
|
config.owner.pseudo + |
|
'_' + |
|
config.title; |
|
str = str.replace(/^\s+|\s+$/g, ''); // trim |
|
str = str.toLowerCase(); |
|
|
|
// remove accents, swap ñ for n, etc |
|
const from = 'àáäâèéëêìíïîòóöôùúüûñç·/_,:;'; |
|
const to = 'aaaaeeeeiiiioooouuuunc------'; |
|
for (let i = 0, l = from.length; i < l; i++) { |
|
str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i)); |
|
} |
|
|
|
str = str |
|
.replace(/[^a-z0-9 -]/g, '') // remove invalid chars |
|
.replace(/\s+/g, '-') // collapse whitespace and replace by - |
|
.replace(/-+/g, '-'); // collapse dashes |
|
|
|
return str + '-' + this.uuidService.getUUID(); |
|
} |
|
|
|
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 n’a é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; |
|
} |
|
|
|
newPollFromForm(form: any) { |
|
const newpoll = new Poll( |
|
this.userService.getCurrentUser(), |
|
this.uuidService.getUUID(), |
|
form.controls.title.value |
|
); |
|
return newpoll; |
|
} |
|
}
|
|
|