Merge branch 'feature/reformat_all_files' into 'develop'

reformat all files + move routes.ts to AppRoutingModule

See merge request framasoft/framadate/funky-framadate-front!28
This commit is contained in:
ty kayn 2020-04-14 12:05:48 +02:00
commit d9c325a0e9
151 changed files with 4347 additions and 5151 deletions

View File

@ -6,7 +6,6 @@
"ng": "ng",
"start": "ng serve",
"compodoc": "compodoc -p tsconfig.json",
"serve": "ng serve",
"build": "ng build --crossOrigin=anonymous --prod",
"package": "cat dist/framadate/*.js > dist/framadate/framadate-scripts-bundled.js && ls -l dist/framadate",
"bld:pkg": "npm run build && npm run package",

View File

@ -1,12 +1,48 @@
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AdminComponent } from './pages/admin/admin.component';
import { AnswersComponent } from './pages/answers/answers.component';
import { BaseComponent } from './pages/base-page/base.component';
import { CreateOrRetrieveComponent } from './pages/create-or-retrieve/create-or-retrieve.component';
import { DatesComponent } from './pages/dates/dates.component';
import { EndConfirmationComponent } from './pages/end-confirmation/end-confirmation.component';
import { HomeComponent } from './pages/home/home.component';
import { KindComponent } from './pages/kind/kind.component';
import { PasswordComponent } from './pages/password/password.component';
import { PicturesComponent } from './pages/pictures/pictures.component';
import { PollDisplayComponent } from './pages/poll-display/poll-display.component';
import { ResumeComponent } from './pages/resume/resume.component';
import { VisibilityComponent } from './pages/visibility/visibility.component';
import { VotingChoiceComponent } from './pages/voting/voting-choice/voting-choice.component';
import { VotingComponent } from './pages/voting/voting.component';
import { PollGraphicComponent } from './poll-graphic/poll-graphic.component';
const routes: Routes = [];
const routes: Routes = [
{ path: '', redirectTo: 'step/creation', pathMatch: 'full' },
{ 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 },
{ path: 'step/answers', component: AnswersComponent },
{ path: 'step/admin', component: AdminComponent },
{ path: 'step/pictures', component: PicturesComponent },
{ path: 'step/visibility', component: VisibilityComponent },
{ path: 'step/resume', component: ResumeComponent },
{ path: 'step/end', component: EndConfirmationComponent },
{ path: 'graphic/:poll', component: PollGraphicComponent },
{ path: 'vote/poll/id/:poll', component: PollDisplayComponent },
{ path: 'vote/poll/slug/:pollSlug', component: PollDisplayComponent },
{ path: 'votingchoice', component: VotingChoiceComponent },
{ path: 'voting', component: VotingComponent },
{ path: 'step/password', component: PasswordComponent },
{ path: '**', redirectTo: '/home', pathMatch: 'full' },
];
@NgModule({
imports: [RouterModule.forRoot(routes, {useHash: true, anchorScrolling: 'enabled',})],
exports: [RouterModule]
imports: [RouterModule.forRoot(routes, { useHash: true, anchorScrolling: 'enabled' })],
exports: [RouterModule],
})
export class AppRoutingModule {
}
export class AppRoutingModule {}

View File

@ -1,47 +1,31 @@
<div
id='big_container'
class={{this.config.preferences.themeClass}}
>
<header class='big-header'>
<div class='container'>
<div class='columns'>
<div class='column'>
<div id="big_container" class="{{ this.config.preferences.themeClass }}">
<header class="big-header">
<div class="container">
<div class="columns">
<div class="column">
<framadate-master-head></framadate-master-head>
</div>
<div class='column'>
<div class="column">
<framadate-language></framadate-language>
</div>
</div>
</div>
</header>
<main>
<div class="container">
<div class="columns">
<div class="column is-one-quarter">
<framadate-theme-selector></framadate-theme-selector>
<framadate-navigation
*ngIf="config.menuVisible"
[step]="step"
></framadate-navigation>
<framadate-debugger
*ngIf="isDevelopmentEnv"
></framadate-debugger>
<framadate-navigation *ngIf="config.menuVisible" [step]="step"></framadate-navigation>
<framadate-debugger *ngIf="isDevelopmentEnv"></framadate-debugger>
<p-toast position="top-right"></p-toast>
</div>
<div class="column">
<router-outlet></router-outlet>
</div>
</div>
</div>
</main>
</div>

View File

@ -5,12 +5,8 @@ import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
imports: [RouterTestingModule],
declarations: [AppComponent],
}).compileComponents();
}));

View File

@ -1,46 +1,43 @@
import {Component, Inject} from '@angular/core';
import {TranslateService} from '@ngx-translate/core';
import {NavigationStart, Router} from '@angular/router';
import {DOCUMENT} from '@angular/common';
import {filter} from 'rxjs/operators';
import {ConfigService} from './services/config.service';
import {environment} from '../environments/environment';
import { Component, Inject } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { NavigationStart, Router } from '@angular/router';
import { DOCUMENT } from '@angular/common';
import { filter } from 'rxjs/operators';
import { ConfigService } from './services/config.service';
import { environment } from '../environments/environment';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
step: string;
isDevelopmentEnv=false;
isDevelopmentEnv = false;
constructor(private translate: TranslateService,
constructor(
private translate: TranslateService,
public config: ConfigService,
@Inject(DOCUMENT) private document,
private route: Router) {
private route: Router
) {
this.detectCurrentTabOnRouteChange();
this.isDevelopmentEnv = !environment.production
this.isDevelopmentEnv = !environment.production;
}
detectCurrentTabOnRouteChange() {
this.route.events.subscribe((event: any) => {
});
this.route.events.pipe(filter(event => event instanceof NavigationStart)).subscribe((event: NavigationStart) => {
this.route.events.subscribe((event: any) => {});
this.route.events
.pipe(filter((event) => event instanceof NavigationStart))
.subscribe((event: NavigationStart) => {
this.scrollGoToTop();
this.updateCurrentTab(event);
// only if there is a poll ID
this.config.fetchPollFromRoute(event);
})
});
}
scrollGoToTop() {
this.document.documentElement.scrollTop = 0;
}
@ -55,6 +52,4 @@ export class AppComponent {
}
}
}
}

View File

@ -1,65 +1,63 @@
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';
import {BaseComponent} from './pages/base-page/base.component';
import {KindComponent} from './pages/kind/kind.component';
import {HeaderComponent} from './header/header.component';
import {FormsModule} from '@angular/forms';
import {NavigationComponent} from './ui/navigation/navigation.component';
import {RouterModule} from '@angular/router';
import {Routes} from './config/Routes';
import {CommonModule, registerLocaleData} from '@angular/common';
import {DatesComponent} from './pages/dates/dates.component';
import {DebuggerComponent} from './debugger/debugger.component';
import {VisibilityComponent} from './pages/visibility/visibility.component';
import {ResumeComponent} from './pages/resume/resume.component';
import {PicturesComponent} from './pages/pictures/pictures.component';
import {AnswersComponent} from './pages/answers/answers.component';
import {EndConfirmationComponent} from './pages/end-confirmation/end-confirmation.component';
import {CreateOrRetrieveComponent} from './pages/create-or-retrieve/create-or-retrieve.component';
import localeFr from '@angular/common/locales/fr';
import { CommonModule, registerLocaleData } from '@angular/common';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import localeEn from '@angular/common/locales/en';
import {VotingSummaryComponent} from './pages/voting/voting-summary/voting-summary.component';
import {VotingGraphComponent} from './pages/voting/voting-graph/voting-graph.component';
import {VotingChoiceComponent} from './pages/voting/voting-choice/voting-choice.component';
import {PasswordComponent} from './pages/password/password.component';
import {HomeComponent} from './pages/home/home.component';
import {HttpClient, HttpClientModule} from '@angular/common/http';
import {MarkdownModule} from 'ngx-markdown';
import localeFr from '@angular/common/locales/fr';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {
MissingTranslationHandler,
MissingTranslationHandlerParams,
TranslateLoader,
TranslateModule,
TranslateService
TranslateService,
} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
import {PollGraphicComponent} from './poll-graphic/poll-graphic.component';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { ClipboardModule } from 'ngx-clipboard';
import { MarkdownModule } from 'ngx-markdown';
import { ConfirmationService, MessageModule, MessageService } from 'primeng';
import { ConfirmDialogModule } from 'primeng/confirmdialog';
import { DialogModule } from 'primeng/dialog';
import { ToastModule } from 'primeng/toast';
import {AdminComponent} from './pages/admin/admin.component';
import {SelectorComponent} from './ui/selector/selector.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {ConfigService} from './services/config.service';
import {PollService} from './services/poll.service';
import {ToastModule} from 'primeng/toast';
import {ConfirmationService, MessageModule, MessageService} from 'primeng';
import {PollDisplayComponent} from './pages/poll-display/poll-display.component';
import {VotingComponent} from './pages/voting/voting.component';
import {VotingCommentComponent} from './pages/voting/voting-comment/voting-comment.component';
import {ResettableInputDirective} from './ui/directives/resettable-input.directive';
import {ClipboardModule} from 'ngx-clipboard';
import {ErasableInputComponent} from './ui/erasable-input/erasable-input.component';
import {ConfirmDialogModule} from 'primeng/confirmdialog';
import {DialogModule} from 'primeng/dialog';
import {DateValueAccessorModule} from './custom-lib/date-value-accessor';
import {CopyTextComponent} from './ui/copy-text/copy-text.component';
import {CommentsListComponent} from './pages/voting/comments-list/comments-list.component';
import {ChoicesListComponent} from './pages/voting/choices-list/choices-list.component';
import {VotingNavigationComponent} from './pages/voting/voting-navigation/voting-navigation.component';
import { ThemeSelectorComponent } from './ui/theme-selector/theme-selector.component';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { DateValueAccessorModule } from './custom-lib/date-value-accessor';
import { DebuggerComponent } from './debugger/debugger.component';
import { HeaderComponent } from './header/header.component';
import { AdminComponent } from './pages/admin/admin.component';
import { AnswersComponent } from './pages/answers/answers.component';
import { BaseComponent } from './pages/base-page/base.component';
import { CreateOrRetrieveComponent } from './pages/create-or-retrieve/create-or-retrieve.component';
import { DatesComponent } from './pages/dates/dates.component';
import { EndConfirmationComponent } from './pages/end-confirmation/end-confirmation.component';
import { HomeComponent } from './pages/home/home.component';
import { KindComponent } from './pages/kind/kind.component';
import { PasswordComponent } from './pages/password/password.component';
import { PicturesComponent } from './pages/pictures/pictures.component';
import { PollDisplayComponent } from './pages/poll-display/poll-display.component';
import { ResumeComponent } from './pages/resume/resume.component';
import { VisibilityComponent } from './pages/visibility/visibility.component';
import { ChoicesListComponent } from './pages/voting/choices-list/choices-list.component';
import { CommentsListComponent } from './pages/voting/comments-list/comments-list.component';
import { VotingChoiceComponent } from './pages/voting/voting-choice/voting-choice.component';
import { VotingCommentComponent } from './pages/voting/voting-comment/voting-comment.component';
import { VotingGraphComponent } from './pages/voting/voting-graph/voting-graph.component';
import { VotingNavigationComponent } from './pages/voting/voting-navigation/voting-navigation.component';
import { VotingSummaryComponent } from './pages/voting/voting-summary/voting-summary.component';
import { VotingComponent } from './pages/voting/voting.component';
import { PollGraphicComponent } from './poll-graphic/poll-graphic.component';
import { ConfigService } from './services/config.service';
import { PollService } from './services/poll.service';
import { CopyTextComponent } from './ui/copy-text/copy-text.component';
import { ResettableInputDirective } from './ui/directives/resettable-input.directive';
import { ErasableInputComponent } from './ui/erasable-input/erasable-input.component';
import { MasterHeadComponent } from './ui/navigation/master-head/master-head.component';
import { NavigationComponent } from './ui/navigation/navigation.component';
import { LanguageComponent } from './ui/selector/language/language.component';
import { SelectorComponent } from './ui/selector/selector.component';
import { ThemeSelectorComponent } from './ui/theme-selector/theme-selector.component';
export class MyMissingTranslationHandler implements MissingTranslationHandler {
handle(params: MissingTranslationHandlerParams) {
@ -70,7 +68,7 @@ export class MyMissingTranslationHandler implements MissingTranslationHandler {
registerLocaleData(localeFr, 'fr');
registerLocaleData(localeEn, 'en');
export function HttpLoaderFactory(http: HttpClient) {
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
return new TranslateHttpLoader(http);
}
@ -109,7 +107,6 @@ export function HttpLoaderFactory(http: HttpClient) {
ThemeSelectorComponent,
MasterHeadComponent,
LanguageComponent,
],
imports: [
ConfirmDialogModule,
@ -132,15 +129,13 @@ export function HttpLoaderFactory(http: HttpClient) {
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
deps: [HttpClient],
},
}),
HttpClientModule,
FormsModule,
RouterModule.forRoot(Routes, {useHash: true})
],
providers: [TranslateService, ConfigService, PollService, MessageService, ConfirmationService],
bootstrap: [AppComponent]
bootstrap: [AppComponent],
})
export class AppModule {
}
export class AppModule {}

View File

