start participation landing texts

This commit is contained in:
Tykayn 2022-02-07 12:09:59 +01:00 committed by tykayn
parent 0e22b2bc93
commit 5dde4415eb
8 changed files with 353 additions and 216 deletions

View File

@ -1,159 +1,28 @@
<section class="poll_loaded padded consultation" *ngIf="!fetching && poll"> <section class="poll_loaded padded consultation" *ngIf="!fetching && poll">
<!-- messages--> <div class="step">
<div class="rounded-box">
<div class="message is-warning" *ngIf="isArchived">
<div class="message-body">
{{ 'participation.poll_expired' | translate }}
</div>
</div>
<div class="message is-warning" *ngIf="poll && poll.admin_key">
<div class="message-body">
{{ 'participation.you_are_admin' | translate }}
</div>
</div>
<div class="message is-info" *ngIf="poll.modification_policy == 'self'">
<div class="message-body">
{{ 'participation.edit_only_self' | translate }}
</div>
</div>
<router-outlet></router-outlet>
<!-- actions-->
<!-- affichage des possibilités de réponse -->
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="card"> <h2 class="title is-2">
<header class="card-header padded"> {{ poll.title }}
<div class="columns"> </h2>
<div class="column">
<p class="card-header-title is-1 title">{{ poll.title }}</p>
<p class="descr">{{ poll.description }}</p>
<div class="voters-count padded">
<i class="fa fa-users"></i> {{ poll.stacks.length }}
{{ 'participation.voters' | translate }}
</div> </div>
<p class="card-header-icon" *ngIf="poll.owner"> <div class="column is-narrow">
{{ 'participation.author' | translate }} {{ poll.owner?.pseudo }} <button class="options-button pull-right" (click)="displayOptions()">
{{ 'participation.menu_label' | translate }}
<i class="fa fa-chevron-down"></i>
</button>
</div>
</div>
<p class="description">
{{ poll.description }}
</p> </p>
</div> </div>
<div class="column"> </div>
<app-actions-menu></app-actions-menu> </section>
</div> <section class="loadin_poll" *ngIf="fetching">
</div> <div class="step has-text-centered">
</header> <p>loading ... <i class="fa fa-spinner fa-spin"></i></p>
<div class="card-content">
<div class="content">
<div class="columns">
<div class="column">
<button
class="btn is-info"
(click)="isCompactMode = !isCompactMode"
[ngClass]="{ 'is-primary': isCompactMode, 'is-default': !isCompactMode }"
>
changer d'affichage
</button>
</div>
<div class="column">
<!-- le bouton affiche l'état alternatif possible, et non l'état actuel-->
<div class="buttons has-addons is-small is-right">
<button
class="button"
[class.is-active]="isCompactMode"
(click)="isCompactMode = true"
>
{{ 'participation.mode_detailed' | translate }}
</button>
<button
class="button"
[class.is-active]="!isCompactMode"
(click)="isCompactMode = false"
>
{{ 'participation.mode_compact' | translate }}
</button>
</div>
</div>
</div>
<div class="pseudo-land" *ngIf="isCompactMode && !isArchived">
<label for="vote_pseudo_vote_stack">
Votre pseudo:
</label>
<input
class="is-block"
type="text"
id="vote_pseudo_vote_stack"
[(ngModel)]="storageService.vote_stack.pseudo"
/>
</div>
<app-poll-results-compact *ngIf="isCompactMode" [poll]="poll"></app-poll-results-compact>
<app-poll-results-detailed *ngIf="!isCompactMode" [poll]="poll"></app-poll-results-detailed>
</div>
</div>
<!-- static buttons-->
<div class="padded">
<div class="message is-info" *ngIf="poll.stacks.length == 0">
<div class="message-body">
aucun vote pour le moment
</div>
</div>
<section class="loading_poll" *ngIf="fetching">
<i class="fa fa-spinner fa-4x"></i>
</section>
<button
class="button is-block submit-votestack is-primary"
(click)="addVoteStack()"
*ngIf="(!isArchived && !storageService.vote_stack) || !storageService.vote_stack.id"
>
<i class="fa fa-paper-plane" aria-hidden="true"></i> Envoyer
</button>
<button
class="btn btn--primary btn-block submit-votestack update"
(click)="updateVoteStack()"
*ngIf="storageService.vote_stack && storageService.vote_stack.id"
>
<i class="fa fa-edit" aria-hidden="true"></i> Mettre à jour
</button>
</div>
<div class="columns">
<div class="column">
<app-comments
*ngIf="poll.allow_comments"
[poll]="poll"
[vote_stack]="storageService.vote_stack"
></app-comments>
<div class="alert has-background-info" *ngIf="!poll.allow_comments">
Ce sondage ne permet pas d'ajouter de commentaires
</div>
</div>
</div>
<!-- fixed bottom buttons-->
<div class="bar-votestack" *ngIf="!isArchived">
<button
class="btn btn-block submit-votestack"
(click)="addVoteStack()"
*ngIf="!storageService.vote_stack || !storageService.vote_stack.id"
>
<i class="fa fa-paper-plane" aria-hidden="true"></i> Envoyer
</button>
<button
class="btn btn--primary btn-block submit-votestack update"
(click)="updateVoteStack()"
*ngIf="storageService.vote_stack && storageService.vote_stack.id"
>
<i class="fa fa-edit" aria-hidden="true"></i> Mettre à jour
</button>
</div>
<div class="alert has-background-info" *ngIf="isArchived">
Ce sondage est archivé
</div>
</div>
</div>
</div> </div>
</section> </section>

