boussole-pluss/frontend/components/BundleAxeModal.vue

244 lines
7.2 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script lang="ts" setup>
import type {PropType} from "vue";
import type {Axe} from "~/store/axe";
import type {Question} from "~/store/question";
const questions = ref<Question[]>([]);
const newQuestionMode = ref(false);
const newQuestionLabel = ref("");
const newQuestionDescription = ref("");
const emit = defineEmits(["changed", "close"]);
const props = defineProps({
axe: {
type: Object as PropType<Axe>,
},
questions: {
type: Object as PropType<Question[]>,
},
questionsExample: {
type: Object as PropType<Question[]>,
default: [{
label: "",
description: ""
}]
},
visible: Boolean
});
onMounted(() => {
questions.value = props.questions ? props.questions.map(q => {
return {
label: q.label,
description: q.description
}
}) : [];
});
function removeQuestion(index: number) {
questions.value.splice(index, 1);
}
function moveQuestion(fromIndex, toIndex) {
if (toIndex > questions.value.length || toIndex < 0) {
return;
}
const element = questions.value[fromIndex];
questions.value.splice(fromIndex, 1);
questions.value.splice(toIndex, 0, element);
}
function questionChanged(event, {index, newQuestion}) {
questions.value[index] = newQuestion;
}
function addNewQuestion() {
questions.value.push({label: newQuestionLabel.value, description: newQuestionDescription.value});
newQuestionMode.value = false;
}
function changeToNewQuestionMode() {
newQuestionLabel.value = "";
newQuestionDescription.value = "";
newQuestionMode.value = true;
}
function validate() {
emit("changed", {axeId: props.axe.id, newQuestions: questions.value});
emit("close");
}
</script>
<template>
<div :class="`modal${visible ? ' visible' : ''}`" v-if="axe">
<section class="modal-content">
<header class="modal-content-header">
<h1>{{ axe.identifier }} - {{ axe.shortTitle }}</h1>
<p>{{ axe.title }}</p>
<p v-if="axe.description">{{ axe.description }}</p>
<button class="close_modal" @click="$emit('close')">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.6 16L0 14.4L6.4 8L0 1.6L1.6 0L8 6.4L14.4 0L16 1.6L9.6 8L16 14.4L14.4 16L8 9.6L1.6 16Z"
fill="#1C1B1F"/>
</svg>
<span>Fermer</span>
</button>
</header>
<main class="modal-content-body">
<div v-if="newQuestionMode" class="new-question">
<div class="new-question__inputs">
<label for="label-new-question">Libellé *</label>
<input id="label-new-question" type="text" list="question-labels" v-model="newQuestionLabel" maxlength="200"/>
<label for="description-new-question">Description</label>
<input id="description-new-question" type="text" list="question-labels" v-model="newQuestionDescription" maxlength="500"/>
</div>
<h2>Historique des questions</h2>
<ul class="new-question__example-list">
<li v-for="(question, index) in questionsExample">
<input :id="'example-'+index" type="radio" name="example-radio" @input="() => {newQuestionLabel = question.label;newQuestionDescription = question.description;}">
<label :for="'example-'+index">
<span class="new-question__example-list__item-label">{{ question.label }}</span>
<span class="new-question__example-list__item-description" v-if="question.description">{{ question.description }}</span>
</label>
</li>
</ul>
</div>
<div v-else>
<ul class="question-list">
<li v-for="(question, index) in questions" class="question-list__item">
<div class="question-list__item__inputs">
<span class="question-list__item__inputs__title">Question {{index+1}}</span>
<label :for="'label-'+index">Libellé *</label>
<input :id="'label-'+index" type="text" list="question-labels" :value="question.label" maxlength="200"
@change="event => questionChanged(event, {index, newQuestion: {label: event.target.value, description: question.description}})"/>
<label :for="'description-'+index">Description</label>
<input :id="'description-'+index" type="text" list="question-descriptions" :value="question.description" maxlength="500"
@change="event => questionChanged(event, {index, newQuestion: {label: question.label, description: event.target.value}})"/>
</div>
<div class="question-list__item__buttons">
<button class="button-icon button-up" aria-label="Déplacer vers le haut"
@click="moveQuestion(index, index-1)" :disabled="index === 0">
</button>
<button class="button-icon button-down" aria-label="Déplacer vers le bas"
@click="moveQuestion(index, index+1)" :disabled="index === questions.length -1">
</button>
<button class="button-icon" @click="removeQuestion(index)">
🗑
</button>
</div>
</li>
</ul>
</div>
</main>
<footer class="modal-content-footer">
<button v-if="newQuestionMode" class="button gray button-back"
@click="newQuestionMode = false">
</button>
<button v-if="newQuestionMode" class="button orange" :disabled="!newQuestionLabel"
@click="addNewQuestion()">Ajouter
</button>
<button v-if="!newQuestionMode" class="button blue" @click="changeToNewQuestionMode()">Ajouter une question
</button>
<button v-if="!newQuestionMode" class="button orange" @click="validate()">Valider</button>
</footer>
</section>
<div class="modal-overlay" @click="$emit('close')"></div>
</div>
</template>
<style scoped lang="scss">
@import "assets/css/modal";
.modal-content-body {
//overflow: unset;
}
.question-list,
.new-question__example-list {
//overflow-y: scroll;
//overflow-x: hidden;
//height: 30%;
}
.new-question {
&__inputs {
display: flex;
flex-direction: column;
gap: $xx_small;
}
h2 {
margin: $xx_small 0;
font-size: $secondary-font-size;
}
&__example-list {
display: flex;
flex-direction: column;
gap: $xx_small;
&__item-description {
font-style: italic;
}
input {
//align-content: start;
}
li {
display: flex;
gap: $xxx_small;
//align-items: start;
}
label {
display: flex;
flex-direction: column;
gap: $xxxx_small;
}
}
}
.question-list {
list-style: none;
display: flex;
flex-direction: column;
gap: $small;
&__item {
display: flex;
gap: $xxx_small;
&__inputs {
display: flex;
flex-direction: column;
flex: 1;
gap: $xxx_small;
&__title {
font-weight: bold;
}
}
&__buttons {
//align-self: center;
display: flex;
flex-direction: column;
align-self: end;
//gap: $xxx_small;
}
}
}
.button-up {
rotate: -90deg;
}
.button-down {
rotate: 90deg;
}
</style>