@ -1,10 +1,9 @@
import {Injectable} from "@angular/core";
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class DateUtilities {
/**
* add some days to a date, to compute intervals
* @param days
@ -14,7 +13,7 @@ export class DateUtilities {
date = new Date(date.valueOf());
date.setDate(date.getDate() + days);
return date;
};
}
/**
*
@ -29,9 +28,9 @@ export class DateUtilities {
while (+d1 < +d2) {
dates.push({
literal: this.formateDate(d1),
date_object: d1
date_object: d1,
});
d1.setDate(d1.getDate() + interval)
d1.setDate(d1.getDate() + interval);
}
return dates.slice(0);
}
@ -42,7 +41,7 @@ export class DateUtilities {
* @param d2
*/
dayDiff(d1: Date, d2: Date): Number {
return Number(((d2.getTime()) - (d1.getTime()) / 31536000000));
return Number(d2.getTime() - d1.getTime() / 31536000000);
}
/**
@ -55,10 +54,10 @@ export class DateUtilities {
date.getFullYear(),
this.getDoubleDigits(date.getMonth() + 1),
this.getDoubleDigits(date.getDate()),
].join('-')
].join('-');
}
getDoubleDigits(str) {
return ("00" + str).slice(-2);
return ('00' + str).slice(-2);
}
}

View File

@ -1,8 +1,8 @@
/**
* une option de date dans les sondages spéciaux
*/
import {environment} from '../../environments/environment';
import {DateChoice, defaultAnswers, otherDefaultDates, PollAnswer} from './defaultConfigs';
import { environment } from '../../environments/environment';
import { DateChoice, defaultAnswers, otherDefaultDates, PollAnswer } from './defaultConfigs';
export interface DateOption {
timeList: any;
@ -18,22 +18,17 @@ const baseConfigValues = {
myEmail: '',
};
/**
* configuration of the poll, add new fields at will
*/
export class PollConfig {
menuVisible = true;
expiracyDateDefaultInDays = 60;
deletionDateAfterLastModification = 180;
step = 0; // step in the progress of creating a poll
stepMax = 3; // step max in the progress of creating a poll
pollType = 'dates';// classic or dates
pollType = 'dates'; // classic or dates
title: string = environment.production ? '' : 'titre';
description: string = environment.production ? '' : 'ma description';
@ -43,7 +38,7 @@ export class PollConfig {
myVoteStack: any;
myTempVoteStack = 0;
myEmail: string = environment.production ? '' : 'tktest@tktest.com';
myPolls: any = [];// list of retrieved polls from the backend api
myPolls: any = []; // list of retrieved polls from the backend api
/*
date specific poll, we have the choice to setup different hours (timeList) for all possible dates (dateList), or use the same hours for all dates
*/
@ -66,9 +61,9 @@ export class PollConfig {
urlAdmin = environment.baseHref + '/#/admin/d65es45fd45sdf45sd345f312sdf31sgfd345';
adminKey = ''; // key to change config of the poll
owner_modifier_token = ''; // key to change a vote stack
canModifyAnswers = true;// bool for the frontend selector
whoModifiesAnswers = 'everybody';// everybody, self, nobody (= just admin)
whoCanChangeAnswers = 'everybody';// everybody, self, nobody (= just admin)
canModifyAnswers = true; // bool for the frontend selector
whoModifiesAnswers = 'everybody'; // everybody, self, nobody (= just admin)
whoCanChangeAnswers = 'everybody'; // everybody, self, nobody (= just admin)
dateList: any = otherDefaultDates; // sets of days as strings, config to set identical time for days in a special days poll
timeList: DateChoice[] = otherDefaultDates; // ranges of time expressed as strings

View File

@ -1,9 +1,9 @@
import {HttpHeaders} from "@angular/common/http";
import {PollConfig} from "./PollConfig";
import {Injectable} from "@angular/core";
import { HttpHeaders } from '@angular/common/http';
import { PollConfig } from './PollConfig';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class PollUtilities {
// utils functions
@ -12,7 +12,8 @@ export class PollUtilities {
*/
makeUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
var r = (Math.random() * 16) | 0,
v = c == 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
@ -23,18 +24,28 @@ export class PollUtilities {
*/
makeSlug(config: PollConfig) {
let str = '';
str = config.creationDate.getFullYear() + '_' + (config.creationDate.getMonth() + 1) + '_' + config.creationDate.getDate() + '_' + config.myName + '_' + config.title;
str =
config.creationDate.getFullYear() +
'_' +
(config.creationDate.getMonth() + 1) +
'_' +
config.creationDate.getDate() +
'_' +
config.myName +
'_' +
config.title;
str = str.replace(/^\s+|\s+$/g, ''); // trim
str = str.toLowerCase();
// remove accents, swap ñ for n, etc
var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;";
var to = "aaaaeeeeiiiioooouuuunc------";
var from = 'àáäâèéëêìíïîòóöôùúüûñç·/_,:;';
var to = 'aaaaeeeeiiiioooouuuunc------';
for (var 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
str = str
.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
.replace(/\s+/g, '-') // collapse whitespace and replace by -
.replace(/-+/g, '-'); // collapse dashes
@ -46,18 +57,17 @@ export class PollUtilities {
* @param bodyContent
*/
makeHeaders(bodyContent?: any) {
const headerDict = {
'Charset': 'UTF-8',
Charset: 'UTF-8',
'Content-Type': 'application/json',
'Accept': 'application/json',
Accept: 'application/json',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Origin': '*'
'Access-Control-Allow-Origin': '*',
};
const requestOptions = {
headers: new HttpHeaders(headerDict),
body: bodyContent
body: bodyContent,
};
return requestOptions;

View File

@ -1,45 +1,42 @@
import {KindComponent} from '../pages/kind/kind.component';
import {DatesComponent} from '../pages/dates/dates.component';
import {VisibilityComponent} from '../pages/visibility/visibility.component';
import {ResumeComponent} from '../pages/resume/resume.component';
import {PicturesComponent} from '../pages/pictures/pictures.component';
import {EndConfirmationComponent} from '../pages/end-confirmation/end-confirmation.component';
import {AnswersComponent} from '../pages/answers/answers.component';
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 {PollDisplayComponent} from "../pages/poll-display/poll-display.component";
import {VotingComponent} from "../pages/voting/voting.component";
import {PasswordComponent} from "../pages/password/password.component";
import {VotingChoiceComponent} from "../pages/voting/voting-choice/voting-choice.component";
import { AdminComponent } from '../pages/admin/admin.component';
import { AnswersComponent } from '../pages/answers/answers.component';
import { BaseComponent } from '../pages/base-page/base.component';
import { CreateOrRetrieveComponent } from '../pages/create-or-retrieve/create-or-retrieve.component';
import { DatesComponent } from '../pages/dates/dates.component';
import { EndConfirmationComponent } from '../pages/end-confirmation/end-confirmation.component';
import { HomeComponent } from '../pages/home/home.component';
import { KindComponent } from '../pages/kind/kind.component';
import { PasswordComponent } from '../pages/password/password.component';
import { PicturesComponent } from '../pages/pictures/pictures.component';
import { PollDisplayComponent } from '../pages/poll-display/poll-display.component';
import { ResumeComponent } from '../pages/resume/resume.component';
import { VisibilityComponent } from '../pages/visibility/visibility.component';
import { VotingChoiceComponent } from '../pages/voting/voting-choice/voting-choice.component';
import { VotingComponent } from '../pages/voting/voting.component';
import { PollGraphicComponent } from '../poll-graphic/poll-graphic.component';
/**
* each step in the form is a component
*/
export const Routes =
[
{path: '', redirectTo: 'step/creation', pathMatch: 'full'},
{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},
{path: 'step/answers', component: AnswersComponent},
{path: 'step/admin', component: AdminComponent},
{path: 'step/pictures', component: PicturesComponent},
{path: 'step/visibility', component: VisibilityComponent},
{path: 'step/resume', component: ResumeComponent},
{path: 'step/end', component: EndConfirmationComponent},
{path: 'graphic/:poll', component: PollGraphicComponent},
{path: 'vote/poll/id/:poll', component: PollDisplayComponent},
{path: 'vote/poll/slug/:pollSlug', component: PollDisplayComponent},
{path: 'votingchoice', component: VotingChoiceComponent},
{path: 'voting', component: VotingComponent},
{path: 'step/password', component: PasswordComponent},
{path: '**', redirectTo: '/home', pathMatch: 'full'},
]
;
export const Routes = [
{ path: '', redirectTo: 'step/creation', pathMatch: 'full' },
{ 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 },
{ path: 'step/answers', component: AnswersComponent },
{ path: 'step/admin', component: AdminComponent },
{ path: 'step/pictures', component: PicturesComponent },
{ path: 'step/visibility', component: VisibilityComponent },
{ path: 'step/resume', component: ResumeComponent },
{ path: 'step/end', component: EndConfirmationComponent },
{ path: 'graphic/:poll', component: PollGraphicComponent },
{ path: 'vote/poll/id/:poll', component: PollDisplayComponent },
{ path: 'vote/poll/slug/:pollSlug', component: PollDisplayComponent },
{ path: 'votingchoice', component: VotingChoiceComponent },
{ path: 'voting', component: VotingComponent },
{ path: 'step/password', component: PasswordComponent },
{ path: '**', redirectTo: '/home', pathMatch: 'full' },
];

View File

@ -1,106 +1,107 @@
export interface DateChoice {
literal: string,
timeList: TimeSlices[],
date_object: Date
literal: string;
timeList: TimeSlices[];
date_object: Date;
}
export interface TimeSlices {
literal: string
literal: string;
}
export interface PollAnswer {
id: number,
text: string,
url: string,
file: string,
literal: string,
date_object: Date,
timeList: TimeSlices[]
id: number;
text: string;
url: string;
file: string;
literal: string;
date_object: Date;
timeList: TimeSlices[];
}
const currentYear = new Date().getFullYear();
const currentMonth = new Date().getMonth();
const currentDay = new Date().getDate();
export const basicSlicesOfDay: TimeSlices[] = [
{literal: 'matin'},
{literal: 'midi'},
{literal: 'soir'}
];
export const basicSlicesOfDay: TimeSlices[] = [{ literal: 'matin' }, { literal: 'midi' }, { literal: 'soir' }];
export const otherSlicesOfDay: TimeSlices[] = [
{literal: 'aux aurores'},
{literal: 'au petit dej'},
{literal: 'au deuxième petit dej des hobbits'}
{ literal: 'aux aurores' },
{ literal: 'au petit dej' },
{ literal: 'au deuxième petit dej des hobbits' },
];
export const defaultTimeOfDay: TimeSlices[] = (() => {
return [...basicSlicesOfDay]
return [...basicSlicesOfDay];
})();
export const otherTimeOfDay: TimeSlices[] = (() => {
return [...otherSlicesOfDay]
return [...otherSlicesOfDay];
})();
export const moreTimeOfDay: TimeSlices[] = (() => {
return [...otherSlicesOfDay]
return [...otherSlicesOfDay];
})();
export const defaultDates: DateChoice[] = [
{
literal: `${currentYear}-${currentMonth}-${currentDay}`,
date_object: new Date(),
timeList: defaultTimeOfDay
timeList: defaultTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 1}`,
date_object: new Date(),
timeList: defaultTimeOfDay
timeList: defaultTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 2}`,
date_object: new Date(),
timeList: defaultTimeOfDay
}
timeList: defaultTimeOfDay,
},
];
export const otherDefaultDates: DateChoice[] = [
{
literal: `${currentYear}-${currentMonth}-${currentDay}`,
date_object: new Date(),
timeList: defaultTimeOfDay
timeList: defaultTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 1}`,
date_object: new Date(currentYear, currentMonth, currentDay + 1),
timeList: otherTimeOfDay
timeList: otherTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 2}`,
date_object: new Date(),
timeList: moreTimeOfDay
}
timeList: moreTimeOfDay,
},
];
export const defaultAnswers: PollAnswer[] = [{
export const defaultAnswers: PollAnswer[] = [
{
id: 0,
text: 'réponse de démo 1',
file: '',
url: 'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
url:
'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
literal: `${currentYear}-${currentMonth}-${currentDay}`,
date_object: new Date(),
timeList: otherSlicesOfDay
},
timeList: otherSlicesOfDay,
},
{
id: 1,
text: 'réponse 2',
file: '',
url: 'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
url:
'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
literal: `${currentYear}-${currentMonth}-${currentDay + 1}`,
date_object: new Date(),
timeList: basicSlicesOfDay
timeList: basicSlicesOfDay,
},
{
id: 2,
text: 'la réponse D',
file: '',
url: 'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
url:
'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
literal: `${currentYear}-${currentMonth}-${currentDay + 2}`,
date_object: new Date(),
timeList: otherSlicesOfDay
}];
timeList: otherSlicesOfDay,
},
];

View File

@ -1,24 +1,24 @@
export var graphOptions = {
legend: {display: false},
legend: { display: false },
scales: {
xAxes: [
{
gridLines: {drawBorder: false, display: false},
gridLines: { drawBorder: false, display: false },
display: false,
stacked: true,
ticks: {
beginAtZero: true,
maxRotation: 0,
minRotation: 0
}
}
minRotation: 0,
},
},
],
yAxes: [
{
gridLines: {drawBorder: true, display: false},
gridLines: { drawBorder: true, display: false },
display: true,
stacked: true
}
]
}
stacked: true,
},
],
},
};

View File

@ -1,11 +1,11 @@
export const mockChoice = {
"id": 11,
"date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 11,
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"text": "Les mondes engloutis",
"url": null,
"answer": null,
text: 'Les mondes engloutis',
url: null,
answer: null,
};

View File

@ -1,20 +1,21 @@
export const mockComments = [
{
pseudo: "Bulbizarre",
"date": {
"date": "2020-01-22 16:00:22.000000",
"timezone_type": 3,
"timezone": "Europe/Paris"
pseudo: 'Bulbizarre',
date: {
date: '2020-01-22 16:00:22.000000',
timezone_type: 3,
timezone: 'Europe/Paris',
},
text: "Pokem ipsum dolor sit amet Electric Cottonee Scratch Leech Life Ice Berry Ducklett. Leaf Green Durant Zoroark\n" +
" Skitty Rock Luxio Surskit. Glacier Badge",
text:
'Pokem ipsum dolor sit amet Electric Cottonee Scratch Leech Life Ice Berry Ducklett. Leaf Green Durant Zoroark\n' +
' Skitty Rock Luxio Surskit. Glacier Badge',
},
{
pseudo: "Marylin",
"date": {
"date": "2020-01-22 16:00:22.000000",
"timezone_type": 3,
"timezone": "Europe/Paris"
pseudo: 'Marylin',
date: {
date: '2020-01-22 16:00:22.000000',
timezone_type: 3,
timezone: 'Europe/Paris',
},
text: "j'ai vu de la lumière o_o",
},

View File

@ -1,52 +1,52 @@
export const mockGraphConfig = {
step: 0,
stepMax: 3,
pollType: "special dates",
title: "",
description: "",
myName: "",
visibility: "link_only",
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
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"
text: 'no',
},
{
id: 1,
text: "yes"
text: 'yes',
},
{
id: 2,
text: "maybe"
text: 'maybe',
},
{
id: 3,
text: "maybe"
text: 'maybe',
},
{
id: 4,
text: "maybe"
text: 'maybe',
},
{
id: 5,
text: "maybe"
text: 'maybe',
},
{
id: 6,
text: "maybe"
text: 'maybe',
},
{
id: 7,
text: "maybe"
text: 'maybe',
},
{
id: 8,
text: "maybe"
}
]
text: 'maybe',
},
],
};

View File

@ -1,569 +1,529 @@
export const mockPoll3 = {
"message": "your poll config",
"poll": {
"id": 4,
"title": "dessin animé préféré",
"customUrl": null,
"description": "choisissez votre animé préféré",
"creationDate": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
message: 'your poll config',
poll: {
id: 4,
title: 'dessin animé préféré',
customUrl: null,
description: 'choisissez votre animé préféré',
creationDate: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"expiracyDate": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
expiracyDate: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"owner": {
"__initializer__": null,
"__cloner__": null,
"__isInitialized__": true,
"pseudo": "tk_TEST",
"email": "tktest@tktest.com"
owner: {
__initializer__: null,
__cloner__: null,
__isInitialized__: true,
pseudo: 'tk_TEST',
email: 'tktest@tktest.com',
},
"kind": "text",
"allowedAnswers": [
kind: 'text',
allowedAnswers: [
// "yes", "maybe", "no"
"yes",
'yes',
],
"modificationPolicy": "everybody",
"mailOnComment": null,
"mailOnVote": null,
"hideResults": null,
"showResultEvenIfPasswords": null,
"votes": {},
"stacksOfVotes": {},
"choices": {},
"choices_count": {
"counts": {
"10": {
"choice_id": 10,
"choice_text": "Les mystérieuses cités d'or",
"id": 4,
"score": 2.5,
"yes": {
"count": 2,
"people": [
"voting_people_TEST",
"voting_people_TEST"
]
modificationPolicy: 'everybody',
mailOnComment: null,
mailOnVote: null,
hideResults: null,
showResultEvenIfPasswords: null,
votes: {},
stacksOfVotes: {},
choices: {},
choices_count: {
counts: {
'10': {
choice_id: 10,
choice_text: "Les mystérieuses cités d'or",
id: 4,
score: 2.5,
yes: {
count: 2,
people: ['voting_people_TEST', 'voting_people_TEST'],
},
"maybe": {
"count": 1,
"people": [
"Nikolas Edison"
]
maybe: {
count: 1,
people: ['Nikolas Edison'],
},
"no": {
"count": 1,
"people": [
"voting_people_TEST"
]
}
no: {
count: 1,
people: ['voting_people_TEST'],
},
"9": {
"choice_id": 9,
"choice_text": "Boumbo petite automobile",
"id": 5,
"score": 2.5,
"yes": {
"count": 2,
"people": [
"voting_people_TEST",
"Billie Jean"
]
},
"maybe": {
"count": 1,
"people": [
"voting_people_TEST"
]
'9': {
choice_id: 9,
choice_text: 'Boumbo petite automobile',
id: 5,
score: 2.5,
yes: {
count: 2,
people: ['voting_people_TEST', 'Billie Jean'],
},
"no": {
"count": 0,
"people": []
}
maybe: {
count: 1,
people: ['voting_people_TEST'],
},
"12": {
"choice_id": 12,
"choice_text": "Foot 2 rue",
"id": 14,
"score": 0.5,
"yes": {
"count": 0,
"people": []
no: {
count: 0,
people: [],
},
"maybe": {
"count": 1,
"people": [
"Nikolas Edison"
]
},
"no": {
"count": 0,
"people": []
}
'12': {
choice_id: 12,
choice_text: 'Foot 2 rue',
id: 14,
score: 0.5,
yes: {
count: 0,
people: [],
},
"11": {
"choice_id": 11,
"choice_text": "Les mondes engloutis",
"id": 15,
"score": 1.5,
"yes": {
"count": 1,
"people": [
"Billie Jean"
]
maybe: {
count: 1,
people: ['Nikolas Edison'],
},
"maybe": {
"count": 1,
"people": [
"Wulfila"
]
no: {
count: 0,
people: [],
},
"no": {
"count": 0,
"people": []
}
},
"13": {
"choice_id": 13,
"choice_text": "Le chat, la vache, et l'océan",
"id": 16,
"score": 1,
"yes": {
"count": 1,
"people": [
"Wulfila"
]
'11': {
choice_id: 11,
choice_text: 'Les mondes engloutis',
id: 15,
score: 1.5,
yes: {
count: 1,
people: ['Billie Jean'],
},
"maybe": {
"count": 0,
"people": []
maybe: {
count: 1,
people: ['Wulfila'],
},
"no": {
"count": 0,
"people": []
}
}
no: {
count: 0,
people: [],
},
"maxScore": 2.5
},
"comments": {},
"defaultExpiracyDaysFromNow": 60
'13': {
choice_id: 13,
choice_text: "Le chat, la vache, et l'océan",
id: 16,
score: 1,
yes: {
count: 1,
people: ['Wulfila'],
},
"stacks_count": 5,
"stacks": [
maybe: {
count: 0,
people: [],
},
no: {
count: 0,
people: [],
},
},
},
maxScore: 2.5,
},
comments: {},
defaultExpiracyDaysFromNow: 60,
},
stacks_count: 5,
stacks: [
{
"id": 3,
"pseudo": "voting_people_TEST",
"creation_date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 3,
pseudo: 'voting_people_TEST',
creation_date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"votes": {
"8": {
"choice_id": 8
votes: {
'8': {
choice_id: 8,
},
"9": {
"id": 3,
"vote_id": 5,
"value": "maybe",
"choice_id": 9,
"text": "Boumbo petite automobile"
'9': {
id: 3,
vote_id: 5,
value: 'maybe',
choice_id: 9,
text: 'Boumbo petite automobile',
},
"10": {
"id": 3,
"vote_id": 4,
"value": "yes",
"choice_id": 10,
"text": "Les mystérieuses cités d'or"
'10': {
id: 3,
vote_id: 4,
value: 'yes',
choice_id: 10,
text: "Les mystérieuses cités d'or",
},
"11": {
"choice_id": 11
'11': {
choice_id: 11,
},
"12": {
"choice_id": 12
'12': {
choice_id: 12,
},
'13': {
choice_id: 13,
},
'14': {
choice_id: 14,
},
"13": {
"choice_id": 13
},
"14": {
"choice_id": 14
}
}
},
{
"id": 4,
"pseudo": "voting_people_TEST",
"creation_date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 4,
pseudo: 'voting_people_TEST',
creation_date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"votes": {
"8": {
"choice_id": 8
votes: {
'8': {
choice_id: 8,
},
"9": {
"id": 4,
"vote_id": 6,
"value": "yes",
"choice_id": 9,
"text": "Boumbo petite automobile"
'9': {
id: 4,
vote_id: 6,
value: 'yes',
choice_id: 9,
text: 'Boumbo petite automobile',
},
"10": {
"id": 4,
"vote_id": 8,
"value": "no",
"choice_id": 10,
"text": "Les mystérieuses cités d'or"
'10': {
id: 4,
vote_id: 8,
value: 'no',
choice_id: 10,
text: "Les mystérieuses cités d'or",
},
"11": {
"choice_id": 11
'11': {
choice_id: 11,
},
"12": {
"choice_id": 12
'12': {
choice_id: 12,
},
'13': {
choice_id: 13,
},
'14': {
choice_id: 14,
},
"13": {
"choice_id": 13
},
"14": {
"choice_id": 14
}
}
},
{
"id": 7,
"pseudo": "Nikolas Edison",
"creation_date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 7,
pseudo: 'Nikolas Edison',
creation_date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"votes": {
"8": {
"choice_id": 8
votes: {
'8': {
choice_id: 8,
},
"9": {
"choice_id": 9
'9': {
choice_id: 9,
},
"10": {
"id": 7,
"vote_id": 13,
"value": "maybe",
"choice_id": 10,
"text": "Les mystérieuses cités d'or"
'10': {
id: 7,
vote_id: 13,
value: 'maybe',
choice_id: 10,
text: "Les mystérieuses cités d'or",
},
"11": {
"choice_id": 11
'11': {
choice_id: 11,
},
"12": {
"id": 7,
"vote_id": 14,
"value": "maybe",
"choice_id": 12,
"text": "Foot 2 rue"
'12': {
id: 7,
vote_id: 14,
value: 'maybe',
choice_id: 12,
text: 'Foot 2 rue',
},
'13': {
choice_id: 13,
},
'14': {
choice_id: 14,
},
"13": {
"choice_id": 13
},
"14": {
"choice_id": 14
}
}
},
{
"id": 8,
"pseudo": "Wulfila",
"creation_date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 8,
pseudo: 'Wulfila',
creation_date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"votes": {
"8": {
"choice_id": 8
votes: {
'8': {
choice_id: 8,
},
"9": {
"choice_id": 9
'9': {
choice_id: 9,
},
"10": {
"choice_id": 10
'10': {
choice_id: 10,
},
"11": {
"id": 8,
"vote_id": 15,
"value": "maybe",
"choice_id": 11,
"text": "Les mondes engloutis"
'11': {
id: 8,
vote_id: 15,
value: 'maybe',
choice_id: 11,
text: 'Les mondes engloutis',
},
"12": {
"choice_id": 12
'12': {
choice_id: 12,
},
'13': {
id: 8,
vote_id: 16,
value: 'yes',
choice_id: 13,
text: "Le chat, la vache, et l'océan",
},
'14': {
choice_id: 14,
},
"13": {
"id": 8,
"vote_id": 16,
"value": "yes",
"choice_id": 13,
"text": "Le chat, la vache, et l'océan"
},
"14": {
"choice_id": 14
}
}
},
{
"id": 9,
"pseudo": "Billie Jean",
"creation_date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 9,
pseudo: 'Billie Jean',
creation_date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"votes": {
"8": {
"choice_id": 8
votes: {
'8': {
choice_id: 8,
},
"9": {
"id": 9,
"vote_id": 17,
"value": "yes",
"choice_id": 9,
"text": "Boumbo petite automobile"
'9': {
id: 9,
vote_id: 17,
value: 'yes',
choice_id: 9,
text: 'Boumbo petite automobile',
},
"10": {
"choice_id": 10
'10': {
choice_id: 10,
},
"11": {
"id": 9,
"vote_id": 18,
"value": "yes",
"choice_id": 11,
"text": "Les mondes engloutis"
'11': {
id: 9,
vote_id: 18,
value: 'yes',
choice_id: 11,
text: 'Les mondes engloutis',
},
'12': {
choice_id: 12,
},
'13': {
choice_id: 13,
},
'14': {
choice_id: 14,
},
"12": {
"choice_id": 12
},
"13": {
"choice_id": 13
},
"14": {
"choice_id": 14
}
}
}
],
"choices_count": {
"counts": {
"10": {
"choice_id": 10,
"choice_text": "Les mystérieuses cités d'or",
"id": 4,
"score": 2.5,
"yes": {
"count": 2,
"people": [
"voting_people_TEST",
"voting_people_TEST"
]
choices_count: {
counts: {
'10': {
choice_id: 10,
choice_text: "Les mystérieuses cités d'or",
id: 4,
score: 2.5,
yes: {
count: 2,
people: ['voting_people_TEST', 'voting_people_TEST'],
},
"maybe": {
"count": 1,
"people": [
"Nikolas Edison"
]
maybe: {
count: 1,
people: ['Nikolas Edison'],
},
"no": {
"count": 1,
"people": [
"voting_people_TEST"
]
}
no: {
count: 1,
people: ['voting_people_TEST'],
},
"9": {
"choice_id": 9,
"choice_text": "Boumbo petite automobile",
"id": 5,
"score": 2.5,
"yes": {
"count": 2,
"people": [
"voting_people_TEST",
"Billie Jean"
]
},
"maybe": {
"count": 1,
"people": [
"voting_people_TEST"
]
'9': {
choice_id: 9,
choice_text: 'Boumbo petite automobile',
id: 5,
score: 2.5,
yes: {
count: 2,
people: ['voting_people_TEST', 'Billie Jean'],
},
"no": {
"count": 0,
"people": []
}
maybe: {
count: 1,
people: ['voting_people_TEST'],
},
"12": {
"choice_id": 12,
"choice_text": "Foot 2 rue",
"id": 14,
"score": 0.5,
"yes": {
"count": 0,
"people": []
no: {
count: 0,
people: [],
},
"maybe": {
"count": 1,
"people": [
"Nikolas Edison"
]
},
"no": {
"count": 0,
"people": []
}
'12': {
choice_id: 12,
choice_text: 'Foot 2 rue',
id: 14,
score: 0.5,
yes: {
count: 0,
people: [],
},
"11": {
"choice_id": 11,
"choice_text": "Les mondes engloutis",
"id": 15,
"score": 1.5,
"yes": {
"count": 1,
"people": [
"Billie Jean"
]
maybe: {
count: 1,
people: ['Nikolas Edison'],
},
"maybe": {
"count": 1,
"people": [
"Wulfila"
]
no: {
count: 0,
people: [],
},
"no": {
"count": 0,
"people": []
}
},
"13": {
"choice_id": 13,
"choice_text": "Le chat, la vache, et l'océan",
"id": 16,
"score": 1,
"yes": {
"count": 1,
"people": [
"Wulfila"
]
'11': {
choice_id: 11,
choice_text: 'Les mondes engloutis',
id: 15,
score: 1.5,
yes: {
count: 1,
people: ['Billie Jean'],
},
"maybe": {
"count": 0,
"people": []
maybe: {
count: 1,
people: ['Wulfila'],
},
"no": {
"count": 0,
"people": []
}
}
no: {
count: 0,
people: [],
},
"maxScore": 2.5
},
"choices": [
'13': {
choice_id: 13,
choice_text: "Le chat, la vache, et l'océan",
id: 16,
score: 1,
yes: {
count: 1,
people: ['Wulfila'],
},
maybe: {
count: 0,
people: [],
},
no: {
count: 0,
people: [],
},
},
},
maxScore: 2.5,
},
choices: [
{
"id": 8,
"date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 8,
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"text": "Vic le viking",
"url": null
text: 'Vic le viking',
url: null,
},
{
"id": 9,
"date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 9,
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"text": "Boumbo petite automobile",
"url": null
text: 'Boumbo petite automobile',
url: null,
},
{
"id": 10,
"date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 10,
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"text": "Les mystérieuses cités d'or",
"url": null
text: "Les mystérieuses cités d'or",
url: null,
},
{
"id": 11,
"date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 11,
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"text": "Les mondes engloutis",
"url": null
text: 'Les mondes engloutis',
url: null,
},
{
"id": 12,
"date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 12,
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"text": "Foot 2 rue",
"url": null
text: 'Foot 2 rue',
url: null,
},
{
"id": 13,
"date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 13,
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
"text": "Le chat, la vache, et l'océan",
"url": null
text: "Le chat, la vache, et l'océan",
url: null,
},
{
"id": 14,
"date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
id: 14,
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
text: 'Digimon',
url: null,
},
"text": "Digimon",
"url": null
}
],
"comments": [
comments: [
{
"id": 3,
"text": "allez boumbo!",
"pseudo": "tk_TEST_commentateur",
"date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
}
id: 3,
text: 'allez boumbo!',
pseudo: 'tk_TEST_commentateur',
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
},
{
"id": 4,
"text": "je suis pour la team rocket de digimon",
"pseudo": "tk_TEST",
"date": {
"date": "2020-01-30 12:25:13.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
}
}
id: 4,
text: 'je suis pour la team rocket de digimon',
pseudo: 'tk_TEST',
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
},
],
"comments_count": 2
comments_count: 2,
};

File diff suppressed because it is too large Load Diff

View File

@ -1,43 +1,44 @@
export const mockMyPolls =
[{
"id": 1000001,
"title": "blehehehe heh hehhe e test1",
"customUrl": null,
"description": "maaaaaaaaaaah",
"creationDate": {"date": "2020-01-20 14:21:16.270157", "timezone_type": 3, "timezone": "Europe/Paris"},
"expiracyDate": {"date": "2020-01-20 14:21:16.270178", "timezone_type": 3, "timezone": "Europe/Paris"},
"owner": null,
"kind": "text",
"allowedAnswers": ["yes"],
"modificationPolicy": "nobody",
"mailOnComment": null,
"mailOnVote": null,
"hideResults": null,
"showResultEvenIfPasswords": null,
"votes": {},
"stacksOfVotes": {},
"choices": {},
"comments": {},
"defaultExpiracyDaysFromNow": 60
}, {
"id": 1000002,
"title": "bleh z zr erth tuyjikioy yylil test2",
"customUrl": null,
"description": "maaaaaaaaaaah 2",
"creationDate": {"date": "2020-01-20 14:21:16.270157", "timezone_type": 3, "timezone": "Europe/Paris"},
"expiracyDate": {"date": "2020-01-20 14:21:16.270178", "timezone_type": 3, "timezone": "Europe/Paris"},
"owner": null,
"kind": "text",
"allowedAnswers": ["yes"],
"modificationPolicy": "nobody",
"mailOnComment": null,
"mailOnVote": null,
"hideResults": null,
"showResultEvenIfPasswords": null,
"votes": {},
"stacksOfVotes": {},
"choices": {},
"comments": {},
"defaultExpiracyDaysFromNow": 60
}]
;
export const mockMyPolls = [
{
id: 1000001,
title: 'blehehehe heh hehhe e test1',
customUrl: null,
description: 'maaaaaaaaaaah',
creationDate: { date: '2020-01-20 14:21:16.270157', timezone_type: 3, timezone: 'Europe/Paris' },
expiracyDate: { date: '2020-01-20 14:21:16.270178', timezone_type: 3, timezone: 'Europe/Paris' },
owner: null,
kind: 'text',
allowedAnswers: ['yes'],
modificationPolicy: 'nobody',
mailOnComment: null,
mailOnVote: null,
hideResults: null,
showResultEvenIfPasswords: null,
votes: {},
stacksOfVotes: {},
choices: {},
comments: {},
defaultExpiracyDaysFromNow: 60,
},
{
id: 1000002,
title: 'bleh z zr erth tuyjikioy yylil test2',
customUrl: null,
description: 'maaaaaaaaaaah 2',
creationDate: { date: '2020-01-20 14:21:16.270157', timezone_type: 3, timezone: 'Europe/Paris' },
expiracyDate: { date: '2020-01-20 14:21:16.270178', timezone_type: 3, timezone: 'Europe/Paris' },
owner: null,
kind: 'text',
allowedAnswers: ['yes'],
modificationPolicy: 'nobody',
mailOnComment: null,
mailOnVote: null,
hideResults: null,
showResultEvenIfPasswords: null,
votes: {},
stacksOfVotes: {},
choices: {},
comments: {},
defaultExpiracyDaysFromNow: 60,
},
];

View File

@ -1,10 +1,10 @@
import {Directive, ElementRef, forwardRef, HostListener, Renderer2} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import { Directive, ElementRef, forwardRef, HostListener, Renderer2 } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
export const DATE_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DateValueAccessor),
multi: true
multi: true,
};
/**
@ -19,17 +19,13 @@ export const DATE_VALUE_ACCESSOR: any = {
// this selector is an opt-in version
selector: '[useValueAsDate]',
providers: [DATE_VALUE_ACCESSOR]
providers: [DATE_VALUE_ACCESSOR],
})
export class DateValueAccessor implements ControlValueAccessor {
@HostListener('input', ['$event.target.valueAsDate']) onChange = (_: any) => {};
@HostListener('blur', []) onTouched = () => {};
@HostListener('input', ['$event.target.valueAsDate']) onChange = (_: any) => {
};
@HostListener('blur', []) onTouched = () => {
};
constructor(private _renderer: Renderer2, private _elementRef: ElementRef) {
}
constructor(private _renderer: Renderer2, private _elementRef: ElementRef) {}
writeValue(value: Date): void {
if (!value) {

View File

@ -1,3 +1,2 @@
export * from './module';
export * from './date-value-accessor';

View File

@ -3,6 +3,6 @@ import { DateValueAccessor } from './date-value-accessor';
@NgModule({
declarations: [DateValueAccessor],
exports: [DateValueAccessor]
exports: [DateValueAccessor],
})
export class DateValueAccessorModule { }
export class DateValueAccessorModule {}

View File

@ -1,52 +1,30 @@
<div class="well debug" >
<strong >
<h2 i18n >
<div class="well debug">
<strong>
<h2 i18n>
infos de debug - environement de Dev
</h2 >
<span class="demo" >
{{"config.demo"|translate}}
</span >
</strong >
<ul >
<li >
étape actuelle {{config.step}} / {{config.stepMax}}
</li >
<li >
formulaire valide : {{formIsValid}}
</li >
<li >
type de formulaire: {{config.pollType}}
</li >
</ul >
<button
class="btn btn--primary"
i18n
(click)="config.createPoll()"
>
</h2>
<span class="demo">
{{ 'config.demo' | translate }}
</span>
</strong>
<ul>
<li>étape actuelle {{ config.step }} / {{ config.stepMax }}</li>
<li>formulaire valide : {{ formIsValid }}</li>
<li>type de formulaire: {{ config.pollType }}</li>
</ul>
<button class="btn btn--primary" i18n (click)="config.createPoll()">
Envoyer le formulaire
</button >
<button
class="btn btn--primary"
i18n
(click)="config.getPollById( '1', 'example password')"
>
</button>
<button class="btn btn--primary" i18n (click)="config.getPollById('1', 'example password')">
get poll 1
</button >
<button
class="btn btn--primary"
i18n
(click)="config.getMyPolls( 'tktest@tktest.com')"
>
</button>
<button class="btn btn--primary" i18n (click)="config.getMyPolls('tktest@tktest.com')">
get my polls
</button >
<button
class="btn btn--success"
(click)="launchToast()" >
</button>
<button class="btn btn--success" (click)="launchToast()">
launch success toast
</button >
<a
[routerLink]="'/vote/poll/id/3'"
class="btn btn--success" >
</button>
<a [routerLink]="'/vote/poll/id/3'" class="btn btn--success">
See example of vote page
</a >
</div >
</a>
</div>

View File

@ -8,9 +8,8 @@ describe('DebuggerComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DebuggerComponent ]
})
.compileComponents();
declarations: [DebuggerComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,19 +1,17 @@
import {Component, OnInit} from '@angular/core';
import {ConfigService} from '../services/config.service';
import { Component, OnInit } from '@angular/core';
import { ConfigService } from '../services/config.service';
@Component({
selector: 'framadate-debugger',
templateUrl: './debugger.component.html',
styleUrls: ['./debugger.component.scss']
styleUrls: ['./debugger.component.scss'],
})
export class DebuggerComponent implements OnInit {
formIsValid = true;
constructor(public config: ConfigService) {
}
constructor(public config: ConfigService) {}
ngOnInit() {
}
ngOnInit() {}
selectOption(key: string, val: any) {
if (!this.config[key]) {
@ -25,6 +23,6 @@ export class DebuggerComponent implements OnInit {
}
launchToast() {
this.config.handleError({message: "hop"})
this.config.handleError({ message: 'hop' });
}
}

View File

@ -8,9 +8,8 @@ describe('HeaderComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HeaderComponent ]
})
.compileComponents();
declarations: [HeaderComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -3,13 +3,10 @@ import { Component, OnInit } from '@angular/core';
@Component({
selector: 'framadate-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
styleUrls: ['./header.component.scss'],
})
export class HeaderComponent implements OnInit {
constructor() {}
constructor() { }
ngOnInit() {
}
ngOnInit() {}
}

View File

@ -2,153 +2,147 @@
<h1>Nom du sondage</h1>
<!--Infos-->
<h2>{{"admin.info_section_title"|translate}}</h2>
<h2>{{ 'admin.info_section_title' | translate }}</h2>
<label for="title">
{{"admin.choose_title"|translate}}
{{ 'admin.choose_title' | translate }}
</label>
<input type="text" name="title">
<input type="text" name="title" />
<label for="desc">
{{"admin.description"|translate}}
{{ 'admin.description' | translate }}
</label>
<textarea name="desc"> </textarea>
<label for="name">
{{"creation.name"|translate}}
{{ 'creation.name' | translate }}
</label>
<input type="text" name="name">
<input type="text" name="name" />
<!--Params-->
<h2>{{"admin.settings_section_title"|translate}}</h2>
<h3>{{"visibility.title"|translate}}</h3>
<h2>{{ 'admin.settings_section_title' | translate }}</h2>
<h3>{{ 'visibility.title' | translate }}</h3>
<section class="row">
<label for="answer-visible">
{{"visibility.visibility_want"|translate}}
{{ 'visibility.visibility_want' | translate }}
</label>
<select name="answer-visible">
<option value="all" selected>
{{"visibility.visibility_link"|translate}}
{{ 'visibility.visibility_link' | translate }}
</option>
<option value="per">
{{"visibility.visibility_nobody"|translate}}
{{ 'visibility.visibility_nobody' | translate }}
</option>
</select>
<label for="answer-visible">
{{"visibility.visibility_see"|translate}}
{{ 'visibility.visibility_see' | translate }}
</label>
</section>
<h3>{{"visibility.votes"|translate}}</h3>
<h3>{{ 'visibility.votes' | translate }}</h3>
<section>
<label for="vote-date">
{{"visibility.archiving"|translate}}
{{ 'visibility.archiving' | translate }}
</label>
<input type="date" name="vote-date">
<input type="date" name="vote-date" />
</section>
<section>
<label for="alter-vote">
{{"visibility.archiving_start"|translate}}
{{ 'visibility.archiving_start' | translate }}
</label>
<select name="alter-vote">
<option value="yes" selected>
{{"visibility.archiving_can"|translate}}
{{ 'visibility.archiving_can' | translate }}
</option>
<option value="no">
{{"visibility.archiving_can_not"|translate}}
{{ 'visibility.archiving_can_not' | translate }}
</option>
</select>
<label for="type-vote">
{{"visibility.archiving_end"|translate}}
{{ 'visibility.archiving_end' | translate }}
</label>
<select name="type-vote">
<option value="solo" selected>
{{"visibility.modfiy_their"|translate}}
{{ 'visibility.modfiy_their' | translate }}
</option>
<option value="all">
{{"visibility.modfiy_everyone"|translate}}
{{ 'visibility.modfiy_everyone' | translate }}
</option>
</select>
</section>
<label for="del-vote">
{{"admin.votes_deletion_desc"|translate}}
{{ 'admin.votes_deletion_desc' | translate }}
</label>
<button class="btn btn--alert btn--outline"
(click)="config.deleteVotes()"
>
<button class="btn btn--alert btn--outline" (click)="config.deleteVotes()">
<i class="fa fa-trash"></i>
{{'admin.votes_deletion_btn'|translate}}
<i class="fa fa-object-group"></i></button>
{{ 'admin.votes_deletion_btn' | translate }}
<i class="fa fa-object-group"></i>
</button>
<h3>{{"admin.comments_deletion_title"|translate}}</h3>
<h3>{{ 'admin.comments_deletion_title' | translate }}</h3>
<label for="del-com">
{{"admin.comments_deletion_desc"|translate}}
{{ 'admin.comments_deletion_desc' | translate }}
</label>
<button class="btn btn--alert btn--outline"
(click)="config.deleteComments()"
>
<button class="btn btn--alert btn--outline" (click)="config.deleteComments()">
<i class="fa fa-trash"></i>
{{'admin.comments_deletion_btn'|translate}}
<i class="fa fa-comments-o"></i></button>
{{ 'admin.comments_deletion_btn' | translate }}
<i class="fa fa-comments-o"></i>
</button>
<h3>{{"admin.archiving_title"|translate}}</h3>
<h3>{{ 'admin.archiving_title' | translate }}</h3>
<section class="row">
<label for="arch">
{{"admin.archiving_desc"|translate}}
{{ 'admin.archiving_desc' | translate }}
</label>
<input type="date" name="arch">
<input type="date" name="arch" />
</section>
<h3>{{"visibility.access"|translate}}</h3>
<h3>{{ 'visibility.access' | translate }}</h3>
<section class="row">
<label for="password">Je</label>
<select name="password">
<option value="yes" selected>
{{"visibility.access_want_yes"|translate}}
{{ 'visibility.access_want_yes' | translate }}
</option>
<option value="no">
{{"visibility.access_want_no"|translate}}
{{ 'visibility.access_want_no' | translate }}
</option>
</select>
<label for="alter-vote">
{{"visibility.access_protect"|translate}}
{{ 'visibility.access_protect' | translate }}
</label>
</section>
<h3>{{"admin.deletion"|translate}}</h3>
<label for="del"> {{"admin.deletion_desc"|translate}} </label>
<input class="btn btn--alert" type="submit"
name="del" value="{{'admin.deletion_btn'|translate}}">
<h3>{{ 'admin.deletion' | translate }}</h3>
<label for="del"> {{ 'admin.deletion_desc' | translate }} </label>
<input class="btn btn--alert" type="submit" name="del" value="{{ 'admin.deletion_btn' | translate }}" />
<!-- Access link -->
<h2>{{"admin.link"|translate}}</h2>
<h3>{{"admin.link_admin"|translate}}</h3>
<h2>{{ 'admin.link' | translate }}</h2>
<h3>{{ 'admin.link_admin' | translate }}</h3>
<label for="copy-link-admin">
{{"admin.link_admin_desc"|translate}}
{{ 'admin.link_admin_desc' | translate }}
https://framadate.org/urladmindusondage
</label>
<input class="btn btn--mini" type="submit" name="copy-link-admin"
value="{{'admin.copy_link'|translate}}">
<a href="#" class="next">{{"admin.link_admin_btn"|translate}}</a>
<input class="btn btn--mini" type="submit" name="copy-link-admin" value="{{ 'admin.copy_link' | translate }}" />
<a href="#" class="next">{{ 'admin.link_admin_btn' | translate }}</a>
<h3>{{"admin.polled_people"|translate}}</h3>
<h3>{{ 'admin.polled_people' | translate }}</h3>
<label for="copy-link">
{{"admin.polled_people_desc"|translate}}
{{config.urlPublic}}</label>
<input class="btn btn--mini" type="submit" name="copy-link"
value="{{'admin.copy_link'|translate}}">
<a href="#" class="next">{{"admin.polled_people_btn"|translate}}</a>
<h3>{{"admin.email_links"|translate}}</h3>
<label for="mail">{{"admin.email_links_desc"|translate}}</label>
<input type="email" name="mail">
<input class="btn btn--mini" type="submit" name="send-mail"
value="{{'admin.email_links_btn'|translate}}">
{{ 'admin.polled_people_desc' | translate }}
{{ config.urlPublic }}</label
>
<input class="btn btn--mini" type="submit" name="copy-link" value="{{ 'admin.copy_link' | translate }}" />
<a href="#" class="next">{{ 'admin.polled_people_btn' | translate }}</a>
<h3>{{ 'admin.email_links' | translate }}</h3>
<label for="mail">{{ 'admin.email_links_desc' | translate }}</label>
<input type="email" name="mail" />
<input class="btn btn--mini" type="submit" name="send-mail" value="{{ 'admin.email_links_btn' | translate }}" />
</form>
<p-confirmDialog header="Confirmation" icon="pi pi-exclamation-triangle"></p-confirmDialog>

View File

@ -1,39 +1,41 @@
form{
display:flex;
form {
display: flex;
flex-direction: column;
width:340px;
margin:auto;
width: 340px;
margin: auto;
}
.row{
.row {
flex-direction: row;
flex-wrap: wrap;
padding-bottom: 65px;
}
textarea{
height:115px;
textarea {
height: 115px;
margin-bottom: 50px;
}
label{
label {
padding-bottom: 10px;
flex-wrap: wrap;
}
h2,h1{
h2,
h1 {
margin-bottom: 40px;
}
h2{
h2 {
margin-top: 40px;
padding-left:16px;
padding-left: 16px;
}
.btn--alert{
.btn--alert {
font-weight: 600;
}
h3{
h3 {
padding-left: 28px;
padding-bottom:15px;
padding-bottom: 15px;
}
select,input[type=date]{
select,
input[type='date'] {
max-width: 130px;
}
.btn--outline{
.btn--outline {
margin-bottom: 70px;
}

View File

@ -8,9 +8,8 @@ describe('AdminComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AdminComponent ]
})
.compileComponents();
declarations: [AdminComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,17 +1,13 @@
import {Component, OnInit} from '@angular/core';
import {ConfigService} from '../../services/config.service';
import { Component, OnInit } from '@angular/core';
import { ConfigService } from '../../services/config.service';
@Component({
selector: 'framadate-admin',
templateUrl: './admin.component.html',
styleUrls: ['./admin.component.scss']
styleUrls: ['./admin.component.scss'],
})
export class AdminComponent implements OnInit {
constructor(public config: ConfigService) {}
constructor(public config: ConfigService) {
}
ngOnInit() {
}
ngOnInit() {}
}

View File

@ -1,102 +1,76 @@
<div class="answers" >
<h1 i18n >
<div class="answers">
<h1 i18n>
Choisir les propositions
</h1 >
</h1>
<p
class="subtitle"
i18n >
<p class="subtitle" i18n>
Vous pouvez utiliser la syntaxe markdown, et naviguer entre les inputs avec les flèches du clavier.
</p >
</p>
<ol >
<li
#answers
*ngFor="let answer of config.answers; index as i;trackBy trackFunction"
class="answer-item" >
<button
class='btn btn--default'
title='ajouter une image'
(click)='showModalForPictureOfAnswer(answer)' >
<i class='fa fa-image' ></i >
</button >
<label
for='answer_{{answer.id}}_url'
(click)='showModalForPictureOfAnswer(answer)' >
<ol>
<li #answers *ngFor="let answer of config.answers; index as i; trackBy: trackFunction" class="answer-item">
<button class="btn btn--default" title="ajouter une image" (click)="showModalForPictureOfAnswer(answer)">
<i class="fa fa-image"></i>
</button>
<label for="answer_{{ answer.id }}_url" (click)="showModalForPictureOfAnswer(answer)">
<img class="img-thumbnail" src="{{ answer.url }}" alt="image {{ answer.url }}" />
</label>
<p-dialog class="url-dialog" [(visible)]="display" [modal]="true">
<p-header>
{{ answer.text }}
</p-header>
<img
class='img-thumbnail'
src='{{answer.url}}'
alt='image {{answer.url}}' >
</label >
<p-dialog
class='url-dialog'
[(visible)]="display"
[modal]='true' >
<p-header >
{{answer.text}}
</p-header >
<form
action='#'
(submit)='display=false' >
<label for='answer_{{answer.id}}_url' >
<form action="#" (submit)="display = false">
<label for="answer_{{ answer.id }}_url">
Choisissez une URL pour illustrer le choix de réponse
</label >
<i class='fa fa-image' ></i >
<br >
</label>
<i class="fa fa-image"></i>
<br />
<input
class='input is-block'
id='answer_{{answer.id}}_url'
type='text'
autofocus='autofocus'
name='answer-url'
[(ngModel)]='answer.url' >
</form >
</p-dialog >
class="input is-block"
id="answer_{{ answer.id }}_url"
type="text"
autofocus="autofocus"
name="answer-url"
[(ngModel)]="answer.url"
/>
</form>
</p-dialog>
<input
type="name"
class="answer"
id='answer_{{answer.id}}'
id="answer_{{ answer.id }}"
[(ngModel)]="answer.text"
(keyup.enter)="addAnswer()"
(keyup)="navigateOrDelete($event,i)"
required='required'
(keyup)="navigateOrDelete($event, i)"
required="required"
placeholder="réponse"
>
<button
class="btn btn--alert"
(click)="config.answers.splice(i,1)" >X
</button >
</li >
</ol >
/>
<button class="btn btn--alert" (click)="config.answers.splice(i, 1)">X</button>
</li>
</ol>
<button
class="btn btn--primary btn--outline"
(click)="addAnswer()"
[ngClass]="{'btn--primary': allAnswersAreValid}"
[ngClass]="{ 'btn--primary': allAnswersAreValid }"
i18n
>
<i class='fa fa-plus' ></i >
<i class="fa fa-plus"></i>
Ajouter une proposition
</button >
<br >
</button>
<br />
<button
[routerLink]="'/step/resume'"
class="btn btn--full "
class="btn btn--full"
i18n
[ngClass]="{'btn--primary': allAnswersAreValid}"
[disabled]='!allAnswersAreValid'
[ngClass]="{ 'btn--primary': allAnswersAreValid }"
[disabled]="!allAnswersAreValid"
>
Voyons ce que ça donne
</button >
<br >
<a
[routerLink]="'/home'"
class="prev"
i18n >
</button>
<br />
<a [routerLink]="'/home'" class="prev" i18n>
Retour
</a >
</div >
</a>
</div>

View File

@ -8,9 +8,8 @@ describe('AnswersComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AnswersComponent ]
})
.compileComponents();
declarations: [AnswersComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,41 +1,36 @@
import {AfterViewInit, ChangeDetectorRef, Component, Inject, OnChanges, OnInit} from '@angular/core';
import {BaseComponent} from '../base-page/base.component';
import {ConfigService} from '../../services/config.service';
import { AfterViewInit, ChangeDetectorRef, Component, Inject, OnChanges, OnInit } from '@angular/core';
import { BaseComponent } from '../base-page/base.component';
import { ConfigService } from '../../services/config.service';
import {DOCUMENT} from '@angular/common';
import { DOCUMENT } from '@angular/common';
@Component({
selector: 'framadate-answers',
templateUrl: './answers.component.html',
styleUrls: ['./answers.component.scss']
styleUrls: ['./answers.component.scss'],
})
export class AnswersComponent extends BaseComponent implements OnInit, AfterViewInit, OnChanges {
allAnswersAreValid = false;
answerList = [];
currentHeader: any = "";
currentHeader: any = '';
display: boolean;
constructor(public config: ConfigService,
@Inject(DOCUMENT) private document: any,
private cd: ChangeDetectorRef) {
constructor(public config: ConfigService, @Inject(DOCUMENT) private document: any, private cd: ChangeDetectorRef) {
super(config);
this.answerList = this.config.answers;
}
// todo, manage validation of each page in a common way
ngOnInit() {
}
ngOnInit() {}
ngOnChanges() {
this.checkValidAnswers();
}
checkValidAnswers() {
this.allAnswersAreValid = true;
this.config.answers.forEach(answer => {
this.config.answers.forEach((answer) => {
if (!answer.text.length) {
this.allAnswersAreValid = false;
return;
@ -53,18 +48,17 @@ export class AnswersComponent extends BaseComponent implements OnInit, AfterView
}
addAnswer() {
this.config.answers.push(
{
this.config.answers.push({
id: this.config.answers.length + 1,
text: '',
url: '',
file: '',
literal: '',
date_object: null,
timeList: []
timeList: [],
});
this.cd.detectChanges(); // to refresh the view before focusing on the new input
this.focusOnAnswer(this.config.answers.length - 1)
this.focusOnAnswer(this.config.answers.length - 1);
}
focusOnAnswer(i) {
@ -79,13 +73,13 @@ export class AnswersComponent extends BaseComponent implements OnInit, AfterView
}
navigateOrDelete(event: KeyboardEvent, i) {
if (event.ctrlKey && event.key == "d") {
this.config.answers.splice(i, 1)
if (event.ctrlKey && event.key == 'd') {
this.config.answers.splice(i, 1);
}
if (event.key == "ArrowUp" && i > 0) {
if (event.key == 'ArrowUp' && i > 0) {
this.focusOnAnswer(i - 1);
}
if (event.key == "ArrowDown" && i < this.config.answers.length) {
if (event.key == 'ArrowDown' && i < this.config.answers.length) {
this.focusOnAnswer(i + 1);
}
}

View File

@ -1,4 +1,4 @@
<h1>Ce composant est celui de base pour les pages</h1>
<a [routerLink]="'/step/end'" class="btn btn-block" i18n="@@confirm">
{{"config.perfect"|translate}}
{{ 'config.perfect' | translate }}
</a>

View File

@ -8,9 +8,8 @@ describe('BaseComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BaseComponent ]
})
.compileComponents();
declarations: [BaseComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,22 +1,18 @@
import {Component, OnInit} from '@angular/core';
import {ConfigService} from '../../services/config.service';
import { Component, OnInit } from '@angular/core';
import { ConfigService } from '../../services/config.service';
@Component({
selector: 'framadate-base-page',
templateUrl: './base.component.html',
styleUrls: ['./base.component.scss']
styleUrls: ['./base.component.scss'],
})
/**
* base page is aware of the state of the filling
*/
export class BaseComponent implements OnInit {
constructor(public config: ConfigService) {}
constructor(public config: ConfigService) {
}
ngOnInit() {
}
ngOnInit() {}
checkValidity() {
// TODO with form controls

View File

@ -1,46 +1,33 @@
<div class="container" >
<div class="container">
<div class="columns">
<div class="column" id="newPoll">
<section class="creation" >
<h1 >
{{"creation.title"|translate}}
</h1 >
<p
class="description margin-btm-x5"
i18n >
{{"config.description"|translate}}
</p >
<div class="btn-next" >
<button
[routerLink]="'step/date'"
class="btn btn--full btn--primary" >
{{"config.letsgo"|translate}}
</button >
</div >
</section >
<section class="creation">
<h1>
{{ 'creation.title' | translate }}
</h1>
<p class="description margin-btm-x5" i18n>
{{ 'config.description' | translate }}
</p>
<div class="btn-next">
<button [routerLink]="'step/date'" class="btn btn--full btn--primary">
{{ 'config.letsgo' | translate }}
</button>
</div>
</section>
</div>
<div class="column" id="searchMyPolls">
<section class="recuperation" >
<h1 >
{{"config.find_my_polls"|translate}}
</h1 >
<form
(ngSubmit)="findMyPollsByEmail(config.myEmail)"
>
<label
class="description"
for="sendemail"
i18n
>
<i class='fa fa-envelope' ></i >
{{"config.find_helper"|translate}} :
</label >
<section class="recuperation">
<h1>
{{ 'config.find_my_polls' | translate }}
</h1>
<form (ngSubmit)="findMyPollsByEmail(config.myEmail)">
<label class="description" for="sendemail" i18n>
<i class="fa fa-envelope"></i>
{{ 'config.find_helper' | translate }} :
</label>
<input
[(ngModel)]="config.myEmail"
class='input'
class="input"
autofocus="autofocus"
id="sendemail"
name="mail"
@ -49,48 +36,36 @@
/>
<input
[disabled]="!config.myEmail || !config.myEmail.length"
[ngClass]="{'btn--primary': config.myEmail}"
[ngClass]="{ 'btn--primary': config.myEmail }"
class="btn btn--full"
id='sendemailbutton'
id="sendemailbutton"
i18n-value="'config.find_button'|translate"
type="submit"
/>
</form >
</section >
<section
class="list-my-polls"
*ngIf="!config.loading" >
<h2 >
</form>
</section>
<section class="list-my-polls" *ngIf="!config.loading">
<h2>
Mes Sondages trouvés:
</h2 >
<ul
class="poll-list"
*ngFor="let poll of config.myPolls ; index as i;trackBy trackFunction" >
<li >
<a href='{{poll.url}}' >
{{poll.title}}
<sub >
{{poll.description}}
</sub >
</a >
</li >
</ul >
</h2>
<ul class="poll-list" *ngFor="let poll of config.myPolls; index as i; trackBy: trackFunction">
<li>
<a href="{{ poll.url }}">
{{ poll.title }}
<sub>
{{ poll.description }}
</sub>
</a>
</li>
</ul>
<div
class="no-polls"
*ngIf="! config.myPolls || !config.myPolls.length" >
<div class="no-polls" *ngIf="!config.myPolls || !config.myPolls.length">
Aucun sondage.
</div >
</section >
<div
class="loading"
*ngIf="config.loading" >
<i class="fa fa-refresh fa-spin fa-3x fa-fw" ></i >
</div >
</div>
</section>
<div class="loading" *ngIf="config.loading">
<i class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
</div>
</div>
</div >
</div>
</div>

View File

@ -1,7 +1,7 @@
.container{
display:flex;
.container {
display: flex;
flex-direction: column;
margin:auto;
margin: auto;
}
h1 {
display: inline-block;
@ -9,7 +9,7 @@ h1 {
font-size: 2.6rem;
&::after {
content: "";
content: '';
display: block;
width: 27.4%;
height: 2px;
@ -18,10 +18,10 @@ h1 {
margin-left: auto;
// background-color: $primary_color;
}
}
label{
float:left;
}
input[type=email]{
display:block;
label {
float: left;
}
input[type='email'] {
display: block;
}

View File

@ -8,9 +8,8 @@ describe('CreateOrRetrieveComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CreateOrRetrieveComponent ]
})
.compileComponents();
declarations: [CreateOrRetrieveComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,17 +1,15 @@
import {Component, OnInit} from '@angular/core';
import {BaseComponent} from "../base-page/base.component";
import {ConfigService} from "../../services/config.service";
import { Component, OnInit } from '@angular/core';
import { BaseComponent } from '../base-page/base.component';
import { ConfigService } from '../../services/config.service';
@Component({
selector: 'framadate-create-or-retrieve',
templateUrl: './create-or-retrieve.component.html',
styleUrls: ['./create-or-retrieve.component.scss']
styleUrls: ['./create-or-retrieve.component.scss'],
})
export class CreateOrRetrieveComponent extends BaseComponent implements OnInit {
loadedMyPolls: boolean = false;
constructor(public config: ConfigService) {
super(config);
}
@ -20,12 +18,11 @@ export class CreateOrRetrieveComponent extends BaseComponent implements OnInit {
// if (!environment.production) {
// this.findMyPollsByEmail('tktest@tktest.com')
// }
}
findMyPollsByEmail(email: string) {
if (!email) {
return
return;
}
this.config.findPollsByEmail(email);
this.loadedMyPolls = true;
@ -33,5 +30,5 @@ export class CreateOrRetrieveComponent extends BaseComponent implements OnInit {
trackFunction(index: number, item: any): number {
return item.id;
};
}
}

View File

@ -1,223 +1,168 @@
<h1 class="title is-1" >
<i class="fa fa-calendar"></i> {{"dates.title"|translate}}
</h1 >
<h1 class="title is-1"><i class="fa fa-calendar"></i> {{ 'dates.title' | translate }}</h1>
<div >
<label for="multi_hours" >
<span >
{{"dates.hours_different"|translate}}
</span >
<select
[(ngModel)]="config.allowSeveralHours"
id="multi_hours"
name="multi_hours"
>
<option value=true >{{"dates.multiple.different"|translate}}</option >
<option value=false >{{"dates.multiple.identical"|translate}}</option >
</select >
<span i18n >
{{"dates.hours_each_day"|translate}}
</span >
</label >
</div >
<div>
<label for="multi_hours">
<span>
{{ 'dates.hours_different' | translate }}
</span>
<select [(ngModel)]="config.allowSeveralHours" id="multi_hours" name="multi_hours">
<option value="true">{{ 'dates.multiple.different' | translate }}</option>
<option value="false">{{ 'dates.multiple.identical' | translate }}</option>
</select>
<span i18n>
{{ 'dates.hours_each_day' | translate }}
</span>
</label>
</div>
<button (click)="addDate()" class="btn btn--primary" id="add_date_button">
<i class="fa fa-plus"></i>
{{ 'dates.add' | translate }}
</button>
<button
(click)="addDate()"
class="btn btn--primary"
id="add_date_button"
>
<i class='fa fa-plus' ></i >
{{"dates.add"|translate}}
</button >
<button
(click)="showDateInterval = !showDateInterval "
[ngClass]="{active: showDateInterval}"
(click)="showDateInterval = !showDateInterval"
[ngClass]="{ active: showDateInterval }"
class="btn btn--primary"
id="toggle_interval_button"
>
<i class='fa fa-clock-o' ></i >
{{"dates.add_interval"|translate}}
</button >
<i class="fa fa-clock-o"></i>
{{ 'dates.add_interval' | translate }}
</button>
<button
(click)="emptyAll()"
class="btn btn--warning"
id="empty_button"
>
<i class='fa fa-trash' ></i >
{{"dates.empty"|translate}}
</button >
<section
*ngIf="showDateInterval"
class="date-interval " >
<button (click)="emptyAll()" class="btn btn--warning" id="empty_button">
<i class="fa fa-trash"></i>
{{ 'dates.empty' | translate }}
</button>
<section *ngIf="showDateInterval" class="date-interval">
<!-- TODO à mettre en popup-->
<hr >
<h2 > {{"dates.add_interval"|translate}}</h2 >
<p >
{{"dates.interval_propose"|translate}}
<input
(change)="countDays()"
[(ngModel)]="startDateInterval"
type="date" >
{{"dates.interval_span"|translate}}
<input
(change)="countDays()"
[(ngModel)]="endDateInterval"
type="date" >
<br >
</p >
<button
(click)="addIntervalOfDates()"
class="btn btn-block btn--primary" >
<i class='fa fa-plus' ></i >
{{"dates.interval_button"|translate}}
{{intervalDays}}
{{"dates.interval_button_dates"|translate}}
</button >
<hr >
</section >
<div class='columns' >
<div class='column' >
<div class="dates-list " >
<div class='title' >
<span class="count-dates" >
{{config.timeList.length}}
</span >
<span class="count-dates-txt " >
{{"dates.count_time"|translate}}
<hr />
<h2>{{ 'dates.add_interval' | translate }}</h2>
<p>
{{ 'dates.interval_propose' | translate }}
<input (change)="countDays()" [(ngModel)]="startDateInterval" type="date" />
{{ 'dates.interval_span' | translate }}
<input (change)="countDays()" [(ngModel)]="endDateInterval" type="date" />
<br />
</p>
<button (click)="addIntervalOfDates()" class="btn btn-block btn--primary">
<i class="fa fa-plus"></i>
{{ 'dates.interval_button' | translate }}
{{ intervalDays }}
{{ 'dates.interval_button_dates' | translate }}
</button>
<hr />
</section>
<div class="columns">
<div class="column">
<div class="dates-list">
<div class="title">
<span class="count-dates">
{{ config.timeList.length }}
</span>
<span class="count-dates-txt">
{{ 'dates.count_time' | translate }}
(pour chaque jour)
</span >
</div >
<div class='actions' >
</span>
</div>
<div class="actions">
<button
(click)="addTime()"
*ngIf=" 'false' === config.allowSeveralHours "
*ngIf="'false' === config.allowSeveralHours"
class="btn btn--primary"
id="add_time_button"
>
<i class='fa fa-plus' ></i >
{{"dates.add_time"|translate}}
</button >
<i class="fa fa-plus"></i>
{{ 'dates.add_time' | translate }}
</button>
<button
(click)="removeAllTimes()"
*ngIf=" 'false' === config.allowSeveralHours "
*ngIf="'false' === config.allowSeveralHours"
class="btn btn--warning"
id="remove_time_button"
>
<i class='fa fa-trash' ></i >
<i class="fa fa-trash"></i>
Aucune plage horaire
</button >
</button>
<button
(click)="resetTimes()"
*ngIf=" 'false' === config.allowSeveralHours"
*ngIf="'false' === config.allowSeveralHours"
class="btn btn--warning"
id="reset_time_button"
>
<i class='fa fa-refresh' ></i >
<i class="fa fa-refresh"></i>
réinitialiser
</button >
</div >
</button>
</div>
<div
*ngIf=" 'false' === config.allowSeveralHours"
class="identical-dates"
>
<div
*ngFor="let time of config.timeList; index as id"
class="time-choice"
>
<label for='timeChoices_{{id}}' >
<i class='fa fa-clock-o' ></i >
</label >
<div *ngIf="'false' === config.allowSeveralHours" class="identical-dates">
<div *ngFor="let time of config.timeList; index as id" class="time-choice">
<label for="timeChoices_{{ id }}">
<i class="fa fa-clock-o"></i>
</label>
<input
[(ngModel)]="time.literal"
name="timeChoices_{{id}}"
name="timeChoices_{{ id }}"
type="text"
id='timeChoices_{{id}}'
>
<button
(click)="time.timeList.splice(id, 1)"
class="btn btn-warning" ><i class="fa fa-times" ></i >
</button >
</div >
</div >
<hr >
<span class="count-dates title" >
{{config.dateList.length}}
</span >
<span >
{{"dates.count_dates"|translate}}
</span >
<button
class='btn btn--primary'
(click)='addDate()' >
{{"dates.add"|translate}}
</button >
<div
*ngFor="let choice of config.dateList; index as id"
class="date-choice"
>
{{id}})
id="timeChoices_{{ id }}"
/>
<button (click)="time.timeList.splice(id, 1)" class="btn btn-warning">
<i class="fa fa-times"></i>
</button>
</div>
</div>
<hr />
<span class="count-dates title">
{{ config.dateList.length }}
</span>
<span>
{{ 'dates.count_dates' | translate }}
</span>
<button class="btn btn--primary" (click)="addDate()">
{{ 'dates.add' | translate }}
</button>
<div *ngFor="let choice of config.dateList; index as id" class="date-choice">
{{ id }})
<input
[(ngModel)]="choice.date_object"
name="dateChoices_{{id}}"
id="dateChoices_{{id}}"
name="dateChoices_{{ id }}"
id="dateChoices_{{ id }}"
useValueAsDate
type="date"
>
<button
(click)="config.dateList.splice(id, 1)"
class="btn btn-warning"
><i class="fa fa-times" ></i >
</button >
/>
<button (click)="config.dateList.splice(id, 1)" class="btn btn-warning">
<i class="fa fa-times"></i>
</button>
<button
(click)="addTimeToDate(choice, id)"
*ngIf=" 'true' === config.allowSeveralHours"
*ngIf="'true' === config.allowSeveralHours"
class="btn btn--primary"
>
{{"dates.add_time"|translate}}
</button >
<div
*ngIf=" 'true' === config.allowSeveralHours"
class="several-times"
>
<div
*ngFor="let timeItem of choice.timeList; index as idTime"
class="time-choice"
>
{{ 'dates.add_time' | translate }}
</button>
<div *ngIf="'true' === config.allowSeveralHours" class="several-times">
<div *ngFor="let timeItem of choice.timeList; index as idTime" class="time-choice">
<input
[(ngModel)]="timeItem.literal"
name="dateTime_{{id}}_Choices_{{idTime}}"
id="dateTime_{{id}}_Choices_{{idTime}}"
name="dateTime_{{ id }}_Choices_{{ idTime }}"
id="dateTime_{{ id }}_Choices_{{ idTime }}"
type="text"
>
<button
(click)="choice.timeList.splice(idTime, 1)"
class="btn btn-warning"
><i class="fa fa-times" ></i >
</button >
</div >
</div >
</div >
</div >
</div >
<div class='column' >
<framadate-resume ></framadate-resume >
</div >
</div >
/>
<button (click)="choice.timeList.splice(idTime, 1)" class="btn btn-warning">
<i class="fa fa-times"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="column">
<framadate-resume></framadate-resume>
</div>
</div>
<a
[routerLink]="'/step/resume'"
class="btn btn--full btn--primary"
>
<a [routerLink]="'/step/resume'" class="btn btn--full btn--primary">
C'est parfait!
</a >
<a
[routerLink]="'/step/home'"
class="prev"
>
</a>
<a [routerLink]="'/step/home'" class="prev">
Retour
</a >
</a>

View File

@ -12,10 +12,10 @@
}
:host {
input, button {
input,
button {
+ button {
margin-left: 1em;
}
}
}

View File

@ -8,9 +8,8 @@ describe('DatesComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DatesComponent ]
})
.compileComponents();
declarations: [DatesComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,15 +1,15 @@
import {ChangeDetectorRef, Component, Inject, OnInit} from '@angular/core';
import {ConfigService} from '../../services/config.service';
import {BaseComponent} from '../base-page/base.component';
import {DOCUMENT} from '@angular/common';
import {MessageService} from "primeng/api";
import {otherDefaultDates} from "../../config/defaultConfigs";
import {DateUtilities} from "../../config/DateUtilities";
import { ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core';
import { ConfigService } from '../../services/config.service';
import { BaseComponent } from '../base-page/base.component';
import { DOCUMENT } from '@angular/common';
import { MessageService } from 'primeng/api';
import { otherDefaultDates } from '../../config/defaultConfigs';
import { DateUtilities } from '../../config/DateUtilities';
@Component({
selector: 'framadate-dates',
templateUrl: './dates.component.html',
styleUrls: ['./dates.component.scss']
styleUrls: ['./dates.component.scss'],
})
export class DatesComponent extends BaseComponent implements OnInit {
showDateInterval: boolean = false;
@ -18,7 +18,8 @@ export class DatesComponent extends BaseComponent implements OnInit {
intervalDaysDefault: number = 7;
endDateInterval: any;
constructor(public config: ConfigService,
constructor(
public config: ConfigService,
private cd: ChangeDetectorRef,
private messageService: MessageService,
private dateUtilities: DateUtilities,
@ -30,7 +31,7 @@ export class DatesComponent extends BaseComponent implements OnInit {
countDays() {
// compute the number of days in the date interval
if (this.endDateInterval && this.startDateInterval) {
this.intervalDays = (this.dateUtilities.dayDiff(this.endDateInterval, this.startDateInterval)).toFixed(0)
this.intervalDays = this.dateUtilities.dayDiff(this.endDateInterval, this.startDateInterval).toFixed(0);
}
}
@ -41,14 +42,17 @@ export class DatesComponent extends BaseComponent implements OnInit {
let 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.endDateInterval = this.dateUtilities
.addDaysToDate(this.intervalDaysDefault, dateCurrent)
.toISOString()
.substring(0, 10);
}
addDate() {
this.config.dateList.push({
literal: '',
date_object: new Date(),
timeList: []
timeList: [],
});
let selector = '[ng-reflect-name="dateChoices_' + (this.config.dateList.length - 1) + '"]';
this.cd.detectChanges();
@ -62,13 +66,11 @@ export class DatesComponent extends BaseComponent implements OnInit {
* change time spans
*/
addTime() {
this.config.timeList.push(
{
this.config.timeList.push({
literal: '',
timeList: [],
date_object: new Date()
}
);
date_object: new Date(),
});
}
removeAllTimes() {
@ -79,7 +81,6 @@ export class DatesComponent extends BaseComponent implements OnInit {
this.config.timeList = otherDefaultDates;
}
/**
* add a time period to a specific date choice,
* focus on the new input
@ -87,7 +88,7 @@ export class DatesComponent extends BaseComponent implements OnInit {
* @param id
*/
addTimeToDate(config: any, id: number) {
config.timeList.push({literal: ''});
config.timeList.push({ literal: '' });
let selector = '[ng-reflect-name="dateTime_' + id + '_Choices_' + (config.timeList.length - 1) + '"]';
this.cd.detectChanges();
const elem = this.document.querySelector(selector);
@ -100,17 +101,16 @@ export class DatesComponent extends BaseComponent implements OnInit {
* remove all input contents, does not reset to default
*/
emptyAll() {
this.config.dateList.forEach(element => {
this.config.dateList.forEach((element) => {
element.literal = '';
element.date_object = new Date();
element.timeList = ['', '', ''];
});
this.config.timeList.forEach(element => {
this.config.timeList.forEach((element) => {
element.literal = '';
});
}
/**
* add all the dates between the start and end dates in the interval section
*/
@ -118,11 +118,11 @@ export class DatesComponent extends BaseComponent implements OnInit {
let newIntervalArray = this.dateUtilities.getDatesInRange(this.startDateInterval, this.endDateInterval, 1);
const converted = [];
newIntervalArray.forEach(element => {
newIntervalArray.forEach((element) => {
converted.push({
literal: element.literal,
date_object: element.date_object,
timeList: []
timeList: [],
});
});
this.config.dateList = [...new Set(converted)]; // add only dates that are not already present with a Set of unique items
@ -131,10 +131,7 @@ export class DatesComponent extends BaseComponent implements OnInit {
this.messageService.add({
severity: 'success',
summary: 'Dates ajoutées',
detail: `les dates ont été ajoutées aux réponses possibles`
detail: `les dates ont été ajoutées aux réponses possibles`,
});
}
}

View File

@ -1,74 +1,56 @@
<h1 i18n >
{{"resume.title"|translate}}
</h1 >
<section class="admin" >
<h2 i18n >{{"resume.admins"|translate}}</h2 >
<p >
<h1 i18n>
{{ 'resume.title' | translate }}
</h1>
<section class="admin">
<h2 i18n>{{ 'resume.admins' | translate }}</h2>
<p>
Votre sondage «
<span class="poll-title">
{{ config.title }}
</span>
» a bien été créé !
</p>
<p>
Voici les liens daccès au sondage, conservez-les soigneusement ! (Si vous les perdez vous pourrez toujours les
recevoir par email)
</p>
Votre sondage « 
<span class="poll-title" >
{{config.title}}
</span >
 » a bien été créé !
</p >
<p >
Voici les liens daccès au sondage, conservez-les soigneusement !
(Si vous les perdez vous pourrez toujours les recevoir par email)
</p >
<p >
<p>
Pour accéder au sondage et à tous ses paramètres :
<a href="{{config.urlAdmin}}" >{{config.urlAdmin}}
</a >
</p >
<framadate-copy-text [textToCopy]='config.urlAdmin' ></framadate-copy-text >
<a href="{{config.urlAdmin}}" >
<a href="{{ config.urlAdmin }}">{{ config.urlAdmin }} </a>
</p>
<framadate-copy-text [textToCopy]="config.urlAdmin"></framadate-copy-text>
<a href="{{ config.urlAdmin }}">
Voir le sondage coté administrateur·ice
</a >
<p class="note" >
Note : Le sondage sera supprimé {{config.deletionDateAfterLastModification}} jours après la date de sa dernière
modification.
</p >
</section >
<section class="public" >
<h2 i18n >{{"resume.users"|translate}}</h2 >
<p >
</a>
<p class="note">
Note : Le sondage sera supprimé {{ config.deletionDateAfterLastModification }} jours après la date de sa
dernière modification.
</p>
</section>
<section class="public">
<h2 i18n>{{ 'resume.users' | translate }}</h2>
<p>
Pour accéder au sondage :
<a href="{{config.urlPublic}}" >{{config.urlPublic}}
</a >
</p >
<framadate-copy-text [textToCopy]='config.urlPublic' ></framadate-copy-text >
<a href="{{config.urlPublic}}" >
<a href="{{ config.urlPublic }}">{{ config.urlPublic }} </a>
</p>
<framadate-copy-text [textToCopy]="config.urlPublic"></framadate-copy-text>
<a href="{{ config.urlPublic }}">
Voir le sondage
</a >
</section >
<section class="mail" >
</a>
</section>
<section class="mail">
<h2 i18n>{{ 'resume.links_mail' | translate }}</h2>
<p>
Pour être sur de retrouver ces liens, nous pouvons vous les envoyer sur votre mail mail :
<input type="email" [(ngModel)]="mailToRecieve" paceholder="email" />
</p>
<h2 i18n >{{"resume.links_mail"|translate}}</h2 >
<p >
Pour être sur de retrouver ces liens, nous pouvons vous les envoyer sur votre mail
mail :
<input
type="email"
[(ngModel)]="mailToRecieve"
paceholder="email"
>
</p >
<button
class="btn btn--primary"
(click)="sendToEmail()"
><i class="fa fa-paper-plane" ></i >
<button class="btn btn--primary" (click)="sendToEmail()">
<i class="fa fa-paper-plane"></i>
Envoyer les liens du sondage
</button >
<a href="{{config.urlPublic}}" >
</button>
<a href="{{ config.urlPublic }}">
Voir le sondage
</a >
</section >
</a>
</section>

View File

@ -8,9 +8,8 @@ describe('EndConfirmationComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ EndConfirmationComponent ]
})
.compileComponents();
declarations: [EndConfirmationComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,37 +1,31 @@
import {Component, OnInit} from '@angular/core';
import {BaseComponent} from '../base-page/base.component';
import {HttpClient} from '@angular/common/http';
import {ConfigService} from "../../services/config.service";
import {MessageService} from 'primeng/api';
import { Component, OnInit } from '@angular/core';
import { BaseComponent } from '../base-page/base.component';
import { HttpClient } from '@angular/common/http';
import { ConfigService } from '../../services/config.service';
import { MessageService } from 'primeng/api';
@Component({
selector: 'framadate-end-confirmation',
templateUrl: './end-confirmation.component.html',
styleUrls: ['./end-confirmation.component.scss']
styleUrls: ['./end-confirmation.component.scss'],
})
export class EndConfirmationComponent extends BaseComponent implements OnInit {
mailToRecieve = '';
constructor(public config: ConfigService,
public http: HttpClient,
private messageService: MessageService
) {
constructor(public config: ConfigService, public http: HttpClient, private messageService: MessageService) {
super(config);
this.mailToRecieve = this.config.myEmail;
}
ngOnInit() {
}
ngOnInit() {}
copyLink(str: any) {
this.messageService.add({
severity: 'success',
summary: 'Lien copié',
detail: str
detail: str,
});
}
sendToEmail() {
}
sendToEmail() {}
}

View File

@ -1,84 +1,58 @@
<div class="description" >
<router-outlet ></router-outlet >
<div class="description">
<router-outlet></router-outlet>
<h1 i18n >
{{"creation.title"|translate}}
</h1 >
<span
class="pre-selector"
i18n
>
{{"creation.want"|translate}}
</span >
<button
(click)='config.resetConfig()'
class='btn btn--warning' >
<h1 i18n>
{{ 'creation.title' | translate }}
</h1>
<span class="pre-selector" i18n>
{{ 'creation.want' | translate }}
</span>
<button (click)="config.resetConfig()" class="btn btn--warning">
Reset all
</button >
<select
[(ngModel)]="config.pollType"
autofocus="autofocus"
id="selector"
name='polltype'
>
<option
value="dates"
name='polltype_date' >
{{"creation.kind.date"|translate}}
</option >
<option
value="classic"
name='polltype_classic' >
{{"creation.kind.classic"|translate}}
</option >
</select >
</button>
<select [(ngModel)]="config.pollType" autofocus="autofocus" id="selector" name="polltype">
<option value="dates" name="polltype_date">
{{ 'creation.kind.date' | translate }}
</option>
<option value="classic" name="polltype_classic">
{{ 'creation.kind.classic' | translate }}
</option>
</select>
<span class="post-selector" >
</span >
<span class="post-selector"> </span>
<div >
<label
class="title-label"
for="poll_title"
i18n
>
{{"creation.choose_title"|translate}}
</label >
<div>
<label class="title-label" for="poll_title" i18n>
{{ 'creation.choose_title' | translate }}
</label>
<input
[(ngModel)]="config.title"
id="poll_title"
name="poll_title"
placeholder="{{'creation.choose_title_placeholder'|translate}}"
placeholder="{{ 'creation.choose_title_placeholder' | translate }}"
type="name"
>
<framadate-erasable-input [(inputModel)]="config.title" ></framadate-erasable-input >
</div >
/>
<framadate-erasable-input [(inputModel)]="config.title"></framadate-erasable-input>
</div>
<div >
<label for="my_name" >
{{"creation.name"|translate}} :
</label >
<div>
<label for="my_name"> {{ 'creation.name' | translate }} : </label>
<input
[(ngModel)]="config.myName"
id="my_name"
name="my_name"
placeholder="{{'creation.name_placeholder'|translate}}"
placeholder="{{ 'creation.name_placeholder' | translate }}"
type="name"
>
<framadate-erasable-input [(inputModel)]="config.myName" ></framadate-erasable-input >
</div >
/>
<framadate-erasable-input [(inputModel)]="config.myName"></framadate-erasable-input>
</div>
<div >
<label
class="title-label"
for="poll_description"
i18n
>
{{"creation.description"|translate}}:
<framadate-erasable-input [(inputModel)]="config.description" ></framadate-erasable-input >
</label >
<br >
<div>
<label class="title-label" for="poll_description" i18n>
{{ 'creation.description' | translate }}:
<framadate-erasable-input [(inputModel)]="config.description"></framadate-erasable-input>
</label>
<br />
<textarea
[(ngModel)]="config.description"
cols="50"
@ -86,12 +60,12 @@
lines="5"
name="poll_description"
placeholder="description"
></textarea >
</div >
<div >
<label for="email" >
></textarea>
</div>
<div>
<label for="email">
Mon email pour administrer le sondage est
</label >
</label>
<input
[(ngModel)]="config.myEmail"
autofocus="autofocus"
@ -100,33 +74,19 @@
required="required"
type="email"
/>
<framadate-erasable-input [(inputModel)]="config.myEmail" ></framadate-erasable-input >
</div >
<framadate-erasable-input [(inputModel)]="config.myEmail"></framadate-erasable-input>
</div>
<button
[routerLink]="'/step/answers'"
class="btn btn--primary btn--full"
*ngIf="config.pollType == 'classic'"
i18n
>
<button [routerLink]="'/step/answers'" class="btn btn--primary btn--full" *ngIf="config.pollType == 'classic'" i18n>
Continuer
<i class='fa fa-file-text' ></i >
</button >
<button
[routerLink]="'/step/date'"
class="btn btn--primary btn--full"
*ngIf="config.pollType == 'dates'"
i18n
>
<i class="fa fa-file-text"></i>
</button>
<button [routerLink]="'/step/date'" class="btn btn--primary btn--full" *ngIf="config.pollType == 'dates'" i18n>
Continuer
<i class='fa fa-calendar-check-o' ></i >
</button >
<a
[routerLink]="'/step/creation'"
class="prev"
i18n
>
<i class="fa fa-calendar-check-o"></i>
</button>
<a [routerLink]="'/step/creation'" class="prev" i18n>
Retour
</a >
<hr >
</div >
</a>
<hr />
</div>

View File

@ -8,9 +8,8 @@ describe('HomeComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HomeComponent ]
})
.compileComponents();
declarations: [HomeComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,20 +1,17 @@
import {Component, OnInit} from '@angular/core';
import {ConfigService} from "../../services/config.service";
import {BaseComponent} from "../base-page/base.component";
import { Component, OnInit } from '@angular/core';
import { ConfigService } from '../../services/config.service';
import { BaseComponent } from '../base-page/base.component';
@Component({
selector: 'framadate-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
styleUrls: ['./home.component.scss'],
})
export class HomeComponent extends BaseComponent implements OnInit {
nextStep = '/step/answers';
constructor(public config: ConfigService) {
super(config);
}
ngOnInit() {
}
ngOnInit() {}
}

View File

@ -1,343 +1,265 @@
<h1 >page de démo</h1 >
<p >cette étape est en cours de développement. <br > S'inspirer de la page de Home pour réaliser d'autres pages
</p >
<a
[routerLink]="'/step/end'"
class="btn btn--primary"
i18n="@@confirm" >C'est parfait!</a >
<h1 >Atoms</h1 >
<section >
<article >
<h2 >Headings</h2 >
<h1>page de démo</h1>
<p>
cette étape est en cours de développement. <br />
S'inspirer de la page de Home pour réaliser d'autres pages
</p>
<a [routerLink]="'/step/end'" class="btn btn--primary" i18n="@@confirm">C'est parfait!</a>
<h1>Atoms</h1>
<section>
<article>
<h2>Headings</h2>
<h1 >Ceci est un h1</h1 >
<h2 >Ceci est un h2</h2 >
<h3 >Ceci est un h3</h3 >
</article >
<h1>Ceci est un h1</h1>
<h2>Ceci est un h2</h2>
<h3>Ceci est un h3</h3>
</article>
<article >
<h2 >Links</h2 >
<div >
<a
[routerLink]="'/home'"
class="next" >
<span
class="text"
i18n >
<article>
<h2>Links</h2>
<div>
<a [routerLink]="'/home'" class="next">
<span class="text" i18n>
C'est parti !
</span >
</a >
</div >
<div >
<a
[routerLink]="'/home'"
class="prev" >
<span
class="text"
i18n >
</span>
</a>
</div>
<div>
<a [routerLink]="'/home'" class="prev">
<span class="text" i18n>
C'est parti !
</span >
</a >
</div >
</article >
</span>
</a>
</div>
</article>
<article >
<h2 >Buttons</h2 >
<article>
<h2>Buttons</h2>
<button
type="submit"
class="btn btn--primary" >
<button type="submit" class="btn btn--primary">
primary - default
</button >
</button>
<br >
<br />
<button
type="submit"
class="btn btn--primary btn--small" >
<button type="submit" class="btn btn--primary btn--small">
primary - small
</button >
</button>
<br >
<br />
<a
href="#"
class="btn btn--primary btn--outline" >
<a href="#" class="btn btn--primary btn--outline">
primary - outline - default
</a >
</a>
<br >
<br />
<button
type="submit"
class="btn btn--primary btn--outline btn--small" >
<button type="submit" class="btn btn--primary btn--outline btn--small">
primary - outline - small
</button >
</button>
<br >
<br />
<input
type="submit"
class="btn btn--alert"
value="alert - default" >
<input type="submit" class="btn btn--alert" value="alert - default" />
<br >
<br />
<button
type="submit"
class="btn btn--alert btn--small" >
<button type="submit" class="btn btn--alert btn--small">
alert - small
</button >
</button>
<br >
<br />
<button
type="submit"
class="btn btn--alert btn--outline" >
<button type="submit" class="btn btn--alert btn--outline">
alert - outline - default
</button >
</button>
<br >
<br />
<button
type="submit"
class="btn btn--alert btn--outline btn--small" >
<button type="submit" class="btn btn--alert btn--outline btn--small">
alert - outline - small
</button >
</button>
<br ><br >
<br /><br />
<button
type="submit"
class="btn btn--primary btn--full" >
<button type="submit" class="btn btn--primary btn--full">
primary - full
</button >
</button>
<button
type="submit"
class="btn btn--primary btn--outline btn--full" >
<button type="submit" class="btn btn--primary btn--outline btn--full">
primary - outline - full
</button >
</button>
<button
type="submit"
class="btn btn--alert btn--full" >
<button type="submit" class="btn btn--alert btn--full">
alert - full
</button >
</button>
<button
type="submit"
class="btn btn--alert btn--outline btn--full" >
<button type="submit" class="btn btn--alert btn--outline btn--full">
alert - outline - full
</button >
</button>
</article>
</article >
<article>
<h2>Forms element</h2>
<article >
<h2 >Forms element</h2 >
<h3>Labels</h3>
<h3 >Labels</h3 >
<label for="">Un label pour les labelliser tous</label>
<label for="" >Un label pour les labelliser tous</label >
<h3>Input name</h3>
<input type="name" name="" id="" /><br />
<input type="name" name="" id="" value="texte" />
<h3 >Input name</h3 >
<input
type="name"
name=""
id="" ><br >
<input
type="name"
name=""
id=""
value="texte" >
<h3>Input email</h3>
<input type="email" name="" id="" /><br />
<input type="email" name="" id="" value="adresse@email.com" />
<h3 >Input email</h3 >
<input
type="email"
name=""
id="" ><br >
<input
type="email"
name=""
id=""
value="adresse@email.com" >
<h3>Input password</h3>
<input type="password" name="" id="" /><br />
<input type="password" name="" id="" value="password" />
<h3 >Input password</h3 >
<input
type="password"
name=""
id="" ><br >
<input
type="password"
name=""
id=""
value="password" >
<h3>Input date</h3>
<input type="date" name="" id="" /><br />
<input type="date" name="" id="" value="1985-11-23" />
<h3 >Input date</h3 >
<input
type="date"
name=""
id="" ><br >
<input
type="date"
name=""
id=""
value="1985-11-23" >
<h3 >Select</h3 >
<select
name=""
id="" >
<option value="" >
<h3>Select</h3>
<select name="" id="">
<option value="">
1
</option >
<option value="" >
</option>
<option value="">
2
</option >
<option value="" >
</option>
<option value="">
3
</option >
</select >
</option>
</select>
<h3 >Textarea</h3 >
<textarea
name=""
id=""
cols="30"
rows="10" ></textarea >
</article >
<h3>Textarea</h3>
<textarea name="" id="" cols="30" rows="10"></textarea>
</article>
<article >
<h2 >Paragraphs</h2 >
<article>
<h2>Paragraphs</h2>
<p >Lorem, ipsum dolor sit amet consectetur adipisicing elit. Magnam perspiciatis minus libero error dolores.
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Magnam perspiciatis minus libero error dolores.
Corrupti repellat vero repellendus reiciendis assumenda minus. Nobis, quaerat ut nihil minima sed animi
delectus beatae!</p >
</article >
delectus beatae!
</p>
</article>
<article >
<h2 >Lists</h2 >
<article>
<h2>Lists</h2>
<h3 >Unordered list</h3 >
<ul >
<li >
<h3>Unordered list</h3>
<ul>
<li>
plop
</li >
<li >
</li>
<li>
plop
</li >
<li >
</li>
<li>
plop
</li >
</ul >
</li>
</ul>
<h3 >Ordered list</h3 >
<ol >
<li >
<h3>Ordered list</h3>
<ol>
<li>
plop
</li >
<li >
</li>
<li>
plop
</li >
<li >
</li>
<li>
plop
</li >
</ol >
</article >
</li>
</ol>
</article>
<article >
<h2 >Images</h2 >
<img
src="http://placekitten.com/200/300"
alt="" >
</article >
</section >
<article>
<h2>Images</h2>
<img src="http://placekitten.com/200/300" alt="" />
</article>
</section>
<section >
<h1 >Molecules</h1 >
<framadate-voting-choice ></framadate-voting-choice >
<article >
<h2 >Useful classes</h2 >
<section>
<h1>Molecules</h1>
<framadate-voting-choice></framadate-voting-choice>
<article>
<h2>Useful classes</h2>
<h3 >Align right</h3 >
<div class="align-right" >
<a
[routerLink]="'/home'"
class="next" >
<span
class="text"
i18n >
<h3>Align right</h3>
<div class="align-right">
<a [routerLink]="'/home'" class="next">
<span class="text" i18n>
C'est parti !
</span >
</a >
</div >
</article >
</span>
</a>
</div>
</article>
<article >
<h2 >Label + input name</h2 >
<label for="test-text" >Ceci est un label un peu long mais pas trop</label >
<input
type="name"
name="test-text"
id="test-text" >
</article >
<article>
<h2>Label + input name</h2>
<label for="test-text">Ceci est un label un peu long mais pas trop</label>
<input type="name" name="test-text" id="test-text" />
</article>
<article >
<h2 >Label + select</h2 >
<label for="test-select" >Ceci est un label un peu long mais pas trop</label >
<select
name="test-select"
id="test-select" >
<option value="" >
<article>
<h2>Label + select</h2>
<label for="test-select">Ceci est un label un peu long mais pas trop</label>
<select name="test-select" id="test-select">
<option value="">
1
</option >
<option value="" >
</option>
<option value="">
2
</option >
<option value="" >
</option>
<option value="">
3
</option >
</select >
</article >
</option>
</select>
</article>
<article >
<h2 >Input name with info</h2 >
<a href="https://sketch.cloud/s/00A80/a/MAl5q7" >like here</a >
</article >
<article>
<h2>Input name with info</h2>
<a href="https://sketch.cloud/s/00A80/a/MAl5q7">like here</a>
</article>
<article >
<h2 >Commentaries</h2 >
</article >
</section >
<article>
<h2>Commentaries</h2>
</article>
</section>
<section >
<h1 >Components</h1 >
<section>
<h1>Components</h1>
<article >
<h2 >Images list</h2 >
<a href="https://sketch.cloud/s/00A80/a/bQA9wj" >that</a >
</article >
<article>
<h2>Images list</h2>
<a href="https://sketch.cloud/s/00A80/a/bQA9wj">that</a>
</article>
<article >
<h2 >Calendar</h2 >
</article >
<article>
<h2>Calendar</h2>
</article>
<article >
<h2 >Modale</h2 >
</article >
<article>
<h2>Modale</h2>
</article>
<article >
<h2 >Way to vote</h2 >
<a href="https://sketch.cloud/s/00A80/a/Ol0598" >that</a >
</article >
<article>
<h2>Way to vote</h2>
<a href="https://sketch.cloud/s/00A80/a/Ol0598">that</a>
</article>
<article >
<h2 >Voted</h2 >
<a href="https://sketch.cloud/s/00A80/a/OlJZo2" >that</a >
</article >
<article>
<h2>Voted</h2>
<a href="https://sketch.cloud/s/00A80/a/OlJZo2">that</a>
</article>
<article >
<h2 >Graphics</h2 >
<a href="https://sketch.cloud/s/00A80/a/megprw" >that</a >
</article >
</section >
<article>
<h2>Graphics</h2>
<a href="https://sketch.cloud/s/00A80/a/megprw">that</a>
</article>
</section>

View File

@ -8,7 +8,6 @@ section {
+ section {
margin: 0 !important;
}
}
article {

View File

@ -8,9 +8,8 @@ describe('KindComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ KindComponent ]
})
.compileComponents();
declarations: [KindComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,19 +1,16 @@
import {Component, OnInit} from '@angular/core';
import {BaseComponent} from '../base-page/base.component';
import {ConfigService} from '../../services/config.service';
import { Component, OnInit } from '@angular/core';
import { BaseComponent } from '../base-page/base.component';
import { ConfigService } from '../../services/config.service';
@Component({
selector: 'framadate-page-kind',
templateUrl: './kind.component.html',
styleUrls: ['./kind.component.scss']
styleUrls: ['./kind.component.scss'],
})
export class KindComponent extends BaseComponent implements OnInit {
constructor(public config: ConfigService) {
super(config);
}
ngOnInit() {
}
ngOnInit() {}
}

View File

@ -4,9 +4,9 @@
<form>
<label for="password">Mot de passe :</label>
<section class="row">
<input class="margin-btm-x5" type="password" name="password">
<input type="submit" name="view" value="Voir" class="btn btn--small btn--purple">
<input class="margin-btm-x5" type="password" name="password" />
<input type="submit" name="view" value="Voir" class="btn btn--small btn--purple" />
</section>
<input type="submit" name="go" value="Accéder au sondage" class="btn btn--primary btn--full btn--semi-bold">
<input type="submit" name="go" value="Accéder au sondage" class="btn btn--primary btn--full btn--semi-bold" />
</form>

View File

@ -1,12 +1,12 @@
form{
display:flex;
form {
display: flex;
flex-direction: column;
}
label{
label {
font-weight: 600;
font-size: 18px;
}
h1{
display:flex;
h1 {
display: flex;
align-self: center;
}

View File

@ -8,9 +8,8 @@ describe('PasswordComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PasswordComponent ]
})
.compileComponents();
declarations: [PasswordComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,19 +1,16 @@
import { Component, OnInit } from '@angular/core';
import {BaseComponent} from "../base-page/base.component";
import {ConfigService} from "../../services/config.service";
import { BaseComponent } from '../base-page/base.component';
import { ConfigService } from '../../services/config.service';
@Component({
selector: 'framadate-password',
templateUrl: './password.component.html',
styleUrls: ['./password.component.scss']
styleUrls: ['./password.component.scss'],
})
export class PasswordComponent extends BaseComponent implements OnInit {
constructor(public config: ConfigService) {
super(config);
}
ngOnInit() {
}
ngOnInit() {}
}

View File

@ -3,4 +3,3 @@
Images
</h1>
<a [routerLink]="'/step/visibility'" class="btn btn--primary">ok</a>

View File

@ -8,9 +8,8 @@ describe('PicturesComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PicturesComponent ]
})
.compileComponents();
declarations: [PicturesComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,19 +1,16 @@
import {Component, OnInit} from '@angular/core';
import {ConfigService} from '../../services/config.service';
import {BaseComponent} from '../base-page/base.component';
import { Component, OnInit } from '@angular/core';
import { ConfigService } from '../../services/config.service';
import { BaseComponent } from '../base-page/base.component';
@Component({
selector: 'framadate-pictures',
templateUrl: './pictures.component.html',
styleUrls: ['./pictures.component.scss']
styleUrls: ['./pictures.component.scss'],
})
export class PicturesComponent extends BaseComponent implements OnInit {
constructor(public config: ConfigService) {
super(config);
}
ngOnInit() {
}
ngOnInit() {}
}

View File

@ -1,87 +1,67 @@
<div
class="poll"
>
<button
class='btn btn--primary'
(click)='config.execStuff()'
*ngIf='config.isAdmin' >
<div class="poll">
<button class="btn btn--primary" (click)="config.execStuff()" *ngIf="config.isAdmin">
launch admin action execStuff !
</button >
<button
class='btn btn--primary'
(click)='config.exportJson()'
*ngIf='config.isAdmin' >
</button>
<button class="btn btn--primary" (click)="config.exportJson()" *ngIf="config.isAdmin">
<i class="fa fa-file-archive-o"></i>
export CSV
</button >
</button>
<div
class='loading'
*ngIf='config.loading' >
<i class='fa fa-refresh fa-spin' ></i >
</div >
<div
class='loaded-poll'
*ngIf='!config.loading && config.currentPoll' >
<div id='choices' >
<framadate-choices-list ></framadate-choices-list >
</div >
<div id='table' >
<div class="loading" *ngIf="config.loading">
<i class="fa fa-refresh fa-spin"></i>
</div>
<div class="loaded-poll" *ngIf="!config.loading && config.currentPoll">
<div id="choices">
<framadate-choices-list></framadate-choices-list>
</div>
<div id="table">
<!-- <framadate-voting-navigation ></framadate-voting-navigation >-->
<framadate-voting-summary ></framadate-voting-summary >
</div >
<div id='poll_comments' >
<framadate-comments-list ></framadate-comments-list >
</div >
<div id='graph' >
<framadate-voting-summary></framadate-voting-summary>
</div>
<div id="poll_comments">
<framadate-comments-list></framadate-comments-list>
</div>
<div id="graph">
<!--<framadate-voting-graph ></framadate-voting-graph >-->
</div >
<div id='export_and_share' >
</div>
<div id="export_and_share">
<div class="sharing" *ngIf="config.currentPoll">
<h3 class="margin-top-x8">
Partager le sondage
<div
class="sharing"
*ngIf='config.currentPoll' >
<h3 class="margin-top-x8" >Partager le sondage
<i class="fa fa-share"></i>
</h3>
<p class="nobold text-14" for="copyLink">
Pour partager le sondage, vous pouvez diffuser ce lien :
<a href="{{ config.currentPoll.urlPublic }}">
{{ config.currentPoll.urlPublic }}
</a>
</p>
<i class='fa fa-share' ></i ></h3 >
<p
class="nobold text-14"
for="copyLink" >Pour partager le sondage, vous pouvez diffuser ce lien :
<a href='{{config.currentPoll.urlPublic}}' >
{{config.currentPoll.urlPublic}}
</a >
</p >
<framadate-copy-text [textToCopy]='config.currentPoll.urlPublic' ></framadate-copy-text >
<h3 class="margin-top-x6 margin-btm-x3" >
<framadate-copy-text [textToCopy]="config.currentPoll.urlPublic"></framadate-copy-text>
<h3 class="margin-top-x6 margin-btm-x3">
Exporter/Imprimer
</h3 >
</h3>
<input
type="submit"
name="export"
class="margin-btm-x3 btn btn--primary btn--outline"
value="Exporter en .csv"
(click)="config.exportCSV()" >
(click)="config.exportCSV()"
/>
<input
type="submit"
name="copy-link"
class="btn btn--primary btn--outline"
value="Imprimer le sondage"
(click)="config.print()" >
</div >
</div >
</div >
<div
class='badly-loaded'
*ngIf='config.loading && !config.currentPoll' >
<div class='well is-warning' >
(click)="config.print()"
/>
</div>
</div>
</div>
<div class="badly-loaded" *ngIf="config.loading && !config.currentPoll">
<div class="well is-warning">
No current poll available
</div >
</div >
</div >
</div>
</div>
</div>

View File

@ -1,3 +1 @@
@import "../../../assets/scss/variables";
@import '../../../assets/scss/variables';

View File

@ -8,9 +8,8 @@ describe('PollDisplayComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PollDisplayComponent ]
})
.compileComponents();
declarations: [PollDisplayComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,25 +1,22 @@
import {Component, OnInit} from '@angular/core';
import {BaseComponent} from "../base-page/base.component";
import {ConfigService} from "../../services/config.service";
import {mockComments} from "../../config/mocks/mock-comments";
import {ActivatedRoute, Router} from "@angular/router";
import {environment} from "../../../environments/environment";
import {mockPoll3} from "../../config/mocks/mock-poll3";
import { Component, OnInit } from '@angular/core';
import { BaseComponent } from '../base-page/base.component';
import { ConfigService } from '../../services/config.service';
import { mockComments } from '../../config/mocks/mock-comments';
import { ActivatedRoute, Router } from '@angular/router';
import { environment } from '../../../environments/environment';
import { mockPoll3 } from '../../config/mocks/mock-poll3';
@Component({
selector: 'framadate-poll-display',
templateUrl: './poll-display.component.html',
styleUrls: ['./poll-display.component.scss']
styleUrls: ['./poll-display.component.scss'],
})
export class PollDisplayComponent extends BaseComponent implements OnInit {
comments = mockComments;
constructor(public config: ConfigService,
private router: Router,
public activeRoute: ActivatedRoute) {
constructor(public config: ConfigService, private router: Router, public activeRoute: ActivatedRoute) {
super(config);
this.activeRoute.paramMap.subscribe(params => {
this.activeRoute.paramMap.subscribe((params) => {
console.log('params', params);
this.config.pollId = params.get('poll');
this.config.pollSlug = params.get('pollSlug');
@ -29,10 +26,7 @@ export class PollDisplayComponent extends BaseComponent implements OnInit {
});
}
ngOnInit() {
}
ngOnInit() {}
// fetch poll with its ID or slug.
fetchPoll() {
@ -52,10 +46,11 @@ export class PollDisplayComponent extends BaseComponent implements OnInit {
console.log('res', res);
this.config.updateCurrentPollFromResponse(res);
this.config.loading = false;
}, (e) => {
},
(e) => {
// handle need for a password
console.log('e', e);
this.config.handleError(e)
this.config.handleError(e);
}
);
} else if (pollSlug) {
@ -64,13 +59,12 @@ export class PollDisplayComponent extends BaseComponent implements OnInit {
(res: any) => {
this.config.loading = false;
this.config.updateCurrentPollFromResponse(res);
}, (e) => {
},
(e) => {
// handle need for a password
this.config.handleError(e)
this.config.handleError(e);
}
);
}
}
}

View File

@ -1,113 +1,71 @@
<h1 >
<h1>
Récapitulatif
</h1 >
<div class='card content' >
<h2 class="hero-title title" >
{{config.title}}
</h2 >
<div class="creation" >
</h1>
<div class="card content">
<h2 class="hero-title title">
{{ config.title }}
</h2>
<div class="creation">
créé par
<i class='pseudo' >
{{config.myName}}
</i >
</div >
<div class="description" >
<cite >
{{config.description}}
</cite >
</div >
<section
class='preview type-classic'
*ngIf='config.pollType == "classic"' >
<ul >
<li
markdown
*ngFor="let questions of config.answers" >
<img
class='img-thumbnail'
src='{{questions.url}}'
alt='image {{questions.url}}' >
{{questions.id + 1}}. {{questions.text}}
</li >
</ul >
</section >
<section
class='type-date'
*ngIf='config.pollType !== "classic"' >
<i class='fa fa-clock-o' ></i >
<span
class='well'
*ngIf="'true' === config.allowSeveralHours" >
{{"dates.multiple.different"|translate}}
</span >
<span
class='well'
*ngIf="'false' === config.allowSeveralHours" >
{{"dates.multiple.identical"|translate}}
</span >
<div
*ngFor="let choice of config.dateList; index as id"
class="date-choice"
>
<div
class='only-one-slice'
*ngIf='!choice.timeList.length' >
<i class='fa fa-square-o' ></i >
</div >
{{choice.literal}}
<i class="pseudo">
{{ config.myName }}
</i>
</div>
<div class="description">
<cite>
{{ config.description }}
</cite>
</div>
<section class="preview type-classic" *ngIf="config.pollType == 'classic'">
<ul>
<li markdown *ngFor="let questions of config.answers">
<img class="img-thumbnail" src="{{ questions.url }}" alt="image {{ questions.url }}" />
{{ questions.id + 1 }}. {{ questions.text }}
</li>
</ul>
</section>
<section class="type-date" *ngIf="config.pollType !== 'classic'">
<i class="fa fa-clock-o"></i>
<span class="well" *ngIf="'true' === config.allowSeveralHours">
{{ 'dates.multiple.different' | translate }}
</span>
<span class="well" *ngIf="'false' === config.allowSeveralHours">
{{ 'dates.multiple.identical' | translate }}
</span>
<div *ngFor="let choice of config.dateList; index as id" class="date-choice">
<div class="only-one-slice" *ngIf="!choice.timeList.length">
<i class="fa fa-square-o"></i>
</div>
{{ choice.literal }}
<!-- CASE different slices of the day-->
<div
*ngIf="'true' === config.allowSeveralHours"
class="several-times"
>
<div
*ngFor="let time of choice.timeList ; index as idTime"
class="time-choice"
>
{{idTime}})
<i class='fa fa-square-o' ></i >
{{time.literal}}
</div >
</div >
<div *ngIf="'true' === config.allowSeveralHours" class="several-times">
<div *ngFor="let time of choice.timeList; index as idTime" class="time-choice">
{{ idTime }})
<i class="fa fa-square-o"></i>
{{ time.literal }}
</div>
</div>
<!-- CASE all dates having the same slices of the day-->
<div
*ngIf="'false' === config.allowSeveralHours"
class="same-times"
>
<div
*ngFor="let time of config.timeList "
class="time-choice"
>
<i class='fa fa-square-o' ></i >
{{time.literal}}
</div >
</div >
</div >
</section >
<div *ngIf="'false' === config.allowSeveralHours" class="same-times">
<div *ngFor="let time of config.timeList" class="time-choice">
<i class="fa fa-square-o"></i>
{{ time.literal }}
</div>
</div>
</div>
</section>
</div>
</div >
<button
[routerLink]="'/step/visibility'"
class="btn btn--primary btn--full" >
<button [routerLink]="'/step/visibility'" class="btn btn--primary btn--full">
C'est parfait!
</button >
</button>
<div class="back" >
<a
*ngIf='config.pollType == "classic"'
[routerLink]="'/step/answers'"
class="prev" >
<div class="back">
<a *ngIf="config.pollType == 'classic'" [routerLink]="'/step/answers'" class="prev">
Retour
</a >
<a
*ngIf='config.pollType == "dates"'
[routerLink]="'/step/date'"
class="prev" >
</a>
<a *ngIf="config.pollType == 'dates'" [routerLink]="'/step/date'" class="prev">
Retour
</a >
</div >
</a>
</div>

View File

@ -8,9 +8,8 @@ describe('ResumeComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ResumeComponent ]
})
.compileComponents();
declarations: [ResumeComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,18 +1,15 @@
import {Component} from '@angular/core';
import {BaseComponent} from '../base-page/base.component';
import {ConfigService} from '../../services/config.service';
import {Router} from "@angular/router";
import { Component } from '@angular/core';
import { BaseComponent } from '../base-page/base.component';
import { ConfigService } from '../../services/config.service';
import { Router } from '@angular/router';
@Component({
selector: 'framadate-resume',
templateUrl: './resume.component.html',
styleUrls: ['./resume.component.scss']
styleUrls: ['./resume.component.scss'],
})
export class ResumeComponent extends BaseComponent {
constructor(public config: ConfigService,
private router: Router) {
constructor(public config: ConfigService, private router: Router) {
super(config);
}
}

View File

@ -1,195 +1,163 @@
<h1 i18n >
{{"visibility.top_txt"|translate}}
</h1 >
<section class="answers" >
<h2 >
{{"visibility.title"|translate}}
</h2 >
<span >
{{"visibility.visibility_want"|translate}}
</span >
<select
name="visible_people"
id="visible_people"
[(ngModel)]="config.visibility"
>
<option value="link_only" >
{{"visibility.visibility_link"|translate}}
</option >
<option value="only_me" >
{{"visibility.visibility_nobody"|translate}}
</option >
</select >
<span >
{{"visibility.visibility_see"|translate}}
</span >
</section >
<section class="possible_votes" >
<h2 >
{{"visibility.votes"|translate}}
</h2 >
<label for="votes" >
{{"visibility.votes_possible"|translate}}
</label >
<select
name="votes"
id="votes"
[(ngModel)]="config.voteChoices"
>
<option value="only_yes" >
{{"visibility.votes_possible_single"|translate}}
</option >
<option value="normal" >
{{"visibility.votes_possible_normal"|translate}}
</option >
<option value="full" >
{{"visibility.votes_possible_full"|translate}}
</option >
</select >
</section >
<section class="expiracy" >
<label for="expirationDate" >
{{"visibility.archiving"|translate}}
</label >
<input
type="date"
id="expirationDate"
[(ngModel)]="config.expirationDate" >
<div class="modification" >
<label for="modificationAbility" >
{{"visibility.archiving_start"|translate}}
</label >
<select
name="modificationAbility"
id="modificationAbility"
[(ngModel)]="config.canModifyAnswers" >
<option value=true >
{{"visibility.archiving_can"|translate}}
</option >
<option value=false >
{{"visibility.archiving_can_not"|translate}}
</option >
</select >
<span *ngIf=" config.canModifyAnswers == false">
{{"visibility.archiving_end_not"|translate}}
<h1 i18n>
{{ 'visibility.top_txt' | translate }}
</h1>
<section class="answers">
<h2>
{{ 'visibility.title' | translate }}
</h2>
<span>
{{ 'visibility.visibility_want' | translate }}
</span>
<span class="can_modify_votes" *ngIf="config.canModifyAnswers== true ">
<label for="modificationScope">
{{"visibility.archiving_end"|translate}}
<select name="visible_people" id="visible_people" [(ngModel)]="config.visibility">
<option value="link_only">
{{ 'visibility.visibility_link' | translate }}
</option>
<option value="only_me">
{{ 'visibility.visibility_nobody' | translate }}
</option>
</select>
<span>
{{ 'visibility.visibility_see' | translate }}
</span>
</section>
<section class="possible_votes">
<h2>
{{ 'visibility.votes' | translate }}
</h2>
<label for="votes">
{{ 'visibility.votes_possible' | translate }}
</label>
<span *ngIf="false == !!config.canModifyAnswers" >
{{"visibility.modfiy_their"|translate}}
</span >
<select name="votes" id="votes" [(ngModel)]="config.voteChoices">
<option value="only_yes">
{{ 'visibility.votes_possible_single' | translate }}
</option>
<option value="normal">
{{ 'visibility.votes_possible_normal' | translate }}
</option>
<option value="full">
{{ 'visibility.votes_possible_full' | translate }}
</option>
</select>
</section>
<section class="expiracy">
<label for="expirationDate">
{{ 'visibility.archiving' | translate }}
</label>
<input type="date" id="expirationDate" [(ngModel)]="config.expirationDate" />
<div class="modification">
<label for="modificationAbility">
{{ 'visibility.archiving_start' | translate }}
</label>
<select name="modificationAbility" id="modificationAbility" [(ngModel)]="config.canModifyAnswers">
<option value="true">
{{ 'visibility.archiving_can' | translate }}
</option>
<option value="false">
{{ 'visibility.archiving_can_not' | translate }}
</option>
</select>
<span *ngIf="config.canModifyAnswers == false">
{{ 'visibility.archiving_end_not' | translate }}
</span>
<span class="can_modify_votes" *ngIf="config.canModifyAnswers == true">
<label for="modificationScope">
{{ 'visibility.archiving_end' | translate }}
</label>
<span *ngIf="false == !!config.canModifyAnswers">
{{ 'visibility.modfiy_their' | translate }}
</span>
<select
name="modificationScope"
id="modificationScope"
*ngIf="true == !!config.canModifyAnswers"[(ngModel)]="config.whoModifiesAnswers"
[disabled]="false == !!config.canModifyAnswers">
*ngIf="true == !!config.canModifyAnswers"
[(ngModel)]="config.whoModifiesAnswers"
[disabled]="false == !!config.canModifyAnswers"
>
<option value="self">
{{"visibility.modfiy_their"|translate}}
{{ 'visibility.modfiy_their' | translate }}
</option>
<option value="everybody">
{{"visibility.modfiy_everyone"|translate}}
{{ 'visibility.modfiy_everyone' | translate }}
</option>
</select>
</span>
</div>
</section>
<section class="access">
<h2 class="title">
{{ 'visibility.access' | translate }}
</h2>
<label for="url">
{{ 'visibility.access_url' | translate }}
<br />
{{ 'visibility.access_url_key' | translate }}
</label>
<br />
<input type="name" class="input-lg" name="url" id="url" [(ngModel)]="config.customUrl" />
</div >
<sub class="instructions">
{{ 'visibility.access_instructions' | translate }}
</sub>
<div class="preview-url">
<a [href]="'/#/vote/poll/slug/' + config.customUrl">
{{ environment.baseHref + '#/vote/poll/slug/' + config.customUrl }}
</a>
<framadate-copy-text [textToCopy]="config.urlPublic"></framadate-copy-text>
</div>
<br />
<label for="passwordAccess">
{{ 'visibility.access_want' | translate }}
</label>
<select name="passwordAccess" id="passwordAccess" [(ngModel)]="config.passwordAccess">
<option value="0"> {{ 'visibility.access_want_no' | translate }}</option>
<option value="1"> {{ 'visibility.access_want_yes' | translate }}</option>
</select>
</section >
<section class="access" >
<h2 class='title' >
{{"visibility.access"|translate}}
</h2 >
<label for="url" >
{{"visibility.access_url"|translate}}
<br >
{{"visibility.access_url_key"|translate}}
</label >
<br >
<input
type="name"
class="input-lg"
name="url"
id="url"
[(ngModel)]="config.customUrl" >
<label for="password">
{{ 'visibility.access_protect' | translate }}
</label>
<sub class="instructions" >
{{"visibility.access_instructions"|translate}}
</sub >
<div class="preview-url" >
<a [href]="'/#/vote/poll/slug/' + config.customUrl" >
{{environment.baseHref + '#/vote/poll/slug/' + config.customUrl}}
</a >
<framadate-copy-text [textToCopy]='config.urlPublic' ></framadate-copy-text >
</div >
<br >
<label for="passwordAccess" >
{{"visibility.access_want"|translate}}
</label >
<select
name="passwordAccess"
id="passwordAccess"
[(ngModel)]="config.passwordAccess" >
<option value="0" > {{"visibility.access_want_no"|translate}}</option >
<option value="1" > {{"visibility.access_want_yes"|translate}}</option >
</select >
<label for="password" >
{{"visibility.access_protect"|translate}}
</label >
<div
class="enablepassword"
*ngIf="config.passwordAccess == 1" >
<div class="enablepassword" *ngIf="config.passwordAccess == 1">
<input
type="password"
name="password"
id="password"
min="8"
*ngIf="!showCustomPassword"
[(ngModel)]="config.password" >
[(ngModel)]="config.password"
/>
<input
type="name"
name="password_visible"
id="password_visible"
min="8"
*ngIf="showCustomPassword"
[(ngModel)]="config.password" >
[(ngModel)]="config.password"
/>
<button
(click)="showCustomPassword = !showCustomPassword"
[disabled]="!config.password"
class="btn btn--default" >
<i class="fa fa-eye" ></i >
{{"visibility.see_pass"|translate}}
</button >
</div >
</section >
class="btn btn--default"
>
<i class="fa fa-eye"></i>
{{ 'visibility.see_pass' | translate }}
</button>
</div>
</section>
<button
(click)='submitCreationAndGoToEnd()'
class="btn btn--primary btn--full"
i18n="@@confirm" >
{{"visibility.validate_btn"|translate}}
<i
class='fa fa-paper-plane'
*ngIf="!config.loading" ></i >
<span
class="loading"
*ngIf="config.loading" >
<i class="fa fa-refresh fa-spin fa-fw" ></i >
</span >
</button >
<button (click)="submitCreationAndGoToEnd()" class="btn btn--primary btn--full" i18n="@@confirm">
{{ 'visibility.validate_btn' | translate }}
<i class="fa fa-paper-plane" *ngIf="!config.loading"></i>
<span class="loading" *ngIf="config.loading">
<i class="fa fa-refresh fa-spin fa-fw"></i>
</span>
</button>
<div class="back" >
<a
[routerLink]="'/step/answers'"
class="prev" >
<div class="back">
<a [routerLink]="'/step/answers'" class="prev">
Retour
</a >
</div >
</a>
</div>

View File

@ -8,9 +8,8 @@ describe('VisibilityComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ VisibilityComponent ]
})
.compileComponents();
declarations: [VisibilityComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,31 +1,32 @@
import {Component, OnInit} from '@angular/core';
import {BaseComponent} from '../base-page/base.component';
import {ConfigService} from '../../services/config.service';
import {environment} from "../../../environments/environment";
import {PollUtilities} from "../../config/PollUtilities";
import { Component, OnInit } from '@angular/core';
import { BaseComponent } from '../base-page/base.component';
import { ConfigService } from '../../services/config.service';
import { environment } from '../../../environments/environment';
import { PollUtilities } from '../../config/PollUtilities';
@Component({
selector: 'framadate-visibility',
templateUrl: './visibility.component.html',
styleUrls: ['./visibility.component.scss']
styleUrls: ['./visibility.component.scss'],
})
export class VisibilityComponent extends BaseComponent implements OnInit {
showCustomPassword = false;
baseUrl = environment.baseApiHref;
environment = environment;
constructor(public config: ConfigService,
public utils: PollUtilities) {
constructor(public config: ConfigService, public utils: PollUtilities) {
super(config);
}
ngOnInit() {
this.config.customUrl = this.utils.makeSlug(this.config);
this.config.expirationDate = (this.config.addDaysToDate(this.config.expiracyDateDefaultInDays, new Date())).toISOString().substring(0, 10);
this.config.expirationDate = this.config
.addDaysToDate(this.config.expiracyDateDefaultInDays, new Date())
.toISOString()
.substring(0, 10);
}
submitCreationAndGoToEnd() {
this.config.createPoll();
}
}

View File

@ -1,27 +1,26 @@
<div
*ngIf='config.currentPoll'
class="list-of-choices" >
<div *ngFor="let choice of config.currentPoll.choices" >
<div *ngIf="config.currentPoll" class="list-of-choices">
<div *ngFor="let choice of config.currentPoll.choices">
<framadate-voting-choice
[choice]="choice"
[choices_count]="config.currentPoll.choices_count"
[pollIsSpecialDate]="config.currentPoll.poll.kind == 'date'"
[poll]='config.currentPoll' ></framadate-voting-choice >
</div >
</div >
[poll]="config.currentPoll"
></framadate-voting-choice>
</div>
</div>
<button
class='btn btn-block submit-votestack'
(click)='config.addVote()'
[disabled]='!config.myTempVoteStack'
[ngClass]='{"btn--primary" : config.myTempVoteStack } '
*ngIf='!config.myVoteStack || !config.myVoteStack.id' >
<i class='fa fa-paper-plane' ></i > Envoyer
</button >
class="btn btn-block submit-votestack"
(click)="config.addVote()"
[disabled]="!config.myTempVoteStack"
[ngClass]="{ 'btn--primary': config.myTempVoteStack }"
*ngIf="!config.myVoteStack || !config.myVoteStack.id"
>
<i class="fa fa-paper-plane"></i> Envoyer
</button>
<button
class='btn btn--primary btn-block submit-votestack update'
(click)='config.updateVote(config.myVoteStack)'
*ngIf='config.myVoteStack && config.myVoteStack.id' >
<i class='fa fa-pencil' ></i > Mettre à jour
</button >
class="btn btn--primary btn-block submit-votestack update"
(click)="config.updateVote(config.myVoteStack)"
*ngIf="config.myVoteStack && config.myVoteStack.id"
>
<i class="fa fa-pencil"></i> Mettre à jour
</button>

View File

@ -8,9 +8,8 @@ describe('ChoicesListComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ChoicesListComponent ]
})
.compileComponents();
declarations: [ChoicesListComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,15 +1,11 @@
import {Component} from '@angular/core';
import {ConfigService} from "../../../services/config.service";
import { Component } from '@angular/core';
import { ConfigService } from '../../../services/config.service';
@Component({
selector: 'framadate-choices-list',
templateUrl: './choices-list.component.html',
styleUrls: ['./choices-list.component.scss']
styleUrls: ['./choices-list.component.scss'],
})
export class ChoicesListComponent {
constructor(public config: ConfigService) {
}
constructor(public config: ConfigService) {}
}

View File

@ -1,61 +1,34 @@
<section class="name" >
<label for="name" >
<i class='fa fa-user' ></i >
Votre nom :</label >
<input
type="text"
name="name"
id="name"
[(ngModel)]="config.myName" >
<input
type="text"
name="name"
id="email"
[(ngModel)]="config.myEmail" >
<i class='fa fa-envelope' ></i >
</section >
<div
class="comments"
id='comments' >
<h2 class="margin-top-x7" >Laisser un commentaire</h2 >
<label for="crname" >Votre nom :</label >
<input
type="text"
class="margin-btm-x3"
name="crname"
[(ngModel)]='config.myName'
id="crname" >
<input
type="text"
name="cremail"
id="email_comment"
[(ngModel)]="config.myEmail" >
<label for='email_comment' >
<i class='fa fa-envelope' ></i >
</label >
<div >
<label for="comment" >Votre commentaire :</label >
<br >
<textarea
name="comment"
id="comment"
[(ngModel)]='config.myComment'
<section class="name">
<label for="name">
<i class="fa fa-user"></i>
Votre nom :</label
>
</textarea >
</div >
<input type="text" name="name" id="name" [(ngModel)]="config.myName" />
<input type="text" name="name" id="email" [(ngModel)]="config.myEmail" />
<i class="fa fa-envelope"></i>
</section>
<div class="comments" id="comments">
<h2 class="margin-top-x7">Laisser un commentaire</h2>
<label for="crname">Votre nom :</label>
<input type="text" class="margin-btm-x3" name="crname" [(ngModel)]="config.myName" id="crname" />
<input type="text" name="cremail" id="email_comment" [(ngModel)]="config.myEmail" />
<label for="email_comment">
<i class="fa fa-envelope"></i>
</label>
<div>
<label for="comment">Votre commentaire :</label>
<br />
<textarea name="comment" id="comment" [(ngModel)]="config.myComment"> </textarea>
</div>
<input
type="submit"
name="add-comment"
class="btn btn--primary btn--outline"
value="Ajouter mon commentaire"
(click)='config.addComment()' >
<div
class='comments-part'
*ngIf='config.currentPoll' >
<framadate-voting-comment
[comment]="c"
*ngFor="let c of config.currentPoll.comments " >
</framadate-voting-comment >
</div >
</div >
(click)="config.addComment()"
/>
<div class="comments-part" *ngIf="config.currentPoll">
<framadate-voting-comment [comment]="c" *ngFor="let c of config.currentPoll.comments">
</framadate-voting-comment>
</div>
</div>

View File

@ -1,13 +1,13 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {CommentsListComponent} from './comments-list.component';
import {FormsModule} from "@angular/forms";
import {HttpClient, HttpClientModule} from "@angular/common/http";
import {BrowserModule} from "@angular/platform-browser";
import {CommonModule} from "@angular/common";
import {ConfirmationService, MessageService} from "primeng";
import {Router} from "@angular/router";
import {ConfigService} from "../../../services/config.service";
import { CommentsListComponent } from './comments-list.component';
import { FormsModule } from '@angular/forms';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { ConfirmationService, MessageService } from 'primeng';
import { Router } from '@angular/router';
import { ConfigService } from '../../../services/config.service';
const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);
@ -17,18 +17,16 @@ describe('CommentsListComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [FormsModule,
BrowserModule,
CommonModule,
HttpClientModule],
declarations: [CommentsListComponent,]
, providers: [HttpClient,
imports: [FormsModule, BrowserModule, CommonModule, HttpClientModule],
declarations: [CommentsListComponent],
providers: [
HttpClient,
MessageService,
ConfirmationService,
ConfigService,
{provide: Router, useValue: routerSpy}]
})
.compileComponents();
{ provide: Router, useValue: routerSpy },
],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,15 +1,11 @@
import {Component} from '@angular/core';
import {ConfigService} from "../../../services/config.service";
import { Component } from '@angular/core';
import { ConfigService } from '../../../services/config.service';
@Component({
selector: 'framadate-comments-list',
templateUrl: './comments-list.component.html',
styleUrls: ['./comments-list.component.scss']
styleUrls: ['./comments-list.component.scss'],
})
export class CommentsListComponent {
constructor(public config: ConfigService) {
}
constructor(public config: ConfigService) {}
}

View File

@ -1,171 +1,142 @@
<div class="choicebox selection-{{choice.answer}}" >
<div class="choicebox selection-{{ choice.answer }}">
<!-- add .choicebox--active to most voted -->
<button
*ngIf='showChangeChoicebutton'
class='btn btn--primary'
(click)=' choice.simpleAnswer = !choice.simpleAnswer' >
<i class='fa fa-gears' ></i >
</button >
*ngIf="showChangeChoicebutton"
class="btn btn--primary"
(click)="choice.simpleAnswer = !choice.simpleAnswer"
>
<i class="fa fa-gears"></i>
</button>
<div class="choicebox__subject" >
<div class='columns' >
<div class='column' >
<div
class="text title clickable"
(click)="setAnswserTo('yes')" >
{{choice.text}}
</div > <!-- TEXT CASE --><!--
<div class="choicebox__subject">
<div class="columns">
<div class="column">
<div class="text title clickable" (click)="setAnswserTo('yes')">
{{ choice.text }}
</div>
<!-- TEXT CASE --><!--
<p class="choicebox__txt">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Nulla nobis nam culpa !
</p>
--><!-- TEXT CASE -->
<!-- IMG CASE -->
<img
*ngIf='choice.url'
class="choicebox__img"
[src]="choice.url"
alt="{{choice.url}}"
>
<img *ngIf="choice.url" class="choicebox__img" [src]="choice.url" alt="{{ choice.url }}" />
<!-- IMG CASE -->
<!-- DATE CASE -->
<div
class="dates"
*ngIf="pollIsSpecialDate" >
<div class="choicebox__date" >
{{choice.date.date | date:'EEE'}} <span
class="choicebox__day" >{{choice.date.date | date:'dd'}}</span > {{choice.date.date | date:'LLL'}}
</div >
<div class="choicebox__hour" >
{{choice.date.date | date:'H:m'}}
</div >
</div >
<div class="dates" *ngIf="pollIsSpecialDate">
<div class="choicebox__date">
{{ choice.date.date | date: 'EEE' }}
<span class="choicebox__day">{{ choice.date.date | date: 'dd' }}</span>
{{ choice.date.date | date: 'LLL' }}
</div>
<div class="choicebox__hour">
{{ choice.date.date | date: 'H:m' }}
</div>
</div>
<!-- DATE CASE -->
</div >
<div class='column' >
<div class="choicebox__actions" >
</div>
<div class="column">
<div class="choicebox__actions">
<!-- show only the yes check if the config is set to simpleAnswer -->
<!-- add .choicebox__btn--active to selected <button> -->
<span class="simple-answer" >
<span class="simple-answer">
<button
class="choicebox__btn choicebox__btn--yes"
type="button"
[ngClass]="{'choicebox__btn--active': choice.answer === 'yes'}"
(click)="setAnswserTo('yes')" >
<img
src="../../../assets/img/check.svg"
alt="" >
</button >
</span >
<span
class="complex-answers"
*ngIf="!simpleAnswer" >
[ngClass]="{ 'choicebox__btn--active': choice.answer === 'yes' }"
(click)="setAnswserTo('yes')"
>
<img src="../../../assets/img/check.svg" alt="" />
</button>
</span>
<span class="complex-answers" *ngIf="!simpleAnswer">
<button
class="choicebox__btn choicebox__btn--maybe"
type="button"
[ngClass]="{'choicebox__btn--active': choice.answer === 'maybe'}"
(click)="setAnswserTo('maybe')" >
<img
src="../../../assets/img/check-2.svg"
alt="" >
</button >
[ngClass]="{ 'choicebox__btn--active': choice.answer === 'maybe' }"
(click)="setAnswserTo('maybe')"
>
<img src="../../../assets/img/check-2.svg" alt="" />
</button>
<button
class="choicebox__btn choicebox__btn--no"
type="button"
[ngClass]="{'choicebox__btn--active': choice.answer === 'no'}"
[ngClass]="{ 'choicebox__btn--active': choice.answer === 'no' }"
(click)="setAnswserTo('no')"
>
<img
src="../../../assets/img/croix.svg"
alt="" >
</button >
</span >
</div >
</div >
<div class='column' >
<div class="choicebox__count" >
<div
class='no-votes'
*ngIf='! poll.choices_count.counts[choice.id] ' >
<img src="../../../assets/img/croix.svg" alt="" />
</button>
</span>
</div>
</div>
<div class="column">
<div class="choicebox__count">
<div class="no-votes" *ngIf="!poll.choices_count.counts[choice.id]">
aucun vote
</div >
</div>
<button
type="button"
aria-describedby="choicebox-tooltip"
class="choicebox__votes"
*ngIf="poll.choices_count && choice && poll.choices_count.counts[choice.id]" >
<div class="choicebox__vote" >
{{poll.choices_count.counts[choice.id].yes.count}}
<img
width="20px"
height="21px"
src="../../../assets/img/votant-sur.svg"
alt="" >
</div >
<div class="choicebox__vote" >
{{poll.choices_count.counts[choice.id].maybe.count}}
<img
width="22px"
height="24px"
src="../../../assets/img/votant-pas-sur.svg"
alt="" >
</div >
<div
class="choicebox__tooltip"
id="choicebox-tooltip" >
<div class="choicebox__tooltiplist" >
<div class="choicebox__tooltipttl" >
<img
width="20px"
height="21px"
src="../../../assets/img/votant-sur.svg"
alt="" >
{{poll.choices_count.counts[choice.id].yes.count}} "Oui"
</div >
*ngIf="poll.choices_count && choice && poll.choices_count.counts[choice.id]"
>
<div class="choicebox__vote">
{{ poll.choices_count.counts[choice.id].yes.count }}
<img width="20px" height="21px" src="../../../assets/img/votant-sur.svg" alt="" />
</div>
<div class="choicebox__vote">
{{ poll.choices_count.counts[choice.id].maybe.count }}
<img width="22px" height="24px" src="../../../assets/img/votant-pas-sur.svg" alt="" />
</div>
<div class="choicebox__tooltip" id="choicebox-tooltip">
<div class="choicebox__tooltiplist">
<div class="choicebox__tooltipttl">
<img width="20px" height="21px" src="../../../assets/img/votant-sur.svg" alt="" />
{{ poll.choices_count.counts[choice.id].yes.count }} "Oui"
</div>
<!-- liste des gens qui ont répondu oui-->
<ul >
<li *ngFor='let pseudo of choices_count.counts[choice.id].yes.people ' >{{pseudo}}</li >
</ul >
</div >
<div
class="choicebox__tooltiplist"
*ngIf='!simpleAnswer' >
<div class="choicebox__tooltipttl" >
<ul>
<li *ngFor="let pseudo of choices_count.counts[choice.id].yes.people">
{{ pseudo }}
</li>
</ul>
</div>
<div class="choicebox__tooltiplist" *ngIf="!simpleAnswer">
<div class="choicebox__tooltipttl">
<img
width="22px"
height="24px"
src="../../../assets/img/votant-pas-sur.svg"
alt="" >
{{poll.choices_count.counts[choice.id].maybe.count}} "Peut-être"
</div >
<ul >
<li *ngFor='let pseudo of choices_count.counts[choice.id].maybe.people ' >{{pseudo}}</li >
</ul >
</div >
<div
class="choicebox__tooltiplist"
*ngIf='!simpleAnswer' >
<div class="choicebox__tooltipttl" >
<i class='fa fa-times' ></i >
{{poll.choices_count.counts[choice.id].no.count}} "Non"
</div >
<ul >
<li *ngFor='let pseudo of choices_count.counts[choice.id].no.people ' >{{pseudo}}</li >
</ul >
</div >
</div >
</button >
<div class="choicebox__countxt" >
alt=""
/>
{{ poll.choices_count.counts[choice.id].maybe.count }} "Peut-être"
</div>
<ul>
<li *ngFor="let pseudo of choices_count.counts[choice.id].maybe.people">
{{ pseudo }}
</li>
</ul>
</div>
<div class="choicebox__tooltiplist" *ngIf="!simpleAnswer">
<div class="choicebox__tooltipttl">
<i class="fa fa-times"></i>
{{ poll.choices_count.counts[choice.id].no.count }} "Non"
</div>
<ul>
<li *ngFor="let pseudo of choices_count.counts[choice.id].no.people">
{{ pseudo }}
</li>
</ul>
</div>
</div>
</button>
<div class="choicebox__countxt">
Choix ayant reçu le plus de votes
</div >
</div >
</div >
</div >
</div >
</div >
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -5,14 +5,13 @@
// -- IMPORTS
// ----------------------------
@import "../../../../assets/scss/variables";
@import '../../../../assets/scss/variables';
// -- VARIABLES
// ----------------------------
$box-padding: 2rem;
$box-border-width: .6rem;
$box-border-width: 0.6rem;
$btn-size: 5rem;
$btn-margin-x: 1rem;
$btn-margin-y: 1.5rem;
@ -20,7 +19,6 @@ $btn-wrap-size: calc(2 * #{$btn-size} + 4 * #{$btn-margin-x});
$img-maxheight: 12rem;
$breakpoint-responsive: 640px; // à définir
// -- GLOBAL
// ----------------------------
@ -32,7 +30,7 @@ $breakpoint-responsive: 640px; // à définir
padding: $box-padding $box-padding $box-padding calc(#{$box-padding} - #{$box-border-width});
border-left: $box-border-width solid transparent;
background-color: $white;
box-shadow: 0 0 .6rem 0 rgba($black, .2);
box-shadow: 0 0 0.6rem 0 rgba($black, 0.2);
&--active {
padding-left: $box-padding;
@ -54,13 +52,12 @@ $breakpoint-responsive: 640px; // à définir
}
}
// -- DATE
// ----------------------------
.choicebox__date {
font-size: 1.8rem;
margin-bottom: .5rem;
margin-bottom: 0.5rem;
white-space: nowrap;
text-transform: capitalize;
@ -74,7 +71,6 @@ $breakpoint-responsive: 640px; // à définir
font-weight: bold;
}
// -- IMG
// ----------------------------
@ -83,7 +79,6 @@ $breakpoint-responsive: 640px; // à définir
max-height: $img-maxheight;
}
// -- TXT
// ----------------------------
@ -93,7 +88,6 @@ $breakpoint-responsive: 640px; // à définir
min-width: 10em;
}
// -- VOTE BTNS
// ----------------------------
@ -119,7 +113,7 @@ $breakpoint-responsive: 640px; // à définir
align-items: center;
justify-content: center;
margin: $btn-margin-y $btn-margin-x;
border: .3rem solid #ccc9c9;
border: 0.3rem solid #ccc9c9;
background-color: transparent;
border-radius: 50%;
cursor: pointer;
@ -133,24 +127,22 @@ $breakpoint-responsive: 640px; // à définir
left: auto;
}
}
&:focus, &:active {
&:focus,
&:active {
border-color: #bf83c2;
color: #bf83c2;
background: #000;
}
&--active {
border-color: #bf83c2;
}
@media (min-width: $breakpoint-responsive) {
margin-top: 0;
margin-bottom: 0;
}
}
// -- VOTE COUNT
// ----------------------------
@ -184,7 +176,7 @@ $breakpoint-responsive: 640px; // à définir
.choicebox__countxt {
display: none;
margin-top: .5rem;
margin-top: 0.5rem;
.choicebox--active & {
display: block;
@ -194,7 +186,6 @@ $breakpoint-responsive: 640px; // à définir
}
}
// -- TOOLTIP
// ----------------------------
@ -208,7 +199,7 @@ $breakpoint-responsive: 640px; // à définir
left: 50%;
z-index: 1;
padding: 2rem;
border: .1rem solid rgba($black, .1);
border: 0.1rem solid rgba($black, 0.1);
background-color: $white;
text-align: left;
transform: translateX(-50%);
@ -219,7 +210,7 @@ $breakpoint-responsive: 640px; // à définir
height: 0;
bottom: 100%;
left: 50%;
content: " ";
content: ' ';
pointer-events: none;
border: solid transparent;
}
@ -233,7 +224,7 @@ $breakpoint-responsive: 640px; // à définir
margin-left: -1.6rem;
border-width: 1.6rem;
border-color: rgba($black, 0);
border-bottom-color: rgba($black, .1);
border-bottom-color: rgba($black, 0.1);
}
ul {
margin: 0;
@ -261,7 +252,7 @@ $breakpoint-responsive: 640px; // à définir
font-weight: bold;
white-space: nowrap;
img {
margin-right: .5rem;
margin-right: 0.5rem;
vertical-align: sub;
}
& ~ .choicebox__tooltipttl {

View File

@ -1,14 +1,14 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {FormsModule} from "@angular/forms";
import {HttpClient, HttpClientModule} from "@angular/common/http";
import {BrowserModule} from "@angular/platform-browser";
import {CommonModule} from "@angular/common";
import {ConfirmationService, MessageService} from "primeng";
import {Router} from "@angular/router";
import {ConfigService} from "../../../services/config.service";
import {VotingChoiceComponent} from './voting-choice.component';
import {mockChoice} from "../../../config/mocks/choice";
import {mockPoll3} from "../../../config/mocks/mock-poll3";
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { ConfirmationService, MessageService } from 'primeng';
import { Router } from '@angular/router';
import { ConfigService } from '../../../services/config.service';
import { VotingChoiceComponent } from './voting-choice.component';
import { mockChoice } from '../../../config/mocks/choice';
import { mockPoll3 } from '../../../config/mocks/mock-poll3';
const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);
@ -18,24 +18,22 @@ describe('VotingChoiceComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [FormsModule,
BrowserModule,
CommonModule,
HttpClientModule],
declarations: [VotingChoiceComponent]
, providers: [HttpClient,
imports: [FormsModule, BrowserModule, CommonModule, HttpClientModule],
declarations: [VotingChoiceComponent],
providers: [
HttpClient,
MessageService,
ConfirmationService,
ConfigService,
{provide: Router, useValue: routerSpy}]
})
.compileComponents();
{ provide: Router, useValue: routerSpy },
],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(VotingChoiceComponent);
component = fixture.componentInstance;
component.choice = {...mockChoice};
component.choice = { ...mockChoice };
component.choices_count = mockPoll3.choices_count;
component.choice_id = mockChoice.id;
component.poll = mockPoll3.poll;
@ -76,7 +74,6 @@ describe('VotingChoiceComponent', () => {
expect(component.choice.answer).toBe('no');
});
it('should consider to have simple answer when allowedAnswers is only one answer long, which is yes', () => {
expect(component.poll.allowedAnswers[0]).toBe('yes');
expect(component.poll.allowedAnswers.length).toBe(1);
expect(component.simpleAnswer).toBeTruthy();

View File

@ -1,17 +1,17 @@
import {Component, ElementRef, Input} from '@angular/core';
import {ConfigService} from "../../../services/config.service";
import { Component, ElementRef, Input } from '@angular/core';
import { ConfigService } from '../../../services/config.service';
interface VoteChoice {
votes?: {
yes: number
no: number
maybe: number
notAnswered: number
yes: number;
no: number;
maybe: number;
notAnswered: number;
};
name?: string;
date?: Date;
answer: 'yes' | 'no' | 'maybe' | null;
simpleAnswer?: boolean
simpleAnswer?: boolean;
false; // enable if we display only a togglable "yes"
}
@ -22,10 +22,9 @@ interface VoteChoice {
@Component({
selector: 'framadate-voting-choice',
templateUrl: './voting-choice.component.html',
styleUrls: ['./voting-choice.component.scss']
styleUrls: ['./voting-choice.component.scss'],
})
export class VotingChoiceComponent {
public showChangeChoicebutton = false;
@Input() public choice: any;
@Input() public choices_count: any;
@ -34,11 +33,9 @@ export class VotingChoiceComponent {
@Input() public simpleAnswer: boolean = true;
@Input() public pollIsSpecialDate: boolean = false;
constructor(private el: ElementRef,
private config: ConfigService) {
constructor(private el: ElementRef, private config: ConfigService) {
if (this.poll && this.poll.allowedAnswers) {
this.simpleAnswer = this.poll.allowedAnswers.length == 1
this.simpleAnswer = this.poll.allowedAnswers.length == 1;
}
}
@ -52,7 +49,6 @@ export class VotingChoiceComponent {
this.choice.answer = newAnswer;
this.config.myTempVoteStack++;
}
} else {
this.choice.answer = newAnswer;
if (this.choice.answer !== newAnswer) {
@ -60,11 +56,9 @@ export class VotingChoiceComponent {
this.config.myTempVoteStack++;
}
} else {
console.info('same answer as before')
console.info('same answer as before');
}
}
this.el.nativeElement.blur();
}
}

View File

@ -1,13 +1,11 @@
<div class="comment" >
<span class="cname" >
{{comment.pseudo}}
</span >, le
<span class="date padding-btm-x1" >
{{comment.date.date }}
</span >
<blockquote >
<p class="text" >
{{comment.text}}
</p >
</blockquote >
</div >
<div class="comment">
<span class="cname"> {{ comment.pseudo }} </span>, le
<span class="date padding-btm-x1">
{{ comment.date.date }}
</span>
<blockquote>
<p class="text">
{{ comment.text }}
</p>
</blockquote>
</div>

View File

@ -1,6 +1,6 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {VotingCommentComponent} from './voting-comment.component';
import { VotingCommentComponent } from './voting-comment.component';
describe('VotingCommentComponent', () => {
let component: VotingCommentComponent;
@ -8,9 +8,8 @@ describe('VotingCommentComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [VotingCommentComponent]
})
.compileComponents();
declarations: [VotingCommentComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,19 +1,15 @@
import {Component, Input, OnInit} from '@angular/core';
import {mockComments} from "../../../config/mocks/mock-comments";
import { Component, Input, OnInit } from '@angular/core';
import { mockComments } from '../../../config/mocks/mock-comments';
@Component({
selector: 'framadate-voting-comment',
templateUrl: './voting-comment.component.html',
styleUrls: ['./voting-comment.component.scss']
styleUrls: ['./voting-comment.component.scss'],
})
export class VotingCommentComponent implements OnInit {
@Input() comment = mockComments[0];
constructor() {
}
ngOnInit() {
}
constructor() {}
ngOnInit() {}
}

View File

@ -8,9 +8,8 @@ describe('VotingGraphComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ VotingGraphComponent ]
})
.compileComponents();
declarations: [VotingGraphComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,19 +1,16 @@
import { Component, OnInit } from '@angular/core';
import {BaseComponent} from "../../base-page/base.component";
import {ConfigService} from "../../../services/config.service";
import { BaseComponent } from '../../base-page/base.component';
import { ConfigService } from '../../../services/config.service';
@Component({
selector: 'framadate-voting-graph',
templateUrl: './voting-graph.component.html',
styleUrls: ['./voting-graph.component.scss']
styleUrls: ['./voting-graph.component.scss'],
})
export class VotingGraphComponent extends BaseComponent implements OnInit {
constructor(public config: ConfigService) {
super(config);
}
ngOnInit() {
}
ngOnInit() {}
}

View File

@ -1,34 +1,31 @@
<nav id='navigation'>
<nav class='sections-nav' >
<ul >
<li >
<a href='#title' >
{{config.currentPoll.poll.title}}
</a >
</li >
<li >
<a href='#table' >
{{config.currentPoll.stacks.length}}
<nav id="navigation">
<nav class="sections-nav">
<ul>
<li>
<a href="#title">
{{ config.currentPoll.poll.title }}
</a>
</li>
<li>
<a href="#table">
{{ config.currentPoll.stacks.length }}
votes
</a >
</li >
<li >
<a href='#graph' >
</a>
</li>
<li>
<a href="#graph">
Graphique
</a >
</li >
<li >
<a href='#comments' >
<i class='fa fa-comments' ></i >
<span
*ngIf='config.currentPoll && config.currentPoll.comments'
class='comments-count' >
{{config.currentPoll.comments.length}}
</span >
</a>
</li>
<li>
<a href="#comments">
<i class="fa fa-comments"></i>
<span *ngIf="config.currentPoll && config.currentPoll.comments" class="comments-count">
{{ config.currentPoll.comments.length }}
</span>
commentaires
</a >
</li >
</ul >
</nav >
</a>
</li>
</ul>
</nav>
</nav>

View File

@ -8,9 +8,8 @@ describe('VotingNavigationComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ VotingNavigationComponent ]
})
.compileComponents();
declarations: [VotingNavigationComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,14 +1,11 @@
import {Component} from '@angular/core';
import {ConfigService} from "../../../services/config.service";
import { Component } from '@angular/core';
import { ConfigService } from '../../../services/config.service';
@Component({
selector: 'framadate-voting-navigation',
templateUrl: './voting-navigation.component.html',
styleUrls: ['./voting-navigation.component.scss']
styleUrls: ['./voting-navigation.component.scss'],
})
export class VotingNavigationComponent {
constructor(public config: ConfigService) {
}
constructor(public config: ConfigService) {}
}

View File

@ -1,81 +1,68 @@
<h2 >Résumé</h2 >
<div class='heading' >
<div class='col-xs-6' >
<h1 id='title' >{{config.currentPoll.poll.title}}</h1 >
<p >{{config.currentPoll.poll.description}}</p >
<span class="creationDate" >
Créé le {{config.currentPoll.poll.creationDate.date}}
</span >
<span class="expiracyDate" >
Expire le {{config.currentPoll.poll.expiracyDate.date}}
</span >
<div class="votants" >
<i class='fa fa-users' ></i >
{{config.currentPoll.stacks.length}} votants,
{{config.currentPoll.choices.length}} choix,
</div >
</div >
</div >
<div class="preferred" >
<i class='fa fa-star' ></i >
<h2>Résumé</h2>
<div class="heading">
<div class="col-xs-6">
<h1 id="title">{{ config.currentPoll.poll.title }}</h1>
<p>{{ config.currentPoll.poll.description }}</p>
<span class="creationDate"> Créé le {{ config.currentPoll.poll.creationDate.date }} </span>
<span class="expiracyDate"> Expire le {{ config.currentPoll.poll.expiracyDate.date }} </span>
<div class="votants">
<i class="fa fa-users"></i>
{{ config.currentPoll.stacks.length }} votants, {{ config.currentPoll.choices.length }} choix,
</div>
</div>
</div>
<div class="preferred">
<i class="fa fa-star"></i>
Pour l'instant,
<span *ngIf='severalPreferred' >
<span *ngIf="severalPreferred">
les
</span > <span *ngIf='!severalPreferred' >
</span>
<span *ngIf="!severalPreferred">
le
</span >
choix ayant reçu le plus grand nombre de votes ( {{config.currentPoll.choices_count.maxScore}} points )
<span *ngIf='severalPreferred' >
</span>
choix ayant reçu le plus grand nombre de votes ( {{ config.currentPoll.choices_count.maxScore }} points )
<span *ngIf="severalPreferred">
sont à égalité
</span > <span *ngIf='!severalPreferred' >
</span>
<span *ngIf="!severalPreferred">
est
</span >
</span>
:
<span class='preferred-result' >
{{preferred}}
</span >
</div >
<table class='table is-striped is-bordered is-hoverable' >
<thead >
<tr *ngIf='config.currentPoll.choices && config.currentPoll.choices_count' >
<td >
<span class="preferred-result">
{{ preferred }}
</span>
</div>
<table class="table is-striped is-bordered is-hoverable">
<thead>
<tr *ngIf="config.currentPoll.choices && config.currentPoll.choices_count">
<td>
Pseudo
</td >
<td
*ngFor='let choice of config.currentPoll.choices'
>
{{choice.text}}
</td >
</tr >
</td>
<td *ngFor="let choice of config.currentPoll.choices">
{{ choice.text }}
</td>
</tr>
<!-- somme des points, dont un demi point pour les "peut être" -->
</thead >
<tbody >
<tr
title='somme des points, dont un demi point pour les "peut être"' >
<td >
<i class='fa fa-plus-circle' ></i > points
</td >
</thead>
<tbody>
<tr title='somme des points, dont un demi point pour les "peut être"'>
<td><i class="fa fa-plus-circle"></i> points</td>
<!-- <td-->
<!-- *ngFor='let choice of config.currentPoll.choices'-->
<!-- [ngClass]='{"has-max-score" : config.currentPoll.choices_count.maxScore === config.currentPoll.choices_count.counts[choice.id].score}' >-->
<!-- {{config.currentPoll.choices[choice.id].score}}-->
<!-- </td >-->
<td
*ngFor='let choice of config.currentPoll.choices'
>
{{pollconfig.choices_count.counts[this.pollconfig.choices[2].id].score}}
</td >
</tr >
<tr class='details' >
<td >
<i class='fa fa-eye' ></i >
</td >
<td *ngFor='let choice of config.currentPoll.choices' >
id: {{choice.id}}
<br >
<td *ngFor="let choice of config.currentPoll.choices">
{{ pollconfig.choices_count.counts[this.pollconfig.choices[2].id].score }}
</td>
</tr>
<tr class="details">
<td>
<i class="fa fa-eye"></i>
</td>
<td *ngFor="let choice of config.currentPoll.choices">
id: {{ choice.id }}
<br />
<!-- yes {{config.currentPoll.choices_count.counts[choice.id].yes.count}}-->
<!-- <br >-->
<!-- maybe-->
@ -83,56 +70,53 @@
<!-- <br >-->
<!-- no {{(config.currentPoll.choices_count.counts[k].yes.maybe ? config.currentPoll.choices_count.counts[k].maybe.count * 0.5 : 0)}}-->
<br >
<br />
<!-- score :-->
<!-- {{(config.currentPoll.choices_count.counts[choice.id].score)}}-->
</td >
</tr >
<tr
class='votes-of-the-person'
*ngFor='let voteStack of config.currentPoll.stacks'
>
<td >
</td>
</tr>
<tr class="votes-of-the-person" *ngFor="let voteStack of config.currentPoll.stacks">
<td>
<!-- // TODO show modify if this is our own vote-->
<button
(click)='config.loadVoteStack(voteStack)'
(click)="config.loadVoteStack(voteStack)"
*ngIf="config.currentPoll.poll.modificationPolicy === 'everybody'"
class='btn btn--primary pull-left btn--small'
class="btn btn--primary pull-left btn--small"
>
<i class='fa fa-pencil' ></i >
</button >
{{voteStack.pseudo}}
</td >
<td *ngFor='let v of getKeys(voteStack.votes)' >
<span *ngIf='voteStack.votes[v].value' >
<i class="fa fa-pencil"></i>
</button>
{{ voteStack.pseudo }}
</td>
<td *ngFor="let v of getKeys(voteStack.votes)">
<span *ngIf="voteStack.votes[v].value">
<img
*ngIf="voteStack.votes[v].value == 'yes'"
src='../../../../assets/img/votant-sur.svg'
alt='yes' >
src="../../../../assets/img/votant-sur.svg"
alt="yes"
/>
<img
*ngIf="voteStack.votes[v].value == 'maybe'"
src='../../../../assets/img/votant-pas-sur.svg'
alt='yes' >
</span >
</td >
</tr >
src="../../../../assets/img/votant-pas-sur.svg"
alt="yes"
/>
</span>
</td>
</tr>
<!-- bottom line shows each answer details-->
</tbody >
</table >
</tbody>
</table>
<button
*ngIf='config.isAdmin'
*ngIf="config.isAdmin"
type="button"
(click)="showModalDialog()"
pButton
icon="pi pi-external-link"
label="Show" >
label="Show"
>
show admin confirmation modal
</button >
</button>
<p-dialog
[(visible)]="config.displayConfirmVoteModalAdmin"
[modal]="true"
@ -140,32 +124,29 @@
[draggable]="false"
[resizable]="false"
[showHeader]="false"
[transitionOptions]="'200ms'" >
<div style='max-width: 30em; padding: 2em 1em;' >
<h4 class='title' >
[transitionOptions]="'200ms'"
>
<div style="max-width: 30em; padding: 2em 1em;">
<h4 class="title">
Participation validée !
</h4 >
<p class="margin-btm-x1" >
Votre vote a bien été pris en compte, mais faites attention, ce sondage n'autorise
l'édition de votre vote qu'avec le lien personnalisé suivant :
</p >
<br >
<a
href='{{config.urlAdmin}}'
class='text-ellipsis' >{{config.urlAdmin}}</a >
<framadate-copy-text [textToCopy]='config.urlAdmin' ></framadate-copy-text >
<br >
<p class="margin-btm-x6 margin-top-x2" >Conservez-le précieusement !</p >
<br >
</h4>
<p class="margin-btm-x1">
Votre vote a bien été pris en compte, mais faites attention, ce sondage n'autorise l'édition de votre vote
qu'avec le lien personnalisé suivant :
</p>
<br />
<a href="{{ config.urlAdmin }}" class="text-ellipsis">{{ config.urlAdmin }}</a>
<framadate-copy-text [textToCopy]="config.urlAdmin"></framadate-copy-text>
<br />
<p class="margin-btm-x6 margin-top-x2">Conservez-le précieusement !</p>
<br />
<button
type="button btn--large btn btn--block"
pButton
icon="fa fa-check"
(click)="config.displayConfirmVoteModalAdmin=false"
label='Revenir au sondage'
class="btn btn--primary btn--default btn--purple btn--black-text" >
</button >
</div >
</p-dialog >
(click)="config.displayConfirmVoteModalAdmin = false"
label="Revenir au sondage"
class="btn btn--primary btn--default btn--purple btn--black-text"
></button>
</div>
</p-dialog>

View File

@ -1,4 +1,4 @@
@import "../../../../assets/scss/variables";
@import '../../../../assets/scss/variables';
.person {
font-weight: 700;

View File

@ -8,9 +8,8 @@ describe('VotingSummaryComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ VotingSummaryComponent ]
})
.compileComponents();
declarations: [VotingSummaryComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,29 +1,26 @@
import {Component, Input, OnInit} from '@angular/core';
import {ConfigService} from "../../../services/config.service";
import {mockPoll3} from "../../../config/mocks/mock-poll3";
import { Component, Input, OnInit } from '@angular/core';
import { ConfigService } from '../../../services/config.service';
import { mockPoll3 } from '../../../config/mocks/mock-poll3';
@Component({
selector: 'framadate-voting-summary',
templateUrl: './voting-summary.component.html',
styleUrls: ['./voting-summary.component.scss']
styleUrls: ['./voting-summary.component.scss'],
})
export class VotingSummaryComponent implements OnInit {
preferred: string = 'rien';
severalPreferred: boolean = false;
@Input() pollconfig = mockPoll3;
constructor(public config: ConfigService) {
}
constructor(public config: ConfigService) {}
ngOnInit() {
this.computePreferred();
}
getKeys(obj) {
return Object.keys(obj)
return Object.keys(obj);
}
/**
@ -35,21 +32,18 @@ export class VotingSummaryComponent implements OnInit {
this.severalPreferred = false;
let maxScore = this.pollconfig.choices_count.maxScore;
keys.forEach(item => {
keys.forEach((item) => {
if (maxScore === this.pollconfig.choices_count.counts[item].score) {
if (this.preferred.length) {
this.preferred += ', '
this.preferred += ', ';
this.severalPreferred = true;
}
// find the favourite
this.preferred += this.pollconfig.choices_count.counts[item].choice_text;
}
});
}
showModalDialog() {
this.config.displayConfirmVoteModalAdmin = true;
}

View File

@ -1,6 +1,4 @@
<form>
<a class="next">Voir le graphique</a>
<h2 class="margin-top-x4">Les commentaires</h2>
@ -9,9 +7,4 @@
<span class="date date padding-btm-x1"> le 26 novembre 2019</span>
Rock Luxio Surskit. Glacier Badge
</p>
</form>

View File

@ -8,9 +8,8 @@ describe('VotingComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ VotingComponent ]
})
.compileComponents();
declarations: [VotingComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -3,14 +3,11 @@ import { Component, OnInit } from '@angular/core';
@Component({
selector: 'framadate-voting',
templateUrl: './voting.component.html',
styleUrls: ['./voting.component.scss']
styleUrls: ['./voting.component.scss'],
})
export class VotingComponent implements OnInit {
show_mask=true;
constructor() {
}
ngOnInit() {
}
show_mask = true;
constructor() {}
ngOnInit() {}
}

View File

@ -6,24 +6,19 @@
(change)="toggleColorblind()"
class="input"
>
<option value="true" >
{{ "pollGraphic.choiceColorblind" | translate }}
</option >
<option value="false" >
{{ "pollGraphic.choiceNotColorblind" | translate }}
</option >
</select >
<span class="colorblind" >
{{ "pollGraphic.colorblindText" | translate }}
</span >
<div class='well' >
<option value="true">
{{ 'pollGraphic.choiceColorblind' | translate }}
</option>
<option value="false">
{{ 'pollGraphic.choiceNotColorblind' | translate }}
</option>
</select>
<span class="colorblind">
{{ 'pollGraphic.colorblindText' | translate }}
</span>
<div class="well">
work in progress to link data with poll config
</div >
<div >
<canvas
id="graph"
width="100%"
height="15em" ></canvas >
</div >
</div>
<div>
<canvas id="graph" width="100%" height="15em"></canvas>
</div>

View File

@ -8,9 +8,8 @@ describe('PollGraphicComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PollGraphicComponent ]
})
.compileComponents();
declarations: [PollGraphicComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,60 +1,58 @@
import {Component, Inject, OnInit} from "@angular/core";
import {Chart} from "chart.js";
import {DOCUMENT} from '@angular/common';
import {mockGraphConfig} from "../config/mocks/mock-graph";
import {graphOptions} from "../config/graph-canevas-options";
import {ConfigService} from "../services/config.service";
import {mockPoll3} from "../config/mocks/mock-poll3";
import { Component, Inject, OnInit } from '@angular/core';
import { Chart } from 'chart.js';
import { DOCUMENT } from '@angular/common';
import { mockGraphConfig } from '../config/mocks/mock-graph';
import { graphOptions } from '../config/graph-canevas-options';
import { ConfigService } from '../services/config.service';
import { mockPoll3 } from '../config/mocks/mock-poll3';
@Component({
selector: "framadate-poll-graphic",
templateUrl: "./poll-graphic.component.html",
styleUrls: ["./poll-graphic.component.scss"]
selector: 'framadate-poll-graphic',
templateUrl: './poll-graphic.component.html',
styleUrls: ['./poll-graphic.component.scss'],
})
export class PollGraphicComponent implements OnInit {
isColorblind: boolean = false;
pollConfigRetrieved: any = mockPoll3;
graphicConfig: any = mockGraphConfig;
preferred: any = "rien";
preferred: any = 'rien';
yesList: number[] = [];
maybeList: number[] = [];
noList: number[] = [];
nbPoll: number = 0;
dateList: string[] = [];
constructor(@Inject(DOCUMENT) private document: any,
private config: ConfigService) {
}
constructor(@Inject(DOCUMENT) private document: any, private config: ConfigService) {}
ngOnInit() {
this.formatDataAnswers(this.graphicConfig);
this.isColorblind = false;
this.pollConfigRetrieved = new Chart(this.document.getElementById("graph"), {
type: "horizontalBar",
this.pollConfigRetrieved = new Chart(this.document.getElementById('graph'), {
type: 'horizontalBar',
data: {
labels: this.pollConfigRetrieved.choices.map(choice => choice.name),
labels: this.pollConfigRetrieved.choices.map((choice) => choice.name),
datasets: [
{
type: "horizontalBar",
stack: "Yes",
backgroundColor: "#429a00",
data: this.yesList
type: 'horizontalBar',
stack: 'Yes',
backgroundColor: '#429a00',
data: this.yesList,
},
{
type: "horizontalBar",
stack: "Yes",
backgroundColor: "#f5a623",
data: this.maybeList
type: 'horizontalBar',
stack: 'Yes',
backgroundColor: '#f5a623',
data: this.maybeList,
},
{
type: "horizontalBar",
stack: "No",
backgroundColor: "#cd0000",
data: this.noList
}
]
type: 'horizontalBar',
stack: 'No',
backgroundColor: '#cd0000',
data: this.noList,
},
options: graphOptions
],
},
options: graphOptions,
});
}
@ -65,15 +63,15 @@ export class PollGraphicComponent implements OnInit {
formatDataAnswers(poll) {
// if (poll && poll.pollType === "date") {
this.initPollCounter();
poll.answers.forEach(response => {
poll.answers.forEach((response) => {
switch (response.text) {
case "yes":
case 'yes':
this.yesList[this.nbPoll - 1]++;
break;
case "maybe":
case 'maybe':
this.maybeList[this.nbPoll - 1]++;
break;
case "no":
case 'no':
this.noList[this.nbPoll - 1]++;
break;
}
@ -83,7 +81,7 @@ export class PollGraphicComponent implements OnInit {
initPollCounter() {
this.nbPoll++;
this.dateList[this.nbPoll - 1] = "jeudi";
this.dateList[this.nbPoll - 1] = 'jeudi';
this.maybeList[this.nbPoll - 1] = 0;
this.yesList[this.nbPoll - 1] = 0;
this.noList[this.nbPoll - 1] = 0;

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More