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

871 lines
27 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 { Inject, Injectable } from '@angular/core';
import { ActivatedRoute, ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { Answer } from '../enums/answer.enum';
import { Choice } from '../models/choice.model';
import { Poll } from '../models/poll.model';
import { ApiService } from './api.service';
import { ToastService } from './toast.service';
import { UserService } from './user.service';
import { UuidService } from './uuid.service';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../../environments/environment';
import { StorageService } from './storage.service';
import { Title } from '@angular/platform-browser';
import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { DOCUMENT } from '@angular/common';
import { DateChoice, TimeSlices } from '../models/dateChoice.model';
import { DateUtilitiesService } from './date.utilities.service';
import { Owner } from '../models/owner.model';
import { Stack } from '../models/stack.model';
import { Vote } from '../models/vote.model';
import { ClipboardService } from 'ngx-clipboard';
import { TranslateService } from '@ngx-translate/core';
import { CommentDTO } from '../models/comment.model';
@Injectable({
providedIn: 'root',
})
export class PollService implements Resolve<Poll> {
public _poll: BehaviorSubject<Poll | undefined> = new BehaviorSubject<Poll | undefined>(undefined);
public readonly poll: Observable<Poll | undefined> = this._poll.asObservable();
public form: UntypedFormGroup;
public startDateInterval: string;
public endDateInterval: string;
public intervalDays: number = 1;
public intervalDaysDefault = 7;
public dateChoiceList: DateChoice[] = []; // sets of days as strings, config to set identical time for days in a special days poll
public timeList: TimeSlices[] = [{ literal: '' }]; // 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 = 7;
public round: Function;
public pass_hash: string;
public admin_key: string;
public urlPrefix: string = window.location.origin;
public advancedDisplayEnabled = false;
public showDateInterval = false;
public allowSeveralHours = false;
public richTextMode = false;
public mode_calendar = true; // default input to select dates in creation step
public calendar: Date[] = [];
public disabled_dates: Date[] = [];
constructor(
private http: HttpClient,
private router: Router,
private apiService: ApiService,
private storageService: StorageService,
private userService: UserService,
private uuidService: UuidService,
private toastService: ToastService,
private titleService: Title,
public DateUtilitiesService: DateUtilitiesService,
public route: ActivatedRoute,
private _clipboardService: ClipboardService,
private translate: TranslateService,
@Inject(DOCUMENT) private document: any,
private fb: UntypedFormBuilder
) {
this.createFormGroup();
// disable days before today
for (let i = 1; i < 31; i++) {
this.disabled_dates.push(this.DateUtilitiesService.addDaysToDate(-i, new Date()));
}
if (environment.autofill_creation) {
this.setDemoValues();
// fill in the next 3 days of the calendar date picker
this.calendar = this.DateUtilitiesService.makeDefaultCalendarDateChoices();
this.dateChoiceList = this.DateUtilitiesService.makeDefaultDateChoices();
}
if (environment.autoSendNewPoll) {
this.createPoll();
}
}
updateTitle() {
let suppl = environment.production ? ' [DEV]' : '';
let apptitle = environment.appTitle + suppl;
let step_current;
if (this.step_current) {
// in creation tunnel
let stepsTitle = {
date: [
'creation.title',
'creation.want',
'dates.title',
'hours.title',
'advanced.title',
'owner.title',
'resume.title',
],
text: [
'creation.title',
'creation.want',
'dates.title',
'hours.title',
'advanced.title',
'owner.title',
'resume.title',
],
};
let kind = 'date';
step_current = this.step_current | 1;
if (this.form.value.isAboutDate) {
kind = 'text';
}
let keyToTranslate = stepsTitle[kind][(step_current - 1) | 0];
this.translate.getTranslation(this.translate.getBrowserLang()).subscribe((response) => {
let step = this.translate.getParsedResult(response, 'nav.step');
let on = this.translate.getParsedResult(response, 'nav.on');
let no_title = this.translate.getParsedResult(response, 'nav.no_title');
let titleText = this.form.value.title ? ' - ' + this.form.value.title : no_title + ' -';
let stepTitle = this.translate.getParsedResult(response, keyToTranslate);
if (this.step_current == 1) {
titleText = stepTitle;
}
console.log('a', step, this.translate.getBrowserCultureLang());
let fullTitle = `${titleText} ${step} ${this.step_current} ${on} ${this.step_max} - ${environment.appTitle} `;
console.log('fullTitle', fullTitle);
// ex: Nom de mon sondage - étape 3 sur 7 - Framadate
this.titleService.setTitle(fullTitle);
});
} else {
this.titleService.setTitle(apptitle);
}
}
/**
* add example values to the form for demo env
*/
setDemoValues(): void {
this.form.patchValue({
title: 'Mon titre de sondage du ' + this.DateUtilitiesService.formateDateToInputStringNg(new Date()),
description: 'répondez SVP <3 ! *-* ',
custom_url: this.uuidService.getUUID(),
creatorPseudo: 'Chuck Norris',
creatorEmail: 'chucknorris@example.com',
isAboutDate: false,
whoModifiesAnswers: 'everybody',
whoCanChangeAnswers: 'everybody',
isProtectedByPassword: false,
richTextMode: false,
areResultsPublic: true,
expiresDaysDelay: environment.expiresDaysDelay,
});
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 minlengthValidation = environment.production ? 12 : 0;
let form = this.fb.group({
title: ['', [Validators.required, Validators.minLength(minlengthValidation)]],
creatorPseudo: ['', []],
created_at: [new Date(), [Validators.required]],
creatorEmail: ['', [environment.creation_email_is_required ? Validators.required : null]],
custom_url: [this.uuidService.getUUID(), [Validators.required]],
description: ['', []],
password: ['', []],
password_repeat: ['', []],
choices: new UntypedFormArray([]),
whoModifiesAnswers: ['self', [Validators.required]],
whoCanChangeAnswers: ['self', [Validators.required]],
isAboutDate: [false, [Validators.required]],
expiresDaysDelay: [environment.expiresDaysDelay, []],
expiracy_date: [this.DateUtilitiesService.addDaysToDate(environment.expiresDaysDelay, new Date()), []],
isZeroKnoledge: [false, [Validators.required]],
isProtectedByPassword: [false, [Validators.required]],
isOwnerNotifiedByEmailOnNewVote: [true, [Validators.required]],
isOwnerNotifiedByEmailOnNewComment: [true, [Validators.required]],
areResultsPublic: [true, [Validators.required]],
richTextMode: [false, [Validators.required]],
isYesAnswerAvailable: [true, [Validators.required]],
isMaybeAnswerAvailable: [true, [Validators.required]],
isNoAnswerAvailable: [true, [Validators.required]],
allowComments: [true, [Validators.required]],
maxCountOfAnswers: ['', []],
hasMaxCountOfAnswers: ['', [Validators.required]],
useVoterUniqueLink: [false, [Validators.required]],
voterEmailList: ['', []],
hasSeveralHours: [true, []],
hideResults: [false, []],
allowNewDateTime: [true, [Validators.required]],
});
this.form = form;
return form;
}
/**
* set default configs to the form
*/
public patchFormDefaultValues() {
this.form.patchValue({
title: 'Mon titre de sondage',
description: '',
custom_url: this.uuidService.getUUID(),
creatorPseudo: '',
creatorEmail: '',
whoModifiesAnswers: 'everybody',
whoCanChangeAnswers: 'everybody',
isProtectedByPassword: false,
richTextMode: false,
areResultsPublic: true,
expiresDaysDelay: environment.expiresDaysDelay,
maxCountOfAnswers: 1000,
voterEmailList: '',
password: '',
});
this.setDefaultDatesForInterval();
}
/**
* get a new slug from form title and creation date
*/
public updateSlug(): void {
this.form.patchValue({ custom_url: this.makeSlug(this.form) });
}
/**
* auto fetch a poll when route is looking for one in the administration pattern
* DO NOT USE - needs refacto
* @param route
* @param state
*/
public async resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<Poll> {
console.log('resolve route,state', route, state);
const segments: string[] = state.url.split('/');
const wantedcustom_url: string = segments.includes('poll') ? segments[segments.indexOf('poll') + 1] : '';
if (
!this._poll.getValue() ||
!this._poll.getValue().custom_url ||
this._poll.getValue().custom_url !== wantedcustom_url
) {
if (this.pass_hash) {
this.storageService.vote_stack.pass_hash = this.pass_hash;
await this.loadPollByCustomUrlWithPasswordHash(wantedcustom_url, this.pass_hash);
} else {
await this.loadPollByCustomUrl(wantedcustom_url);
}
}
const loadedPoll = this._poll.getValue();
if (loadedPoll) {
this.storageService.vote_stack.custom_url = loadedPoll.custom_url;
return loadedPoll;
} else {
this.router.navigate(['page-not-found']);
return;
}
}
/**
* get all polls
*/
getAllAvailablePolls(): void {
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);
}
}
/**
* load a poll data and update the current poll of PollService
* @param custom_url
*/
public async loadPollByCustomUrl(custom_url: string): Promise<void> {
if (custom_url) {
const poll: Poll | undefined = await this.apiService.getPollByCustomUrl(custom_url);
if (poll) {
this.updateCurrentPoll(poll);
this.titleService.setTitle(`☑️ ${poll.title} - ${environment.appTitle}`);
} else {
this.toastService.display(`sondage ${custom_url} non trouvé`);
this.router.navigate(['page-not-found']);
}
} else {
this.toastService.display(`sondage sans custom url : ${custom_url}`);
}
}
public async loadPollByCustomUrlWithPasswordHash(custom_url: string, hash: string): Promise<void> {
if (custom_url) {
const poll: Poll | undefined = await this.apiService.getPollByCustomUrlWithHash(custom_url, hash);
if (poll) {
this.updateCurrentPoll(poll);
this.titleService.setTitle(`☑️ ${poll.title} - ${environment.appTitle}`);
} else {
this.toastService.display(`sondage ${custom_url} non trouvé`);
this.router.navigate(['page-not-found']);
}
} else {
this.toastService.display(`sondage sans custom url : ${custom_url}`);
}
}
/**
* update poll and parse its fields
* @param poll
*/
public updateCurrentPoll(poll: Poll, displayToast = false): Poll {
console.log('this.storageService.vote_stack.id', this.storageService.vote_stack.id);
this._poll.next(poll);
console.log('next poll', poll);
this.storageService.setChoicesForVoteStack(poll.choices);
if (displayToast) {
this.toastService.display(`sondage ${poll.title} bien mis à jour`, 'success');
}
return poll;
}
/**
* add all the dates between the start and end dates in the interval section
*/
addIntervalOfDates(): void {
const newIntervalArray = this.DateUtilitiesService.getDatesInRange(
this.DateUtilitiesService.parseInputDateToDateObject(new Date(this.startDateInterval)),
this.DateUtilitiesService.parseInputDateToDateObject(new Date(this.endDateInterval)),
1
);
const converted = [];
newIntervalArray.forEach((element) => {
converted.push({
literal: element.literal,
date_object: element.date_object,
timeList: [
{
literal: 'matin',
},
],
});
});
this.dateChoiceList = [...new Set(converted)];
// add only dates that are not already present with a Set of unique items
console.log('this.dateChoiceList', this.dateChoiceList);
this.showDateInterval = false;
this.form.patchValue({ choices: this.dateChoiceList });
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();
const lastChoice = this.choices.length - 1 === choice_number;
// reset field with Ctrl + D
// add a field with Ctrl + N
// go to previous timeSlice with arrow up
// go to next timeSlice with arrow down
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 timeSlice
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: '',
});
}
removeAllTimes() {
this.timeList = [];
}
resetTimes() {
this.timeList = [];
}
/**
* add a time period to a specific date timeSlice,
* focus on the new input
* @param config
* @param id
*/
addTimeToDate(config: any, id: number) {
this.timeList.push({
literal: '',
});
const selector = '[ng-reflect-choice_label="dateTime_' + id + '_Choices_' + (this.timeList.length - 1) + '"]';
const elem = this.document.querySelector(selector);
if (elem) {
elem.focus();
}
}
/**
* convert form data to DTO to create a new poll, and store the admin key
*/
public createPoll(): Promise<any> {
this.toastService.display('sending...');
const newpoll = this.newPollFromForm();
return this.apiService.createPoll(newpoll).then(
(resp: any) => {
console.log('poll created resp', resp);
this.admin_key = resp.data.poll.admin_key;
this.storageService.userPolls.push(resp.data.poll);
},
(error) => {
this.toastService.display('BOOM, the createPoll went wrong');
this.apiService.ousideHandleError(error);
}
);
}
/**
* 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.DateUtilitiesService.addDaysToDate(this.intervalDaysDefault, dateCurrent)
.toISOString()
.substring(0, 10);
this.form.patchValue({
startDateInterval: this.startDateInterval,
endDateInterval: this.endDateInterval,
});
this.countDays();
}
askInitFormDefault(): void {
this.initFormDefault(environment.autofill_creation);
// this.toastService.display('formulaire réinitialisé');
}
countDays(): void {
this.intervalDays = this.DateUtilitiesService.countDays(
this.DateUtilitiesService.parseInputDateToDateObject(new Date(this.startDateInterval)),
this.DateUtilitiesService.parseInputDateToDateObject(new Date(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();
this.patchFormDefaultValues();
this.setDefaultDatesForInterval();
if (showDemoValues) {
this.setDemoValues();
}
}
get choices(): UntypedFormArray {
return this.form.get('choices') as UntypedFormArray;
}
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);
this.focusOnChoice(this.choices.length - 1);
}
/**
* make a uniq slug for the current poll creation
* @param form
*/
makeSlug(form: UntypedFormGroup): string {
let str = '';
str =
form.value.created_at.getFullYear() +
'_' +
(form.value.created_at.getMonth() + 1) +
'_' +
form.value.created_at.getDate() +
'_' +
form.value.creatorPseudo +
'_' +
form.value.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: Subscription = 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: Owner, response: Answer): void {
const currentPoll = this._poll.getValue();
currentPoll.choices.find((c) => c.name === choice.name)?.updateParticipation(user, response);
this.updateCurrentPoll(currentPoll);
this.apiService.createParticipation(currentPoll.custom_url, choice.name, 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().custom_url);
this.toastService.display('Les participations des votants à ce sondage ont été supprimées.');
}
public async addComment(comment: CommentDTO): Promise<void> {
await this.apiService.createComment(this._poll.getValue().custom_url, comment).then(
(resp) => {
console.log('resp', resp);
this.loadPollByCustomUrl(this._poll.getValue().custom_url);
console.log('resp', resp);
this.toastService.display('Votre commentaire a été enregistré.');
},
(err) => this.apiService.ousideHandleError(err)
);
}
public async deleteComments(): Promise<void> {
await this.apiService.deletePollComments(this._poll.getValue().custom_url);
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<Owner>) => {
users.forEach((user: Owner) => {
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.name, undefined];
})
)
);
});
poll.choices.forEach((choice: Choice) => {
choice.participants.forEach((users: Set<Owner>, answer: Answer) => {
users.forEach((user: Owner) => {
list.get(user.pseudo).set(choice.name, answer);
});
});
});
return list;
}
public getParticipationUrlFromForm(): string {
return `${environment.frontDomain}#/poll/${this.form.value.custom_url}/consultation`;
}
public getAdministrationUrlFromForm(): string {
// admin_key is filled after creation
// example http://localhost:4200/#/administration/key/8Ubcg2YI99f69xz946cn4O64bQAeb
return `${environment.frontDomain}#/administration/key/${this.admin_key}`;
}
public getParticipationUrl(): string {
// http://localhost:4200/#/poll/dessin-anime/consultation
// handle secure access
// http://localhost:4200/#/poll/citron/consultation/secure/1c01ed9c94fc640a1be864f197ff808c
// http://localhost:4200/#/poll/citron/consultation/prompt pour entrer le pass à double hasher en md5
let url = '';
let suffix_password = '';
const currentPoll = this._poll.getValue();
if (this._poll && currentPoll) {
if (currentPoll.password) {
// handle pass access
suffix_password = '/prompt';
}
if (currentPoll) {
url = `${environment.frontDomain}/#/poll/${currentPoll.custom_url}/consultation${suffix_password}`;
} else {
url = `${environment.frontDomain}/#/poll/${this.form.value.custom_url}/consultation${suffix_password}`;
}
} else {
url = `${environment.frontDomain}/#/poll/${this.form.value.custom_url}/consultation${suffix_password}`;
}
return url;
}
public getAdministrationUrl(): string {
// http://localhost:4200/#/admin/9S75b70ECXI5J5xDc058d3H40H9r2CHfO0Kj8T02EK2U8rY8fYTn-eS659j2Dhp794Oa6R1b9V70e3WGaE30iD9h45zwdm76C85SWB4LcUCrc7e0Ncc0
let url = '';
if (this._poll && this._poll.getValue) {
const polltemp = this._poll.getValue();
if (polltemp) {
url = `${environment.frontDomain}/#/admin/${polltemp.admin_key}`;
}
} else {
url = `${environment.frontDomain}/#/admin/${this.form.value.admin_key}`;
}
return url;
}
/**
* enrich vote stack with missing default votes
* @param vote_stack
*/
enrichVoteStackWithCurrentPollChoicesDefaultVotes(vote_stack: Stack) {
if (this._poll && this._poll.getValue) {
const polltemp = this._poll.getValue();
polltemp.choices.map((choice) => {
// for each vote, if it has the choice_id, do nothing, else, add a default vote
if (!this.findExistingVoteFromChoiceId(choice.id, vote_stack.votes)) {
vote_stack.votes.push(new Vote(choice.id));
}
});
}
}
/**
* find an existing vote in vote_stack from its choice_id
* @param choice_id
* @param votes
*/
findExistingVoteFromChoiceId(choice_id: number, votes: Vote[]) {
return votes.find((vote: Vote) => {
if (vote.choice_id === choice_id) {
return vote;
}
});
}
/**
* convertir les dates de la propriété Calendar en objets de saisie de texte
*/
convertCalendarToText() {
console.log('this.dateChoiceList', this.dateChoiceList);
if (this.calendar && this.calendar.length) {
let converted = [];
for (let someDate of this.calendar) {
converted.push(this.DateUtilitiesService.convertDateToDateChoiceObject(someDate));
}
this.dateChoiceList = converted.sort((first: any, second: any) => {
return first.date_object - second.date_object;
});
return converted;
} else {
this.dateChoiceList = [];
}
return this.dateChoiceList;
}
/**
* convert the DateChoices to an arrray of Dates for calendar picker
*/
convertTextToCalendar(): Date[] {
console.log('convert text to calendar', this.dateChoiceList);
let converted = [];
for (let someDateChoice of this.dateChoiceList) {
let dateObj = new Date(someDateChoice.date_input);
console.log('dateObj', dateObj);
// check that date is not part of the disabled dates
if (this.disabled_dates.indexOf(dateObj) === -1) {
converted.push(dateObj);
}
}
console.log('converted', converted);
this.calendar = converted;
return converted;
}
patchFormWithPoll(poll: Poll) {
this.form.patchValue({
...poll,
isAboutDate: poll.kind == 'date',
});
}
/**
* @description convert to API version 1 data transition object
*/
newPollFromForm(): Poll {
let form = this.form;
const newOwner = this.storageService.vote_stack.owner;
newOwner.pseudo = form.value.creatorPseudo;
newOwner.email = form.value.creatorEmail;
const newpoll = new Poll(newOwner, form.value.custom_url, form.value.title);
const pollKeys = Object.keys(newpoll);
const formFields = Object.keys(form.value);
newpoll.allowed_answers = [];
// comparer les champs de formulaire avec le DTO de création de sondage
for (const pk of pollKeys) {
if (formFields.indexOf(pk) !== -1) {
const field = form.value[pk];
newpoll[pk] = field;
} else {
console.log('newPollFromForm : manque pollKey', pk);
}
}
if (form.value.isYesAnswerAvailable) {
newpoll.allowed_answers.push('yes');
}
if (form.value.isMaybeAnswerAvailable) {
newpoll.allowed_answers.push('maybe');
}
if (form.value.isNoAnswerAvailable) {
newpoll.allowed_answers.push('no');
}
newpoll.description = form.value.description;
newpoll.has_several_hours = form.value.hasSeveralHours;
newpoll.max_count_of_answers = form.value.maxCountOfAnswers | (1024 * 10);
newpoll.maxCountOfAnswers = form.value.maxCountOfAnswers | (1024 * 10);
newpoll.password = form.value.password;
newpoll.kind = form.value.isAboutDate ? 'date' : 'classic';
newpoll.allow_comments = form.value.allowComments;
// merge choices from storage
if (form.value.isAboutDate) {
// first we convert calendar picker dates.
// we want a list of date object, and we want the kind of dates who was lastly edited by the user
// depending on the manual or datepicker mode, we need to get a converted list of dates
let convertedDates = [];
if (this.mode_calendar) {
// mode calendar date picker, we take the list of date objects in calendar property
convertedDates = this.calendar;
} else {
// mode text, we convert to calendar list, and take that list
convertedDates = this.convertTextToCalendar();
}
console.log('this.calendar', this.calendar);
for (let elem of convertedDates) {
console.log('elem', elem);
let converted_day = this.DateUtilitiesService.convertDateToDateChoiceObject(elem);
newpoll.dateChoices.push(converted_day);
}
console.log('newpoll.dateChoices', newpoll.dateChoices);
} else {
// text choices
newpoll.choicesText = Object.assign([], this.storageService.choicesText);
}
newpoll.choices = Object.assign([], this.storageService.choices);
// newpoll.dateChoices = Object.assign([], this.storageService.dateChoices);
newpoll.timeSlices = Object.assign([], this.storageService.timeSlices);
console.log('newpoll', newpoll);
return newpoll;
}
/**
* copy public url of new poll
* @param textToCopy
*/
copyText(textToCopy: string) {
this._clipboardService.copyFromContent(textToCopy);
this.translate.get('success.copy_message').subscribe((resp) => {
console.log('resp', resp);
this.toastService.display(`${resp} ${textToCopy}`);
});
}
}