boussole-pluss/frontend/components/BundleAxeModal.vue

168 lines
4.7 KiB
Vue

<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 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 addQuestion() {
questions.value.push({
label: "", description: ""
});
window.scrollTo({
bottom: 0,
behavior: "smooth",
});
}
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 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.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">
<ul class="question-list">
<li v-for="(question, index) in questions" class="question-list__item">
<div class="question-list__item__inputs">
<label :for="'label-'+index">Libellé *</label>
<input :id="'label-'+index" type="text" list="question-labels" :value="question.label"
@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"
@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>
<datalist id="question-labels">
<option v-for="question in questionsExample" :value="question.label"></option>
</datalist>
<datalist id="question-descriptions">
<option v-for="question in questionsExample" :value="question.description"></option>
</datalist>
</main>
<footer class="modal-content-footer">
<button class="button orange" @click="addQuestion()">Ajouter une question</button>
<button 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";
.question-list {
list-style: none;
display: flex;
flex-direction: column;
gap: $x_small;
&__item {
display: flex;
gap: $xxx_small;
&__inputs {
display: flex;
flex-direction: column;
flex: 1;
gap: $xxx_small;
}
&__buttons {
//align-self: center;
display: flex;
flex-direction: column;
align-self: end;
//gap: $xxx_small;
}
}
}
.button-up {
rotate: -90deg;
}
.button-down {
rotate: 90deg;
}
</style>