-
- {{ 'home.title' | translate }}
- {{ env.appTitle }}
-
+
+
+
+ {{ 'home.title' | translate }}
+ {{ env.appTitle }}
+
+
+ {{
+ 'SENTENCES.framadate-is-an-online-service-for-planning-an-appointment-or-making-a-decision-quickly-and-easily'
+ | translate
+ }}
+
+
+
@@ -19,50 +29,144 @@
+
-
-
- {{
- 'SENTENCES.framadate-is-an-online-service-for-planning-an-appointment-or-making-a-decision-quickly-and-easily'
- | translate
- }}
- {{ 'SENTENCES.here-is-how-it-works' | translate }}
- {{ 'SENTENCES.send-the-poll-link-to-your-friends-or-colleagues' | translate }}
-
-
- {{ 'SENTENCES.what-is-framadate' | translate }}
- {{ 'SENTENCES.view-an-example' | translate }}
- {{ 'SENTENCES.framadate-is-licensed-under-the' | translate }}
-
- GNU Affero v3 Licence
-
-
-
- {{ 'SENTENCES.grow-your-own' | translate }}
- {{
- 'SENTENCES.if-you-want-to-install-the-software-for-your-own-use-and-thus-increase-your-independence-we-can-help'
- | translate
- }}
- {{
- 'SENTENCES.to-participate-in-the-software-development-suggest-improvements-or-simply-download-it-please-visit'
- | translate
- }}
- {{ 'SENTENCES.the-development-site' | translate }}
-
+
+
+
+
+ {{ 'SENTENCES.here-is-how-it-works' | translate }}
+
+
+ {{ 'SENTENCES.send-the-poll-link-to-your-friends-or-colleagues' | translate }}
+
+ {{ 'SENTENCES.what-you-can-do' | translate }}
+
+
+
+ {{ 'SENTENCES.view-an-example' | translate }}
+
+
+
+ Orange ou citron?
+
+
+
+
+
+ {{ 'SENTENCES.framadate-is-licensed-under-the' | translate }}
+
+
+ GNU Affero v3 Licence
+
+
+
+
+
+
+
+ {{ 'SENTENCES.grow-your-own' | translate }}
+
+
+ {{
+ 'SENTENCES.if-you-want-to-install-the-software-for-your-own-use-and-thus-increase-your-independence-we-can-help'
+ | translate
+ }}
+ {{
+ 'SENTENCES.to-participate-in-the-software-development-suggest-improvements-or-simply-download-it-please-visit'
+ | translate
+ }}
+ {{ 'SENTENCES.the-development-site' | translate }}
+
+
+
+
+
+
Statistiques
+
+
+
+
+
+
+ 62 346
+
+
sondages
+
+
+
+
+ 223 124
+
+
votes
+
+
+
+
+
+ 41 875
+
+
commentaires
+
+
+
+
+
+
+ 44 985
+
+
sondages de type date
+
+
+
+
+
+ 22 985
+
+
sondages de type classique
+
+
+
+
+ 123
+
+
consensus parfaits
+
+
+
+
diff --git a/src/app/core/models/configuration.model.ts b/src/app/core/models/configuration.model.ts
index 8ec766f2..8b723adc 100644
--- a/src/app/core/models/configuration.model.ts
+++ b/src/app/core/models/configuration.model.ts
@@ -3,26 +3,34 @@ import { DateService } from '../services/date.service';
export class PollConfiguration {
constructor(
- public isAboutDate: boolean = false,
- public isProtectedByPassword: boolean = false,
+ public allowComments: boolean = true,
+ public areResultsPublic: boolean = true,
+ public dateCreated: Date = new Date(Date.now()),
public password: string = '',
+ public isAboutDate: boolean = false,
+ public isAllowingtoChangeOwnAnswers: boolean = true,
+ public isMaybeAnswerAvailable: boolean = false,
+ public isProtectedByPassword: boolean = false,
public isOwnerNotifiedByEmailOnNewVote: boolean = false,
public isOwnerNotifiedByEmailOnNewComment: boolean = false,
- public isMaybeAnswerAvailable: boolean = false,
- public areResultsPublic: boolean = true,
- public isAllowingtoChangeOwnAnswers: boolean = true,
- public whoCanChangeAnswers: string = 'everybody',
- public dateCreated: Date = new Date(Date.now()),
- public expiresDaysDelay: number = environment.poll.defaultConfig.expiracyInDays,
+ public isZeroKnoledge: boolean = true,
+ public hasSeveralHours: boolean = false,
+ 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 maxCountOfAnswers: number = environment.poll.defaultConfig.maxCountOfAnswers,
+ public expiresDaysDelay: number = environment.poll.defaultConfig.expiresDaysDelay,
public expiracyAfterLastModificationInDays: number = environment.poll.defaultConfig
.expiracyAfterLastModificationInDays,
- public expires: Date = DateService.addDaysToDate(
- environment.poll.defaultConfig.expiracyInDays,
+ // date after creation day when people will not be able to vote anymore
+ public expiracyDate: Date = DateService.addDaysToDate(
+ environment.poll.defaultConfig.expiresDaysDelay,
new Date(Date.now())
)
) {}
public static isArchived(configuration: PollConfiguration): boolean {
- return configuration.expires ? DateService.isDateInPast(configuration.expires) : undefined;
+ return configuration.expiracyDate ? DateService.isDateInPast(configuration.expiracyDate) : undefined;
}
}
diff --git a/src/app/core/models/poll.model.ts b/src/app/core/models/poll.model.ts
index 8d616c3f..59c18a49 100644
--- a/src/app/core/models/poll.model.ts
+++ b/src/app/core/models/poll.model.ts
@@ -8,14 +8,18 @@ import { User } from './user.model';
export class Poll {
constructor(
public owner: User = new User(),
- public slug: string = 'default-slug',
- public title: string = 'default title',
+ public slug: string = '',
+ public title: string = '',
public description?: string,
+ public creatorPseudo?: string,
+ public creatorEmail?: string,
+ public allowSeveralHours?: boolean,
+ public archiveNumberOfDays?: number,
public configuration: PollConfiguration = new PollConfiguration(),
public comments: Comment[] = [],
public choices: Choice[] = [],
- public dateChoices: Choice[] = [],
- public timeChoices: Choice[] = []
+ public dateChoices: Choice[] = [], // sets of days as strings, config to set identical time for days in a special days poll
+ public timeChoices: Choice[] = [] // ranges of time expressed as strings
) {}
public getAdministrationUrl(): string {
@@ -33,22 +37,22 @@ export class Poll {
new User(item.owner.pseudo, item.owner.email, undefined),
item.slug,
item.title,
- item.description,
- item.configuration,
- item.comments
- .map(
- (c: Pick
) =>
- new Comment(c.author, c.content, new Date(c.dateCreated))
- )
- .sort(Comment.sortChronologically),
- item.choices.map((c: Pick) => {
- const choice = new Choice(c.label, c.imageUrl, new Map(c.participants));
- choice.participants.forEach((value, key) => {
- choice.participants.set(key, new Set(value));
- });
- choice.updateCounts();
- return choice;
- })
+ item.description
+ // item.configuration,
+ // item.comments
+ // .map(
+ // (c: Pick) =>
+ // new Comment(c.author, c.content, new Date(c.dateCreated))
+ // )
+ // .sort(Comment.sortChronologically),
+ // item.choices.map((c: Pick) => {
+ // const choice = new Choice(c.label, c.imageUrl, new Map(c.participants));
+ // choice.participants.forEach((value, key) => {
+ // choice.participants.set(key, new Set(value));
+ // });
+ // choice.updateCounts();
+ // return choice;
+ // })
);
}
}
diff --git a/src/app/core/services/api.service.ts b/src/app/core/services/api.service.ts
index 12b14318..3bf4faeb 100644
--- a/src/app/core/services/api.service.ts
+++ b/src/app/core/services/api.service.ts
@@ -49,7 +49,7 @@ export class ApiService {
public async createPoll(poll: Poll): Promise {
// this.loader.setStatus(true);
- console.log('config', poll);
+ console.log('createPoll config', poll);
// const baseHref = this.useDevLocalServer ? 'http://localhost:8000' : apiBaseHref;
// return this.http
// .post(`${baseHref}${currentApiRoutes['api_new_poll']}`, poll, ApiService.makeHeaders())
diff --git a/src/app/core/services/poll.service.ts b/src/app/core/services/poll.service.ts
index d597e52d..e8d16e15 100644
--- a/src/app/core/services/poll.service.ts
+++ b/src/app/core/services/poll.service.ts
@@ -64,7 +64,7 @@ export class PollService implements Resolve {
console.log('getAllAvailablePolls res', res);
});
} catch (e) {
- console.log('getAllAvailablePolls e', e);
+ console.error('getAllAvailablePolls e', e);
}
}
@@ -86,6 +86,7 @@ export class PollService implements Resolve {
* @param config
*/
makeSlug(config: Poll): string {
+ console.log('config', config);
let str = '';
str =
config.configuration.dateCreated.getFullYear() +
@@ -228,7 +229,6 @@ export class PollService implements Resolve {
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
diff --git a/src/app/features/administration/administration.module.ts b/src/app/features/administration/administration.module.ts
index 051ead96..5a3b196b 100644
--- a/src/app/features/administration/administration.module.ts
+++ b/src/app/features/administration/administration.module.ts
@@ -1,6 +1,6 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
-import { ReactiveFormsModule } from '@angular/forms';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { SharedModule } from '../../shared/shared.module';
@@ -10,16 +10,38 @@ import { StepperComponent } from './stepper/stepper.component';
import { NamingComponent } from './naming/naming.component';
import { FormComponent } from './form/form.component';
import { DateValueAccessorModule } from 'angular-date-value-accessor';
+import { SuccessComponent } from './success/success.component';
+import { DateSelectComponent } from './form/date-select/date-select.component';
+import { TextSelectComponent } from './form/text-select/text-select.component';
+import { KindSelectComponent } from './form/kind-select/kind-select.component';
+import { BaseConfigComponent } from './form/base-config/base-config.component';
+import { AdvancedConfigComponent } from './form/advanced-config/advanced-config.component';
+import { CalendarModule } from 'primeng';
+import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({
- declarations: [AdministrationComponent, StepperComponent, NamingComponent, FormComponent],
+ declarations: [
+ AdministrationComponent,
+ StepperComponent,
+ NamingComponent,
+ FormComponent,
+ SuccessComponent,
+ DateSelectComponent,
+ TextSelectComponent,
+ KindSelectComponent,
+ BaseConfigComponent,
+ AdvancedConfigComponent,
+ ],
imports: [
+ CalendarModule,
AdministrationRoutingModule,
CommonModule,
ReactiveFormsModule,
SharedModule,
+ FormsModule,
TranslateModule.forChild({ extend: true }),
DateValueAccessorModule,
+ DragDropModule,
],
})
export class AdministrationModule {}
diff --git a/src/app/features/administration/form/advanced-config/advanced-config.component.html b/src/app/features/administration/form/advanced-config/advanced-config.component.html
new file mode 100644
index 00000000..1bd574b7
--- /dev/null
+++ b/src/app/features/administration/form/advanced-config/advanced-config.component.html
@@ -0,0 +1,165 @@
+
diff --git a/src/app/features/administration/form/advanced-config/advanced-config.component.scss b/src/app/features/administration/form/advanced-config/advanced-config.component.scss
new file mode 100644
index 00000000..e69de29b
diff --git a/src/app/features/administration/form/advanced-config/advanced-config.component.spec.ts b/src/app/features/administration/form/advanced-config/advanced-config.component.spec.ts
new file mode 100644
index 00000000..5407c267
--- /dev/null
+++ b/src/app/features/administration/form/advanced-config/advanced-config.component.spec.ts
@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AdvancedConfigComponent } from './advanced-config.component';
+
+describe('AdvancedConfigComponent', () => {
+ let component: AdvancedConfigComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [AdvancedConfigComponent],
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AdvancedConfigComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/features/administration/form/advanced-config/advanced-config.component.ts b/src/app/features/administration/form/advanced-config/advanced-config.component.ts
new file mode 100644
index 00000000..cfc1b286
--- /dev/null
+++ b/src/app/features/administration/form/advanced-config/advanced-config.component.ts
@@ -0,0 +1,19 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { Poll } from '../../../../core/models/poll.model';
+import { FormGroup } from '@angular/forms';
+
+@Component({
+ selector: 'app-advanced-config',
+ templateUrl: './advanced-config.component.html',
+ styleUrls: ['./advanced-config.component.scss'],
+})
+export class AdvancedConfigComponent implements OnInit {
+ public urlPrefix: string = window.location.origin + '/participation/';
+ @Input()
+ public poll?: Poll;
+ @Input()
+ public form: FormGroup;
+ constructor() {}
+
+ ngOnInit(): void {}
+}
diff --git a/src/app/features/administration/form/base-config/base-config.component.html b/src/app/features/administration/form/base-config/base-config.component.html
new file mode 100644
index 00000000..85decc75
--- /dev/null
+++ b/src/app/features/administration/form/base-config/base-config.component.html
@@ -0,0 +1,102 @@
+
diff --git a/src/app/features/administration/form/base-config/base-config.component.scss b/src/app/features/administration/form/base-config/base-config.component.scss
new file mode 100644
index 00000000..e69de29b
diff --git a/src/app/features/administration/form/base-config/base-config.component.spec.ts b/src/app/features/administration/form/base-config/base-config.component.spec.ts
new file mode 100644
index 00000000..4acc1c58
--- /dev/null
+++ b/src/app/features/administration/form/base-config/base-config.component.spec.ts
@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { BaseConfigComponent } from './base-config.component';
+
+describe('BaseConfigComponent', () => {
+ let component: BaseConfigComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [BaseConfigComponent],
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(BaseConfigComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/features/administration/form/base-config/base-config.component.ts b/src/app/features/administration/form/base-config/base-config.component.ts
new file mode 100644
index 00000000..2a27d8e1
--- /dev/null
+++ b/src/app/features/administration/form/base-config/base-config.component.ts
@@ -0,0 +1,69 @@
+import { ChangeDetectorRef, Component, Inject, Input, OnInit } from '@angular/core';
+import { ToastService } from '../../../../core/services/toast.service';
+import { FormBuilder, FormGroup } from '@angular/forms';
+import { UuidService } from '../../../../core/services/uuid.service';
+import { PollService } from '../../../../core/services/poll.service';
+import { ApiService } from '../../../../core/services/api.service';
+import { Router } from '@angular/router';
+import { DOCUMENT } from '@angular/common';
+import { Poll } from '../../../../core/models/poll.model';
+
+@Component({
+ selector: 'app-base-config',
+ templateUrl: './base-config.component.html',
+ styleUrls: ['./base-config.component.scss'],
+})
+export class BaseConfigComponent {
+ @Input()
+ public poll?: Poll;
+ @Input()
+ public form: FormGroup;
+
+ constructor(
+ private fb: FormBuilder,
+ private cd: ChangeDetectorRef,
+ private uuidService: UuidService,
+ private toastService: ToastService,
+ private pollService: PollService,
+ private apiService: ApiService,
+ private router: Router,
+ @Inject(DOCUMENT) private document: Document
+ ) {}
+
+ askInitFormDefault(): void {
+ // this.initFormDefault(false);
+ this.toastService.display('formulaire réinitialisé');
+ }
+
+ public createPoll(): void {
+ console.log('this.form', this.form);
+ const newpoll = this.pollService.newPollFromForm(this.form);
+ console.log('newpoll', newpoll);
+ const router = this.router;
+
+ if (this.form.valid) {
+ console.log('Le sondage est correctement rempli, prêt à enregistrer.');
+ const newpoll = this.pollService.newPollFromForm(this.form);
+ // TODO : save the poll
+
+ this.apiService.createPoll(newpoll).then((resp) => {
+ console.log('resp', resp);
+ router.navigate(['success']);
+ });
+ } else {
+ this.toastService.display('invalid form');
+ }
+ }
+
+ public updateSlug(): void {
+ const newValueFormatted = 'TODO';
+ this.form.patchValue({ slug: newValueFormatted });
+ }
+
+ /**
+ * set the poll slug from other data of the poll
+ */
+ automaticSlug() {
+ this.form.patchValue({ slug: this.pollService.makeSlug(this.form.value) });
+ }
+}
diff --git a/src/app/features/administration/form/date-select/date-select.component.html b/src/app/features/administration/form/date-select/date-select.component.html
new file mode 100644
index 00000000..6ebedc37
--- /dev/null
+++ b/src/app/features/administration/form/date-select/date-select.component.html
@@ -0,0 +1,238 @@
+
+
+
+
+
+
+ Chaque jour aura ses plages de temps personnalisées
+
+
+ Tous les jours auront les mêmes plages de temps
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dateList.length }}
+
+
+ {{ 'dates.count_dates' | translate }}
+
+
+
+
+
+
+
+
Dates
+
+ {{ id }})
+
+
+
+
+ plage horaire distincte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/features/administration/form/date-select/date-select.component.scss b/src/app/features/administration/form/date-select/date-select.component.scss
new file mode 100644
index 00000000..e1f049d0
--- /dev/null
+++ b/src/app/features/administration/form/date-select/date-select.component.scss
@@ -0,0 +1,43 @@
+:host {
+ .time-choice {
+ background: rgba(255, 255, 255, 0.8);
+ border: solid 1px #dedede;
+ padding: 0.5em;
+ //padding: 20px 10px;
+ border-bottom: solid 1px #ccc;
+ color: rgba(0, 0, 0, 0.87);
+ box-sizing: border-box;
+ cursor: move;
+ background: white;
+ font-size: 14px;
+ }
+ .btn i + span {
+ margin-left: 1ch;
+ }
+ .btn + .btn {
+ margin-left: 1em;
+ }
+
+ .cdk-drag-preview {
+ box-sizing: border-box;
+ border-radius: 4px;
+ box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14),
+ 0 3px 14px 2px rgba(0, 0, 0, 0.12);
+ border: 2px solid #ccc;
+ background: rgba(255, 255, 255, 0.8);
+ }
+
+ .cdk-drag-placeholder {
+ * {
+ opacity: 0;
+ }
+ background: #dedede;
+ }
+
+ .cdk-drag-animating {
+ transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
+ }
+ .movable {
+ cursor: move;
+ }
+}
diff --git a/src/app/features/administration/form/date-select/date-select.component.spec.ts b/src/app/features/administration/form/date-select/date-select.component.spec.ts
new file mode 100644
index 00000000..d5f4b90f
--- /dev/null
+++ b/src/app/features/administration/form/date-select/date-select.component.spec.ts
@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DateSelectComponent } from './date-select.component';
+
+describe('DateSelectComponent', () => {
+ let component: DateSelectComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [DateSelectComponent],
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DateSelectComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/features/administration/form/date-select/date-select.component.ts b/src/app/features/administration/form/date-select/date-select.component.ts
new file mode 100644
index 00000000..4ed63371
--- /dev/null
+++ b/src/app/features/administration/form/date-select/date-select.component.ts
@@ -0,0 +1,259 @@
+import { ChangeDetectorRef, Component, Inject, Input, OnInit } from '@angular/core';
+import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { UuidService } from '../../../../core/services/uuid.service';
+import { ToastService } from '../../../../core/services/toast.service';
+import { PollService } from '../../../../core/services/poll.service';
+import { DateUtilities } from '../../../old-stuff/config/DateUtilities';
+import { ApiService } from '../../../../core/services/api.service';
+import { Router } from '@angular/router';
+import { DOCUMENT } from '@angular/common';
+import { DateChoice, moreTimeOfDay, otherDefaultDates, TimeSlices } from '../../../old-stuff/config/defaultConfigs';
+import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
+import { TranslateService } from '@ngx-translate/core';
+
+@Component({
+ selector: 'app-date-select',
+ templateUrl: './date-select.component.html',
+ styleUrls: ['./date-select.component.scss'],
+})
+export class DateSelectComponent implements OnInit {
+ @Input()
+ public form: FormGroup;
+
+ public showDateInterval = true;
+ public allowSeveralHours = true;
+ today = new Date();
+ startDateInterval: string;
+ endDateInterval: string;
+ intervalDays: any;
+ intervalDaysDefault = 7;
+ dateList: DateChoice[] = otherDefaultDates; // sets of days as strings, config to set identical time for days in a special days poll
+ timeList: TimeSlices[] = moreTimeOfDay; // ranges of time expressed as strings
+ dateCalendarEnum: Date[] = [new Date('02/09/2021')];
+ selectionKind = 'range';
+
+ constructor(
+ private fb: FormBuilder,
+ private cd: ChangeDetectorRef,
+ private uuidService: UuidService,
+ private toastService: ToastService,
+ private pollService: PollService,
+ public dateUtilities: DateUtilities,
+ private apiService: ApiService,
+ private router: Router,
+ private translateService: TranslateService,
+ @Inject(DOCUMENT) private document: any
+ ) {}
+
+ ngOnInit(): void {
+ // this.setDefaultDatesForInterval();
+ }
+
+ get choices(): FormArray {
+ return this.form.get('choices') as FormArray;
+ }
+
+ /**
+ * 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.dateCalendarEnum = [dateCurrent, this.dateUtilities.addDaysToDate(this.intervalDaysDefault, dateCurrent)];
+ this.countDays();
+ }
+
+ countDays(): void {
+ this.intervalDays = this.dateUtilities.countDays(
+ this.dateUtilities.parseInputDateToDateObject(this.startDateInterval),
+ this.dateUtilities.parseInputDateToDateObject(this.endDateInterval)
+ );
+ // this.cd.detectChanges();
+ }
+
+ /**
+ * 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.dateList.forEach(elem=>{
+ // const newControlGroup = this.fb.group({
+ // label: this.fb.control('', [Validators.required]),
+ // imageUrl: ['', [Validators.required]],
+ // });
+ //
+ // this.choices.push(newControlGroup);
+ // })
+
+ this.toastService.display(`les dates ont été ajoutées aux réponses possibles.`);
+ }
+
+ /**
+ * change time spans
+ */
+ addTime() {
+ this.timeList.push({
+ literal: '',
+ });
+ }
+
+ removeAllTimes() {
+ this.timeList = [];
+ }
+
+ resetTimes() {
+ this.timeList = otherDefaultDates;
+ }
+
+ /**
+ * add a time period to a specific date choice,
+ * 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) + '"]';
+ // this.cd.detectChanges();
+ const elem = this.document.querySelector(selector);
+ if (elem) {
+ elem.focus();
+ }
+ }
+
+ get dateChoices() {
+ return this.form.get('dateChoices') as FormArray;
+ }
+
+ 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.dateChoices.push(newControlGroup);
+ // this.cd.detectChanges();
+ console.log('this.choices.length', this.choices.length);
+
+ this.focusOnChoice(this.choices.length - 1);
+ }
+
+ 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);
+ }
+ }
+
+ reinitChoices(): void {
+ this.choices.setValue([]);
+ }
+
+ /**
+ * 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;
+ // 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
+ 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.cd.detectChanges();
+ 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();
+ }
+ }
+ }
+
+ setDemoValues(): void {
+ this.addChoice('orange');
+ this.addChoice('raisin');
+ this.addChoice('abricot');
+ }
+
+ dropTimeItem(event: any) {
+ // moveItemInArray(this.timeList, event.previousIndex, event.currentIndex);
+ if (event.previousContainer === event.container) {
+ moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
+ } else {
+ transferArrayItem(
+ event.previousContainer.data,
+ event.container.data,
+ event.previousIndex,
+ event.currentIndex
+ );
+ }
+ }
+}
diff --git a/src/app/features/administration/form/form.component.html b/src/app/features/administration/form/form.component.html
index 922e9258..1938a652 100644
--- a/src/app/features/administration/form/form.component.html
+++ b/src/app/features/administration/form/form.component.html
@@ -1,421 +1,69 @@
-