View File

@ -15,17 +15,14 @@ import { ToastService } from '../../core/services/toast.service';
styleUrls: ['./consultation.component.scss'], styleUrls: ['./consultation.component.scss'],
}) })
export class ConsultationComponent implements OnInit, OnDestroy { export class ConsultationComponent implements OnInit, OnDestroy {
// public isCompactMode = false;
public isCompactMode = true;
public poll: Poll;
public pollSlug: string;
public pass_hash: string;
public fetching = true; public fetching = true;
public isArchived: boolean;
public isAdmin: boolean;
private routeSubscription: Subscription; private routeSubscription: Subscription;
window: any; window: any;
private isArchived: boolean;
private poll: Poll;
private pollSlug: string;
private pass_hash: string;
constructor( constructor(
private router: Router, private router: Router,
@ -47,8 +44,6 @@ export class ConsultationComponent implements OnInit, OnDestroy {
this.poll = newpoll; this.poll = newpoll;
if (newpoll) { if (newpoll) {
this.isArchived = new Date(newpoll.expiracy_date) < new Date(); this.isArchived = new Date(newpoll.expiracy_date) < new Date();
this.poll.is_archived = this.isArchived;
this.isAdmin = this.poll.admin_key !== null;
this.poll.choices_grouped.map((elem) => (elem.subSetToYes = false)); this.poll.choices_grouped.map((elem) => (elem.subSetToYes = false));
} }
}); });
@ -83,60 +78,7 @@ export class ConsultationComponent implements OnInit, OnDestroy {
} }
} }
/** displayOptions() {
* update existing vote stack alert('TODO');
* @param Stack
*/
updateVoteStack(): void {
const vote_stack = this.storageService.vote_stack;
vote_stack.poll_custom_url = this.poll.custom_url;
console.log('updateVoteStack vote_stack.votes', vote_stack.votes.length, vote_stack.votes);
const handlingError = this.api.ousideHandleError;
this.api
.sendUpdateVoteStack(vote_stack)
.then((resp) => {
console.log('sendUpdateVoteStack updated resp', resp);
this.storeVoteStackAndReloadPoll(resp);
this.toastService.display('vote bien mis à jour', 'success');
})
.catch(handlingError);
}
/**
* create a new vote stack
*/
addVoteStack(): void {
this.storageService.vote_stack.poll_custom_url = this.poll.custom_url;
this.pollService.pass_hash = this.pass_hash;
this.toastService.display('envoi du vote ....');
this.api
.sendNewVoteStackOfPoll(this.storageService.vote_stack)
.then((resp: any) => {
console.log('sendNewVoteStackOfPoll resp', resp);
this.storeVoteStackAndReloadPoll(resp);
})
// eslint-disable-next-line @typescript-eslint/unbound-method
.catch(this.api.ousideHandleError);
}
/**
* store the updated vote stack
* @param voteStack
*/
storeVoteStackAndReloadPoll(voteStack: any) {
if (voteStack.status == 200) {
this.storageService.mapVotes(voteStack.data);
this.pollService.enrichVoteStackWithCurrentPollChoicesDefaultVotes(this.storageService.vote_stack);
if (this.pass_hash) {
this.pollService.loadPollByCustomUrlWithPasswordHash(this.poll.custom_url, this.pass_hash);
} else {
this.pollService.loadPollByCustomUrl(this.poll.custom_url);
}
} else {
this.toastService.display('erreur à l enregistrement');
}
} }
} }

