diff --git a/package-lock.json b/package-lock.json index 61b24493..64de0fed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2512,6 +2512,32 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "chart.js": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.3.tgz", + "integrity": "sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw==", + "requires": { + "chartjs-color": "^2.1.0", + "moment": "^2.10.2" + } + }, + "chartjs-color": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz", + "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==", + "requires": { + "chartjs-color-string": "^0.6.0", + "color-convert": "^1.9.3" + } + }, + "chartjs-color-string": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", + "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==", + "requires": { + "color-name": "^1.0.0" + } + }, "chokidar": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.0.2.tgz", @@ -2739,7 +2765,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -2747,8 +2772,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "colors": { "version": "1.1.2", @@ -5659,8 +5683,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -5703,8 +5726,7 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", @@ -5715,8 +5737,7 @@ "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5833,8 +5854,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -5846,7 +5866,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5876,7 +5895,6 @@ "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5895,7 +5913,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5989,7 +6006,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -6075,8 +6091,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -6112,7 +6127,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6132,7 +6146,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6176,14 +6189,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -6913,6 +6924,11 @@ } } }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -11265,8 +11281,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -11309,8 +11324,7 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", @@ -11321,8 +11335,7 @@ "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -11439,8 +11452,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -11452,7 +11464,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -11482,7 +11493,6 @@ "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -11501,7 +11511,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -11595,7 +11604,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -11681,8 +11689,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -11718,7 +11725,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -11738,7 +11744,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -11782,14 +11787,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index 19a49403..5cb7f424 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@angular/router": "~8.2.0", "@ngx-translate/core": "^11.0.1", "@ngx-translate/http-loader": "^4.0.0", + "chart.js": "^2.8.0", "ngx-markdown": "^8.2.1", "rxjs": "~6.4.0", "tslib": "^1.10.0", @@ -32,9 +33,9 @@ "@angular/cli": "~8.2.1", "@angular/compiler-cli": "~8.2.0", "@angular/language-service": "~8.2.0", - "@types/node": "~8.9.4", "@types/jasmine": "~3.3.8", "@types/jasminewd2": "~2.0.3", + "@types/node": "~8.9.4", "codelyzer": "^5.0.0", "jasmine-core": "~3.4.0", "jasmine-spec-reporter": "~4.2.1", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 33f0f37a..66f42676 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -38,6 +38,7 @@ import { TranslateService } from '@ngx-translate/core'; import {TranslateHttpLoader} from '@ngx-translate/http-loader'; +import { PollGraphicComponent } from './poll-graphic/poll-graphic.component'; import { AdminComponent } from './pages/admin/admin.component'; @@ -75,6 +76,7 @@ export function HttpLoaderFactory(http: HttpClient) { VotingChoiceComponent, PasswordComponent, HomeComponent, + PollGraphicComponent, VoteChoiceComponent, AdminComponent, diff --git a/src/app/config.service.ts b/src/app/config.service.ts index 8cb4ebdf..39d1dcaf 100644 --- a/src/app/config.service.ts +++ b/src/app/config.service.ts @@ -1,5 +1,7 @@ import {Injectable} from '@angular/core'; import {PollConfig} from './config/PollConfig'; +import {HttpClient} from "@angular/common/http"; +import {environment} from "../environments/environment"; /** @@ -9,9 +11,11 @@ import {PollConfig} from './config/PollConfig'; providedIn: 'root' }) export class ConfigService extends PollConfig { + myEmail: string; + myPolls: any;// list of retrieved polls from the backend api - constructor() { + constructor(public http: HttpClient) { super(); } @@ -19,9 +23,15 @@ export class ConfigService extends PollConfig { this[key] = val; } - sendForm() { + createPoll() { // todo console.log('sends the form'); - alert('envoi de formulaire en XHR à faire'); + alert('envoi de formulaire pour création de sondage en XHR à faire'); + const payload = this; + this.http.post(`${environment.baseApiHref}/poll`, payload) + .subscribe(res => { + console.log('res', res) + }, + err => console.error('err', err)) } } diff --git a/src/app/config/PollConfig.ts b/src/app/config/PollConfig.ts index b21772c2..722298c6 100644 --- a/src/app/config/PollConfig.ts +++ b/src/app/config/PollConfig.ts @@ -2,24 +2,28 @@ * une option de date dans les sondages spéciaux */ export interface DateOption { + timeList: any; literal: string; } -export const timeOfDay = [{literal: 'matin'}, - {literal: 'midi'}, - {literal: 'après-midi'}, - {literal: 'soirée'}]; +export const timeOfDay = [{ + timeList: [], + literal: 'matin' +}, + {timeList: [], literal: 'midi'}, + {timeList: [], literal: 'après-midi'}, + {timeList: [], literal: 'soirée'}]; export const defaultDates = [ { - literal: `${new Date().getDate()}-${new Date().getMonth()}-${new Date().getFullYear()}`, + literal: `${new Date().getFullYear()}-${new Date().getMonth()}-${new Date().getDate()}`, timeList: [{literal: 'matin'}, {literal: 'midi'}, {literal: 'soir'}] }, { - literal: `${new Date().getDate() + 1}-${new Date().getMonth()}-${new Date().getFullYear()}`, + literal: `${new Date().getFullYear()}-${new Date().getMonth()}-${new Date().getDate() + 1}`, timeList: [{literal: 'matin'}, {literal: 'midi'}, {literal: 'soir'}] }, { - literal: `${new Date().getDate() + 2}-${new Date().getMonth()}-${new Date().getFullYear()}`, + literal: `${new Date().getFullYear()}-${new Date().getMonth()}-${new Date().getDate() + 2}`, timeList: [{literal: 'matin'}, {literal: 'midi'}, {literal: 'soir'}] } ]; @@ -34,10 +38,14 @@ export class PollConfig { title = ''; description = ''; myName = ''; - visibility = 'link_only'; + // date specific poll - allowSeveralHours = 'true'; - dateList: DateOption[] = defaultDates; // sets of days as strings + allowSeveralHours = 'false'; + // access + visibility = 'link_only'; // visible to anyone with the link: + password = ''; + whoCanChangeAnswers = 'everybody';// everybody, self, nobody (= just admin) + dateList: DateOption[] = defaultDates; // sets of days as strings, config to set identical time for days in a special days poll timeList: DateOption[] = timeOfDay; // ranges of time expressed as strings answers: any = [{ id: 0, diff --git a/src/app/config/Routes.ts b/src/app/config/Routes.ts index 1c64a672..52360ff5 100644 --- a/src/app/config/Routes.ts +++ b/src/app/config/Routes.ts @@ -9,6 +9,7 @@ import {AdminComponent} from '../pages/admin/admin.component'; import {CreateOrRetrieveComponent} from '../pages/create-or-retrieve/create-or-retrieve.component'; import {BaseComponent} from '../pages/base-page/base.component'; import {HomeComponent} from "../pages/home/home.component"; +import {PollGraphicComponent} from '../poll-graphic/poll-graphic.component'; import {VoteChoiceComponent} from "../vote-choice/vote-choice.component"; /** @@ -19,6 +20,7 @@ export const Routes = {path: '', component: CreateOrRetrieveComponent}, {path: 'home', component: HomeComponent}, {path: 'base', component: BaseComponent}, + {path: 'step/base', component: BaseComponent}, {path: 'step/creation', component: CreateOrRetrieveComponent}, {path: 'step/date', component: DatesComponent}, {path: 'step/kind', component: KindComponent}, @@ -28,6 +30,7 @@ export const Routes = {path: 'step/visibility', component: VisibilityComponent}, {path: 'step/resume', component: ResumeComponent}, {path: 'step/end', component: EndConfirmationComponent}, + {path: 'graphic/:poll', component: PollGraphicComponent}, {path: 'votechoice', component: VoteChoiceComponent}, ] ; diff --git a/src/app/debugger/debugger.component.html b/src/app/debugger/debugger.component.html index 1af1e473..c9e8a4f6 100644 --- a/src/app/debugger/debugger.component.html +++ b/src/app/debugger/debugger.component.html @@ -1,29 +1,29 @@
- -

- infos de debug -

- + +

+ infos de debug +

+ {{"config.demo"|translate}} -
-
@@ -62,7 +62,7 @@ diff --git a/src/app/pages/create-or-retrieve/create-or-retrieve.component.html b/src/app/pages/create-or-retrieve/create-or-retrieve.component.html index 50753eca..20c0b141 100644 --- a/src/app/pages/create-or-retrieve/create-or-retrieve.component.html +++ b/src/app/pages/create-or-retrieve/create-or-retrieve.component.html @@ -1,55 +1,60 @@
-

- {{"creation.title"|translate}} -

-

- {{"config.title"|translate}} -

-
-

- {{"config.find_my_polls"|translate}} -

-
- - - -
+

+ {{"config.find_my_polls"|translate}} +

+
+ + + +
+
+
+
diff --git a/src/app/pages/create-or-retrieve/create-or-retrieve.component.ts b/src/app/pages/create-or-retrieve/create-or-retrieve.component.ts index 81dfb0ba..12ee44f1 100644 --- a/src/app/pages/create-or-retrieve/create-or-retrieve.component.ts +++ b/src/app/pages/create-or-retrieve/create-or-retrieve.component.ts @@ -1,19 +1,24 @@ -import { Component, OnInit } from '@angular/core'; +import {Component, OnInit} from '@angular/core'; import {BaseComponent} from "../base-page/base.component"; import {ConfigService} from "../../config.service"; +import {PollServiceService} from "../../services/poll-service.service"; @Component({ - selector: 'framadate-create-or-retrieve', - templateUrl: './create-or-retrieve.component.html', - styleUrls: ['./create-or-retrieve.component.scss'] + selector: 'framadate-create-or-retrieve', + templateUrl: './create-or-retrieve.component.html', + styleUrls: ['./create-or-retrieve.component.scss'] }) export class CreateOrRetrieveComponent extends BaseComponent implements OnInit { - constructor(public config: ConfigService) { + constructor(public config: ConfigService, public pollService: PollServiceService) { super(config); } ngOnInit() { - } + } + + findMyPollsByEmail(email: string) { + this.pollService.findPollsByEmail(email); + } } diff --git a/src/app/pages/dates/dates.component.html b/src/app/pages/dates/dates.component.html index 36f43d29..43b43923 100644 --- a/src/app/pages/dates/dates.component.html +++ b/src/app/pages/dates/dates.component.html @@ -4,66 +4,100 @@
+ +
+ +
+

{{"dates.add_interval"|translate}}

+

+ {{"dates.interval_propose"|translate}} + + {{"dates.interval_span"|translate}} + +

+ +
+
- {{config.dateList.length}} - - {{"dates.count_dates"|translate}} + + {{config.timeList.length}} + + + {{"dates.count_time"|translate}} + +
- +

+ + {{config.dateList.length}} + {{"dates.count_dates"|translate}} @@ -72,36 +106,38 @@ class="date-choice" >
diff --git a/src/app/pages/dates/dates.component.scss b/src/app/pages/dates/dates.component.scss index a62fa1c8..84c17656 100644 --- a/src/app/pages/dates/dates.component.scss +++ b/src/app/pages/dates/dates.component.scss @@ -1,7 +1,11 @@ .several-times { padding-left: 1em; +} - input { - margin-right: 1em; +:host { + input, button { + + button { + margin-left: 1em; + } } } diff --git a/src/app/pages/dates/dates.component.ts b/src/app/pages/dates/dates.component.ts index 300d1580..7e0d8f6a 100644 --- a/src/app/pages/dates/dates.component.ts +++ b/src/app/pages/dates/dates.component.ts @@ -1,6 +1,7 @@ -import {ChangeDetectorRef, Component, OnInit} from '@angular/core'; +import {ChangeDetectorRef, Component, Inject, OnInit} from '@angular/core'; import {ConfigService} from '../../config.service'; import {BaseComponent} from '../base-page/base.component'; +import {DOCUMENT} from '@angular/common'; @Component({ selector: 'framadate-dates', @@ -8,41 +9,145 @@ import {BaseComponent} from '../base-page/base.component'; styleUrls: ['./dates.component.scss'] }) export class DatesComponent extends BaseComponent implements OnInit { - constructor(public config: ConfigService, private cd: ChangeDetectorRef) { + showDateInterval: boolean = true; + startDateInterval: any; + intervalDays: any; + intervalDaysDefault: number = 7; + endDateInterval: any; + + constructor(public config: ConfigService, + private cd: ChangeDetectorRef, + @Inject(DOCUMENT) private document: any + ) { super(config); } + countDays() { + // compute the number of days in the date interval + if (this.endDateInterval && this.startDateInterval) { + this.intervalDays = (this.dayDiff(this.endDateInterval, this.startDateInterval)).toFixed(0) + } + } + + /** + * set the interval options + */ ngOnInit() { + let dateCurrent = new Date(); + const dateJson = dateCurrent.toISOString(); + this.startDateInterval = dateJson.substring(0, 10); + this.endDateInterval = this.addDaysToDate(this.intervalDaysDefault, dateCurrent).toISOString().substring(0, 10); } addDate() { - this.config.dateList.push({literal: ''}); + this.config.dateList.push({literal: '', timeList: []}); + let selector = '[ng-reflect-name="dateChoices_' + (this.config.dateList.length - 1) + '"]'; + this.cd.detectChanges(); + const elem = this.document.querySelector(selector); + if (elem) { + elem.focus(); + } } - addtime() { - this.config.timeList.push({literal: ''}); + addTime() { + this.config.timeList.push({literal: '', timeList: []}); } + /** + * add some days to a date, to compute intervals + * @param days + * @param date + */ + addDaysToDate(days: number, date: Date) { + date = new Date(date.valueOf()); + date.setDate(date.getDate() + days); + return date; + }; + /** * add a time period to a specific date choice, * focus on the new input * @param config * @param id */ - addTimetoDate(config: any, id: number) { + addTimeToDate(config: any, id: number) { config.timeList.push({literal: ''}); let selector = '[ng-reflect-name="dateTime_' + id + '_Choices_' + (config.timeList.length - 1) + '"]'; - console.log('selector', selector); this.cd.detectChanges(); - const elem = document.querySelector(selector); + const elem = this.document.querySelector(selector); if (elem) { - //this.elem.focus(); + elem.focus(); } } + /** + * remove all input contents, does not reset to default + */ emptyAll() { this.config.dateList.forEach(element => { element.literal = ''; + element.timeList = ['', '', '']; + }); + this.config.timeList.forEach(element => { + element.literal = ''; }); } + + /** + * add all the dates between the start and end dates in the interval section + */ + addIntervalOfDates() { + let newIntervalArray = this.getDatesInRange(this.startDateInterval, this.endDateInterval, 1); + + const converted = []; + newIntervalArray.forEach(element => { + converted.push({literal: element, timeList: []}); + }); + this.config.dateList = [...new Set(converted)]; // add only dates that are not already present with a Set of unique items + this.showDateInterval = false; + + } + + /** + * + * @param d1 + * @param d2 + * @param interval + */ + getDatesInRange(d1: Date, d2: Date, interval: number) { + d1 = new Date(d1); + d2 = new Date(d2); + const dates = []; + while (+d1 < +d2) { + dates.push(this.formateDate(d1)); + d1.setDate(d1.getDate() + interval) + } + return dates.slice(0) + } + + /** + * get the number of days between two dates + * @param d1 + * @param d2 + */ + dayDiff(d1: Date, d2: Date): Number { + return Number(((d2.getTime()) - (d1.getTime()) / 31536000000)); + } + + /** + * format a date object to the date format used by the inputs of type date + * YYYY-MM-DD + * @param date + */ + formateDate(date) { + return [ + date.getFullYear(), + this.getDoubleDigits(date.getMonth() + 1), + this.getDoubleDigits(date.getDate()), + ].join('-') + } + + getDoubleDigits(str) { + return ("00" + str).slice(-2); + } } diff --git a/src/app/poll-graphic/poll-graphic.component.html b/src/app/poll-graphic/poll-graphic.component.html new file mode 100644 index 00000000..6f969732 --- /dev/null +++ b/src/app/poll-graphic/poll-graphic.component.html @@ -0,0 +1,19 @@ + +{{ "pollGraphic.colorblindText" | translate }} +
+ +
+ diff --git a/src/app/poll-graphic/poll-graphic.component.scss b/src/app/poll-graphic/poll-graphic.component.scss new file mode 100644 index 00000000..5eb2a3bb --- /dev/null +++ b/src/app/poll-graphic/poll-graphic.component.scss @@ -0,0 +1,4 @@ +#selectColorblind { + direction: rtl; + padding:0; +} diff --git a/src/app/poll-graphic/poll-graphic.component.spec.ts b/src/app/poll-graphic/poll-graphic.component.spec.ts new file mode 100644 index 00000000..ed5118d3 --- /dev/null +++ b/src/app/poll-graphic/poll-graphic.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PollGraphicComponent } from './poll-graphic.component'; + +describe('PollGraphicComponent', () => { + let component: PollGraphicComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PollGraphicComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PollGraphicComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/poll-graphic/poll-graphic.component.ts b/src/app/poll-graphic/poll-graphic.component.ts new file mode 100644 index 00000000..f3ba0682 --- /dev/null +++ b/src/app/poll-graphic/poll-graphic.component.ts @@ -0,0 +1,161 @@ +import {Component, OnInit} from "@angular/core"; +import {Chart} from "chart.js"; + +@Component({ + selector: "framadate-poll-graphic", + templateUrl: "./poll-graphic.component.html", + styleUrls: ["./poll-graphic.component.scss"] +}) +export class PollGraphicComponent implements OnInit { + isColorblind: boolean = false; + lineChart: Chart; + pollData: any; + yesList: number[] = []; + maybeList: number[] = []; + noList: number[] = []; + nbPoll: number = 0; + dateList: string[] = []; + + constructor() { + } + + ngOnInit() { + var toto = { + step: 0, + stepMax: 3, + pollType: "special dates", + title: "", + description: "", + myName: "", + visibility: "link_only", + // date specific poll + allowSeveralHours: "true", + dateLgfgfgfgist: ["jeudi", "vendredi", "samedi"], // sets of days as strings + timeList: ["08:00", "08:30", "09:00"], // ranges of time expressed as strings + answers: [ + { + id: 0, + text: "no" + }, + + { + id: 1, + text: "yes" + }, + { + id: 2, + text: "maybe" + }, + { + id: 3, + text: "maybe" + }, + { + id: 4, + text: "maybe" + }, + { + id: 5, + text: "maybe" + }, + { + id: 6, + text: "maybe" + }, + { + id: 7, + text: "maybe" + }, + { + id: 8, + text: "maybe" + } + ] + }; + + this.formatDataAnswers(toto); + + this.isColorblind = false; + this.pollData = new Chart(document.getElementById("graph"), { + type: "horizontalBar", + data: { + labels: ["jeudi"], + datasets: [ + { + type: "horizontalBar", + stack: "Yes", + backgroundColor: "#429a00", + data: this.yesList + }, + { + type: "horizontalBar", + stack: "Yes", + backgroundColor: "#f5a623", + data: this.maybeList + }, + { + type: "horizontalBar", + stack: "No", + backgroundColor: "#cd0000", + data: this.noList + } + ] + }, + options: { + legend: {display: false}, + scales: { + xAxes: [ + { + gridLines: {drawBorder: false, display: false}, + display: false, + stacked: true, + ticks: { + beginAtZero: true, + maxRotation: 0, + minRotation: 0 + } + } + ], + yAxes: [ + { + gridLines: {drawBorder: true, display: false}, + display: true, + stacked: true + } + ] + } + } + }); + } + + toggleColorblind() { + this.isColorblind = !this.isColorblind; + } + + formatDataAnswers(poll) { + if (poll && poll.pollType === "special dates") { + this.initPollCounter(); + poll.answers.forEach(response => { + switch (response.text) { + case "yes": + this.yesList[this.nbPoll - 1]++; + break; + case "maybe": + this.maybeList[this.nbPoll - 1]++; + break; + case "no": + this.noList[this.nbPoll - 1]++; + break; + } + }); + } + } + + initPollCounter() { + this.nbPoll++; + this.dateList[this.nbPoll - 1] = "jeudi"; + this.maybeList[this.nbPoll - 1] = 0; + this.yesList[this.nbPoll - 1] = 0; + this.noList[this.nbPoll - 1] = 0; + } +} diff --git a/src/app/services/poll-service.service.spec.ts b/src/app/services/poll-service.service.spec.ts new file mode 100644 index 00000000..c9b6bcec --- /dev/null +++ b/src/app/services/poll-service.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { PollServiceService } from './poll-service.service'; + +describe('PollServiceService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: PollServiceService = TestBed.get(PollServiceService); + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/poll-service.service.ts b/src/app/services/poll-service.service.ts new file mode 100644 index 00000000..0bf09ae0 --- /dev/null +++ b/src/app/services/poll-service.service.ts @@ -0,0 +1,32 @@ +import {Injectable} from '@angular/core'; +import {ConfigService} from "../config.service"; +import {HttpClient} from "@angular/common/http"; +import {environment} from "../../environments/environment"; + +class JsonResponse { + message: string; + data: string; +} + +@Injectable({ + providedIn: 'root' +}) +export class PollServiceService { + + private baseHref: string = environment.baseApiHref; + + constructor(private configService: ConfigService, + private http: HttpClient) { + } + + findPollsByEmail(email: string) { + // TODO check if the person has a key to retrieve her polls + // If no key is found in the localstorage, ask the backend to send an email to the user + + this.configService.myEmail = email; + this.http.get(this.baseHref + '/').subscribe(res => { + this.configService.myPolls = res; + }, err => console.error('err', err) + ) + } +} diff --git a/src/app/ui/navigation/navigation.component.html b/src/app/ui/navigation/navigation.component.html index c7fa566b..fcce0856 100644 --- a/src/app/ui/navigation/navigation.component.html +++ b/src/app/ui/navigation/navigation.component.html @@ -1,29 +1,32 @@ diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 14073764..4bc4ecae 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -37,8 +37,15 @@ "identical": "same", "different": "possibly different" }, - "add": "Add a date range", - "count_dates": "choices of dates" + "add": "Add a date choice", + "add_time": "Add a time span", + "count_dates": "choices of dates", + "count_time": "choices of hour span", + "add_interval": "Add a date interval", + "interval_propose": "I want to suggest all the dates from", + "interval_span": "to", + "interval_button": "Add these", + "interval_button_dates": "dates" }, "choices": { "title": "Write the proposals", @@ -60,5 +67,10 @@ "votes": "Votes", "archiving": "Archiving", "access": "Access to the pool" + }, + "pollGraphic":{ + "choiceColorblind":"I am", + "choiceNotColorblind":"I am not", + "colorblindText":"colorblind." } } diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 1f6621e2..53dc4aa1 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -32,15 +32,22 @@ }, "dates": { "title": "Config spécialement pour les dates ", - "hours_different": "Je souhaite mettre des créneaux horaires pour chaque journée", + "hours_different": "Je souhaite mettre des créneaux horaires", + "hours_each_day": "pour chaque journée", "multiple": { "identical": "identiques", "different": "possiblement différentes" }, "add": "Ajouter une plage de dates", - "addTime": "Ajouter une plage d'heure", + "add_time": "Ajouter une plage d'heure", "empty": "Vider", - "count_dates": "choix de dates" + "count_dates": "choix de dates", + "count_time": "choix de plages horaires", + "add_interval": "Ajouter une intervalle de dates", + "interval_propose": "Je souhaite proposer pour mon sondage toutes les dates entre le", + "interval_span": "et le", + "interval_button": "Ajouter ces", + "interval_button_dates": "dates" }, "choices": { "title": "Choisir les propositions", @@ -62,5 +69,10 @@ "votes": "Votes", "archiving": "Archivage", "access": "Accès au sondage" + }, + "pollGraphic":{ + "choiceColorblind":"Je suis", + "choiceNotColorblind":"Je ne suis pas", + "colorblindText":"daltonien." } } diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 3612073b..0a1bc680 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,3 +1,4 @@ export const environment = { - production: true + production: true, + baseApiHref : 'http://127.0.0.1:8000/api/v1/' }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 7b4f817a..918f5d2b 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -3,7 +3,8 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, + baseApiHref: "http://127.0.0.1:8000/api/v1/" }; /* diff --git a/yarn.lock b/yarn.lock index 4fdebb05..3ea57eea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1452,6 +1452,29 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +chart.js@^2.8.0: + version "2.9.3" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.3.tgz#ae3884114dafd381bc600f5b35a189138aac1ef7" + integrity sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw== + dependencies: + chartjs-color "^2.1.0" + moment "^2.10.2" + +chartjs-color-string@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz#1df096621c0e70720a64f4135ea171d051402f71" + integrity sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A== + dependencies: + color-name "^1.0.0" + +chartjs-color@^2.1.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.4.1.tgz#6118bba202fe1ea79dd7f7c0f9da93467296c3b0" + integrity sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w== + dependencies: + chartjs-color-string "^0.6.0" + color-convert "^1.9.3" + "chokidar@>=2.0.0 <4.0.0": version "3.0.2" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.0.2.tgz#0d1cd6d04eb2df0327446188cd13736a3367d681" @@ -1606,7 +1629,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.9.0: +color-convert@^1.9.0, color-convert@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -1618,6 +1641,11 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-name@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + colors@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" @@ -4391,6 +4419,11 @@ mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: dependencies: minimist "0.0.8" +moment@^2.10.2: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"