feature choice text

This commit is contained in:
Tykayn 2022-02-09 12:25:08 +01:00 committed by tykayn
parent 8a6b331355
commit 5edeb34ceb
14 changed files with 188 additions and 57 deletions

View File

@ -10,7 +10,11 @@ export class AnswerStats {
count: number; count: number;
people: Array<string>; people: Array<string>;
} }
export class ChoiceText {
public name: string; // text of the choice, displayed as an option
public url_href: string; // url used as clickable link on a picture
public url_display: string; // url to fetch a picture to display, this picture might be clickable with url_href filled
}
export class Choice { export class Choice {
public id: number; public id: number;
public name: string; public name: string;

View File

@ -1,4 +1,4 @@
import { Choice, ChoiceGroup } from './choice.model'; import { Choice, ChoiceGroup, ChoiceText } from './choice.model';
import { Comment } from './comment.model'; import { Comment } from './comment.model';
import { Owner } from './owner.model'; import { Owner } from './owner.model';
import { DateChoice, TimeSlices } from './dateChoice.model'; import { DateChoice, TimeSlices } from './dateChoice.model';
@ -13,6 +13,7 @@ export class Poll {
public archiveNumberOfDays?: number; public archiveNumberOfDays?: number;
public areResultsPublic?: boolean = true; public areResultsPublic?: boolean = true;
public choices: Choice[] = []; public choices: Choice[] = [];
public choicesText: ChoiceText[] = [];
public choices_grouped: ChoiceGroup[] = []; public choices_grouped: ChoiceGroup[] = [];
public comments: Comment[] = []; public comments: Comment[] = [];
public creation_date?: string = new Date().toISOString(); public creation_date?: string = new Date().toISOString();

View File

@ -126,7 +126,7 @@ export class PollService implements Resolve<Poll> {
choices: new FormArray([]), choices: new FormArray([]),
whoModifiesAnswers: ['self', [Validators.required]], whoModifiesAnswers: ['self', [Validators.required]],
whoCanChangeAnswers: ['self', [Validators.required]], whoCanChangeAnswers: ['self', [Validators.required]],
isAboutDate: [true, [Validators.required]], isAboutDate: [false, [Validators.required]],
expiresDaysDelay: [environment.expiresDaysDelay, []], expiresDaysDelay: [environment.expiresDaysDelay, []],
expiracy_date: [this.DateUtilitiesService.addDaysToDate(environment.expiresDaysDelay, new Date()), []], expiracy_date: [this.DateUtilitiesService.addDaysToDate(environment.expiresDaysDelay, new Date()), []],
isZeroKnoledge: [false, [Validators.required]], isZeroKnoledge: [false, [Validators.required]],
@ -776,6 +776,9 @@ export class PollService implements Resolve<Poll> {
newpoll.dateChoices.push(converted_day); newpoll.dateChoices.push(converted_day);
} }
console.log('newpoll.dateChoices', newpoll.dateChoices); console.log('newpoll.dateChoices', newpoll.dateChoices);
} else {
// text choices
newpoll.choicesText = Object.assign([], this.storageService.choicesText);
} }
newpoll.choices = Object.assign([], this.storageService.choices); newpoll.choices = Object.assign([], this.storageService.choices);
// newpoll.dateChoices = Object.assign([], this.storageService.dateChoices); // newpoll.dateChoices = Object.assign([], this.storageService.dateChoices);

View File

@ -1,20 +1,11 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { LocalStorage } from 'ngx-webstorage'; import { LocalStorage } from 'ngx-webstorage';
import { LanguageEnum } from '../enums/language.enum';
import { Theme } from '../enums/theme.enum'; import { Theme } from '../enums/theme.enum';
import { Stack } from '../models/stack.model'; import { Stack } from '../models/stack.model';
import { Choice } from '../models/choice.model'; import { Choice, ChoiceText } from '../models/choice.model';
import { Vote } from '../models/vote.model'; import { Vote } from '../models/vote.model';
import { environment } from '../../../environments/environment'; import { environment } from '../../../environments/environment';
import { import { DateChoice, defaultTimeOfDay, TimeSlices } from '../../../../mocks/old-stuff/config/defaultConfigs';
basicSlicesOfDay,
DateChoice,
defaultTimeOfDay,
moreTimeOfDay,
otherDefaultDates,
TimeSlices,
} from '../../../../mocks/old-stuff/config/defaultConfigs';
import { Poll } from '../models/poll.model'; import { Poll } from '../models/poll.model';
import { Owner } from '../models/owner.model'; import { Owner } from '../models/owner.model';
import { DateUtilitiesService } from './date.utilities.service'; import { DateUtilitiesService } from './date.utilities.service';
@ -42,9 +33,24 @@ export class StorageService {
@LocalStorage() @LocalStorage()
public vote_stack: Stack = new Stack(); public vote_stack: Stack = new Stack();
/**
* choix de dates
*/
@LocalStorage() @LocalStorage()
public choices: Choice[] = []; public choices: Choice[] = [];
/**
* choix textes dans un sondage classique
*/
@LocalStorage()
public choicesText: ChoiceText[] = [
{
name: '',
url_display: '',
url_href: '',
},
];
constructor(public dateUtilities: DateUtilitiesService, private toastService: ToastService) { constructor(public dateUtilities: DateUtilitiesService, private toastService: ToastService) {
if (environment.autofill_participation) { if (environment.autofill_participation) {
this.userPolls.push(new Poll(new Owner(), 'Démo: Anniversaire de tonton Patrick', 'aujourdhui-ou-demain')); this.userPolls.push(new Poll(new Owner(), 'Démo: Anniversaire de tonton Patrick', 'aujourdhui-ou-demain'));

View File

@ -1 +1,64 @@
<p>option-link works!</p> <div class="options">
<h1 class="title is-1">
{{ 'choices.title' | translate }}
</h1>
<!--{{ 'choices.helper' |translate}}-->
<div class="rounded-block" *ngFor="let choice of StorageService.choicesText; index as ii">
<label [for]="'option_' + ii">{{ 'choices.element' | translate }} {{ ii + 1 }}</label>
<input type="text" [(ngModel)]="choice.name" class="input" />
<div class="image-preview" *ngIf="choice.url_display">
<img src="{{ choice.url_display }}" alt="image" class="icon is-rounded" />
</div>
<div class="href-preview" *ngIf="choice.url_href">
{{ choice.url_href }}
</div>
<button (click)="openLinkModal(choice)" class="has-no-outline" *ngIf="!choice.url_href || !choice.url_display">
<img class="icon" src="assets/icons/link.svg" />
{{ 'choices.add_link' | translate }}
</button>
<button class="button delete-date is-block" (click)="StorageService.choicesText.splice(ii, 1)">
<img class="icon" src="assets/icons/trash.svg" />
{{ 'choices.delete' | translate }}
</button>
</div>
</div>
<button class="is-primary button is-fullwidth" (click)="addLink()">
{{ 'choices.add' | translate }}
</button>
<!-- dialog search-->
<p-dialog
[modal]="true"
[(visible)]="display_option_dialog"
[breakpoints]="{ '960px': '75vw' }"
[style]="{ width: '75vw' }"
[draggable]="false"
[showHeader]="false"
[resizable]="true"
>
<h1 class="title is-1">
{{ 'choices.modal.title' | translate }}
</h1>
<p class="description">
{{ 'choices.modal.description' | translate }}
</p>
<label for="modal_url">
{{ 'choices.modal.url_label' | translate }}
</label>
<input type="text" [(ngModel)]="url_href" id="modal_url" />
<label for="modal_url">
{{ 'choices.modal.img_label' | translate }}
</label>
<input type="text" [(ngModel)]="url_display" id="modal_img_url" />
<div class="bottom has-text-right">
<button class="button marged-right" (click)="closeModal()">
{{ 'SENTENCES.Cancel' | translate }}
</button>
<button class="is-primary" (click)="validateModal()">
{{ 'choices.modal.validate' | translate }}
</button>
</div>
</p-dialog>
<app-wip-todo></app-wip-todo>

View File

@ -0,0 +1,10 @@
.options {
button {
border: 0;
background: transparent;
padding-left: 0.75rem;
img {
margin-right: 1em;
}
}
}

View File

@ -1,4 +1,6 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { StorageService } from '../../../../core/services/storage.service';
import { ChoiceText } from '../../../../core/models/choice.model';
@Component({ @Component({
selector: 'app-option-link', selector: 'app-option-link',
@ -6,7 +8,31 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./option-link.component.scss'], styleUrls: ['./option-link.component.scss'],
}) })
export class OptionLinkComponent implements OnInit { export class OptionLinkComponent implements OnInit {
constructor() {} public url_href: string;
public url_display: string;
public choice_for_modal: ChoiceText; // choice to be modified after validation of modal
public display_option_dialog: boolean = false;
constructor(public StorageService: StorageService) {}
ngOnInit(): void {} ngOnInit(): void {}
openLinkModal(choice: ChoiceText) {
this.choice_for_modal = choice;
this.display_option_dialog = true;
}
addLink() {
this.StorageService.choicesText.push(new ChoiceText());
}
validateModal() {
this.choice_for_modal.url_href = '' + this.url_href;
this.choice_for_modal.url_display = '' + this.url_display;
this.display_option_dialog = false;
}
closeModal() {
this.display_option_dialog = false;
}
} }

View File

@ -1,40 +1,44 @@
<app-stepper [step_current]="3" [step_max]="pollService.step_max"></app-stepper> <app-stepper [step_current]="3" [step_max]="pollService.step_max"></app-stepper>
<div class="step min-height"> <div class="step min-height">
<h2 class="title is-2">
{{ 'dates.title' | translate }}
</h2>
<app-errors-list [form]="pollService.form"></app-errors-list> <app-errors-list [form]="pollService.form"></app-errors-list>
<!-- sélecteur d'interface--> <div class="text-options" *ngIf="!pollService.form.value.isAboutDate">
<button class="button is-fullwidth date-input-selector is-secondary" (click)="changeDateInputMode()"> <app-option-link></app-option-link>
<span *ngIf="pollService.mode_calendar">
{{ 'dates.manual_input' | translate }}
</span>
<span *ngIf="!pollService.mode_calendar">
{{ 'dates.datepicker_input' | translate }}
</span>
</button>
<!-- choix spécialement pour les dates-->
<div class="calendar" *ngIf="pollService.mode_calendar">
<p-calendar
[(ngModel)]="pollService.calendar"
firstDayOfWeek="1"
selectionMode="multiple"
inputId="multiple"
showButtonBar="true"
[locale]="'calendar_widget' | translate"
[disabledDates]="pollService.disabled_dates"
[inline]="true"
[showWeek]="false"
></p-calendar>
</div> </div>
<div class="date-options" *ngIf="pollService.form.value.isAboutDate">
<h2 class="title is-2">
{{ 'dates.title' | translate }}
</h2>
<!-- sélecteur d'interface-->
<button class="button is-fullwidth date-input-selector is-secondary" (click)="changeDateInputMode()">
<span *ngIf="pollService.mode_calendar">
{{ 'dates.manual_input' | translate }}
</span>
<span *ngIf="!pollService.mode_calendar">
{{ 'dates.datepicker_input' | translate }}
</span>
</button>
<div class="text-date-list" *ngIf="!pollService.mode_calendar"> <!-- choix spécialement pour les dates-->
<app-day-list <div class="calendar" *ngIf="pollService.mode_calendar">
[form]="pollService.form" <p-calendar
[hasSeveralHours]="environment.creation_display_hour_per_day && pollService.form.value.hasSeveralHours" [(ngModel)]="pollService.calendar"
></app-day-list> firstDayOfWeek="1"
selectionMode="multiple"
inputId="multiple"
showButtonBar="true"
[locale]="'calendar_widget' | translate"
[disabledDates]="pollService.disabled_dates"
[inline]="true"
[showWeek]="false"
></p-calendar>
</div>
<div class="text-date-list" *ngIf="!pollService.mode_calendar">
<app-day-list
[form]="pollService.form"
[hasSeveralHours]="environment.creation_display_hour_per_day && pollService.form.value.hasSeveralHours"
></app-day-list>
</div>
</div> </div>
</div> </div>
<app-nav-steps <app-nav-steps

View File

@ -12,7 +12,6 @@
table { table {
overflow: scroll; overflow: scroll;
max-width: 90vw !important;
display: block; display: block;
} }
table { table {

View File

@ -8,4 +8,21 @@
amélioration avec le bouton de feedback. amélioration avec le bouton de feedback.
</div> </div>
</div> </div>
<p>
Support:
<a href="mailto:{{ env.appSupportEmail }}">
mail
</a>
<a href="{{ env.appSupportWebpage }}">
Autres canaux
</a>
<a href="https://framagit.org/framasoft/framadate/funky-framadate-front/-/tree/master">
<i class="fa fa-gitlab"></i> Sources</a
>
|
<a href="https://framagit.org/framasoft/framadate/funky-framadate-front/-/tree/master/docs">
<i class="fa fa-book"></i>
🚴 Documentation
</a>
</p>
</div> </div>

View File

@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { environment } from '../../../../../environments/environment';
@Component({ @Component({
selector: 'app-wip-todo', selector: 'app-wip-todo',
@ -6,6 +7,7 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./wip-todo.component.scss'], styleUrls: ['./wip-todo.component.scss'],
}) })
export class WipTodoComponent implements OnInit { export class WipTodoComponent implements OnInit {
env: any = environment;
constructor() {} constructor() {}
ngOnInit(): void {} ngOnInit(): void {}

View File

@ -123,7 +123,7 @@
"answer_preset_1": "réponse de démo 1", "answer_preset_1": "réponse de démo 1",
"answer_preset_2": "réponse 2", "answer_preset_2": "réponse 2",
"answer_preset_3": "la réponse D", "answer_preset_3": "la réponse D",
"add": "Ajouter option", "add": "Ajouter proposition",
"continue": "Voyons ce que ça donne", "continue": "Voyons ce que ça donne",
"modal": { "modal": {
"title": "Ajoutez un lien à loption", "title": "Ajoutez un lien à loption",

View File

@ -36,6 +36,9 @@
.marged { .marged {
margin: 1em; margin: 1em;
} }
.marged-right {
margin-right: 1em;
}
.marged-v { .marged-v {
margin-top: 1em; margin-top: 1em;
margin-bottom: 1em; margin-bottom: 1em;

View File

@ -30,7 +30,6 @@ select,
textarea { textarea {
display: inline-block; display: inline-block;
padding: 1rem; padding: 1rem;
width: calc(100% - 45px);
margin-right: 2px; margin-right: 2px;
margin-bottom: 1em; margin-bottom: 1em;
@ -55,7 +54,6 @@ select,
line-height: 1.25rem; line-height: 1.25rem;
border: solid 1px $font-color !important; border: solid 1px $font-color !important;
border-radius: 4px; border-radius: 4px;
max-width: 90vw !important;
@extend .clickable; @extend .clickable;
&:focus { &:focus {
@extend .outlined; @extend .outlined;
@ -101,7 +99,6 @@ textarea {
width: 100%; width: 100%;
display: inline-block; display: inline-block;
text-align: left; text-align: left;
max-width: 90vw;
} }
} }
input[type='radio'] { input[type='radio'] {
@ -145,14 +142,12 @@ option {
background-position: right 1rem center; background-position: right 1rem center;
background-clip: border-box; background-clip: border-box;
min-width: 10rem; min-width: 10rem;
max-width: 90vw;
margin-bottom: 0.25rem; margin-bottom: 0.25rem;
border-bottom: 2px solid $primary_color !important; border-bottom: 2px solid $primary_color !important;
} }
select { select {
@extend .select, .input; @extend .select, .input;
max-width: 90vw;
} }
#multi_hours select { #multi_hours select {
@ -162,13 +157,11 @@ select {
input { input {
border-color: #4e4c59 !important; border-color: #4e4c59 !important;
@extend .text-ellipsis; @extend .text-ellipsis;
max-width: 90vw;
display: block; display: block;
} }
textarea { textarea {
width: 100%; width: 100%;
max-width: 90vw;
min-height: 213px; min-height: 213px;
padding: 0.5em 1em; padding: 0.5em 1em;
margin-bottom: 1em; margin-bottom: 1em;