diff --git a/src/app/features/administration/form/form.component.html b/src/app/features/administration/form/form.component.html
index 8c76d5ae..ed0098b8 100644
--- a/src/app/features/administration/form/form.component.html
+++ b/src/app/features/administration/form/form.component.html
@@ -65,6 +65,34 @@
+
+
+
+
diff --git a/src/app/features/administration/form/form.component.ts b/src/app/features/administration/form/form.component.ts
index b5217e7e..8b024dc9 100644
--- a/src/app/features/administration/form/form.component.ts
+++ b/src/app/features/administration/form/form.component.ts
@@ -1,10 +1,12 @@
-import { Component, Input, OnInit } from '@angular/core';
+import { ChangeDetectorRef, Component, Inject, Input, OnInit } from '@angular/core';
import { Poll } from '../../../core/models/poll.model';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { UuidService } from '../../../core/services/uuid.service';
import { ApiService } from '../../../core/services/api.service';
import { ToastService } from '../../../core/services/toast.service';
import { PollService } from '../../../core/services/poll.service';
+import { DateUtilities } from '../../old-stuff/config/DateUtilities';
+import { DOCUMENT } from '@angular/common';
@Component({
selector: 'app-admin-form',
@@ -18,13 +20,22 @@ export class FormComponent implements OnInit {
public urlPrefix: string = window.location.origin + '/participation/';
public advancedDisplayEnabled = false;
+ public showDateInterval = true;
+ startDateInterval: any;
+ intervalDays: any;
+ intervalDaysDefault = 7;
+ endDateInterval: any;
+ dateList: any[];
constructor(
private fb: FormBuilder,
+ private cd: ChangeDetectorRef,
private uuidService: UuidService,
private toastService: ToastService,
private pollService: PollService,
- private apiService: ApiService
+ public dateUtilities: DateUtilities,
+ private apiService: ApiService,
+ @Inject(DOCUMENT) private document: any
) {}
ngOnInit(): void {
@@ -61,6 +72,13 @@ export class FormComponent implements OnInit {
});
}
this.choices.push(newControlGroup);
+ this.cd.detectChanges();
+ console.log('this.choices.length', this.choices.length);
+ const selector = '#choice_label_' + (this.choices.length - 1);
+ const elem = this.document.querySelector(selector);
+ if (elem) {
+ elem.focus();
+ }
}
deleteChoiceField(index: number): void {
@@ -73,7 +91,7 @@ export class FormComponent implements OnInit {
this.choices.setValue([]);
}
- initFormDefault(): void {
+ initFormDefault(showDemoValues = true): void {
this.form = this.fb.group({
title: ['', [Validators.required, Validators.minLength(12)]],
creatorPseudo: ['', [Validators.required]],
@@ -82,6 +100,8 @@ export class FormComponent implements OnInit {
description: ['', [Validators.required]],
choices: new FormArray([]),
isAboutDate: [true, [Validators.required]],
+ startDateInterval: ['', [Validators.required]],
+ endDateInterval: ['', [Validators.required]],
isProtectedByPassword: [false, [Validators.required]],
isOwnerNotifiedByEmailOnNewVote: [false, [Validators.required]],
isOwnerNotifiedByEmailOnNewComment: [false, [Validators.required]],
@@ -90,9 +110,33 @@ export class FormComponent implements OnInit {
expiracyNumberOfDays: [60, [Validators.required, Validators.min(0)]],
});
console.log('this.form ', this.form);
- this.setDemoValues();
+ this.setDefaultDatesForInterval();
+
+ if (showDemoValues) {
+ this.setDemoValues();
+ }
}
+ /**
+ * 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,
+ });
+ }
+
+ /**
+ * add example values to the form
+ */
setDemoValues(): void {
this.addChoice('orange');
this.addChoice('raisin');
@@ -116,7 +160,88 @@ export class FormComponent implements OnInit {
}
askInitFormDefault(): void {
- this.initFormDefault();
+ this.initFormDefault(false);
this.toastService.display('formulaire réinitialisé');
}
+
+ countDays(): void {
+ this.intervalDays = this.dateUtilities.countDays(this.startDateInterval, this.endDateInterval);
+ }
+
+ /**
+ * add all the dates between the start and end dates in the interval section
+ */
+ addIntervalOfDates(): void {
+ const newIntervalArray = this.dateUtilities.getDatesInRange(this.startDateInterval, 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.toastService.display(`les dates ont été ajoutées aux réponses possibles.`);
+ }
+
+ /**
+ * handle keyboard shortcuts
+ * @param $event
+ */
+ 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) {
+ const selector = '#choice_label_' + (choice_number - 1);
+ const elem = this.document.querySelector(selector);
+ if (elem) {
+ elem.focus();
+ }
+ }
+ 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 {
+ const selector = '#choice_label_' + (choice_number + 1);
+ const elem = this.document.querySelector(selector);
+ if (elem) {
+ elem.focus();
+ }
+ }
+ }
+ if ($event.ctrlKey && $event.key == 'Backspace') {
+ this.deleteChoiceField(choice_number);
+ this.toastService.display('choix supprimé par raccourci "Ctrl + retour"');
+ this.cd.detectChanges();
+ const selector = '#choice_label_' + Math.min(choice_number - 1, 0);
+ const elem = this.document.querySelector(selector);
+ if (elem) {
+ elem.focus();
+ }
+ }
+ if ($event.ctrlKey && $event.key == 'Enter') {
+ // go to other fields
+ const elem = this.document.querySelector('#creatorEmail');
+ if (elem) {
+ elem.focus();
+ }
+ }
+ }
}
diff --git a/src/app/features/old-stuff/config/DateUtilities.ts b/src/app/features/old-stuff/config/DateUtilities.ts
index 6e60ca21..eec4d518 100644
--- a/src/app/features/old-stuff/config/DateUtilities.ts
+++ b/src/app/features/old-stuff/config/DateUtilities.ts
@@ -60,4 +60,12 @@ export class DateUtilities {
getDoubleDigits(str) {
return ('00' + str).slice(-2);
}
+
+ countDays(startDateInterval: Date, endDateInterval: Date): number {
+ // compute the number of days in the date interval
+ if (endDateInterval && startDateInterval) {
+ return this.dayDiff(endDateInterval, startDateInterval);
+ }
+ return 0;
+ }
}
diff --git a/src/app/features/old-stuff/pages/dates/dates.component.ts b/src/app/features/old-stuff/pages/dates/dates.component.ts
index 31458e4d..1caed356 100644
--- a/src/app/features/old-stuff/pages/dates/dates.component.ts
+++ b/src/app/features/old-stuff/pages/dates/dates.component.ts
@@ -55,7 +55,7 @@ export class DatesComponent extends BaseComponent implements OnInit {
date_object: new Date(),
timeList: [],
});
- const selector = '[ng-reflect-choice_label="dateChoices_' + (this.config.dateList.length - 1) + '"]';
+ const selector = '["choice_label_' + (this.config.dateList.length - 1) + '"]';
this.cd.detectChanges();
const elem = this.document.querySelector(selector);
if (elem) {
diff --git a/src/assets/i18n/FR.json b/src/assets/i18n/FR.json
index 89808c4b..2b885653 100644
--- a/src/assets/i18n/FR.json
+++ b/src/assets/i18n/FR.json
@@ -35,6 +35,7 @@
},
"choose_title": "Dont le titre sera",
"choose_title_placeholder": "titre",
+ "choices_hint": "Utilisez les flèches haut ⬆️ et bas ⬇️ pour passer d'un choix à un autre",
"name": "Je peux aussi préciser mon nom si je le souhaite",
"name_placeholder": "mon nom",
"description": "et la description serait",