View File

@ -16,6 +16,7 @@ import { ConsultationUserComponent } from './consultation-user/consultation-user
import { SuccessComponent } from './success/success.component'; import { SuccessComponent } from './success/success.component';
import { AdministrationModule } from '../administration/administration.module'; import { AdministrationModule } from '../administration/administration.module';
import { EditComponent } from './edit/edit.component'; import { EditComponent } from './edit/edit.component';
import { ResultsRoundedComponent } from './results-rounded/results-rounded.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -28,6 +29,7 @@ import { EditComponent } from './edit/edit.component';
ConsultationUserComponent, ConsultationUserComponent,
SuccessComponent, SuccessComponent,
EditComponent, EditComponent,
ResultsRoundedComponent,
], ],
imports: [ imports: [
CommonModule, CommonModule,

View File

@ -9,7 +9,7 @@
> >
<i class="fa fa-check-circle-o fa"></i> <i class="fa fa-check-circle-o fa"></i>
</button> </button>
{{ showAsDate(group.date_string) | date: 'fullDate':'Europe/Paris':'fr_FR' }} {{ showAsDate(group.date_string) | date: 'fullDate':'Europe/Paris':'fr' }}
</h3> </h3>
<div class="time-slice-choice" *ngFor="let choice of group.choices"> <div class="time-slice-choice" *ngFor="let choice of group.choices">
<div class="columns is-vcentered is-mobile"> <div class="columns is-vcentered is-mobile">

View File

@ -0,0 +1,159 @@
<section class="poll_loaded padded consultation" *ngIf="!fetching && poll">
<!-- messages-->
<div class="message is-warning" *ngIf="isArchived">
<div class="message-body">
{{ 'participation.poll_expired' | translate }}
</div>
</div>
<div class="message is-warning" *ngIf="poll && poll.admin_key">
<div class="message-body">
{{ 'participation.you_are_admin' | translate }}
</div>
</div>
<div class="message is-info" *ngIf="poll.modification_policy == 'self'">
<div class="message-body">
{{ 'participation.edit_only_self' | translate }}
</div>
</div>
<router-outlet></router-outlet>
<!-- actions-->
<!-- affichage des possibilités de réponse -->
<div class="columns">
<div class="column">
<div class="card">
<header class="card-header padded">
<div class="columns">
<div class="column">
<p class="card-header-title is-1 title">{{ poll.title }}</p>
<p class="descr">{{ poll.description }}</p>
<div class="voters-count padded">
<i class="fa fa-users"></i> {{ poll.stacks.length }}
{{ 'participation.voters' | translate }}
</div>
<p class="card-header-icon" *ngIf="poll.owner">
{{ 'participation.author' | translate }} {{ poll.owner?.pseudo }}
</p>
</div>
<div class="column">
<app-actions-menu></app-actions-menu>
</div>
</div>
</header>
<div class="card-content">
<div class="content">
<div class="columns">
<div class="column">
<button
class="btn is-info"
(click)="isCompactMode = !isCompactMode"
[ngClass]="{ 'is-primary': isCompactMode, 'is-default': !isCompactMode }"
>
changer d'affichage
</button>
</div>
<div class="column">
<!-- le bouton affiche l'état alternatif possible, et non l'état actuel-->
<div class="buttons has-addons is-small is-right">
<button
class="button"
[class.is-active]="isCompactMode"
(click)="isCompactMode = true"
>
{{ 'participation.mode_detailed' | translate }}
</button>
<button
class="button"
[class.is-active]="!isCompactMode"
(click)="isCompactMode = false"
>
{{ 'participation.mode_compact' | translate }}
</button>
</div>
</div>
</div>
<div class="pseudo-land" *ngIf="isCompactMode && !isArchived">
<label for="vote_pseudo_vote_stack">
Votre pseudo:
</label>
<input
class="is-block"
type="text"
id="vote_pseudo_vote_stack"
[(ngModel)]="storageService.vote_stack.pseudo"
/>
</div>
<app-poll-results-compact *ngIf="isCompactMode" [poll]="poll"></app-poll-results-compact>
<app-poll-results-detailed *ngIf="!isCompactMode" [poll]="poll"></app-poll-results-detailed>
</div>
</div>
<!-- static buttons-->
<div class="padded">
<div class="message is-info" *ngIf="poll.stacks.length == 0">
<div class="message-body">
aucun vote pour le moment
</div>
</div>
<section class="loading_poll" *ngIf="fetching">
<i class="fa fa-spinner fa-4x"></i>
</section>
<button
class="button is-block submit-votestack is-primary"
(click)="addVoteStack()"
*ngIf="(!isArchived && !storageService.vote_stack) || !storageService.vote_stack.id"
>
<i class="fa fa-paper-plane" aria-hidden="true"></i> Envoyer
</button>
<button
class="btn btn--primary btn-block submit-votestack update"
(click)="updateVoteStack()"
*ngIf="storageService.vote_stack && storageService.vote_stack.id"
>
<i class="fa fa-edit" aria-hidden="true"></i> Mettre à jour
</button>
</div>
<div class="columns">
<div class="column">
<app-comments
*ngIf="poll.allow_comments"
[poll]="poll"
[vote_stack]="storageService.vote_stack"
></app-comments>
<div class="alert has-background-info" *ngIf="!poll.allow_comments">
Ce sondage ne permet pas d'ajouter de commentaires
</div>
</div>
</div>
<!-- fixed bottom buttons-->
<div class="bar-votestack" *ngIf="!isArchived">
<button
class="btn btn-block submit-votestack"
(click)="addVoteStack()"
*ngIf="!storageService.vote_stack || !storageService.vote_stack.id"
>
<i class="fa fa-paper-plane" aria-hidden="true"></i> Envoyer
</button>
<button
class="btn btn--primary btn-block submit-votestack update"
(click)="updateVoteStack()"
*ngIf="storageService.vote_stack && storageService.vote_stack.id"
>
<i class="fa fa-edit" aria-hidden="true"></i> Mettre à jour
</button>
</div>
<div class="alert has-background-info" *ngIf="isArchived">
Ce sondage est archivé
</div>
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ResultsRoundedComponent } from './results-rounded.component';
describe('ResultsRoundedComponent', () => {
let component: ResultsRoundedComponent;
let fixture: ComponentFixture<ResultsRoundedComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ResultsRoundedComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ResultsRoundedComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,141 @@
import { Component, OnInit } from '@angular/core';
import { Poll } from '../../../core/models/poll.model';
import { Subscription } from 'rxjs';
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import { PollUtilitiesService } from '../../../core/services/poll.utilities.service';
import { StorageService } from '../../../core/services/storage.service';
import { ApiService } from '../../../core/services/api.service';
import { PollService } from '../../../core/services/poll.service';
import { DateService } from '../../../core/services/date.service';
import { ToastService } from '../../../core/services/toast.service';
@Component({
selector: 'app-results-rounded',
templateUrl: './results-rounded.component.html',
styleUrls: ['./results-rounded.component.scss'],
})
export class ResultsRoundedComponent implements OnInit {
// public isCompactMode = false;
public isCompactMode = true;
public poll: Poll;
public pollSlug: string;
public pass_hash: string;
public fetching = true;
public isArchived: boolean;
public isAdmin: boolean;
private routeSubscription: Subscription;
window: any;
constructor(
private router: Router,
private utils: PollUtilitiesService,
private _Activatedroute: ActivatedRoute,
public storageService: StorageService,
public api: ApiService,
public pollService: PollService,
public dateService: DateService,
public toastService: ToastService
) {}
/**
* fetch poll data on init
*/
ngOnInit(): void {
console.log('constultation de poll');
this.pollService.poll.subscribe((newpoll: Poll) => {
this.poll = newpoll;
if (newpoll) {
this.isArchived = new Date(newpoll.expiracy_date) < new Date();
this.poll.is_archived = this.isArchived;
this.isAdmin = this.poll.admin_key !== null;
this.poll.choices_grouped.map((elem) => (elem.subSetToYes = false));
}
});
this._Activatedroute.paramMap.subscribe((params: ParamMap) => {
console.log('params _Activatedroute', params);
this.pollSlug = params.get('custom_url');
this.pass_hash = params.get('pass_hash');
console.log('this.pass_hash ', this.pass_hash);
if (this.pass_hash) {
this.pollService.loadPollByCustomUrlWithPasswordHash(this.pollSlug, this.pass_hash).then((resp) => {
console.log('loadPollByCustomUrlWithPasswordHash resp', resp);
this.fetching = false;
this.storageService.vote_stack.id = null;
this.storageService.setChoicesForVoteStack(this.pollService._poll.getValue().choices);
});
} else {
this.pollService.loadPollByCustomUrl(this.pollSlug).then((resp) => {
console.log('loadPollByCustomUrl resp', resp);
this.fetching = false;
this.storageService.vote_stack.id = null;
this.storageService.setChoicesForVoteStack(this.pollService._poll.getValue().choices);
});
}
});
}
ngOnDestroy(): void {
if (this.routeSubscription) {
this.routeSubscription.unsubscribe();
}
}
/**
* update existing vote stack
* @param Stack
*/
updateVoteStack(): void {
const vote_stack = this.storageService.vote_stack;
vote_stack.poll_custom_url = this.poll.custom_url;
console.log('updateVoteStack vote_stack.votes', vote_stack.votes.length, vote_stack.votes);
const handlingError = this.api.ousideHandleError;
this.api
.sendUpdateVoteStack(vote_stack)
.then((resp) => {
console.log('sendUpdateVoteStack updated resp', resp);
this.storeVoteStackAndReloadPoll(resp);
this.toastService.display('vote bien mis à jour', 'success');
})
.catch(handlingError);
}
/**
* create a new vote stack
*/
addVoteStack(): void {
this.storageService.vote_stack.poll_custom_url = this.poll.custom_url;
this.pollService.pass_hash = this.pass_hash;
this.toastService.display('envoi du vote ....');
this.api
.sendNewVoteStackOfPoll(this.storageService.vote_stack)
.then((resp: any) => {
console.log('sendNewVoteStackOfPoll resp', resp);
this.storeVoteStackAndReloadPoll(resp);
})
// eslint-disable-next-line @typescript-eslint/unbound-method
.catch(this.api.ousideHandleError);
}
/**
* store the updated vote stack
* @param voteStack
*/
storeVoteStackAndReloadPoll(voteStack: any) {
if (voteStack.status == 200) {
this.storageService.mapVotes(voteStack.data);
this.pollService.enrichVoteStackWithCurrentPollChoicesDefaultVotes(this.storageService.vote_stack);
if (this.pass_hash) {
this.pollService.loadPollByCustomUrlWithPasswordHash(this.poll.custom_url, this.pass_hash);
} else {
this.pollService.loadPollByCustomUrl(this.poll.custom_url);
}
} else {
this.toastService.display('erreur à l enregistrement');
}
}
}