forked from CGM_Public/pretix_original
question dependencies
This commit is contained in:
@@ -50,13 +50,17 @@ export default {
|
||||
.hidden-question { opacity: 0.3; }
|
||||
.hidden-question label { text-decoration: line-through; }
|
||||
|
||||
.question-editor { margin-right: 140px; }
|
||||
.question-edit-buttons { float:right }
|
||||
.question-edit-buttons div { position: absolute; margin-left: 10px; }
|
||||
.question-editor { margin-right: 180px; }
|
||||
.question-edit-buttons { float:right; }
|
||||
.question-edit-buttons div { position: absolute; margin-left: 10px; min-width: 100px; }
|
||||
.question-edit-buttons button { }
|
||||
.form-group { margin-bottom: 30px }
|
||||
|
||||
.filter-row { background: #fffee6; border: 1px solid #ecead5; padding: 10px; }
|
||||
|
||||
.debuginfo { font-size: 70%; background: rgba(200, 200, 200, 0.5); }
|
||||
.dependency-info { position: absolute; }
|
||||
.dependency-info > span { }
|
||||
</style>
|
||||
<template>
|
||||
<p class="filter-row">
|
||||
|
||||
@@ -2,41 +2,48 @@
|
||||
import { i18n_any, QUESTION_TYPE, QUESTION_TYPE_LABEL, SYSTEM_DATAFIELDS } from './helper';
|
||||
import NativeDialog from './NativeDialog.vue';
|
||||
import I18nTextField from './I18nTextField.vue';
|
||||
import { useId, ref } from 'vue'
|
||||
import {useId, ref, computed} from 'vue'
|
||||
import { DragHandle } from 'vue-slicksort';
|
||||
import {get_datafield_edit_url} from "./api";
|
||||
|
||||
const id = useId();
|
||||
const props = defineProps(['question', 'datafields', 'editable'])
|
||||
const props = defineProps(['question', 'datafields', 'editable', 'possible_dependencies'])
|
||||
const emit = defineEmits(['removeSelf']);
|
||||
const gettext = (window as any).gettext;
|
||||
const question = ref(props.question);
|
||||
|
||||
const df = typeof props.question.question === 'number' ?
|
||||
props.datafields.find(el => el.id === props.question.question) :
|
||||
typeof props.question.question === 'string' ?
|
||||
SYSTEM_DATAFIELDS[props.question.question] :
|
||||
const df = typeof question.value.question === 'number' ?
|
||||
props.datafields.find(el => el.id === question.value.question) :
|
||||
typeof question.value.question === 'string' ?
|
||||
SYSTEM_DATAFIELDS[question.value.question] :
|
||||
null;
|
||||
|
||||
if (!props.question.label) props.question.label = {};
|
||||
if (!props.question.help_text) props.question.help_text = {};
|
||||
const dependency_values_options = computed(() => props.datafields.find(el => el.id === question.value.dependency_question)?.options);
|
||||
const dependency_values_resolved = computed(() => question.value.dependency_values.map(ident => i18n_any(dependency_values_options.value.find(opt => opt.identifier === ident)?.answer) ?? ident));
|
||||
|
||||
if (!question.value.label) question.value.label = {};
|
||||
if (!question.value.help_text) question.value.help_text = {};
|
||||
|
||||
const editor = ref();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="form-group">
|
||||
<div class="question-edit-buttons" v-if="editable"><div>
|
||||
<div class="question-edit-buttons" v-if="editable"><div class="btn-group">
|
||||
<DragHandle tag="button" class="btn btn-default"><i class="fa fa-arrows"></i></DragHandle>
|
||||
<button class="btn btn-default" @click="editor.show()"><i class="fa fa-edit"></i></button>
|
||||
</div></div>
|
||||
|
||||
<template v-if="df">
|
||||
<label class="col-md-3 control-label" :for="id" v-if="df.type !== QUESTION_TYPE.BOOLEAN">
|
||||
<div v-if="question.dependency_question" class="dependency-info debuginfo">
|
||||
<span><span class="fa fa-link"></span> {{ question.dependency_question }} = {{ dependency_values_resolved }}</span>
|
||||
</div>
|
||||
<div class="col-md-3 control-label label-empty" v-if="df.type === QUESTION_TYPE.BOOLEAN"></div>
|
||||
<label class="col-md-3 control-label" :for="id" v-else>
|
||||
{{ i18n_any(question.label) }}
|
||||
</label>
|
||||
<div v-else class="col-md-3 control-label label-empty"></div>
|
||||
<div class="col-md-9">
|
||||
<input :id="id" type="text" v-if="df.type === QUESTION_TYPE.STRING" class="form-control">
|
||||
<input :id="id" type="text" v-if="df.type === QUESTION_TYPE.STRING || df.type === QUESTION_TYPE.PHONENUMBER" class="form-control">
|
||||
<textarea :id="id" v-if="df.type === QUESTION_TYPE.TEXT" class="form-control"></textarea>
|
||||
<div class="checkbox" v-if="df.type === QUESTION_TYPE.BOOLEAN">
|
||||
<label :for="id">
|
||||
@@ -45,12 +52,16 @@ const editor = ref();
|
||||
</div>
|
||||
<input :id="id" type="number" v-if="df.type === QUESTION_TYPE.NUMBER" class="form-control">
|
||||
<input :id="id" type="file" v-if="df.type === QUESTION_TYPE.FILE" class="form-control">
|
||||
<select :id="id"
|
||||
v-if="df.type === QUESTION_TYPE.CHOICE || df.type === QUESTION_TYPE.CHOICE_MULTIPLE"
|
||||
:multiple="df.type === QUESTION_TYPE.CHOICE_MULTIPLE" class="form-control">
|
||||
<select :id="id" class="form-control"
|
||||
v-if="df.type === QUESTION_TYPE.CHOICE || df.type === QUESTION_TYPE.COUNTRYCODE">
|
||||
<option></option>
|
||||
<option v-for="opt in question.options">{{ i18n_any(opt.answer) }}</option>
|
||||
<option v-for="opt in df.options">{{ i18n_any(opt.answer) }}</option>
|
||||
</select>
|
||||
<div class="checkbox" v-if="df.type === QUESTION_TYPE.CHOICE_MULTIPLE" v-for="(opt, index) in df.options">
|
||||
<label :for="`${id}-${index}`">
|
||||
<input :id="`${id}-${index}`" type="checkbox"> {{ i18n_any(opt.answer) }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="help-block">{{ i18n_any(question.help_text) }}</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -58,7 +69,6 @@ const editor = ref();
|
||||
<h3>{{ i18n_any(question.label) }}</h3>
|
||||
<p>{{ i18n_any(question.help_text) }}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<Teleport to="body">
|
||||
@@ -107,6 +117,24 @@ const editor = ref();
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">
|
||||
{{ gettext('Only visible if...') }}
|
||||
</label>
|
||||
<div class="col-md-9">
|
||||
<select v-model="question.dependency_question" class="form-control">
|
||||
<option :value="null">{{ gettext('(none)') }}</option>
|
||||
<option v-for="(qc, index) in possible_dependencies" :value="qc.question">{{ i18n_any(qc.label) }}</option>
|
||||
</select>
|
||||
<select v-model="question.dependency_values" class="form-control" multiple>
|
||||
<option v-for="(qc, index) in dependency_values_options" :value="qc.identifier">{{ i18n_any(qc.answer) }}</option>
|
||||
</select>
|
||||
<div v-if="question.dependency_question">
|
||||
<p><span class="debuginfo">depends on {{ question.dependency_question }} = {{ dependency_values_resolved }}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button @click="editor.close()" class="btn btn-primary pull-right"><span class="fa fa-check"></span> Save and close</button>
|
||||
<button @click="emit('removeSelf')" class="btn btn-default">Remove from questionnaire</button>
|
||||
</NativeDialog>
|
||||
|
||||
@@ -5,7 +5,6 @@ import {i18n_any, QUESTION_TYPE, QUESTION_TYPE_LABEL} from "./helper";
|
||||
import I18nTextField from "./I18nTextField.vue";
|
||||
import NativeDialog from "./NativeDialog.vue";
|
||||
import { SlickList, SlickItem, DragHandle } from 'vue-slicksort';
|
||||
import {update_questionnaire} from "./api";
|
||||
|
||||
const dlgEditor = ref();
|
||||
const dlgAddExisting = ref();
|
||||
@@ -64,7 +63,7 @@ const isEditable = computed(() => props.selected_product && props.questionnaire.
|
||||
|
||||
|
||||
<template>
|
||||
<div class="question-edit-buttons"><div>
|
||||
<div class="question-edit-buttons"><div class="btn-group">
|
||||
<DragHandle tag="button" class="btn btn-default"><i class="fa fa-arrows"></i></DragHandle>
|
||||
<button class="btn btn-default" @click="dlgEditor.show()"><i class="fa fa-edit"></i></button>
|
||||
<button class="btn btn-default" @click="toggleItem()" v-if="selected_product"><i :class="`fa fa-eye${isHidden ? '-slash':''}`"></i></button>
|
||||
@@ -83,16 +82,16 @@ const isEditable = computed(() => props.selected_product && props.questionnaire.
|
||||
:datafields="props.datafields"
|
||||
:question="child"
|
||||
:editable="true"
|
||||
:possible_dependencies="props.questionnaire.children.slice(0, index)"
|
||||
@remove-self="questionnaire.children.splice(index, 1)" />
|
||||
</SlickItem>
|
||||
</SlickList>
|
||||
</div>
|
||||
<p v-if="true">
|
||||
<p v-if="true" class="btn-group" role="group">
|
||||
<button class="btn btn-default" @click="dlgAddExisting.show()"><i class="fa fa-plus"></i> {{ gettext('Existing data field') }}</button>
|
||||
<button class="btn btn-default" @click="newDatafield()"><i class="fa fa-plus"></i> {{ gettext('New data field') }}</button>
|
||||
<button class="btn btn-default" @click="showAddTextblockDialog()"><i class="fa fa-plus"></i> {{ gettext('Text') }}</button>
|
||||
</p>
|
||||
<button @click="update_questionnaire(questionnaire.id, questionnaire)" class="btn btn-default pull-right">save</button>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user