EditeurQuestionnaireQuestion.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <template>
  2. <div>
  3. <styled-input label="Titre" v-model="title" />
  4. <styled-input label="Description" v-model="subTitle" />
  5. <div>
  6. <div class="formcontrol-label">Type de question</div>
  7. <button
  8. class="btn-group small left"
  9. :class="{ selected: type == 'competence' }"
  10. @click="type = 'competence'"
  11. >
  12. Options
  13. </button>
  14. <button
  15. class="btn-group small right"
  16. :class="{ selected: type == 'text' }"
  17. @click="type = 'text'"
  18. >
  19. Text libre
  20. </button>
  21. <button
  22. style="margin-left: 8px"
  23. class="btn-group small left"
  24. :class="{ selected: mandatory }"
  25. @click="mandatory = true"
  26. >
  27. Obligatoire
  28. </button>
  29. <button
  30. class="btn-group small right"
  31. :class="{ selected: mandatory == false }"
  32. @click="mandatory = false"
  33. >
  34. Facultative
  35. </button>
  36. </div>
  37. <div v-if="type == 'competence'">
  38. <chips-input
  39. label="Ajouter une option"
  40. placeholder="Choisir une option"
  41. secondary-placeholder="+ option"
  42. :autocompleteList="autocompleteList"
  43. :strict-autocomplete="true"
  44. v-model="competenceIdList"
  45. />
  46. <styled-input
  47. v-for="(c, idx) in competences"
  48. :key="idx"
  49. :helpText="competenceLabel(c.id)"
  50. :modelValue="c.text"
  51. @input="updateCompetenceText($event, idx)"
  52. />
  53. <styled-input v-if="mandatory" helpText="Réponse par défaut" v-model="mandatoryText" />
  54. <button class="btn small error" @click="$emit('delete')">
  55. <i class="material-icons">delete_forever</i>Supprimer
  56. </button>
  57. </div>
  58. </div>
  59. </template>
  60. <script lang="ts">
  61. import { defineComponent, PropType } from "vue";
  62. import { Question, QuestionCompetence, QuestionType } from "@/models/Questionnaire";
  63. import styledInput from "@/components/input.vue";
  64. import chipsInput from "@/components/SelectChipInput.vue";
  65. import Competence from "@/models/Competence";
  66. import AutocompleteValues from "@/models/AutocompleteOptions";
  67. import "@/assets/css/button-group.css";
  68. export default defineComponent({
  69. components: { styledInput, chipsInput },
  70. data() {
  71. return {
  72. title: "",
  73. subTitle: "",
  74. type: "competence" as QuestionType,
  75. mandatory: false,
  76. mandatoryText: "",
  77. competences: [] as Array<QuestionCompetence>,
  78. competenceIdList: [] as Array<string>,
  79. };
  80. },
  81. props: {
  82. modelValue: {
  83. type: Object as PropType<Question>,
  84. default: () => ({
  85. title: "",
  86. subTitle: "",
  87. type: "competence",
  88. mandatory: false,
  89. competenceList: [] as Array<string>,
  90. order: -1,
  91. }),
  92. },
  93. potentialCompetences: {
  94. type: Array as PropType<Array<Competence>>,
  95. default: () => [],
  96. },
  97. },
  98. watch: {
  99. modelValue: {
  100. handler() {
  101. this.updateValue();
  102. },
  103. deep: true,
  104. },
  105. competenceIdList(val: Array<string>) {
  106. const ids = val.map((i) => parseInt(i));
  107. if (val.length != this.competences.length) {
  108. this.competences = this.competences.filter((c) => ids.includes(c.id));
  109. if (ids.length > this.competences.length) {
  110. const existingId = this.competences.map((c) => c.id);
  111. ids
  112. .filter((i) => !existingId.includes(i))
  113. .forEach((id) =>
  114. this.competences.push({
  115. id,
  116. text: this.potentialCompetences.find((c) => c.id == id)?.name ?? "",
  117. })
  118. );
  119. }
  120. this.updateParent();
  121. }
  122. },
  123. title(val: string) {
  124. if (val != this.modelValue.title) this.updateParent();
  125. },
  126. subTitle(val: string) {
  127. if (val != this.modelValue.subTitle) this.updateParent();
  128. },
  129. type(val: string) {
  130. if (val != this.modelValue.type) this.updateParent();
  131. },
  132. mandatory(val: boolean) {
  133. if (val != this.modelValue.mandatory) this.updateParent();
  134. },
  135. mandatoryText(val: string) {
  136. if (val != this.modelValue.mandatoryText) this.updateParent();
  137. },
  138. },
  139. methods: {
  140. updateValue() {
  141. const val = this.modelValue;
  142. if (this.title != val.title) this.title = val.title;
  143. if (this.subTitle != val.subTitle) this.subTitle = val.subTitle;
  144. if (this.type != val.type) this.type = val.type;
  145. if (this.mandatory != val.mandatory) this.mandatory = val.mandatory;
  146. if (this.mandatoryText != val.mandatoryText) this.mandatoryText = val.mandatoryText;
  147. if (
  148. this.competences
  149. .map((c) => c.id)
  150. .sort()
  151. .join("") !=
  152. val.competenceList
  153. .map((c) => c.id)
  154. .sort()
  155. .join("")
  156. )
  157. this.competences = val.competenceList;
  158. this.competenceIdList = this.competences.map((i) => i.id.toString());
  159. },
  160. updateParent() {
  161. const newQ: Question = {
  162. evtUuid: this.modelValue.evtUuid,
  163. uuid: this.modelValue.uuid,
  164. order: this.modelValue.order,
  165. title: this.title,
  166. subTitle: this.subTitle,
  167. type: this.type,
  168. mandatory: this.mandatory,
  169. competenceList: this.competences,
  170. mandatoryText: this.mandatoryText,
  171. };
  172. this.$emit("update:modelValue", newQ);
  173. },
  174. updateCompetenceText(e: InputEvent, idx: number) {
  175. const newVal = (e.target as HTMLInputElement).value;
  176. if (newVal != this.competences[idx].text) {
  177. this.competences[idx].text = newVal;
  178. this.updateParent();
  179. }
  180. },
  181. competenceLabel(id: number): string {
  182. return this.potentialCompetences.find((c) => c.id == id)?.name ?? "";
  183. },
  184. },
  185. computed: {
  186. autocompleteList(): Array<AutocompleteValues> {
  187. return this.potentialCompetences.map((o) => ({ id: o.id.toString(), name: o.name }));
  188. },
  189. },
  190. mounted() {
  191. this.updateValue();
  192. },
  193. });
  194. </script>
  195. <style scoped></style>