Creation : add hours selection in step 4

This commit is contained in:
Tykayn 2021-11-22 15:30:23 +01:00 committed by tykayn
parent edcb1bdcf8
commit 135cc5e512
14 changed files with 194 additions and 35 deletions

View File

@ -18,7 +18,7 @@ export class PollConfiguration {
public hasMaxCountOfAnswers: boolean = false,
public whoCanChangeAnswers: string = environment.poll.defaultConfig.whoCanChangeAnswers, // everybody, self, nobody (= just admin)
public visibility: string = environment.poll.defaultConfig.visibility, // visible to anyone with the link:
public voteChoices: string = environment.poll.defaultConfig.voteChoices, // possible answers to a vote choice: only "yes", "yes, maybe, no": number = environment.poll.defaultConfig.maxCountOfAnswers,
public voteChoices: string = environment.poll.defaultConfig.voteChoices, // possible answers to a vote timeSlice: only "yes", "yes, maybe, no": number = environment.poll.defaultConfig.maxCountOfAnswers,
public maxCountOfAnswers: number = environment.poll.defaultConfig.maxCountOfAnswers,
public expiresDaysDelay: number = environment.poll.defaultConfig.expiresDaysDelay,
public expiracyAfterLastModificationInDays: number = environment.poll.defaultConfig

View File

@ -8,3 +8,13 @@ export interface DateChoice {
export interface TimeSlices {
literal: string;
}
export const timeSlicesProposals: TimeSlices[] = [
{ literal: 'matin' },
{ literal: 'midi' },
{ literal: 'après-midi' },
{ literal: 'soir' },
{ literal: 'aux aurores' },
{ literal: 'au petit dej' },
{ literal: 'au deuxième petit dej des hobbits' },
];

View File

@ -17,7 +17,7 @@ export class PollDTO {
myPolls; // list of retrieved polls from the backend api
allowSeveralHours;
visibility; // visible to one with the link:
voteChoices = 'yes; maybe; no'; // possible answers to a vote choice: only "yes"; "yes; maybe; no"
voteChoices = 'yes; maybe; no'; // possible answers to a vote timeSlice: only "yes"; "yes; maybe; no"
created_at;
expirationDate; // expiracy date
voteStackId; // id of the vote stack to update

View File

@ -77,7 +77,6 @@ export class PollService implements Resolve<Poll> {
}
if (environment.autofill_creation) {
this.setDemoValues();
this.toastService.display('auto fill de création fait');
}
if (environment.autoSendNewPoll) {
this.createPoll();
@ -303,7 +302,11 @@ export class PollService implements Resolve<Poll> {
converted.push({
literal: element.literal,
date_object: element.date_object,
timeList: [],
timeList: [
{
literal: 'matin',
},
],
});
});
this.dateChoiceList = [...new Set(converted)];
@ -327,14 +330,14 @@ export class PollService implements Resolve<Poll> {
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
// 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 choice
// add a field if we are on the last timeSlice
if (lastChoice) {
this.addChoice();
this.toastService.display('choix ajouté par raccourci "flèche bas"');
@ -374,7 +377,7 @@ export class PollService implements Resolve<Poll> {
}
/**
* add a time period to a specific date choice,
* add a time period to a specific date timeSlice,
* focus on the new input
* @param config
* @param id

View File

@ -71,7 +71,7 @@ export class StorageService {
// console.log('autofill au hasard des votes à ce sondage');
// this.toastService.display('autofill au hasard des votes à ce sondage');
// const defaultvalue = Math.random() > 0.75 ? 'yes' : '';
// this.vote_stack.votes.push(new Vote(choice.id, defaultvalue));
// this.vote_stack.votes.push(new Vote(timeSlice.id, defaultvalue));
// } else {
this.vote_stack.votes.push(new Vote(choice.id));
// }
@ -80,7 +80,7 @@ export class StorageService {
}
/**
* look for a choice in the stored vote stack and change it answer
* look for a timeSlice in the stored vote stack and change it answer
* @param choice_id
* @param value
*/
@ -97,7 +97,7 @@ export class StorageService {
}
/**
* check for the value of a choice in the stored vote stack
* check for the value of a timeSlice in the stored vote stack
* @param choice_id
* @param value
*/
@ -113,7 +113,7 @@ export class StorageService {
}
/**
* set all time slices of a choice to the same answer at once
* set all time slices of a timeSlice to the same answer at once
* @param groupe
* @param newAnswer
*/

View File

@ -24,8 +24,8 @@
>
<!-- <span class="button is-default">-->
<!-- <i class="icon fa fa-arrows-v"></i>-->
<!-- <span *ngIf="choice.date_object">-->
<!-- {{ choice.date_object | date: 'E':'Europe/Paris':'fr_FR' }}-->
<!-- <span *ngIf="timeSlice.date_object">-->
<!-- {{ timeSlice.date_object | date: 'E':'Europe/Paris':'fr_FR' }}-->
<!-- </span>-->
<!-- </span>-->
<div class="columns">

View File

@ -60,7 +60,7 @@ export class DayListComponent {
}
/**
* add a time period to a specific date choice,
* add a time period to a specific date timeSlice,
* focus on the new input
* @param choice DateChoice
* @param id number
@ -79,7 +79,7 @@ export class DayListComponent {
if (firstField) {
firstField.focus();
} else {
console.log('no last time choice found');
console.log('no last time timeSlice found');
}
}
@ -97,15 +97,15 @@ export class DayListComponent {
// TODO handle shortcuts
// 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
// go to previous timeSlice with arrow up
// go to next timeSlice with arrow down
console.log('$event', $event);
if ($event.ctrlKey && $event.key == 'ArrowUp' && choice_number > 0) {
this.focusOnChoice(choice_number - 1);
}
if ($event.ctrlKey && ($event.key == 'ArrowDown' || $event.key == 'ArrowRight')) {
// add a field if we are on the last choice
// add a field if we are on the last timeSlice
if (lastChoice) {
this.addChoice();
this.toastService.display('choix ajouté par raccourci "flèche bas"');

View File

@ -60,7 +60,7 @@ export class TimeListComponent implements OnInit {
focusOnLastField() {
this.cd.detectChanges();
if (!this.focusOnFieldNumber(this.timeSlices.length - 1)) {
console.log('no last time choice found');
console.log('no last time timeSlice found');
this.createNewField();
this.focusOnLastField();
}

View File

@ -1,12 +1,81 @@
<div class="step">
<div class="min-height">
<form action="#" [formGroup]="pollService.form">
<app-stepper [step_current]="4" [step_max]="pollService.step_max"></app-stepper>
<app-errors-list [form]="pollService.form"></app-errors-list>
<h2 class="title is-2">
Choisissez les horaires
</h2>
</form>
<app-wip-todo></app-wip-todo>
<div
class="days-list-having-separated-time-slices rounded-block"
*ngFor="let dayChoice of pollService.dateChoiceList; index as day_id"
>
<div class="heading day-choice">
{{ dayChoice.date_object | date }}
</div>
<section class="time-slice-list-of-a-day">
<div *ngFor="let timeSlice of dayChoice.timeSlices; index as id" class="time-choice padded">
<label for="dateChoices_{{ id }}"> Horaire / option {{ id + 1 }} </label>
<input
class="input is-fullwidth"
type="text"
id="dateChoices_{{ id }}"
[(ngModel)]="timeSlice.literal"
/>
<button class="button input is-full" (click)="pollService.timeList.splice(id, 1)">
<i class="fa fa-trash"></i> supprimer
</button>
</div>
<div class="add-time-choice">
<button (click)="addChoiceForDay(dayChoice)">
<i class="fa fa-plus"></i>
Ajouter horaire / option
</button>
</div>
</section>
</div>
<section class="proposals">
<h3 class="title is-3">
Propositions de créneaux horaires
</h3>
<div class="time-slices-proposals rounded-block">
<div
class="button is-rounded"
*ngFor="let text of timeSlicesProposals"
(click)="addPreselect(text.literal)"
>
{{ text.literal }}
</div>
</div>
</section>
<section class="same-time-slices">
<button class="is-outlined is-primary" (click)="toggleHasSeveralHours()">
Appliquer le même horaire / option à toutes les dates
</button>
<section class="same-time-slices rounded-block" *ngIf="pollService.form.value.hasSeveralHours">
<h3 class="title is-3">
Choisissez les horaires ou options à appliquer à toutes les dates
</h3>
<div *ngFor="let timeSlice of pollService.timeList; index as id" class="time-choice padded">
<label for="timeList_{{ id }}"> Horaire / option {{ id + 1 }} </label>
<input
class="input is-fullwidth"
type="text"
id="timeList_{{ id }}"
[(ngModel)]="timeSlice.literal"
/>
<button class="button is-block" (click)="pollService.timeList.splice(id, 1)">
<i class="fa fa-trash"></i> supprimer
</button>
</div>
<button class="is-primary button" (click)="applyTimeSlicesToDateChoices()">
Appliquer ces créneaux
</button>
</section>
</section>
</div>
<div class="columns">
<div class="column">

View File

@ -1,7 +1,12 @@
import { Component, Input, OnInit } from '@angular/core';
import { Component, Inject, Input, OnInit } from '@angular/core';
import { PollService } from '../../../../../core/services/poll.service';
import { environment } from '../../../../../../environments/environment';
import { Router } from '@angular/router';
import { DateUtilitiesService } from '../../../../../core/services/date.utilities.service';
import { DOCUMENT } from '@angular/common';
import { StorageService } from '../../../../../core/services/storage.service';
import { DateChoice, TimeSlices, timeSlicesProposals } from '../../../../../core/models/dateChoice.model';
import { ToastService } from '../../../../../core/services/toast.service';
@Component({
selector: 'app-step-four',
@ -15,10 +20,78 @@ export class StepFourComponent implements OnInit {
step_max: any;
@Input()
form: any;
showSameTimeSlices: boolean = false;
timeSlicesProposals: TimeSlices[] = timeSlicesProposals;
constructor(private router: Router, public pollService: PollService) {
constructor(
private dateUtilitiesService: DateUtilitiesService,
private router: Router,
private toastService: ToastService,
@Inject(DOCUMENT) private document: any,
private storageService: StorageService,
public pollService: PollService
) {
this.pollService.step_current = 4;
}
ngOnInit(): void {}
/**
* toggle hasSeveralHours to show an other form section
* so that the user can choose between time slices applying equally to all days in her form,
* or have the ability to define different times lices for each day
*/
toggleHasSeveralHours() {
this.pollService.form.patchValue({
hasSeveralHours: !this.pollService.form.value.hasSeveralHours,
});
}
addChoiceForDay(dayChoice: DateChoice): void {
let lastDateChoice = this.pollService.dateChoiceList[this.pollService.dateChoiceList.length];
console.log('lastDateChoice', lastDateChoice);
let lastDateChoiceObject = this.dateUtilitiesService.addDaysToDate(
this.pollService.dateChoiceList.length,
new Date()
);
if (lastDateChoice && lastDateChoice.date_object) {
lastDateChoiceObject = lastDateChoice.date_object;
} else {
lastDateChoiceObject = new Date();
}
dayChoice.timeSlices.push({
literal: '',
});
dayChoice.timeSlices.sort((a: any, b: any) => {
return a.date_object - b.date_object;
});
this.focusOnChoice(this.storageService.dateChoices.length - 1);
}
focusOnChoice(index): void {
const selector = '#choice_label_' + index;
const elem = this.document.querySelector(selector);
if (elem) {
elem.focus();
}
}
addPreselect(literal: string) {
if (
!this.pollService.timeList.find((elem) => {
return elem.literal === literal;
})
) {
this.pollService.timeList.push({ literal });
}
}
applyTimeSlicesToDateChoices() {
let timeSlicesToApply = this.pollService.timeList;
this.pollService.dateChoiceList.forEach((elem) => {
return (elem.timeSlices = timeSlicesToApply);
});
this.toastService.display(`time slices appliquées avec succès`);
}
}

View File

@ -24,7 +24,7 @@
</span>
</div>
<div class="column is-narrow">
<!-- <button class="button is-white" (click)="openModal(poll, choice)">-->
<!-- <button class="button is-white" (click)="openModal(poll, timeSlice)">-->
<!-- <i class="fa fa-info-circle"></i>-->
<!-- </button>-->
</div>

View File

@ -5,7 +5,7 @@
Choix
</th>
<th *ngFor="let choice of poll.choices">
<!-- {{choice.id}}-->
<!-- {{timeSlice.id}}-->
<span class="label" *ngIf="poll.kind == 'text'">
{{ choice.name }}
</span>

View File

@ -15,7 +15,7 @@ export const environment = {
advanced_options_display: false,
autofill_participation: false,
showDemoWarning: false,
autoSendNewPoll: true,
autoSendNewPoll: false,
showStepperShortcuts: true,
interval_days_default: 7,
expiresDaysDelay: 60,

View File

@ -298,7 +298,7 @@ mat-checkbox {
}
}
.block-resume {
.rounded-block {
border-radius: 0.25em;
background: $bg-grey;
padding: 1em;
@ -308,8 +308,8 @@ mat-checkbox {
margin: 0.5em -1em;
background: $rules;
}
.go-to-step {
.go-to-step,
.custom-action {
@extend .clickable;
color: $secondary_color;
padding: 1.5em;
@ -321,3 +321,7 @@ mat-checkbox {
}
}
}
.block-resume {
@extend .rounded-block;
}