mirror of
https://framagit.org/framasoft/framadate/funky-framadate-front.git
synced 2023-08-25 13:53:14 +02:00
feature choice text
This commit is contained in:
parent
8a6b331355
commit
5edeb34ceb
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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'));
|
||||||
|
@ -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>
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
.options {
|
||||||
|
button {
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
padding-left: 0.75rem;
|
||||||
|
img {
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
table {
|
table {
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
max-width: 90vw !important;
|
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
table {
|
table {
|
||||||
|
@ -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>
|
||||||
|
@ -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 {}
|
||||||
|
@ -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 à l’option",
|
"title": "Ajoutez un lien à l’option",
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user