2021-10-19 12:14:11 +02:00
|
|
|
|
import { ChangeDetectorRef, Inject, Injectable } from '@angular/core';
|
|
|
|
|
import { ActivatedRoute, ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
|
2020-11-13 09:38:42 +01:00
|
|
|
|
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
|
2020-04-19 14:22:10 +02:00
|
|
|
|
|
2020-06-12 19:17:39 +02:00
|
|
|
|
import { Answer } from '../enums/answer.enum';
|
2020-05-12 19:16:23 +02:00
|
|
|
|
import { Choice } from '../models/choice.model';
|
2020-04-19 14:22:10 +02:00
|
|
|
|
import { Poll } from '../models/poll.model';
|
2020-05-12 19:16:23 +02:00
|
|
|
|
import { User } from '../models/user.model';
|
2020-04-19 14:22:10 +02:00
|
|
|
|
import { ApiService } from './api.service';
|
2020-06-16 18:40:48 +02:00
|
|
|
|
import { ToastService } from './toast.service';
|
2020-06-25 22:42:26 +02:00
|
|
|
|
import { UserService } from './user.service';
|
|
|
|
|
import { UuidService } from './uuid.service';
|
2020-11-13 09:38:42 +01:00
|
|
|
|
import { HttpClient } from '@angular/common/http';
|
|
|
|
|
import { environment } from '../../../environments/environment';
|
2021-10-19 12:14:11 +02:00
|
|
|
|
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
|
|
|
|
import { DateChoice, defaultTimeOfDay, otherDefaultDates } from '../../features/old-stuff/config/defaultConfigs';
|
|
|
|
|
import { DateUtilities } from '../../features/old-stuff/config/DateUtilities';
|
|
|
|
|
import { DOCUMENT } from '@angular/common';
|
2020-04-19 14:22:10 +02:00
|
|
|
|
|
|
|
|
|
@Injectable({
|
2020-04-21 17:26:25 +02:00
|
|
|
|
providedIn: 'root',
|
2020-04-19 14:22:10 +02:00
|
|
|
|
})
|
2020-06-18 16:15:26 +02:00
|
|
|
|
export class PollService implements Resolve<Poll> {
|
2020-04-21 17:26:25 +02:00
|
|
|
|
private _poll: BehaviorSubject<Poll | undefined> = new BehaviorSubject<Poll | undefined>(undefined);
|
2020-04-22 12:56:18 +02:00
|
|
|
|
public readonly poll: Observable<Poll | undefined> = this._poll.asObservable();
|
2021-10-19 12:14:11 +02:00
|
|
|
|
public form: FormGroup;
|
|
|
|
|
public startDateInterval: string;
|
|
|
|
|
public endDateInterval: string;
|
|
|
|
|
public intervalDays: any;
|
|
|
|
|
public intervalDaysDefault = 7;
|
|
|
|
|
public dateList: DateChoice[] = otherDefaultDates; // sets of days as strings, config to set identical time for days in a special days poll
|
|
|
|
|
public timeList: any = defaultTimeOfDay; // ranges of time expressed as strings
|
|
|
|
|
public previousRouteName: string = '/administration';
|
|
|
|
|
public nextRouteName: string = '/administration/step/2';
|
|
|
|
|
public step_current: number = 1;
|
|
|
|
|
public step_max: number = 5;
|
|
|
|
|
public round: Function;
|
|
|
|
|
public urlPrefix: string = window.location.origin + '/participation/';
|
|
|
|
|
public advancedDisplayEnabled = false;
|
|
|
|
|
public showDateInterval = false;
|
|
|
|
|
public allowSeveralHours = false;
|
|
|
|
|
public richTextMode = false;
|
2020-04-19 14:22:10 +02:00
|
|
|
|
|
2020-06-25 22:42:26 +02:00
|
|
|
|
constructor(
|
2020-11-13 09:38:42 +01:00
|
|
|
|
private http: HttpClient,
|
2020-06-25 22:42:26 +02:00
|
|
|
|
private router: Router,
|
|
|
|
|
private apiService: ApiService,
|
|
|
|
|
private userService: UserService,
|
|
|
|
|
private uuidService: UuidService,
|
2021-10-19 12:14:11 +02:00
|
|
|
|
private toastService: ToastService,
|
|
|
|
|
public dateUtilities: DateUtilities,
|
|
|
|
|
public route: ActivatedRoute,
|
|
|
|
|
@Inject(DOCUMENT) private document: any,
|
|
|
|
|
private fb: FormBuilder
|
|
|
|
|
) {
|
|
|
|
|
this.createFormGroup();
|
|
|
|
|
if (environment.poll.autoFillDemo) {
|
|
|
|
|
this.setDemoValues();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* add example values to the form
|
|
|
|
|
*/
|
|
|
|
|
setDemoValues(): void {
|
|
|
|
|
this.addChoice('orange');
|
|
|
|
|
this.addChoice('raisin');
|
|
|
|
|
this.addChoice('abricot');
|
|
|
|
|
|
|
|
|
|
this.form.patchValue({
|
|
|
|
|
title: 'mon titre',
|
|
|
|
|
description: 'répondez SVP <3 ! *-* ',
|
|
|
|
|
custom_url: this.uuidService.getUUID(),
|
|
|
|
|
creatorPseudo: 'Chuck Norris',
|
|
|
|
|
creatorEmail: 'chucknorris@example.com',
|
|
|
|
|
isAboutDate: true,
|
|
|
|
|
whoModifiesAnswers: 'everybody',
|
|
|
|
|
whoCanChangeAnswers: 'everybody',
|
|
|
|
|
isProtectedByPassword: false,
|
|
|
|
|
isOwnerNotifiedByEmailOnNewVote: false,
|
|
|
|
|
isOwnerNotifiedByEmailOnNewComment: false,
|
|
|
|
|
isMaybeAnswerAvailable: false,
|
|
|
|
|
richTextMode: false,
|
|
|
|
|
areResultsPublic: true,
|
|
|
|
|
expiracyNumberOfDays: 60,
|
|
|
|
|
});
|
|
|
|
|
this.automaticSlug();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* set the poll slug from other data of the poll
|
|
|
|
|
*/
|
|
|
|
|
automaticSlug() {
|
|
|
|
|
this.form.patchValue({ custom_url: this.makeSlug(this.form) });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public createFormGroup() {
|
|
|
|
|
let form = this.fb.group({
|
|
|
|
|
title: ['', [Validators.required, Validators.minLength(12)]],
|
|
|
|
|
creatorPseudo: ['', [Validators.required]],
|
|
|
|
|
created_at: [new Date(), [Validators.required]],
|
|
|
|
|
creatorEmail: ['', [Validators.required]],
|
|
|
|
|
custom_url: [this.uuidService.getUUID(), [Validators.required]],
|
|
|
|
|
description: ['', [Validators.required]],
|
|
|
|
|
choices: new FormArray([]),
|
|
|
|
|
whoModifiesAnswers: ['', [Validators.required]],
|
|
|
|
|
whoCanChangeAnswers: ['', [Validators.required]],
|
|
|
|
|
isAboutDate: [true, [Validators.required]],
|
|
|
|
|
startDateInterval: ['', [Validators.required]],
|
|
|
|
|
endDateInterval: ['', [Validators.required]],
|
|
|
|
|
isProtectedByPassword: [false, [Validators.required]],
|
|
|
|
|
isOwnerNotifiedByEmailOnNewVote: [false, [Validators.required]],
|
|
|
|
|
isOwnerNotifiedByEmailOnNewComment: [false, [Validators.required]],
|
|
|
|
|
isMaybeAnswerAvailable: [false, [Validators.required]],
|
|
|
|
|
areResultsPublic: [true, [Validators.required]],
|
|
|
|
|
richTextMode: [false, [Validators.required]],
|
|
|
|
|
expiracyNumberOfDays: [60, [Validators.required, Validators.min(0)]],
|
|
|
|
|
});
|
|
|
|
|
this.form = form;
|
|
|
|
|
return form;
|
|
|
|
|
}
|
2020-04-19 14:22:10 +02:00
|
|
|
|
|
2020-11-13 09:38:42 +01:00
|
|
|
|
/**
|
|
|
|
|
* auto fetch a poll when route is looking for one in the administration pattern
|
|
|
|
|
* @param route
|
|
|
|
|
* @param state
|
|
|
|
|
*/
|
2020-06-18 16:15:26 +02:00
|
|
|
|
public async resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<Poll> {
|
2020-06-25 22:42:26 +02:00
|
|
|
|
const segments: string[] = state.url.split('/');
|
|
|
|
|
const wantedSlug: string = segments.includes('poll') ? segments[segments.indexOf('poll') + 1] : '';
|
2020-06-18 16:15:26 +02:00
|
|
|
|
if (!wantedSlug && state.url.includes('administration')) {
|
|
|
|
|
// creation of new poll
|
2020-06-25 22:42:26 +02:00
|
|
|
|
const poll = new Poll(this.userService.getCurrentUser(), this.uuidService.getUUID(), '');
|
|
|
|
|
this._poll.next(poll);
|
|
|
|
|
this.router.navigate(['poll/' + poll.slug + '/administration']);
|
2020-06-18 16:15:26 +02:00
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
2020-04-21 17:26:25 +02:00
|
|
|
|
}
|
2020-04-19 14:22:10 +02:00
|
|
|
|
|
2020-11-13 09:38:42 +01:00
|
|
|
|
getAllAvailablePolls() {
|
|
|
|
|
const baseHref = environment.api.version.apiV1.baseHref;
|
|
|
|
|
console.log('getAllAvailablePolls baseHref', baseHref);
|
|
|
|
|
const headers = ApiService.makeHeaders();
|
|
|
|
|
console.log('getAllAvailablePolls headers', headers);
|
|
|
|
|
try {
|
|
|
|
|
this.http.get(`${baseHref}/poll`, headers).subscribe((res: Observable<any>) => {
|
|
|
|
|
console.log('getAllAvailablePolls res', res);
|
|
|
|
|
});
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log('getAllAvailablePolls e', e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-18 16:15:26 +02:00
|
|
|
|
public async loadPollBySlug(slug: string): Promise<void> {
|
2020-10-17 11:12:53 +02:00
|
|
|
|
console.log('slug', slug);
|
|
|
|
|
if (slug) {
|
|
|
|
|
const poll: Poll | undefined = await this.apiService.getPollBySlug(slug);
|
|
|
|
|
console.log({ loadPollBySlugResponse: poll });
|
|
|
|
|
this.updateCurrentPoll(poll);
|
|
|
|
|
}
|
2020-04-21 17:26:25 +02:00
|
|
|
|
}
|
2020-04-19 14:22:10 +02:00
|
|
|
|
|
2020-06-18 16:15:26 +02:00
|
|
|
|
public updateCurrentPoll(poll: Poll): void {
|
|
|
|
|
this._poll.next(poll);
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-09 11:32:12 +01:00
|
|
|
|
/**
|
2021-10-19 12:14:11 +02:00
|
|
|
|
* add all the dates between the start and end dates in the interval section
|
|
|
|
|
*/
|
|
|
|
|
addIntervalOfDates(): void {
|
|
|
|
|
const newIntervalArray = this.dateUtilities.getDatesInRange(
|
|
|
|
|
this.dateUtilities.parseInputDateToDateObject(this.startDateInterval),
|
|
|
|
|
this.dateUtilities.parseInputDateToDateObject(this.endDateInterval),
|
|
|
|
|
1
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const converted = [];
|
|
|
|
|
newIntervalArray.forEach((element) => {
|
|
|
|
|
converted.push({
|
|
|
|
|
literal: element.literal,
|
|
|
|
|
date_object: element.date_object,
|
|
|
|
|
timeList: [],
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
this.dateList = [...new Set(converted)];
|
|
|
|
|
// add only dates that are not already present with a Set of unique items
|
|
|
|
|
console.log('this.dateList', this.dateList);
|
|
|
|
|
this.showDateInterval = false;
|
|
|
|
|
|
|
|
|
|
this.form.patchValue({ choices: this.dateList });
|
|
|
|
|
|
|
|
|
|
this.toastService.display(`les dates ont été ajoutées aux réponses possibles.`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* handle keyboard shortcuts
|
|
|
|
|
* @param $event
|
|
|
|
|
* @param choice_number
|
|
|
|
|
*/
|
|
|
|
|
keyOnChoice($event: KeyboardEvent, choice_number: number): void {
|
|
|
|
|
$event.preventDefault();
|
|
|
|
|
|
|
|
|
|
console.log('this.choices.length', this.choices.length);
|
|
|
|
|
console.log('choice_number', choice_number);
|
|
|
|
|
const lastChoice = this.choices.length - 1 === choice_number;
|
|
|
|
|
// reset field with Ctrl + D
|
|
|
|
|
// add a field with Ctrl + N
|
|
|
|
|
// go to previous choice with arrow up
|
|
|
|
|
// go to next choice with arrow down
|
|
|
|
|
console.log('$event', $event);
|
|
|
|
|
|
|
|
|
|
if ($event.key == 'ArrowUp' && choice_number > 0) {
|
|
|
|
|
this.focusOnChoice(choice_number - 1);
|
|
|
|
|
}
|
|
|
|
|
if ($event.key == 'ArrowDown') {
|
|
|
|
|
// add a field if we are on the last choice
|
|
|
|
|
if (lastChoice) {
|
|
|
|
|
this.addChoice();
|
|
|
|
|
this.toastService.display('choix ajouté par raccourci "flèche bas"');
|
|
|
|
|
} else {
|
|
|
|
|
this.focusOnChoice(choice_number + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ($event.ctrlKey && $event.key == 'Backspace') {
|
|
|
|
|
this.deleteChoiceField(choice_number);
|
|
|
|
|
this.toastService.display('choix supprimé par raccourci "Ctrl + retour"');
|
|
|
|
|
this.focusOnChoice(Math.min(choice_number - 1, 0));
|
|
|
|
|
}
|
|
|
|
|
if ($event.ctrlKey && $event.key == 'Enter') {
|
|
|
|
|
// go to other fields
|
|
|
|
|
const elem = this.document.querySelector('#creatorEmail');
|
|
|
|
|
if (elem) {
|
|
|
|
|
elem.focus();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* change time spans
|
|
|
|
|
*/
|
|
|
|
|
addTime() {
|
|
|
|
|
this.timeList.push({
|
|
|
|
|
literal: '',
|
|
|
|
|
timeList: [],
|
|
|
|
|
date_object: new Date(),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
removeAllTimes() {
|
|
|
|
|
this.timeList = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resetTimes() {
|
|
|
|
|
this.timeList = otherDefaultDates;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* add a time period to a specific date choice,
|
|
|
|
|
* focus on the new input
|
2020-11-09 11:32:12 +01:00
|
|
|
|
* @param config
|
2021-10-19 12:14:11 +02:00
|
|
|
|
* @param id
|
|
|
|
|
*/
|
|
|
|
|
addTimeToDate(config: any, id: number) {
|
|
|
|
|
this.timeList.push({
|
|
|
|
|
literal: '',
|
|
|
|
|
timeList: [],
|
|
|
|
|
date_object: new Date(),
|
|
|
|
|
});
|
|
|
|
|
const selector = '[ng-reflect-choice_label="dateTime_' + id + '_Choices_' + (this.timeList.length - 1) + '"]';
|
|
|
|
|
const elem = this.document.querySelector(selector);
|
|
|
|
|
if (elem) {
|
|
|
|
|
elem.focus();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public createPoll(): void {
|
|
|
|
|
console.log('this.form', this.form);
|
|
|
|
|
const newpoll = this.newPollFromForm(this.form);
|
|
|
|
|
console.log('newpoll', newpoll);
|
|
|
|
|
this.apiService.createPoll(newpoll);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* default interval of dates proposed is from today to 7 days more
|
|
|
|
|
*/
|
|
|
|
|
setDefaultDatesForInterval(): void {
|
|
|
|
|
const dateCurrent = new Date();
|
|
|
|
|
const dateJson = dateCurrent.toISOString();
|
|
|
|
|
this.startDateInterval = dateJson.substring(0, 10);
|
|
|
|
|
this.endDateInterval = this.dateUtilities
|
|
|
|
|
.addDaysToDate(this.intervalDaysDefault, dateCurrent)
|
|
|
|
|
.toISOString()
|
|
|
|
|
.substring(0, 10);
|
|
|
|
|
this.form.patchValue({
|
|
|
|
|
startDateInterval: this.startDateInterval,
|
|
|
|
|
endDateInterval: this.endDateInterval,
|
|
|
|
|
});
|
|
|
|
|
this.countDays();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
askInitFormDefault(): void {
|
|
|
|
|
this.initFormDefault(false);
|
|
|
|
|
this.toastService.display('formulaire réinitialisé');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
countDays(): void {
|
|
|
|
|
this.intervalDays = this.dateUtilities.countDays(
|
|
|
|
|
this.dateUtilities.parseInputDateToDateObject(this.startDateInterval),
|
|
|
|
|
this.dateUtilities.parseInputDateToDateObject(this.endDateInterval)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
focusOnChoice(index): void {
|
|
|
|
|
const selector = '#choice_label_' + index;
|
|
|
|
|
const elem = this.document.querySelector(selector);
|
|
|
|
|
if (elem) {
|
|
|
|
|
elem.focus();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deleteChoiceField(index: number): void {
|
|
|
|
|
if (this.choices.length !== 1) {
|
|
|
|
|
this.choices.removeAt(index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initFormDefault(showDemoValues = true): void {
|
|
|
|
|
this.form = this.createFormGroup();
|
|
|
|
|
console.log('this.form ', this.form);
|
|
|
|
|
this.setDefaultDatesForInterval();
|
|
|
|
|
|
|
|
|
|
if (showDemoValues) {
|
|
|
|
|
this.setDemoValues();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get choices(): FormArray {
|
|
|
|
|
return this.form.get('choices') as FormArray;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reinitChoices(): void {
|
|
|
|
|
this.choices.setValue([]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addChoice(optionalLabel = ''): void {
|
|
|
|
|
const newControlGroup = this.fb.group({
|
|
|
|
|
label: this.fb.control('', [Validators.required]),
|
|
|
|
|
imageUrl: ['', [Validators.required]],
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (optionalLabel) {
|
|
|
|
|
newControlGroup.patchValue({
|
|
|
|
|
label: optionalLabel,
|
|
|
|
|
imageUrl: 'mon url',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
this.choices.push(newControlGroup);
|
|
|
|
|
console.log('this.choices.length', this.choices.length);
|
|
|
|
|
|
|
|
|
|
this.focusOnChoice(this.choices.length - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* make a uniq slug for the current poll creation
|
|
|
|
|
* @param form
|
2020-11-09 11:32:12 +01:00
|
|
|
|
*/
|
2021-10-19 12:14:11 +02:00
|
|
|
|
makeSlug(form: FormGroup): string {
|
2020-11-09 11:32:12 +01:00
|
|
|
|
let str = '';
|
|
|
|
|
str =
|
2021-10-19 12:14:11 +02:00
|
|
|
|
form.value.created_at.getFullYear() +
|
2020-11-09 11:32:12 +01:00
|
|
|
|
'_' +
|
2021-10-19 12:14:11 +02:00
|
|
|
|
(form.value.created_at.getMonth() + 1) +
|
2020-11-09 11:32:12 +01:00
|
|
|
|
'_' +
|
2021-10-19 12:14:11 +02:00
|
|
|
|
form.value.created_at.getDate() +
|
2020-11-09 11:32:12 +01:00
|
|
|
|
'_' +
|
2021-10-19 12:14:11 +02:00
|
|
|
|
form.value.creatorPseudo +
|
2020-11-09 11:32:12 +01:00
|
|
|
|
'_' +
|
2021-10-19 12:14:11 +02:00
|
|
|
|
form.value.title;
|
2020-11-09 11:32:12 +01:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-12 19:16:23 +02:00
|
|
|
|
public async saveCurrentPoll(): Promise<void> {
|
2020-11-13 09:38:42 +01:00
|
|
|
|
const pollUrl: Subscription = await this.apiService.createPoll(this._poll.getValue());
|
2020-05-12 19:16:23 +02:00
|
|
|
|
// TODO: Maybe handle the url to update currentPoll according to backend response
|
|
|
|
|
if (pollUrl) {
|
2020-11-09 12:44:24 +01:00
|
|
|
|
console.log('pollUrl', pollUrl);
|
2020-06-16 18:40:48 +02:00
|
|
|
|
this.toastService.display('Le sondage a été enregistré.');
|
2020-05-12 19:16:23 +02:00
|
|
|
|
} else {
|
2020-06-16 18:40:48 +02:00
|
|
|
|
this.toastService.display('Le sondage n’a été correctement enregistré, veuillez ré-essayer.');
|
2020-05-12 19:16:23 +02:00
|
|
|
|
}
|
2020-04-21 17:26:25 +02:00
|
|
|
|
}
|
2020-04-19 14:22:10 +02:00
|
|
|
|
|
2020-06-12 19:17:39 +02:00
|
|
|
|
public saveParticipation(choice: Choice, user: User, response: Answer): void {
|
2020-05-12 19:16:23 +02:00
|
|
|
|
const currentPoll = this._poll.getValue();
|
2020-06-12 19:17:39 +02:00
|
|
|
|
currentPoll.choices.find((c) => c.label === choice.label)?.updateParticipation(user, response);
|
2020-05-12 19:16:23 +02:00
|
|
|
|
this.updateCurrentPoll(currentPoll);
|
|
|
|
|
this.apiService.createParticipation(currentPoll.slug, choice.label, user.pseudo, response);
|
2020-06-25 22:42:26 +02:00
|
|
|
|
this.toastService.display('Votre participation au sondage a été enregistrée.');
|
2020-04-21 17:26:25 +02:00
|
|
|
|
}
|
2020-04-19 14:22:10 +02:00
|
|
|
|
|
2020-05-12 19:16:23 +02:00
|
|
|
|
public async deleteAllAnswers(): Promise<void> {
|
|
|
|
|
await this.apiService.deletePollAnswers(this._poll.getValue().slug);
|
2020-06-25 22:42:26 +02:00
|
|
|
|
this.toastService.display('Les participations des votants à ce sondage ont été supprimées.');
|
2020-05-01 19:10:17 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-12 19:16:23 +02:00
|
|
|
|
public async addComment(comment: string): Promise<void> {
|
|
|
|
|
await this.apiService.createComment(this._poll.getValue().slug, comment);
|
2020-06-16 18:40:48 +02:00
|
|
|
|
this.toastService.display('Votre commentaire a été enregistré.');
|
2020-05-12 19:16:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async deleteComments(): Promise<void> {
|
|
|
|
|
await this.apiService.deletePollComments(this._poll.getValue().slug);
|
2020-06-16 18:40:48 +02:00
|
|
|
|
this.toastService.display('Les commentaires de ce sondage ont été supprimés.');
|
2020-04-21 17:26:25 +02:00
|
|
|
|
}
|
2020-06-12 19:17:39 +02:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2020-11-05 19:13:43 +01:00
|
|
|
|
|
2020-11-13 09:43:34 +01:00
|
|
|
|
newPollFromForm(form: any): any {
|
2020-11-05 19:13:43 +01:00
|
|
|
|
const newpoll = new Poll(
|
|
|
|
|
this.userService.getCurrentUser(),
|
|
|
|
|
this.uuidService.getUUID(),
|
|
|
|
|
form.controls.title.value
|
|
|
|
|
);
|
2020-11-11 12:14:01 +01:00
|
|
|
|
/**
|
|
|
|
|
* convert to API version 1 config poll
|
|
|
|
|
*/
|
|
|
|
|
const apiV1Poll = {
|
|
|
|
|
menuVisible: true,
|
|
|
|
|
expiracyDateDefaultInDays: newpoll.configuration.expiresDaysDelay,
|
|
|
|
|
deletionDateAfterLastModification: newpoll.configuration.expiracyAfterLastModificationInDays,
|
|
|
|
|
pollType: newpoll.configuration.isAboutDate ? 'dates' : 'classic', // classic or dates
|
|
|
|
|
title: newpoll.title,
|
|
|
|
|
description: newpoll.description,
|
|
|
|
|
myName: newpoll.owner.pseudo,
|
|
|
|
|
myComment: '',
|
|
|
|
|
isAdmin: true, // when we create a poll, we are admin on it
|
|
|
|
|
myVoteStack: {},
|
|
|
|
|
myTempVoteStack: 0,
|
|
|
|
|
myEmail: newpoll.owner.email,
|
|
|
|
|
myPolls: [], // list of retrieved polls from the backend api
|
|
|
|
|
/*
|
|
|
|
|
date specific poll, we have the choice to setup different hours (timeList) for all possible dates (dateList), or use the same hours for all dates
|
|
|
|
|
*/
|
|
|
|
|
allowSeveralHours: 'true',
|
|
|
|
|
// access
|
|
|
|
|
visibility: newpoll.configuration.areResultsPublic, // visible to one with the link:
|
|
|
|
|
voteChoices: newpoll.configuration.isMaybeAnswerAvailable ? 'yes, maybe, no' : 'yes', // possible answers to a vote choice: only "yes", "yes, maybe, no"
|
2021-10-19 12:14:11 +02:00
|
|
|
|
created_at: new Date(),
|
2020-11-11 12:14:01 +01:00
|
|
|
|
expirationDate: '', // expiracy date
|
|
|
|
|
voteStackId: null, // id of the vote stack to update
|
|
|
|
|
pollId: null, // id of the current poll when created. data given by the backend api
|
|
|
|
|
pollSlug: null, // id of the current poll when created. data given by the backend api
|
|
|
|
|
currentPoll: null, // current poll selected with createPoll or getPoll of ConfigService
|
|
|
|
|
passwordAccess: newpoll.configuration.isProtectedByPassword,
|
|
|
|
|
password: newpoll.configuration.password,
|
|
|
|
|
customUrl: newpoll.slug, // custom slug in the url, must be unique
|
|
|
|
|
customUrlIsUnique: null, // given by the backend
|
|
|
|
|
urlSlugPublic: null,
|
|
|
|
|
urlPublic: null,
|
|
|
|
|
urlAdmin: null,
|
|
|
|
|
adminKey: '', // key to change config of the poll
|
|
|
|
|
owner_modifier_token: '', // key to change a vote stack
|
|
|
|
|
canModifyAnswers: newpoll.configuration.isAllowingtoChangeOwnAnswers, // bool for the frontend selector
|
|
|
|
|
whoModifiesAnswers: newpoll.configuration.whoCanChangeAnswers, // everybody, self, nobody (: just admin)
|
|
|
|
|
whoCanChangeAnswers: newpoll.configuration.whoCanChangeAnswers, // everybody, self, nobody (: just admin)
|
|
|
|
|
dateList: newpoll.dateChoices, // sets of days as strings, config to set identical time for days in a special days poll
|
|
|
|
|
timeList: newpoll.timeChoices, // ranges of time expressed as strings
|
|
|
|
|
|
|
|
|
|
answers: newpoll.choices,
|
|
|
|
|
// modals
|
|
|
|
|
displayConfirmVoteModalAdmin: false,
|
|
|
|
|
};
|
2020-11-13 09:43:34 +01:00
|
|
|
|
console.log('apiV1Poll', apiV1Poll);
|
2020-11-11 12:14:01 +01:00
|
|
|
|
return apiV1Poll;
|
2020-11-05 19:13:43 +01:00
|
|
|
|
}
|
2020-04-19 14:22:10 +02:00
|
|
|
|
}
|