mirror of
https://framagit.org/framasoft/framadate/funky-framadate-front.git
synced 2023-08-25 13:53:14 +02:00
Merge branch 'api' into 'dev'
Api calls and merge with dev See merge request framasoft/framadate/funky-framadate-front!24
This commit is contained in:
commit
d63f46483f
@ -28,6 +28,10 @@
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"node_modules/primeicons/primeicons.css",
|
||||
"node_modules/font-awesome/css/font-awesome.css",
|
||||
"node_modules/primeng/resources/themes/nova-light/theme.css",
|
||||
"node_modules/primeng/resources/primeng.min.css",
|
||||
"src/styles.scss"
|
||||
],
|
||||
"scripts": [
|
||||
@ -128,6 +132,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}},
|
||||
}
|
||||
},
|
||||
"defaultProject": "framadate"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ module.exports = function (config) {
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, './coverage/framadate'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
reports: ['html', 'lcovonly', 'name-summary'],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
|
20
package.json
20
package.json
@ -4,6 +4,7 @@
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"serve": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
@ -12,7 +13,8 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~8.2.0",
|
||||
"@angular/animations": "^8.2.14",
|
||||
"@angular/cdk": "^8.2.3",
|
||||
"@angular/common": "~8.2.0",
|
||||
"@angular/compiler": "~8.2.0",
|
||||
"@angular/core": "~8.2.0",
|
||||
@ -20,21 +22,29 @@
|
||||
"@angular/platform-browser": "~8.2.0",
|
||||
"@angular/platform-browser-dynamic": "~8.2.0",
|
||||
"@angular/router": "~8.2.0",
|
||||
"@fullcalendar/core": "^4.3.1",
|
||||
"@ngx-translate/core": "^11.0.1",
|
||||
"@ngx-translate/http-loader": "^4.0.0",
|
||||
"chart.js": "^2.8.0",
|
||||
"font-awesome": "^4.7.0",
|
||||
"ngx-clipboard": "^12.3.0",
|
||||
"ngx-markdown": "^8.2.1",
|
||||
"ngx-toaster": "^1.0.1",
|
||||
"primeicons": "^2.0.0",
|
||||
"primeng": "^9.0.0-rc.2",
|
||||
"quill": "^1.3.7",
|
||||
"rxjs": "~6.4.0",
|
||||
"rxjs-compat": "^6.5.3",
|
||||
"tslib": "^1.10.0",
|
||||
"zone.js": "~0.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^0.803.21",
|
||||
"@angular-devkit/build-angular": "~0.803.21",
|
||||
"@angular/cli": "~8.3.21",
|
||||
"@angular/compiler-cli": "^8.2.14",
|
||||
"@angular/language-service": "^8.2.14",
|
||||
"@angular/compiler-cli": "~8.2.14",
|
||||
"@angular/language-service": "~8.2.14",
|
||||
"@types/jasmine": "~3.3.8",
|
||||
"@types/jasminewd2": "^2.0.8",
|
||||
"@types/jasminewd2": "~2.0.8",
|
||||
"@types/node": "~8.9.4",
|
||||
"codelyzer": "^5.2.1",
|
||||
"jasmine-core": "~3.4.0",
|
||||
|
@ -18,16 +18,20 @@
|
||||
<img
|
||||
src="assets/img/icone-langue.svg"
|
||||
alt="location icon"
|
||||
class="lang_icon"
|
||||
> <img
|
||||
src="assets/img/icone-menu.svg"
|
||||
(click)="changeLanguage()"
|
||||
class="lang_icon clickable"
|
||||
>
|
||||
<img
|
||||
(click)="toggleMenu()"
|
||||
alt="menu icon"
|
||||
class="menu_icon"
|
||||
class="menu_icon clickable"
|
||||
src="assets/img/icone-menu.svg"
|
||||
>
|
||||
<select
|
||||
name="language"
|
||||
class="Language-"
|
||||
(change)="switchLanguage($event.target.value)"
|
||||
(change)="switchLanguage(currentLang)"
|
||||
[(ngModel)]="currentLang"
|
||||
>
|
||||
<option
|
||||
value="d"
|
||||
@ -37,17 +41,16 @@
|
||||
<option value="en">English</option>
|
||||
<option value="fr">Français</option>
|
||||
</select>
|
||||
<span class="menu_label">Menu</span>
|
||||
</div>
|
||||
<h1 i18n>{{"Title"|translate}}</h1>
|
||||
<div>
|
||||
{{"Intro"|translate:user}}
|
||||
<span (click)="toggleMenu()" class="menu_label">Menu</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</header>
|
||||
<framadate-navigation [step]="step"></framadate-navigation>
|
||||
<framadate-navigation *ngIf="menuVisible" [step]="step"></framadate-navigation>
|
||||
<main>
|
||||
<router-outlet></router-outlet>
|
||||
</main>
|
||||
<framadate-debugger></framadate-debugger>
|
||||
<p-toast position="top-right"></p-toast>
|
||||
|
||||
|
@ -8,6 +8,8 @@ import {Router} from '@angular/router';
|
||||
styleUrls: ['./app.component.scss']
|
||||
})
|
||||
export class AppComponent {
|
||||
currentLang = 'fr';
|
||||
langsAvailable = ['fr', 'en'];
|
||||
title = 'framadate';
|
||||
//translation demo:
|
||||
minutes = 12;
|
||||
@ -15,11 +17,17 @@ export class AppComponent {
|
||||
name: 'Arthur',
|
||||
age: 42
|
||||
};
|
||||
menuVisible: boolean = true;
|
||||
private step: string;
|
||||
|
||||
constructor(private translate: TranslateService,
|
||||
private route: Router) {
|
||||
this.translate.setDefaultLang('fr');
|
||||
this.translate.setDefaultLang(this.currentLang);
|
||||
this.detectCurrentTabOnRouteChange();
|
||||
|
||||
}
|
||||
|
||||
detectCurrentTabOnRouteChange() {
|
||||
this.route.events.subscribe((event: any) => {
|
||||
|
||||
// console.log('event', event);
|
||||
@ -39,6 +47,27 @@ export class AppComponent {
|
||||
|
||||
switchLanguage(language: string) {
|
||||
this.translate.use(language);
|
||||
this.currentLang = language;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the next lang or loop to the first
|
||||
* this is to manage future languages available
|
||||
*/
|
||||
changeLanguage() {
|
||||
let langs = this.langsAvailable;
|
||||
let indexofCurrent = langs.indexOf(this.currentLang);
|
||||
if (indexofCurrent > -1) {
|
||||
let newIndex = indexofCurrent + 1;
|
||||
if (newIndex > (langs.length - 1)) {
|
||||
newIndex = 0;
|
||||
}
|
||||
this.currentLang = this.langsAvailable[newIndex];
|
||||
}
|
||||
this.translate.use(this.currentLang);
|
||||
}
|
||||
|
||||
toggleMenu() {
|
||||
this.menuVisible = !this.menuVisible;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
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';
|
||||
@ -21,12 +20,12 @@ import {EndConfirmationComponent} from './pages/end-confirmation/end-confirmatio
|
||||
import {CreateOrRetrieveComponent} from './pages/create-or-retrieve/create-or-retrieve.component';
|
||||
import localeFr from '@angular/common/locales/fr';
|
||||
import localeEn from '@angular/common/locales/en';
|
||||
import {VotingSummaryComponent} from './pages/voting-summary/voting-summary.component';
|
||||
import {VotingGraphComponent} from './pages/voting-graph/voting-graph.component';
|
||||
import {VotingChoiceComponent} from './pages/voting-choice/voting-choice.component';
|
||||
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 {VoteChoiceComponent} from './vote-choice/vote-choice.component';
|
||||
import {VoteChoiceComponent} from './ui/vote-choice/vote-choice.component';
|
||||
import {HttpClient, HttpClientModule} from '@angular/common/http';
|
||||
import {MarkdownModule} from 'ngx-markdown';
|
||||
import {
|
||||
@ -41,7 +40,16 @@ import {PollGraphicComponent} from './poll-graphic/poll-graphic.component';
|
||||
|
||||
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 {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";
|
||||
|
||||
export class MyMissingTranslationHandler implements MissingTranslationHandler {
|
||||
handle(params: MissingTranslationHandlerParams) {
|
||||
@ -80,13 +88,20 @@ export function HttpLoaderFactory(http: HttpClient) {
|
||||
VoteChoiceComponent,
|
||||
AdminComponent,
|
||||
SelectorComponent,
|
||||
PollDisplayComponent,
|
||||
VotingComponent,
|
||||
VotingCommentComponent,
|
||||
ResettableInputDirective,
|
||||
|
||||
],
|
||||
imports: [
|
||||
ClipboardModule,
|
||||
CommonModule,
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
AppRoutingModule,
|
||||
ToastModule,
|
||||
MessageModule,
|
||||
MarkdownModule.forRoot(),
|
||||
TranslateModule.forRoot({
|
||||
missingTranslationHandler: {
|
||||
@ -104,7 +119,7 @@ export function HttpLoaderFactory(http: HttpClient) {
|
||||
FormsModule,
|
||||
RouterModule.forRoot(Routes)
|
||||
],
|
||||
providers: [TranslateService],
|
||||
providers: [TranslateService, ConfigService, PollService, MessageService],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule {
|
||||
|
@ -1,37 +0,0 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {PollConfig} from './config/PollConfig';
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import {environment} from "../environments/environment";
|
||||
|
||||
|
||||
/**
|
||||
* le service transverse à chaque page qui permet de syncroniser la configuration de sondage souhaitée
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ConfigService extends PollConfig {
|
||||
myEmail: string;
|
||||
myPolls: any;// list of retrieved polls from the backend api
|
||||
|
||||
|
||||
constructor(public http: HttpClient) {
|
||||
super();
|
||||
}
|
||||
|
||||
set(key, val) {
|
||||
this[key] = val;
|
||||
}
|
||||
|
||||
createPoll() {
|
||||
// todo
|
||||
console.log('sends the form');
|
||||
alert('envoi de formulaire pour création de sondage en XHR à faire');
|
||||
const payload = this;
|
||||
this.http.post(`${environment.baseApiHref}/poll`, payload)
|
||||
.subscribe(res => {
|
||||
console.log('res', res)
|
||||
},
|
||||
err => console.error('err', err))
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
/**
|
||||
* une option de date dans les sondages spéciaux
|
||||
*/
|
||||
import {environment} from "../../environments/environment";
|
||||
|
||||
export interface DateOption {
|
||||
timeList: any;
|
||||
literal: string;
|
||||
@ -45,22 +47,29 @@ export const defaultAnswers = [{
|
||||
*/
|
||||
export class PollConfig {
|
||||
expiracyDateDefaultInDays = 60;
|
||||
deletionDateAfterLastModification = 180;
|
||||
step = 0;
|
||||
stepMax = 3;
|
||||
pollType = 'classic';// classic or date
|
||||
title = 'titre';
|
||||
description = 'ma description';
|
||||
myName = 'mon pseudo';
|
||||
|
||||
myEmail: string = "";
|
||||
// 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
|
||||
allowSeveralHours = 'false';
|
||||
// access
|
||||
visibility = 'link_only'; // visible to anyone with the link:
|
||||
voteChoices = 'only_yes'; // possible answers to a vote choice: only "yes", "yes, maybe, no"
|
||||
creationDate = new Date();
|
||||
expirationDate = ''; // expiracy date
|
||||
pollId = null; // id of the current poll when created. data given by the backend api
|
||||
selectedPoll = null; // current poll selected with createPoll or getPoll of ConfigService
|
||||
passwordAccess = 0;
|
||||
password = '';
|
||||
customUrl = '';
|
||||
customUrl = ''; // custom slug in the url, must be unique
|
||||
customUrlIsUnique = null; // given by the backend
|
||||
urlPublic = environment.baseApiHref + '/default-url';
|
||||
urlAdmin = environment.baseApiHref + '/default-url/admin/d65es45fd45sdf45sd345f312sdf31sgfd345';
|
||||
canModifyAnswers = 1;// everybody, self, nobody (= just admin)
|
||||
whoModifiesAnswers = "self";// everybody, self, nobody (= just admin)
|
||||
whoCanChangeAnswers = 'everybody';// everybody, self, nobody (= just admin)
|
||||
@ -69,5 +78,6 @@ export class PollConfig {
|
||||
|
||||
answers: any = defaultAnswers;
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
}
|
||||
|
@ -10,15 +10,18 @@ import {CreateOrRetrieveComponent} from '../pages/create-or-retrieve/create-or-r
|
||||
import {BaseComponent} from '../pages/base-page/base.component';
|
||||
import {HomeComponent} from "../pages/home/home.component";
|
||||
import {PollGraphicComponent} from '../poll-graphic/poll-graphic.component';
|
||||
import {VoteChoiceComponent} from "../vote-choice/vote-choice.component";
|
||||
import {VoteChoiceComponent} from "../ui/vote-choice/vote-choice.component";
|
||||
import {PollDisplayComponent} from "../pages/poll-display/poll-display.component";
|
||||
|
||||
import {VotingComponent} from "../pages/voting/voting.component";
|
||||
import {PasswordComponent} from "../pages/password/password.component";
|
||||
|
||||
/**
|
||||
* each step in the form is a component
|
||||
*/
|
||||
export const Routes =
|
||||
[
|
||||
{path: '', component: CreateOrRetrieveComponent},
|
||||
{path: '', redirectTo: 'step/creation', pathMatch: 'full'},
|
||||
{path: 'home', component: HomeComponent},
|
||||
{path: 'base', component: BaseComponent},
|
||||
{path: 'step/base', component: BaseComponent},
|
||||
@ -32,8 +35,10 @@ export const Routes =
|
||||
{path: 'step/resume', component: ResumeComponent},
|
||||
{path: 'step/end', component: EndConfirmationComponent},
|
||||
{path: 'graphic/:poll', component: PollGraphicComponent},
|
||||
{path: 'vote/poll/id/:poll', component: PollDisplayComponent},
|
||||
{path: 'votechoice', component: VoteChoiceComponent},
|
||||
{path: 'voting', component: VotingComponent},
|
||||
{path: 'step/password', component: PasswordComponent},
|
||||
{path: '**', redirectTo: '/home', pathMatch: 'full'},
|
||||
]
|
||||
;
|
||||
|
8
src/app/config/mock-comments.ts
Normal file
8
src/app/config/mock-comments.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export const mockComments = [
|
||||
{
|
||||
name: "Bulbizarre",
|
||||
date: "23 décembre 2019",
|
||||
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",
|
||||
}
|
||||
];
|
52
src/app/config/mock-graph.ts
Normal file
52
src/app/config/mock-graph.ts
Normal file
@ -0,0 +1,52 @@
|
||||
export const mockGraphConfig = {
|
||||
step: 0,
|
||||
stepMax: 3,
|
||||
pollType: "special dates",
|
||||
title: "",
|
||||
description: "",
|
||||
myName: "",
|
||||
visibility: "link_only",
|
||||
// date specific poll
|
||||
allowSeveralHours: "true",
|
||||
dateLgfgfgfgist: ["jeudi", "vendredi", "samedi"], // sets of days as strings
|
||||
timeList: ["08:00", "08:30", "09:00"], // ranges of time expressed as strings
|
||||
answers: [
|
||||
{
|
||||
id: 0,
|
||||
text: "no"
|
||||
},
|
||||
|
||||
{
|
||||
id: 1,
|
||||
text: "yes"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
text: "maybe"
|
||||
}
|
||||
]
|
||||
};
|
186
src/app/config/mock-poll3.ts
Normal file
186
src/app/config/mock-poll3.ts
Normal file
@ -0,0 +1,186 @@
|
||||
export const mockPoll3 = {
|
||||
"message": "your poll config",
|
||||
"data": {
|
||||
"id": 3,
|
||||
"title": "dessin animé préféré",
|
||||
"customUrl": null,
|
||||
"description": "choisissez votre animé préféré",
|
||||
"creationDate": {
|
||||
"date": "2020-01-15 15:07:53.000000",
|
||||
"timezone_type": 3,
|
||||
"timezone": "Europe/Paris"
|
||||
},
|
||||
"expiracyDate": {
|
||||
"date": "2020-01-15 15:07:53.000000",
|
||||
"timezone_type": 3,
|
||||
"timezone": "Europe/Paris"
|
||||
},
|
||||
"owner": {
|
||||
"__initializer__": {},
|
||||
"__cloner__": {},
|
||||
"__isInitialized__": false
|
||||
},
|
||||
"kind": "text",
|
||||
"allowedAnswers": [
|
||||
"yes"
|
||||
],
|
||||
"modificationPolicy": "self",
|
||||
"mailOnComment": null,
|
||||
"mailOnVote": null,
|
||||
"hideResults": null,
|
||||
"showResultEvenIfPasswords": null,
|
||||
"votes": {},
|
||||
"stacksOfVotes": {},
|
||||
"choices": {},
|
||||
"comments": {},
|
||||
"defaultExpiracyDaysFromNow": 60
|
||||
},
|
||||
"stacks_count": 2,
|
||||
"stacks": [
|
||||
{
|
||||
"pseudo": "Wulfila",
|
||||
"votes": {}
|
||||
},
|
||||
{
|
||||
"pseudo": "Tykayn",
|
||||
"votes": {}
|
||||
}
|
||||
],
|
||||
"choices_count": 7,
|
||||
"choices": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Vic le viking",
|
||||
"dateTime": {
|
||||
"date": "2020-01-15 15:07:53.000000",
|
||||
"timezone_type": 3,
|
||||
"timezone": "Europe/Paris"
|
||||
},
|
||||
"votes": {
|
||||
"count": {
|
||||
"yes": 0,
|
||||
"no": 0,
|
||||
"maybe": 0,
|
||||
"null": 0,
|
||||
}
|
||||
},
|
||||
simpleAnswer: true,
|
||||
"answer": null
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "Boumbo petite automobile",
|
||||
"dateTime": {
|
||||
"date": "2020-01-15 15:07:53.000000",
|
||||
"timezone_type": 3,
|
||||
"timezone": "Europe/Paris"
|
||||
},
|
||||
"votes": {
|
||||
"count": {
|
||||
"yes": 0,
|
||||
"no": 0,
|
||||
"maybe": 0,
|
||||
"null": 0,
|
||||
}
|
||||
},
|
||||
simpleAnswer: true,
|
||||
"answer": null
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "Les mystérieuses cités d'or",
|
||||
"dateTime": {
|
||||
"date": "2020-01-15 15:07:53.000000",
|
||||
"timezone_type": 3,
|
||||
"timezone": "Europe/Paris"
|
||||
},
|
||||
"votes": {
|
||||
"count": {
|
||||
"yes": 0,
|
||||
"no": 0,
|
||||
"maybe": 0,
|
||||
"null": 0,
|
||||
}
|
||||
},
|
||||
simpleAnswer: true,
|
||||
"answer": null
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "Les mondes engloutis",
|
||||
"dateTime": {
|
||||
"date": "2020-01-15 15:07:53.000000",
|
||||
"timezone_type": 3,
|
||||
"timezone": "Europe/Paris"
|
||||
},
|
||||
"votes": {
|
||||
"count": {
|
||||
"yes": 0,
|
||||
"no": 0,
|
||||
"maybe": 0,
|
||||
"null": 0,
|
||||
}
|
||||
},
|
||||
simpleAnswer: true,
|
||||
"answer": null
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "Foot 2 rue",
|
||||
"dateTime": {
|
||||
"date": "2020-01-15 15:07:53.000000",
|
||||
"timezone_type": 3,
|
||||
"timezone": "Europe/Paris"
|
||||
},
|
||||
"votes": {
|
||||
"count": {
|
||||
"yes": 0,
|
||||
"no": 0,
|
||||
"maybe": 0,
|
||||
"null": 0,
|
||||
}
|
||||
},
|
||||
simpleAnswer: true,
|
||||
"answer": null
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "Le chat, la vache, et l'océan",
|
||||
"dateTime": {
|
||||
"date": "2020-01-15 15:07:53.000000",
|
||||
"timezone_type": 3,
|
||||
"timezone": "Europe/Paris"
|
||||
},
|
||||
"votes": {
|
||||
"count": {
|
||||
"yes": 0,
|
||||
"no": 0,
|
||||
"maybe": 0,
|
||||
"null": 0,
|
||||
}
|
||||
},
|
||||
simpleAnswer: true,
|
||||
"answer": null
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "Digimon",
|
||||
"dateTime": {
|
||||
"date": "2020-01-15 15:07:53.000000",
|
||||
"timezone_type": 3,
|
||||
"timezone": "Europe/Paris"
|
||||
},
|
||||
"votes": {
|
||||
"count": {
|
||||
"yes": 0,
|
||||
"no": 0,
|
||||
"maybe": 0,
|
||||
"null": 0,
|
||||
}
|
||||
},
|
||||
simpleAnswer: true,
|
||||
"answer": null
|
||||
}
|
||||
],
|
||||
"comments": []
|
||||
}
|
@ -17,48 +17,7 @@
|
||||
<li>
|
||||
type de formulaire: {{config.pollType}}
|
||||
</li>
|
||||
<li>
|
||||
config:
|
||||
<pre>
|
||||
{{config.answers|json}}
|
||||
</pre>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<span i18n>
|
||||
Choix cornélien syncronisé:
|
||||
</span>
|
||||
<!-- todo: factoriser les boutons-->
|
||||
<button
|
||||
(click)="config.set('pollType' , 'classic')"
|
||||
[class.active]="config.pollType == 'classic'"
|
||||
[disabled]="!formIsValid"
|
||||
class="btn btn--primary next"
|
||||
>
|
||||
<span i18n>
|
||||
sondage classique
|
||||
</span>
|
||||
<span *ngIf="config.pollType == 'classic'">
|
||||
[x]
|
||||
</span>
|
||||
|
||||
</button>
|
||||
<button
|
||||
(click)="selectOption('pollType' ,'dates')"
|
||||
[class.active]="config.pollType == 'dates'"
|
||||
[disabled]="!formIsValid"
|
||||
class="btn btn--primary next"
|
||||
>
|
||||
<span i18n>
|
||||
sondage spécial date
|
||||
</span>
|
||||
<span *ngIf="config.pollType == 'dates'">
|
||||
[x]
|
||||
</span>
|
||||
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="btn btn--primary"
|
||||
i18n
|
||||
@ -66,3 +25,24 @@
|
||||
>
|
||||
Envoyer le formulaire
|
||||
</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')"
|
||||
>
|
||||
get my polls
|
||||
</button>
|
||||
<button class="btn btn--success" (click)="launchToast()">
|
||||
launch success toast
|
||||
</button>
|
||||
<a [routerLink]="'/vote/poll/id/3'" class="btn btn--success">
|
||||
See example of vote page
|
||||
</a>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {ConfigService} from '../config.service';
|
||||
import {ConfigService} from '../services/config.service';
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-debugger',
|
||||
@ -23,4 +23,8 @@ export class DebuggerComponent implements OnInit {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
launchToast() {
|
||||
this.config.handleError({message: "hop"})
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {BaseComponent} from '../base-page/base.component';
|
||||
import {ConfigService} from '../../config.service';
|
||||
import {ConfigService} from '../../services/config.service';
|
||||
@Component({
|
||||
selector: 'framadate-admin',
|
||||
templateUrl: './admin.component.html',
|
||||
|
@ -11,7 +11,7 @@
|
||||
<li #answers *ngFor="let answer of config.answers; index as i;trackBy trackFunction"
|
||||
class="answer-item">
|
||||
<input
|
||||
type="text"
|
||||
type="name"
|
||||
class="answer"
|
||||
[(ngModel)]="answer.text"
|
||||
(keyup.enter)="addAnswer()"
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {AfterViewInit, ChangeDetectorRef, Component, Inject, OnInit} from '@angular/core';
|
||||
import {BaseComponent} from '../base-page/base.component';
|
||||
import {ConfigService} from '../../config.service';
|
||||
import {ConfigService} from '../../services/config.service';
|
||||
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {ConfigService} from '../../config.service';
|
||||
import {ConfigService} from '../../services/config.service';
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-base-page',
|
||||
|
@ -8,7 +8,9 @@
|
||||
</p>
|
||||
<div class="btn-next">
|
||||
|
||||
<button class="btn btn--full btn--primary">{{"config.letsgo"|translate}}</button>
|
||||
<button [routerLink]="'step/date'" class="btn btn--full btn--primary">
|
||||
{{"config.letsgo"|translate}}
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
@ -17,23 +19,45 @@
|
||||
<h1 class="margin-top-x8">
|
||||
{{"config.find_my_polls"|translate}}
|
||||
</h1>
|
||||
<section class="list-my-polls">
|
||||
<!--<ul class="poll-list" *ngFor="let poll of config.myPolls">-->
|
||||
<a href="#" class="next margin-btm-x3">Anniversaire de tonton Patrick</a>
|
||||
<a href="#" class="next margin-btm-x5">Anniversaire de Bernard </a>
|
||||
<!--</ul>-->
|
||||
</section>
|
||||
|
||||
<form (ngSubmit)="findMyPollsByEmail(emailToFind.value)">
|
||||
<section class="row">
|
||||
<label class="description" for="email" i18n>
|
||||
<form
|
||||
(ngSubmit)="findMyPollsByEmail(config.myEmail)"
|
||||
>
|
||||
<label
|
||||
class="description"
|
||||
for="email"
|
||||
i18n
|
||||
>
|
||||
{{"config.find_helper"|translate}} :
|
||||
</label>
|
||||
<input class="margin-btm-x5" #emailToFind type="email" name="mail" id="email" autofocus="autofocus">
|
||||
</section>
|
||||
|
||||
<input type="submit" class="btn btn--primary btn--default btn--purple btn--black-text" value='{{"config.find_button"|translate}}'>
|
||||
<input
|
||||
[(ngModel)]="config.myEmail"
|
||||
autofocus="autofocus"
|
||||
id="email"
|
||||
name="mail"
|
||||
required="required"
|
||||
type="email"
|
||||
/>
|
||||
<input
|
||||
[disabled]="!config.myEmail"
|
||||
[ngClass]="{'btn-primary': config.myEmail}"
|
||||
class="btn btn-block"
|
||||
i18n-value="'config.find_button'|translate"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</section>
|
||||
<section class="list-my-polls" *ngIf="!config.loading">
|
||||
<ul class="poll-list" *ngFor="let poll of config.myPolls">
|
||||
<li> poll</li>
|
||||
</ul>
|
||||
|
||||
<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>
|
||||
|
@ -1,7 +1,6 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {BaseComponent} from "../base-page/base.component";
|
||||
import {ConfigService} from "../../config.service";
|
||||
import {PollServiceService} from "../../services/poll-service.service";
|
||||
import {ConfigService} from "../../services/config.service";
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-create-or-retrieve',
|
||||
@ -10,15 +9,25 @@ import {PollServiceService} from "../../services/poll-service.service";
|
||||
})
|
||||
export class CreateOrRetrieveComponent extends BaseComponent implements OnInit {
|
||||
|
||||
constructor(public config: ConfigService, public pollService: PollServiceService) {
|
||||
loadedMyPolls: boolean = false;
|
||||
|
||||
constructor(public config: ConfigService) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
// if (!environment.production) {
|
||||
// this.findMyPollsByEmail('tktest@tktest.com')
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
findMyPollsByEmail(email: string) {
|
||||
this.pollService.findPollsByEmail(email);
|
||||
if (!email) {
|
||||
return
|
||||
}
|
||||
this.config.findPollsByEmail(email);
|
||||
this.loadedMyPolls = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -89,7 +89,7 @@
|
||||
<input
|
||||
[(ngModel)]="choice.literal"
|
||||
name="timeChoices_{{id}}"
|
||||
type="text"
|
||||
type="name"
|
||||
>
|
||||
<button (click)="config.timeList.splice(id, 1)" class="btn btn-warning">X</button>
|
||||
</div>
|
||||
@ -133,7 +133,7 @@
|
||||
<input
|
||||
[(ngModel)]="time.literal"
|
||||
name="dateTime_{{id}}_Choices_{{idTime}}"
|
||||
type="text"
|
||||
type="name"
|
||||
>
|
||||
<button
|
||||
(click)="choice.timeList.splice(idTime, 1)"
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {ChangeDetectorRef, Component, Inject, OnInit} from '@angular/core';
|
||||
import {ConfigService} from '../../config.service';
|
||||
import {ConfigService} from '../../services/config.service';
|
||||
import {BaseComponent} from '../base-page/base.component';
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
|
||||
|
@ -7,27 +7,35 @@
|
||||
|
||||
Votre sondage «
|
||||
<span class="poll-title">
|
||||
{{config.title}} </span>
|
||||
{{config.title}}
|
||||
</span>
|
||||
» a bien été créé !
|
||||
</p>
|
||||
<p>
|
||||
Voici les liens d’accès au sondage, conservez-les soigneusement !
|
||||
(Si vous les perdez vous pourrez toujours les recevoir par email)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Pour accéder au sondage et à tous ses paramètres : https://framadate.org/urladmindusondage
|
||||
Pour accéder au sondage et à tous ses paramètres :
|
||||
<a href="{{config.urlAdmin}}">{{config.urlAdmin}}
|
||||
</a>
|
||||
</p>
|
||||
<button
|
||||
class="btn"
|
||||
(click)="copyLink(adminLink)"
|
||||
(click)="copyLink(config.urlAdmin)"
|
||||
[ngxClipboard]
|
||||
cbContent="{{config.urlAdmin}}"
|
||||
>
|
||||
<i class="fa fa-copy"></i>
|
||||
Copier le lien
|
||||
</button>
|
||||
<a href="{{adminLink}}">
|
||||
<a href="{{config.urlAdmin}}">
|
||||
Voir le sondage coté administrateur·ice
|
||||
</a>
|
||||
<p class="note">
|
||||
Note : Le sondage sera supprimé 180 jours après la date de sa dernière modification.
|
||||
Note : Le sondage sera supprimé {{config.deletionDateAfterLastModification}} jours après la date de sa dernière
|
||||
modification.
|
||||
</p>
|
||||
|
||||
|
||||
@ -36,15 +44,21 @@
|
||||
|
||||
<h2 i18n>{{"resume.users"|translate}}</h2>
|
||||
<p>
|
||||
Pour accéder au sondage : https://framadate.org/urladmindusondage
|
||||
Pour accéder au sondage :
|
||||
<a href="{{config.urlPublic}}">{{config.urlPublic}}
|
||||
</a>
|
||||
|
||||
</p>
|
||||
<button
|
||||
class="btn"
|
||||
(click)="copyLink(publicLink)"
|
||||
(click)="copyLink(config.urlPublic)"
|
||||
[ngxClipboard]
|
||||
cbContent="{{config.urlPublic}}"
|
||||
>
|
||||
<i class="fa fa-copy"></i>
|
||||
Copier le lien
|
||||
</button>
|
||||
<a href="{{publicLink}}">
|
||||
<a href="{{config.urlPublic}}">
|
||||
Voir le sondage
|
||||
</a>
|
||||
</section>
|
||||
@ -60,16 +74,19 @@
|
||||
[(ngModel)]="mailToRecieve"
|
||||
paceholder="email"
|
||||
>
|
||||
|
||||
</p>
|
||||
|
||||
<button
|
||||
class="btn"
|
||||
(click)="sendToEmail()"
|
||||
>
|
||||
><i class="fa fa-paper-plane"></i>
|
||||
Envoyer les liens du sondage
|
||||
</button>
|
||||
<a href="{{publicLink}}">
|
||||
<a href="{{config.urlPublic}}">
|
||||
Voir le sondage
|
||||
</a>
|
||||
|
||||
</section>
|
||||
|
||||
<p-toast position="bottom-right"></p-toast>
|
||||
|
@ -0,0 +1,5 @@
|
||||
:host {
|
||||
button {
|
||||
margin-right: 1em;
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {BaseComponent} from '../base-page/base.component';
|
||||
import {ConfigService} from '../../config.service';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {ConfigService} from "../../services/config.service";
|
||||
import {MessageService} from 'primeng/api';
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-end-confirmation',
|
||||
@ -9,19 +10,25 @@ import {HttpClient} from '@angular/common/http';
|
||||
styleUrls: ['./end-confirmation.component.scss']
|
||||
})
|
||||
export class EndConfirmationComponent extends BaseComponent implements OnInit {
|
||||
public adminLink = '';
|
||||
public publicLink = '';
|
||||
mailToRecieve = '';
|
||||
|
||||
constructor(public config: ConfigService, public http: HttpClient) {
|
||||
constructor(public config: ConfigService,
|
||||
public http: HttpClient,
|
||||
private messageService: MessageService
|
||||
) {
|
||||
super(config);
|
||||
this.mailToRecieve = this.config.myEmail;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
copyLink(adminLink: any) {
|
||||
|
||||
copyLink(str: any) {
|
||||
this.messageService.add({
|
||||
severity: 'success',
|
||||
summary: 'Lien copié',
|
||||
detail: str
|
||||
});
|
||||
}
|
||||
|
||||
sendToEmail() {
|
||||
|
@ -10,10 +10,10 @@
|
||||
{{"creation.want"|translate}}
|
||||
</span>
|
||||
<select
|
||||
[(ngModel)]="config.pollType"
|
||||
autofocus="autofocus"
|
||||
id="selector"
|
||||
name="selector"
|
||||
autofocus="autofocus"
|
||||
[(ngModel)]="config.pollType"
|
||||
>
|
||||
<option value="dates">
|
||||
{{"creation.kind.date"|translate}}
|
||||
@ -29,18 +29,18 @@
|
||||
<div>
|
||||
|
||||
<label
|
||||
for="poll_title"
|
||||
class="title-label"
|
||||
for="poll_title"
|
||||
i18n
|
||||
>
|
||||
{{"creation.choose_title"|translate}}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
[(ngModel)]="config.title"
|
||||
id="poll_title"
|
||||
name="poll_title"
|
||||
placeholder="{{'creation.choose_title_placeholder'|translate}}"
|
||||
[(ngModel)]="config.title"
|
||||
type="name"
|
||||
>
|
||||
</div>
|
||||
|
||||
@ -49,31 +49,44 @@
|
||||
{{"creation.name"|translate}} :
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="my_name"
|
||||
id="my_name"
|
||||
placeholder="{{'creation.name_placeholder'|translate}}"
|
||||
[(ngModel)]="config.myName"
|
||||
id="my_name"
|
||||
name="my_name"
|
||||
placeholder="{{'creation.name_placeholder'|translate}}"
|
||||
type="name"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
for="poll_description"
|
||||
class="title-label"
|
||||
for="poll_description"
|
||||
i18n
|
||||
>
|
||||
{{"creation.description"|translate}}
|
||||
</label>
|
||||
<textarea
|
||||
id="poll_description"
|
||||
name="poll_description"
|
||||
[(ngModel)]="config.description"
|
||||
placeholder="description"
|
||||
cols="50"
|
||||
id="poll_description"
|
||||
lines="5"
|
||||
name="poll_description"
|
||||
placeholder="description"
|
||||
></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label for="email">
|
||||
Mon email pour administrer le sondage est
|
||||
</label>
|
||||
<input
|
||||
[(ngModel)]="config.myEmail"
|
||||
autofocus="autofocus"
|
||||
id="email"
|
||||
name="mail"
|
||||
required="required"
|
||||
type="email"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
[routerLink]="'/step/answers'"
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {ConfigService} from "../../config.service";
|
||||
import {ConfigService} from "../../services/config.service";
|
||||
import {BaseComponent} from "../base-page/base.component";
|
||||
|
||||
@Component({
|
||||
|
@ -104,9 +104,9 @@
|
||||
|
||||
<label for="">Un label pour les labelliser tous</label>
|
||||
|
||||
<h3>Input text</h3>
|
||||
<input type="text" name="" id=""><br>
|
||||
<input type="text" 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>
|
||||
@ -198,9 +198,9 @@
|
||||
</article>
|
||||
|
||||
<article>
|
||||
<h2>Label + input text</h2>
|
||||
<h2>Label + input name</h2>
|
||||
<label for="test-text">Ceci est un label un peu long mais pas trop</label>
|
||||
<input type="text" name="test-text" id="test-text">
|
||||
<input type="name" name="test-text" id="test-text">
|
||||
</article>
|
||||
|
||||
<article>
|
||||
@ -220,7 +220,7 @@
|
||||
</article>
|
||||
|
||||
<article>
|
||||
<h2>Input text with info</h2>
|
||||
<h2>Input name with info</h2>
|
||||
<a href="https://sketch.cloud/s/00A80/a/MAl5q7">like here</a>
|
||||
</article>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {BaseComponent} from '../base-page/base.component';
|
||||
import {ConfigService} from '../../config.service';
|
||||
import {ConfigService} from '../../services/config.service';
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-page-kind',
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {BaseComponent} from "../base-page/base.component";
|
||||
import {ConfigService} from "../../config.service";
|
||||
import {ConfigService} from "../../services/config.service";
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-password',
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {ConfigService} from '../../config.service';
|
||||
import {ConfigService} from '../../services/config.service';
|
||||
import {BaseComponent} from '../base-page/base.component';
|
||||
|
||||
@Component({
|
||||
|
47
src/app/pages/poll-display/poll-display.component.html
Normal file
47
src/app/pages/poll-display/poll-display.component.html
Normal file
@ -0,0 +1,47 @@
|
||||
<div class="poll">
|
||||
|
||||
<h1>{{pollConfigFetched.data.title}}</h1>
|
||||
<p>{{pollConfigFetched.data.description}}</p>
|
||||
<p class="creationDate">{{pollConfigFetched.data.creationDate.date}}</p>
|
||||
<p class="expiracyDate">{{pollConfigFetched.data.creationDate.date}}</p>
|
||||
<p class="votants">
|
||||
{{pollConfigFetched.stacks_count}} votants,
|
||||
{{pollConfigFetched.choices_count}} choix,
|
||||
</p>
|
||||
</div>
|
||||
<section class="row name">
|
||||
<label for="name">Votre nom :</label>
|
||||
<input type="text" name="name" id="name" [(ngModel)]="config.myName">
|
||||
</section>
|
||||
<div class="list-of-choices">
|
||||
<div *ngFor="let choice of pollConfigFetched.choices">
|
||||
<framadate-vote-choice [choice]="choice"></framadate-vote-choice>
|
||||
</div>
|
||||
</div>
|
||||
<framadate-voting-graph></framadate-voting-graph>
|
||||
<framadate-voting-summary></framadate-voting-summary>
|
||||
<div class="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" id="crname">
|
||||
<div>
|
||||
<label for="comment">Votre commentaire :</label>
|
||||
<textarea name="comment" id="comment">
|
||||
</textarea>
|
||||
</div>
|
||||
<input type="submit" name="add-comment" class="btn btn--primary btn--outline" value="Ajouter mon commentaire">
|
||||
<framadate-voting-comment [comment]="c" *ngFor="let c of comments"></framadate-voting-comment>
|
||||
|
||||
</div>
|
||||
<div class="sharing">
|
||||
<h3 class="margin-top-x8">Partager le sondage</h3>
|
||||
<label class="nobold text-14" for="copyLink">Pour partager le sondage, vous pouvez diffuser ce lien :
|
||||
<code>
|
||||
{{config.urlAdmin}}
|
||||
</code>
|
||||
</label>
|
||||
<input type="submit" name="copy-link" class=" btn btn--primary btn--outline" value="Copier le lien" id="copyLink">
|
||||
<h3 class="margin-top-x6 margin-btm-x3">Exporter/Imprimer</h3>
|
||||
<input type="submit" name="export" class="margin-btm-x3 btn btn--primary btn--outline" value="Exporter en .csv" (click)="exportCSV()">
|
||||
<input type="submit" name="copy-link" class="btn btn--primary btn--outline" value="Imprimer le sondage">
|
||||
</div>
|
1
src/app/pages/poll-display/poll-display.component.scss
Normal file
1
src/app/pages/poll-display/poll-display.component.scss
Normal file
@ -0,0 +1 @@
|
||||
@import "../../../assets/scss/variables";
|
25
src/app/pages/poll-display/poll-display.component.spec.ts
Normal file
25
src/app/pages/poll-display/poll-display.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PollDisplayComponent } from './poll-display.component';
|
||||
|
||||
describe('PollDisplayComponent', () => {
|
||||
let component: PollDisplayComponent;
|
||||
let fixture: ComponentFixture<PollDisplayComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ PollDisplayComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PollDisplayComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
29
src/app/pages/poll-display/poll-display.component.ts
Normal file
29
src/app/pages/poll-display/poll-display.component.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {BaseComponent} from "../base-page/base.component";
|
||||
import {ConfigService} from "../../services/config.service";
|
||||
import {mockPoll3} from "../../config/mock-poll3";
|
||||
import {mockComments} from "../../config/mock-comments";
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-poll-display',
|
||||
templateUrl: './poll-display.component.html',
|
||||
styleUrls: ['./poll-display.component.scss']
|
||||
})
|
||||
export class PollDisplayComponent extends BaseComponent implements OnInit {
|
||||
|
||||
private pollConfigFetched = mockPoll3;
|
||||
private comments = mockComments;
|
||||
|
||||
constructor(public config: ConfigService) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
// fetch poll with its ID or slug.
|
||||
// store it in the poll property here
|
||||
}
|
||||
|
||||
exportCSV() {
|
||||
// TODO
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {BaseComponent} from '../base-page/base.component';
|
||||
import {ConfigService} from '../../config.service';
|
||||
import {ConfigService} from '../../services/config.service';
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-resume',
|
||||
|
@ -103,7 +103,7 @@
|
||||
{{"visibility.access_url_key"|translate}}
|
||||
</label>
|
||||
<br>
|
||||
<input type="text"
|
||||
<input type="name"
|
||||
class="input-lg"
|
||||
name="url"
|
||||
id="url"
|
||||
@ -112,6 +112,9 @@
|
||||
<sub class="instructions">
|
||||
{{"visibility.access_instructions"|translate}}
|
||||
</sub>
|
||||
<div class="preview-url">
|
||||
{{baseUrl + '/' + config.customUrl}}
|
||||
</div>
|
||||
<br>
|
||||
<label for="passwordAccess">
|
||||
{{"visibility.access_want"|translate}}
|
||||
@ -133,13 +136,15 @@
|
||||
min="8"
|
||||
*ngIf="!showCustomPassword"
|
||||
[(ngModel)]="config.password">
|
||||
<input type="text"
|
||||
<input type="name"
|
||||
name="password_visible"
|
||||
id="password_visible"
|
||||
min="8"
|
||||
*ngIf="showCustomPassword"
|
||||
[(ngModel)]="config.password">
|
||||
<button class="btn btn--default" (click)="showCustomPassword = !showCustomPassword">
|
||||
<button (click)="showCustomPassword = !showCustomPassword" [disabled]="!config.password"
|
||||
class="btn btn--default">
|
||||
<i class="fa fa-eye"></i>
|
||||
{{"visibility.see_pass"|translate}}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {BaseComponent} from '../base-page/base.component';
|
||||
import {ConfigService} from '../../config.service';
|
||||
import {ConfigService} from '../../services/config.service';
|
||||
import {environment} from "../../../environments/environment";
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-visibility',
|
||||
@ -9,35 +10,16 @@ import {ConfigService} from '../../config.service';
|
||||
})
|
||||
export class VisibilityComponent extends BaseComponent implements OnInit {
|
||||
showCustomPassword = false;
|
||||
baseUrl = environment.baseApiHref;
|
||||
|
||||
constructor(public config: ConfigService) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.config.customUrl = this.makeUuid();
|
||||
this.config.expirationDate = (this.addDaysToDate(this.config.expiracyDateDefaultInDays, new Date())).toISOString().substring(0, 10);
|
||||
this.config.customUrl = this.config.makeSlug();
|
||||
this.config.expirationDate = (this.config.addDaysToDate(this.config.expiracyDateDefaultInDays, new Date())).toISOString().substring(0, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* generate unique id to have a default url for future poll
|
||||
*/
|
||||
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);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* add some days to a date, to compute intervals
|
||||
* @param days
|
||||
* @param date
|
||||
*/
|
||||
addDaysToDate(days: number, date: Date) {
|
||||
date = new Date(date.valueOf());
|
||||
date.setDate(date.getDate() + days);
|
||||
return date;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
<p>voting-graph works!</p>
|
@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {BaseComponent} from "../base-page/base.component";
|
||||
import {ConfigService} from "../../config.service";
|
||||
import {BaseComponent} from "../../base-page/base.component";
|
||||
import {ConfigService} from "../../../services/config.service";
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-voting-choice',
|
@ -0,0 +1,7 @@
|
||||
<div class="comment">
|
||||
<span class="cname">{{comment.name}} </span>, le
|
||||
<span class="date padding-btm-x1">{{comment.date}}</span>
|
||||
<p class="text">
|
||||
{{comment.text}}
|
||||
</p>
|
||||
</div>
|
@ -0,0 +1,25 @@
|
||||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {VotingCommentComponent} from './voting-comment.component';
|
||||
|
||||
describe('VotingCommentComponent', () => {
|
||||
let component: VotingCommentComponent;
|
||||
let fixture: ComponentFixture<VotingCommentComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [VotingCommentComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(VotingCommentComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,19 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {mockComments} from "../../../config/mock-comments";
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-voting-comment',
|
||||
templateUrl: './voting-comment.component.html',
|
||||
styleUrls: ['./voting-comment.component.scss']
|
||||
})
|
||||
export class VotingCommentComponent implements OnInit {
|
||||
|
||||
@Input() private comment = mockComments[0];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<h1>Graphique</h1>
|
||||
<framadate-poll-graphic></framadate-poll-graphic>
|
@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {BaseComponent} from "../base-page/base.component";
|
||||
import {ConfigService} from "../../config.service";
|
||||
import {BaseComponent} from "../../base-page/base.component";
|
||||
import {ConfigService} from "../../../services/config.service";
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-voting-graph',
|
@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {BaseComponent} from "../base-page/base.component";
|
||||
import {ConfigService} from "../../config.service";
|
||||
import {BaseComponent} from "../../base-page/base.component";
|
||||
import {ConfigService} from "../../../services/config.service";
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-voting-summary',
|
@ -1,58 +1,24 @@
|
||||
|
||||
<form>
|
||||
<h1 >Nom du sondage</h1>
|
||||
|
||||
<p>crée par piou</p>
|
||||
|
||||
<p>Pokem ipsum dolor sit amet Electric Cottonee Scratch Leech Life Ice Berry Ducklett. Leaf Green Durant Zoroark Skitty Rock Luxio Surskit. Glacier Badge Fuchsia City Team Rocket Ferroseed Cranidos Exeggcute Entei. Dig Thunder Badge Exeggcute Mightyena Milotic Mantyke Drapion. Hydro Pump Silver Treecko Missingno Growlithe Wingull Registeel. </p>
|
||||
<section class="row name">
|
||||
<label for="name">Votre nom :</label>
|
||||
<input type="text" name="name">
|
||||
</section>
|
||||
<framadate-vote-choice></framadate-vote-choice>
|
||||
<framadate-vote-choice></framadate-vote-choice>
|
||||
<framadate-vote-choice></framadate-vote-choice>
|
||||
<framadate-vote-choice></framadate-vote-choice>
|
||||
<framadate-vote-choice class=" margin-btm-x2"></framadate-vote-choice>
|
||||
<button class="btn btn--primary btn--full" ng-model="show_popup">Valider mes réponses</button>
|
||||
<p class="prefered">Pour l'instant, le choix ayant reçu le plus grand nombre de votes est :
|
||||
<li>- Vendredi 6 juillet
|
||||
</li><li>
|
||||
- Samedi 7 août
|
||||
</li>
|
||||
</p>
|
||||
<a class="next">Voir le graphique</a>
|
||||
<input type="submit" name="modify" class="btn btn--primary btn--outline btn--full"value="Je veux modifier le vote de quelqu'un">
|
||||
<input type="submit" name="modify" class="btn btn--primary btn--outline btn--full"
|
||||
value="Je veux modifier le vote de quelqu'un">
|
||||
<h2 class="margin-top-x4">Les commentaires</h2>
|
||||
<p class="comment">
|
||||
<span class="cname">Pikachu </span>
|
||||
<span class="date date padding-btm-x1"> le 26 novembre 2019</span>
|
||||
Rock Luxio Surskit. Glacier Badge
|
||||
</p>
|
||||
<p class="comment">
|
||||
<span class="cname">Bulbizarre </span>
|
||||
<span class="date padding-btm-x1">le 23 décembre 2019</span>
|
||||
Pokem ipsum dolor sit amet Electric Cottonee Scratch Leech Life Ice Berry Ducklett. Leaf Green Durant Zoroark Skitty Rock Luxio Surskit. Glacier Badge
|
||||
</p>
|
||||
|
||||
<h2 class="margin-top-x7">Laisser un commentaire</h2>
|
||||
<label for="crname">Votre nom :</label>
|
||||
<input type="text" class="margin-btm-x3" name="crname">
|
||||
<label for="comment">Votre commentaire :</label>
|
||||
<textarea name="comment">
|
||||
</textarea>
|
||||
<input type="submit" name="add-comment" class="btn btn--primary btn--outline"value="Ajouter mon commentaire">
|
||||
<h3 class="margin-top-x8">Partager le sondage</h3>
|
||||
<label class="nobold text-14" for="copy-link">Pour partager le sondage, vous pouvez diffuser ce lien : https://framadate.org/urladmindusondage</label>
|
||||
<input type="submit" name="copy-link" class=" btn btn--primary btn--outline"value="Copier le lien">
|
||||
<h3 class="margin-top-x6 margin-btm-x3">Exporter/Imprimer</h3>
|
||||
<input type="submit" name="export" class="margin-btm-x3 btn btn--primary btn--outline"value="Exporter en .csv">
|
||||
<input type="submit" name="copy-link" class="btn btn--primary btn--outline"value="Imprimer le sondage">
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
<div ng-show="show_popup" class="popup">
|
||||
<h4 class="margin-btm-x2">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>
|
||||
<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>
|
||||
<p>https://framadate.org/urladmindusondage</p>
|
||||
<button class="btn btn--primary btn--small btn--purple btn--black-text">Copier le lien</button>
|
||||
<p class="margin-btm-x6 margin-top-x2">Conservez-le précieusement !</p>
|
||||
|
@ -1,71 +0,0 @@
|
||||
@import "../../../assets/scss/variables";
|
||||
form{
|
||||
display:flex;
|
||||
margin:auto;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.popup{
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
z-index:2222222222;
|
||||
}
|
||||
.row{
|
||||
flex-direction: row;
|
||||
}
|
||||
label{
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
}
|
||||
.comment,.prefered{
|
||||
border-left:6px solid $ugly-purple ;
|
||||
padding-left: 5px;
|
||||
margin-top:25px;
|
||||
margin-bottom: 25px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.comment{
|
||||
display:flex;
|
||||
}
|
||||
.commeny span{
|
||||
flex-direction: row;
|
||||
}
|
||||
.cname{
|
||||
padding-left:17px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.btn{
|
||||
max-width: 300px;
|
||||
}
|
||||
.next{
|
||||
max-width:200px;
|
||||
}
|
||||
input[type=text],textarea{
|
||||
max-width:350px;
|
||||
}
|
||||
li{
|
||||
list-style-type: none;
|
||||
}
|
||||
h2{
|
||||
|
||||
}
|
||||
.next{
|
||||
align-self: flex-end;
|
||||
margin-bottom:50px;
|
||||
}
|
||||
textarea{
|
||||
height:213px;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
.name{
|
||||
margin-bottom:50px;
|
||||
margin-top:50px;
|
||||
}
|
||||
label{
|
||||
align-items: flex-start;
|
||||
}
|
||||
.nobold{
|
||||
font-weight: normal;
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
autofocus="autofocus"
|
||||
[(ngModel)]="isColorblind"
|
||||
(change)="toggleColorblind()"
|
||||
class="input"
|
||||
>
|
||||
<option value="true">
|
||||
{{ "pollGraphic.choiceColorblind" | translate }}
|
||||
@ -12,8 +13,14 @@
|
||||
{{ "pollGraphic.choiceNotColorblind" | translate }}
|
||||
</option>
|
||||
</select>
|
||||
<span class="colorblind">
|
||||
{{ "pollGraphic.colorblindText" | translate }}
|
||||
</span>
|
||||
<div>
|
||||
<canvas id="graph" width="100" height="50"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="preferred">
|
||||
Pour l'instant, le choix ayant reçu le plus grand nombre de votes est :
|
||||
{{preferred}}
|
||||
</div>
|
||||
|
@ -1,5 +1,7 @@
|
||||
import {Component, OnInit} from "@angular/core";
|
||||
import {Component, Inject, OnInit} from "@angular/core";
|
||||
import {Chart} from "chart.js";
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import {mockGraphConfig} from "../config/mock-graph";
|
||||
|
||||
@Component({
|
||||
selector: "framadate-poll-graphic",
|
||||
@ -8,75 +10,24 @@ import {Chart} from "chart.js";
|
||||
})
|
||||
export class PollGraphicComponent implements OnInit {
|
||||
isColorblind: boolean = false;
|
||||
lineChart: Chart;
|
||||
pollData: any;
|
||||
preferred: any = "rien";
|
||||
yesList: number[] = [];
|
||||
maybeList: number[] = [];
|
||||
noList: number[] = [];
|
||||
nbPoll: number = 0;
|
||||
dateList: string[] = [];
|
||||
|
||||
constructor() {
|
||||
constructor(@Inject(DOCUMENT) private document: any,) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
var toto = {
|
||||
step: 0,
|
||||
stepMax: 3,
|
||||
pollType: "special dates",
|
||||
title: "",
|
||||
description: "",
|
||||
myName: "",
|
||||
visibility: "link_only",
|
||||
// date specific poll
|
||||
allowSeveralHours: "true",
|
||||
dateLgfgfgfgist: ["jeudi", "vendredi", "samedi"], // sets of days as strings
|
||||
timeList: ["08:00", "08:30", "09:00"], // ranges of time expressed as strings
|
||||
answers: [
|
||||
{
|
||||
id: 0,
|
||||
text: "no"
|
||||
},
|
||||
|
||||
{
|
||||
id: 1,
|
||||
text: "yes"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
text: "maybe"
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
text: "maybe"
|
||||
}
|
||||
]
|
||||
};
|
||||
var toto = mockGraphConfig;
|
||||
|
||||
this.formatDataAnswers(toto);
|
||||
|
||||
this.isColorblind = false;
|
||||
this.pollData = new Chart(document.getElementById("graph"), {
|
||||
this.pollData = new Chart(this.document.getElementById("graph"), {
|
||||
type: "horizontalBar",
|
||||
data: {
|
||||
labels: ["jeudi"],
|
||||
|
377
src/app/services/config.service.ts
Normal file
377
src/app/services/config.service.ts
Normal file
@ -0,0 +1,377 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {PollConfig} from '../config/PollConfig';
|
||||
import {HttpClient, HttpHeaders} from "@angular/common/http";
|
||||
import {environment} from "../../environments/environment";
|
||||
import {MessageService} from 'primeng/api';
|
||||
|
||||
/**
|
||||
* le service transverse à chaque page qui permet de syncroniser la configuration de sondage souhaitée
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ConfigService extends PollConfig {
|
||||
|
||||
loading: boolean = false;
|
||||
baseHref: any = environment.baseApiHref;
|
||||
myPolls: any;// list of retrieved polls from the backend api
|
||||
|
||||
|
||||
constructor(private http: HttpClient,
|
||||
private messageService: MessageService) {
|
||||
super();
|
||||
}
|
||||
|
||||
set(key, val) {
|
||||
this[key] = val;
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.messageService.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* generate unique id to have a default url for future poll
|
||||
*/
|
||||
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);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
makeSlug(str?: string) {
|
||||
if (!str) {
|
||||
str = this.creationDate.getFullYear() + '_' + (this.creationDate.getMonth() + 1) + '_' + this.creationDate.getDate() + '_' + this.myName + '_' + this.title;
|
||||
}
|
||||
str = str.replace(/^\s+|\s+$/g, ''); // trim
|
||||
str = str.toLowerCase();
|
||||
|
||||
// remove accents, swap ñ for n, etc
|
||||
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
|
||||
.replace(/\s+/g, '-') // collapse whitespace and replace by -
|
||||
.replace(/-+/g, '-'); // collapse dashes
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* add some days to a date, to compute intervals
|
||||
* @param days
|
||||
* @param date
|
||||
*/
|
||||
addDaysToDate(days: number, date: Date) {
|
||||
date = new Date(date.valueOf());
|
||||
date.setDate(date.getDate() + days);
|
||||
return date;
|
||||
};
|
||||
|
||||
/** ==================================
|
||||
*
|
||||
* poll public calls to get non authenticated info
|
||||
*
|
||||
* ==================================/
|
||||
/**
|
||||
* convert current poll config to a payload to send to the backend API
|
||||
*/
|
||||
getPollConfig() {
|
||||
const jsonConfig = {
|
||||
method: 'POST',
|
||||
data: {
|
||||
|
||||
owner: {
|
||||
email: this.myEmail,
|
||||
pseudo: this.myName,
|
||||
},
|
||||
title: this.title,
|
||||
description: this.description,
|
||||
type: this.pollType,
|
||||
visibility: this.visibility,
|
||||
voteChoices: this.voteChoices,
|
||||
allowSeveralHours: this.allowSeveralHours,
|
||||
expirationDate: this.expirationDate,
|
||||
passwordAccess: this.passwordAccess,
|
||||
password: this.password,
|
||||
customUrl: this.customUrl,
|
||||
canModifyAnswers: this.canModifyAnswers,
|
||||
whoModifiesAnswers: this.whoModifiesAnswers,
|
||||
dateList: this.dateList,
|
||||
timeList: this.timeList,
|
||||
answers: this.answers,
|
||||
}
|
||||
};
|
||||
console.log('jsonConfig', jsonConfig);
|
||||
return jsonConfig
|
||||
}
|
||||
|
||||
makeHeaders(bodyContent?: any) {
|
||||
|
||||
const headerDict = {
|
||||
'Charset': 'UTF-8',
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
|
||||
'Access-Control-Allow-Origin': '*'
|
||||
};
|
||||
|
||||
const requestOptions = {
|
||||
headers: new HttpHeaders(headerDict),
|
||||
body: bodyContent
|
||||
};
|
||||
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
checkIfSlugIsUniqueInDatabase(slug: string) {
|
||||
this.customUrlIsUnique = null;
|
||||
|
||||
this.loading = true;
|
||||
this.http.get(`${this.baseHref}/check-slug-is-uniq`,
|
||||
this.makeHeaders({slug: this.customUrl}),
|
||||
)
|
||||
.subscribe((res: any) => {
|
||||
|
||||
this.customUrlIsUnique = res.data.isUnique;
|
||||
this.loading = false;
|
||||
},
|
||||
(e) => this.handleError(e))
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* search in localstorage, fallback asking the backend to send an email to the owner if it exists
|
||||
* @param email
|
||||
*/
|
||||
findPollsByEmail(email: string) {
|
||||
|
||||
|
||||
this.findLocalStorageData();
|
||||
// If no key is found in the localstorage, ask the backend to send an email to the user
|
||||
|
||||
this.myEmail = email;
|
||||
|
||||
|
||||
this.loading = true;
|
||||
this.http.get(`${this.baseHref}/my-polls`,
|
||||
this.makeHeaders({email: this.myEmail}),
|
||||
)
|
||||
.subscribe(res => {
|
||||
// message: 'Trouvé! Allez voir votre boite email',
|
||||
this.myPolls = res;
|
||||
console.log('res', res);
|
||||
this.loading = false;
|
||||
this.messageService.add({
|
||||
severity: 'success',
|
||||
summary: 'Service Message',
|
||||
detail: 'Via MessageService'
|
||||
});
|
||||
}, (e) => {
|
||||
this.handleError(e)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* display error message depending on the response of the backend
|
||||
* @param err
|
||||
*/
|
||||
handleError(err: any) {
|
||||
// TODO handle a toast message
|
||||
console.error('err', err);
|
||||
this.loading = false;
|
||||
this.messageService.add({severity: 'warning', summary: "Erreur lors de l'appel ", detail: err.message});
|
||||
}
|
||||
|
||||
|
||||
findLocalStorageData() {
|
||||
// TODO check if the person has a key to retrieve her polls
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get one poll by its slug name
|
||||
* @param url
|
||||
*/
|
||||
getPollByURL(url: string) {
|
||||
this.http.get(`${this.baseHref}/poll/${url}`, this.makeHeaders()).subscribe(
|
||||
(res: any) => {
|
||||
this.myPolls = res.data;
|
||||
}, (e) => {
|
||||
this.handleError(e)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET
|
||||
* api/v1/poll/{id}
|
||||
* @param id
|
||||
*/
|
||||
getPollById(id: string, password: string) {
|
||||
|
||||
this.http
|
||||
.get(`${this.baseHref}/poll/${id}`,
|
||||
this.makeHeaders({body: password}))
|
||||
.subscribe(
|
||||
(res: any) => {
|
||||
this.myPolls = res.data;
|
||||
}, (e) => {
|
||||
this.handleError(e)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET
|
||||
* api/v1/my-polls
|
||||
* @param ownerEmail
|
||||
*/
|
||||
getMyPolls(ownerEmail: string) {
|
||||
this.http
|
||||
.get(`${this.baseHref}/my-polls`,
|
||||
this.makeHeaders({ownerEmail: ownerEmail})
|
||||
)
|
||||
.subscribe(
|
||||
(res: any) => {
|
||||
this.myPolls = res.data;
|
||||
}, (e) => {
|
||||
this.handleError(e)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* action of the form
|
||||
*/
|
||||
createPoll() {
|
||||
console.log('sends the form');
|
||||
// alert('envoi de formulaire pour création de sondage en XHR à faire');
|
||||
this.http.get(`${this.baseHref}/`, this.makeHeaders())
|
||||
.subscribe((res) => {
|
||||
console.log('res', res);
|
||||
this.createPollFromConfig(this.getPollConfig())
|
||||
},
|
||||
this.handleError
|
||||
)
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* POST
|
||||
* /api/v1/poll/{id}/poll
|
||||
* @param config
|
||||
*/
|
||||
createPollFromConfig(config: any) {
|
||||
this.http.post(`${this.baseHref}/poll`, this.makeHeaders({config: config}))
|
||||
.subscribe((res: any) => {
|
||||
// redirect to the page to administrate the new poll
|
||||
this.messageService.add({severity: 'success', summary: 'Sondage Créé',});
|
||||
this.selectedPoll = res;
|
||||
this.pollId = res.pollId;
|
||||
}, (e) => {
|
||||
this.handleError(e)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* UPDATE
|
||||
* /api/v1/poll/{id}/vote
|
||||
* @param voteStack
|
||||
*/
|
||||
updatePoll(voteStack: any) {
|
||||
this.http.put(
|
||||
`${this.baseHref}/poll/${this.pollId}`,
|
||||
voteStack,
|
||||
this.makeHeaders()
|
||||
)
|
||||
.subscribe((res: any) => {
|
||||
this.messageService.add({
|
||||
severity: 'success',
|
||||
summary: 'Sondage mis à jour',
|
||||
});
|
||||
this.myPolls = res;
|
||||
}, (e) => {
|
||||
this.handleError(e)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST
|
||||
* /api/v1/poll/{id}/vote
|
||||
* @param voteStack
|
||||
*/
|
||||
addVote(voteStack: any) {
|
||||
this.http.post(
|
||||
`${this.baseHref}/poll/${this.pollId}/vote`,
|
||||
voteStack,
|
||||
this.makeHeaders())
|
||||
.subscribe((res: any) => {
|
||||
|
||||
this.messageService.add({severity: 'success', summary: 'Vote ajouté'});
|
||||
alert("succès!");
|
||||
this.myPolls = res;
|
||||
}, (e) => {
|
||||
this.handleError(e)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* UPDATE
|
||||
* /api/v1/poll/{id}/vote
|
||||
* @param voteStack
|
||||
*/
|
||||
updateVote(voteStack: any) {
|
||||
this.http.put(
|
||||
`${this.baseHref}/poll/${this.pollId}/vote`,
|
||||
voteStack,
|
||||
this.makeHeaders())
|
||||
.subscribe((res: any) => {
|
||||
this.messageService.add({severity: 'success', summary: 'Vote mis à jour'});
|
||||
this.myPolls = res;
|
||||
}, (e) => {
|
||||
this.handleError(e)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST
|
||||
* /api/v1/poll/{id}/comment
|
||||
* @param comment
|
||||
*/
|
||||
addComment(comment: any) {
|
||||
this.http.post(
|
||||
`${this.baseHref}/poll/${this.pollId}/comment`,
|
||||
comment,
|
||||
this.makeHeaders())
|
||||
.subscribe((res: any) => {
|
||||
this.messageService.add({
|
||||
severity: 'success',
|
||||
summary: 'Commentaire Créé',
|
||||
detail: 'Via MessageService'
|
||||
});
|
||||
}, (e) => {
|
||||
this.handleError(e)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* administrator calls
|
||||
*/
|
||||
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PollServiceService } from './poll-service.service';
|
||||
import { PollService } from './poll.service';
|
||||
|
||||
describe('PollServiceService', () => {
|
||||
beforeEach(() => TestBed.configureTestingModule({}));
|
||||
|
||||
it('should be created', () => {
|
||||
const service: PollServiceService = TestBed.get(PollServiceService);
|
||||
const service: PollService = TestBed.get(PollService);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,32 +0,0 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ConfigService} from "../config.service";
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import {environment} from "../../environments/environment";
|
||||
|
||||
class JsonResponse {
|
||||
message: string;
|
||||
data: string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class PollServiceService {
|
||||
|
||||
private baseHref: string = environment.baseApiHref;
|
||||
|
||||
constructor(private configService: ConfigService,
|
||||
private http: HttpClient) {
|
||||
}
|
||||
|
||||
findPollsByEmail(email: string) {
|
||||
// TODO check if the person has a key to retrieve her polls
|
||||
// If no key is found in the localstorage, ask the backend to send an email to the user
|
||||
|
||||
this.configService.myEmail = email;
|
||||
this.http.get(this.baseHref + '/').subscribe(res => {
|
||||
this.configService.myPolls = res;
|
||||
}, err => console.error('err', err)
|
||||
)
|
||||
}
|
||||
}
|
15
src/app/services/poll.service.ts
Normal file
15
src/app/services/poll.service.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {environment} from "../../environments/environment";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class PollService {
|
||||
|
||||
private baseHref: string = environment.baseApiHref;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
|
||||
}
|
8
src/app/ui/directives/resettable-input.directive.spec.ts
Normal file
8
src/app/ui/directives/resettable-input.directive.spec.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { ResettableInputDirective } from './resettable-input.directive';
|
||||
|
||||
describe('ResettableInputDirective', () => {
|
||||
it('should create an instance', () => {
|
||||
const directive = new ResettableInputDirective();
|
||||
expect(directive).toBeTruthy();
|
||||
});
|
||||
});
|
11
src/app/ui/directives/resettable-input.directive.ts
Normal file
11
src/app/ui/directives/resettable-input.directive.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import {Directive} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[framadateResettableInput]'
|
||||
})
|
||||
export class ResettableInputDirective {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
}
|
@ -69,6 +69,9 @@
|
||||
>
|
||||
Page démo
|
||||
</a>
|
||||
<a [routerLink]="'/vote/poll/id/3'" i18n>
|
||||
Sondage dessins animés
|
||||
</a>
|
||||
<a
|
||||
[routerLink]="'/graphic/toto'"
|
||||
[ngClass]="{'active': step == 'graphic'}"
|
||||
|
@ -1,7 +1,8 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {BaseComponent} from '../../pages/base-page/base.component';
|
||||
import {ConfigService} from '../../config.service';
|
||||
|
||||
import {Router} from '@angular/router';
|
||||
import {ConfigService} from '../../services/config.service';
|
||||
|
||||
@Component({
|
||||
selector: 'framadate-navigation',
|
||||
|
@ -1,7 +1,10 @@
|
||||
<div class="choicebox"><!-- add .choicebox--active to most voted -->
|
||||
|
||||
<div class="choicebox selection-{{choice.answer}}"><!-- add .choicebox--active to most voted -->
|
||||
<div class="text title ">
|
||||
{{choice.name}}
|
||||
</div>
|
||||
<div class="choicebox__subject">
|
||||
|
||||
|
||||
<!-- TEXT CASE --><!--
|
||||
<p class="choicebox__txt">
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Nulla nobis nam culpa !
|
||||
@ -13,12 +16,15 @@
|
||||
--><!-- IMG CASE -->
|
||||
|
||||
<!-- DATE CASE -->
|
||||
<div class="choicebox__date" *ngIf="choice.date">
|
||||
{{choice.date | date:'EEE'}} <span class="choicebox__day">{{choice.date | date:'dd'}}</span> {{choice.date | date:'LLL'}}
|
||||
<div class="dates" *ngIf="choice.date">
|
||||
<div class="choicebox__date">
|
||||
{{choice.date | date:'EEE'}} <span
|
||||
class="choicebox__day">{{choice.date | date:'dd'}}</span> {{choice.date | date:'LLL'}}
|
||||
</div>
|
||||
<div class="choicebox__hour">
|
||||
08:00
|
||||
</div>
|
||||
</div>
|
||||
<!-- DATE CASE -->
|
||||
|
||||
</div>
|
||||
@ -26,32 +32,46 @@
|
||||
<div class="choicebox__actions">
|
||||
<!-- show only the yes check if the config is set to simpleAnswer -->
|
||||
<!-- add .choicebox__btn--active to selected <button> -->
|
||||
<button class="choicebox__btn choicebox__btn--yes" type="button">
|
||||
<img src="../../assets/img/check.svg" (click)="setAnswserTo('yes')" alt="">
|
||||
<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>
|
||||
<button class="choicebox__btn choicebox__btn--maybe" type="button">
|
||||
<img src="../../assets/img/check-2.svg" (click)="setAnswserTo('maybe')" alt="" *ngIf="!choice.simpleAnswer">
|
||||
</span>
|
||||
<span class="complex-answers" *ngIf="!choice.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>
|
||||
<button class="choicebox__btn choicebox__btn--no" type="button">
|
||||
<img src="../../assets/img/croix.svg" (click)="setAnswserTo('no')" alt="" *ngIf="!choice.simpleAnswer">
|
||||
<button class="choicebox__btn choicebox__btn--no" type="button"
|
||||
[ngClass]="{'choicebox__btn--active': choice.answer === 'no'}"
|
||||
(click)="setAnswserTo('no')"
|
||||
>
|
||||
<img src="../../../assets/img/croix.svg" alt="">
|
||||
</button>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="choicebox__count">
|
||||
<button type="button" aria-describedby="choicebox-tooltip" class="choicebox__votes">
|
||||
<button type="button" aria-describedby="choicebox-tooltip" class="choicebox__votes"
|
||||
*ngIf="choice.votes.count">
|
||||
<div class="choicebox__vote">
|
||||
{{choice.votesCount.yes}}
|
||||
<img width="20px" height="21px" src="../../assets/img/votant-sur.svg" alt="">
|
||||
{{choice.votes.count.yes}}
|
||||
<img width="20px" height="21px" src="../../../assets/img/votant-sur.svg" alt="">
|
||||
</div>
|
||||
<div class="choicebox__vote">
|
||||
{{choice.votesCount.maybe}}
|
||||
<img width="22px" height="24px" src="../../assets/img/votant-pas-sur.svg" alt="">
|
||||
{{choice.votes.count.maybe}}
|
||||
<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="">
|
||||
{{choice.votesCount.yes}} "Oui"
|
||||
<img width="20px" height="21px" src="../../../assets/img/votant-sur.svg" alt="">
|
||||
{{choice.votes.count.yes}} "Oui"
|
||||
</div>
|
||||
<ul>
|
||||
<li>Lorem</li>
|
||||
@ -62,8 +82,8 @@
|
||||
</div>
|
||||
<div class="choicebox__tooltiplist">
|
||||
<div class="choicebox__tooltipttl">
|
||||
<img width="22px" height="24px" src="../../assets/img/votant-pas-sur.svg" alt="">
|
||||
{{choice.votesCount.maybe}} "Peut-être"
|
||||
<img width="22px" height="24px" src="../../../assets/img/votant-pas-sur.svg" alt="">
|
||||
{{choice.votes.count.maybe}} "Peut-être"
|
||||
</div>
|
||||
<ul>
|
||||
<li>Lorem</li>
|
@ -5,8 +5,7 @@
|
||||
// -- IMPORTS
|
||||
// ----------------------------
|
||||
|
||||
@import "../../assets/scss/variables";
|
||||
|
||||
@import "../../../assets/scss/variables";
|
||||
|
||||
|
||||
// -- VARIABLES
|
||||
@ -22,7 +21,6 @@ $img-maxheight : 12rem;
|
||||
$breakpoint-responsive: 640px; // à définir
|
||||
|
||||
|
||||
|
||||
// -- GLOBAL
|
||||
// ----------------------------
|
||||
|
||||
@ -34,11 +32,17 @@ $breakpoint-responsive : 640px; // à définir
|
||||
border-left: $box-border-width solid transparent;
|
||||
background-color: $white;
|
||||
box-shadow: 0 0 .6rem 0 rgba($black, .2);
|
||||
|
||||
&--active {
|
||||
padding-left: $box-padding;
|
||||
border-left-color: $primary_color;
|
||||
}
|
||||
|
||||
&.selection-yes {
|
||||
font-weight: 700;
|
||||
background: #e9bdeb;
|
||||
}
|
||||
|
||||
@media (min-width: $breakpoint-responsive) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -58,7 +62,6 @@ $breakpoint-responsive : 640px; // à définir
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- DATE
|
||||
// ----------------------------
|
||||
|
||||
@ -79,7 +82,6 @@ $breakpoint-responsive : 640px; // à définir
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- IMG
|
||||
// ----------------------------
|
||||
|
||||
@ -89,7 +91,6 @@ $breakpoint-responsive : 640px; // à définir
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- TXT
|
||||
// ----------------------------
|
||||
|
||||
@ -99,7 +100,6 @@ $breakpoint-responsive : 640px; // à définir
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- VOTE BTNS
|
||||
// ----------------------------
|
||||
|
||||
@ -129,21 +129,25 @@ $breakpoint-responsive : 640px; // à définir
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: $btn-margin-y $btn-margin-x;
|
||||
border: .1rem solid $primary_color;
|
||||
border: .3rem solid #ccc9c9;
|
||||
background-color: transparent;
|
||||
border-radius: 50%;
|
||||
|
||||
@media (min-width: $breakpoint-responsive) {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:hover,
|
||||
&:active {
|
||||
border-color: #ccc9c9;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
//&:focus,
|
||||
//&:hover,
|
||||
//&:active {
|
||||
//
|
||||
// border-color: #ccc9c9;
|
||||
// background-color: #f7f7f7;
|
||||
//
|
||||
// &--active {
|
||||
// border-color: #bf83c2 !important;
|
||||
// }
|
||||
//}
|
||||
|
||||
&--maybe {
|
||||
position: relative;
|
||||
@ -155,13 +159,11 @@ $breakpoint-responsive : 640px; // à définir
|
||||
}
|
||||
|
||||
&--active {
|
||||
border-width: .3rem;
|
||||
border-color: #bf83c2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- VOTE COUNT
|
||||
// ----------------------------
|
||||
|
||||
@ -195,6 +197,7 @@ $breakpoint-responsive : 640px; // à définir
|
||||
.choicebox__vote {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
& + .choicebox__vote {
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
@ -203,6 +206,7 @@ $breakpoint-responsive : 640px; // à définir
|
||||
.choicebox__countxt {
|
||||
display: none;
|
||||
margin-top: .5rem;
|
||||
|
||||
.choicebox--active & {
|
||||
display: block;
|
||||
@media (min-width: $breakpoint-responsive) {
|
||||
@ -212,7 +216,6 @@ $breakpoint-responsive : 640px; // à définir
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- TOOLTIP
|
||||
// ----------------------------
|
||||
|
||||
@ -265,6 +268,7 @@ $breakpoint-responsive : 640px; // à définir
|
||||
& + .choicebox__tooltiplist {
|
||||
padding-left: 3rem;
|
||||
}
|
||||
|
||||
ul {
|
||||
max-height: 11rem;
|
||||
overflow: auto;
|
@ -1,21 +1,22 @@
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {Component, ElementRef, Input} from '@angular/core';
|
||||
|
||||
interface VoteChoice {
|
||||
votesCount: {
|
||||
votes?: {
|
||||
yes: number
|
||||
no: number
|
||||
maybe: number
|
||||
notAnswered: number
|
||||
};
|
||||
text?: string;
|
||||
name?: string;
|
||||
date?: Date;
|
||||
answer: 'yes' | 'no' | 'maybe' | null;
|
||||
simpleAnswer: boolean; // enable if we display only a togglable "yes"
|
||||
simpleAnswer?: boolean
|
||||
false; // enable if we display only a togglable "yes"
|
||||
}
|
||||
|
||||
/**
|
||||
* each vote choice takes a configuration from the container of all choices.
|
||||
* this component is used to select a date choice, or a text answer
|
||||
* this component is used to select a date choice, or a name answer
|
||||
*/
|
||||
@Component({
|
||||
selector: 'framadate-vote-choice',
|
||||
@ -24,20 +25,9 @@ interface VoteChoice {
|
||||
})
|
||||
export class VoteChoiceComponent {
|
||||
|
||||
@Input() choice: VoteChoice = {
|
||||
date: new Date(),
|
||||
text: 'description ',
|
||||
votesCount: {
|
||||
yes: 0,
|
||||
no: 0,
|
||||
maybe: 0,
|
||||
notAnswered: 0
|
||||
},
|
||||
simpleAnswer: false,
|
||||
answer: null
|
||||
};
|
||||
@Input() private choice: any;
|
||||
|
||||
constructor() {
|
||||
constructor(private el: ElementRef) {
|
||||
|
||||
}
|
||||
|
||||
@ -53,6 +43,7 @@ export class VoteChoiceComponent {
|
||||
} else {
|
||||
this.choice.answer = newAnswer;
|
||||
}
|
||||
this.el.nativeElement.blur();
|
||||
}
|
||||
|
||||
}
|
@ -18,6 +18,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin: .5rem 0;
|
||||
|
@ -51,7 +51,7 @@ option {
|
||||
|
||||
background-color: transparent;
|
||||
background-image: url("./assets/img/fleche_bas.svg");
|
||||
padding-right: 1.5rem;
|
||||
padding-right: 2.5rem;
|
||||
|
||||
background-repeat: no-repeat;
|
||||
background-size: 9px 8px;
|
||||
@ -76,3 +76,91 @@ label {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
&:not([id]) {
|
||||
color: $dusty-orange;
|
||||
|
||||
&:before {
|
||||
content: "cet input n'a pas d'attribut id, c'est mal.";
|
||||
color: $violet;
|
||||
display: block;
|
||||
padding: 1em;
|
||||
background: yellow;
|
||||
position: relative;
|
||||
top: -1em;
|
||||
z-index: 2;
|
||||
margin-right: 0.5em;
|
||||
right: 0;
|
||||
border: solid red 2px;
|
||||
box-shadow: 0 0 10px orange;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.comment, .prefered {
|
||||
border-left: 6px solid $ugly-purple;
|
||||
padding-left: 5px;
|
||||
margin-top: 25px;
|
||||
margin-bottom: 25px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cname {
|
||||
padding-left: 17px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.btn {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.next {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
input[type=text], textarea {
|
||||
max-width: 350px;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
h2 {
|
||||
|
||||
}
|
||||
|
||||
.next {
|
||||
align-self: flex-end;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: 213px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-bottom: 50px;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.nobold {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
select, input, textarea {
|
||||
@extend .clickable;
|
||||
|
||||
&:active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: $primary_color;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
export const environment = {
|
||||
production: true,
|
||||
baseApiHref : 'http://127.0.0.1:8000/api/v1/'
|
||||
baseHref: "https://framadate-api.cipherbliss.com/",
|
||||
baseApiHref: 'https://framadate-api.cipherbliss.com/api/v1'
|
||||
};
|
||||
|
@ -4,7 +4,9 @@
|
||||
|
||||
export const environment = {
|
||||
production: false,
|
||||
baseApiHref: "http://127.0.0.1:8000/api/v1/"
|
||||
baseHref: "https://framadate-api.cipherbliss.com/",
|
||||
baseApiHref: "https://framadate-api.cipherbliss.com/api/v1"
|
||||
// baseApiHref: "http://localhost:8000/api/v1"
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1,343 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="fr" datatype="plaintext" original="ng2.template">
|
||||
<body>
|
||||
<trans-unit id="demo" datatype="html">
|
||||
<source>
|
||||
Ceci est une démo
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/app.component.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">introduction header saying just demo </note>
|
||||
<note priority="1" from="meaning">demo title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="plural_example" datatype="html">
|
||||
<source>
|
||||
Updated <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/>
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/app.component.html</context>
|
||||
<context context-type="linenumber">10</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5a134dee893586d02bffc9611056b9cadf9abfad" datatype="html">
|
||||
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/app.component.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c279d3eb8220c1a0b77adb0a520b3e81f086d046" datatype="html">
|
||||
<source>placeholder à traduire</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/app.component.html</context>
|
||||
<context context-type="linenumber">13</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="confirm" datatype="html">
|
||||
<source>C'est parfait!</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/base-page/base.component.html</context>
|
||||
<context context-type="linenumber">2</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/kind/kind.component.html</context>
|
||||
<context context-type="linenumber">4</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/visibility/visibility.component.html</context>
|
||||
<context context-type="linenumber">14</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/resume/resume.component.html</context>
|
||||
<context context-type="linenumber">10</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8dfa2af2946c94200a9c49226ac8221ddec0834d" datatype="html">
|
||||
<source>
|
||||
Config spécialement pour les dates
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/dates/dates.component.html</context>
|
||||
<context context-type="linenumber">1</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="05c94bdaeec38467e5d8ec67ef06ae02bc2721fd" datatype="html">
|
||||
<source>
|
||||
Je souhaite mettre des créneaux horaires
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/dates/dates.component.html</context>
|
||||
<context context-type="linenumber">16</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3da20d71c6eacf0bf933e2ebefcc8581b77fcd07" datatype="html">
|
||||
<source>
|
||||
pour chaque journée
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/dates/dates.component.html</context>
|
||||
<context context-type="linenumber">20</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0bd3bae4b21407cbd1ab7f12f2516aba84ee8cd5" datatype="html">
|
||||
<source>
|
||||
Ajouter une plage de dates
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/dates/dates.component.html</context>
|
||||
<context context-type="linenumber">30</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d5ac5c6775ece9a7d33e5dc3519806c6edfb87bc" datatype="html">
|
||||
<source>
|
||||
choix de Dates
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/dates/dates.component.html</context>
|
||||
<context context-type="linenumber">35</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6387b579b9b1bdb74c3dfd9d63387adb40076376" datatype="html">
|
||||
<source>
|
||||
infos de debug
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/debugger/debugger.component.html</context>
|
||||
<context context-type="linenumber">4</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ddacf8feec398fe7fcda34b82a7aa4d71e10e755" datatype="html">
|
||||
<source>
|
||||
Choix cornélien syncronisé:
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/debugger/debugger.component.html</context>
|
||||
<context context-type="linenumber">27</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d146b7d3598f0f99412cb115c4c9b9dc6724a3db" datatype="html">
|
||||
<source>
|
||||
sondage classique
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/debugger/debugger.component.html</context>
|
||||
<context context-type="linenumber">37</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9e1841dca6f43cec422f009746b78fa72021aed3" datatype="html">
|
||||
<source>
|
||||
sondage spécial date
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/debugger/debugger.component.html</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9dffbece2b62a762cc013cd9a092a45386644395" datatype="html">
|
||||
<source>
|
||||
Envoyer le formulaire
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/debugger/debugger.component.html</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="a2e46fcfdbcd6457dd6dda15896ff772a4cccb59" datatype="html">
|
||||
<source>
|
||||
Visibilité des réponses
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/visibility/visibility.component.html</context>
|
||||
<context context-type="linenumber">1</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f3fa123ec08a0f55d20203474e459cb166171530" datatype="html">
|
||||
<source>
|
||||
Votes
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/visibility/visibility.component.html</context>
|
||||
<context context-type="linenumber">4</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="07056464cc8e77270490824db1c119774a9605d8" datatype="html">
|
||||
<source>
|
||||
Archivage
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/visibility/visibility.component.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e89a47f338845c2bc853956b810455622ea70d18" datatype="html">
|
||||
<source>
|
||||
Accès au sondage
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/visibility/visibility.component.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="575c777901e66582920b91544ddfc3f1cff6dfdd" datatype="html">
|
||||
<source>
|
||||
Résumé avant validation
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/resume/resume.component.html</context>
|
||||
<context context-type="linenumber">1</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e73989397fa8b6b2a516ec090b7653d7ca8a9f2d" datatype="html">
|
||||
<source>
|
||||
Images
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/pictures/pictures.component.html</context>
|
||||
<context context-type="linenumber">2</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f6d82bb9d11a1a8fbfbc8dd54388b068db42fd4a" datatype="html">
|
||||
<source>
|
||||
Choisir les propositions
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/answers/answers.component.html</context>
|
||||
<context context-type="linenumber">2</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="aa15ed6f3664a52d0532b4caccc5e3862eceaff6" datatype="html">
|
||||
<source>
|
||||
vous pouvez utiliser la syntaxe markdown
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/answers/answers.component.html</context>
|
||||
<context context-type="linenumber">6</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8c8496fbdf12a4a3ef88119cd37deca10bf6c661" datatype="html">
|
||||
<source>
|
||||
Et c'est tout pour nous!
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/end-confirmation/end-confirmation.component.html</context>
|
||||
<context context-type="linenumber">1</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c434b3773c35a5d55a1f5648433e7521e4424aea" datatype="html">
|
||||
<source>Coté administrateur-ice-eux</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/end-confirmation/end-confirmation.component.html</context>
|
||||
<context context-type="linenumber">4</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d0225bc631b962e0c6696ebc3e26cc90ecf15387" datatype="html">
|
||||
<source>Coté sondés</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/end-confirmation/end-confirmation.component.html</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="585c8fc362784c1de91b02f0e69e08c6993f9dd2" datatype="html">
|
||||
<source>recevoir les liens par e-mail</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/end-confirmation/end-confirmation.component.html</context>
|
||||
<context context-type="linenumber">6</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f74e29e3e6b015dc4163c3d43002088d0e1da5dc" datatype="html">
|
||||
<source>
|
||||
Créer un sondage
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/create-or-retrieve/create-or-retrieve.component.html</context>
|
||||
<context context-type="linenumber">2</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="36ab2505621b4451317833191d6a4c2d7c214b3c" datatype="html">
|
||||
<source>
|
||||
Planifiez des rendez-vous avec vos amis ou votre famille ou créez un sondage avec du texte, des images ou des
|
||||
liens… un sondage quoi !
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/create-or-retrieve/create-or-retrieve.component.html</context>
|
||||
<context context-type="linenumber">8</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c3781d8c21f3eba04fe803a3fe0a4560401491d5" datatype="html">
|
||||
<source>
|
||||
C'est parti
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/create-or-retrieve/create-or-retrieve.component.html</context>
|
||||
<context context-type="linenumber">19</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9e1fa5a7ae3c13a9fa4a657d94085e239066377a" datatype="html">
|
||||
<source>
|
||||
Où sont mes sondages ?
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/create-or-retrieve/create-or-retrieve.component.html</context>
|
||||
<context context-type="linenumber">29</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b291d9e84fc9afe337b3450266847c430523bcc5" datatype="html">
|
||||
<source>
|
||||
Je cherche les sondages qui correspondent à mon mail :
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/create-or-retrieve/create-or-retrieve.component.html</context>
|
||||
<context context-type="linenumber">40</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9606f1c734851ad834d5f9eca4fbc79fad2cf406" datatype="html">
|
||||
<source>
|
||||
Pour commencer
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/home/home.component.html</context>
|
||||
<context context-type="linenumber">4</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e40f615c5bada8d5458ede5b03812bdb8074d7d7" datatype="html">
|
||||
<source>
|
||||
Je veux créer un sondage
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/home/home.component.html</context>
|
||||
<context context-type="linenumber">10</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="99eef0ca99f5a0e0aee806ffdefb5ca1ca318b07" datatype="html">
|
||||
<source>
|
||||
Dont le titre sera
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/home/home.component.html</context>
|
||||
<context context-type="linenumber">34</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="77100ae0f206a821d33d9582dd2962f379eaeac7" datatype="html">
|
||||
<source>
|
||||
et la description serait
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/home/home.component.html</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="114007b6744088dc57d792702b19f91f68f7926e" datatype="html">
|
||||
<source>
|
||||
Continuer
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/home/home.component.html</context>
|
||||
<context context-type="linenumber">82</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
Loading…
Reference in New Issue
Block a user