This commit is contained in:
Mira Weller
2026-03-27 18:57:22 +01:00
parent 583184af38
commit bdc720f5a2
5 changed files with 63 additions and 23 deletions

View File

@@ -541,6 +541,7 @@ class LegacyDependencyValueField(serializers.CharField):
class QuestionSerializer(I18nAwareModelSerializer):
options = InlineQuestionOptionSerializer(many=True, required=False)
identifier = serializers.CharField(allow_null=True)
internal_name = serializers.CharField(allow_null=True, source='question', read_only=True)
dependency_value = LegacyDependencyValueField(source='dependency_values', required=False, allow_null=True)
class Meta:
@@ -549,7 +550,7 @@ class QuestionSerializer(I18nAwareModelSerializer):
'ask_during_checkin', 'show_during_checkin', 'identifier', 'dependency_question', 'dependency_values',
'hidden', 'dependency_value', 'print_on_invoice', 'help_text', 'valid_number_min',
'valid_number_max', 'valid_date_min', 'valid_date_max', 'valid_datetime_min', 'valid_datetime_max',
'valid_string_length_max', 'valid_file_portrait')
'valid_string_length_max', 'valid_file_portrait', 'internal_name',)
def validate_identifier(self, value):
Question._clean_identifier(self.context['event'], value, self.instance)

View File

@@ -10,10 +10,12 @@
{% trans "Questionnaires" %}
{% endblock %}
{% block inside %}
<a href="{% url "control:event.items.questions" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default pull-right">
{% icon "wrench" %} {% trans "Manage data fields" %}
</a>
<h1>{% trans "Questionnaires" %}</h1>
<h1>
{% trans "Questionnaires" %}
<a href="{% url "control:event.items.questions" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default pull-right">
{% icon "wrench" %} {% trans "Manage data fields" %}
</a>
</h1>
<p>
{% blocktrans trimmed %}
Questions allow your attendees to fill in additional data about their ticket. If you provide food, one

View File

@@ -61,16 +61,6 @@ const editor = ref();
<I18nTextField :value="question.label"/>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">
Data field type
</label>
<div class="col-md-9">
<select v-model="df.type" class="form-control">
<option v-for="(label, type) in QUESTION_TYPE_LABEL" :value="QUESTION_TYPE[type]">{{ label }}</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">
Help text
@@ -80,6 +70,27 @@ const editor = ref();
<div class="help-block">Wenn diese Frage noch weitere Erklärung braucht, können Sie sie hier eintragen.</div>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">
Data field
</label>
<div class="col-md-9">
<p class="form-control-static">
{{ question.question }}
<a href="" target="_blank">Manage data field details</a>
</p>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">
Data field type
</label>
<div class="col-md-9">
<select v-model="df.type" class="form-control" disabled>
<option v-for="(label, type) in QUESTION_TYPE_LABEL" :value="QUESTION_TYPE[type]">{{ label }}</option>
</select>
</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>

View File

@@ -6,6 +6,7 @@ import I18nTextField from "./I18nTextField.vue";
import NativeDialog from "./NativeDialog.vue";
const id = useId();
const props = defineProps(['questionnaire', 'datafields', 'selected_product', 'items'])
const gettext = (window as any).gettext
function toggleItem() {
const i = props.questionnaire.items.indexOf(props.selected_product);
@@ -16,10 +17,23 @@ function toggleItem() {
}
}
function addExistingDatafield(field) {
props.questionnaire.children.push({
question: field.id,
required: false,
label: {},
help_text: {},
dependency_question: null,
dependency_values: [],
});
dlgAddExisting.value.close();
}
const isHidden = computed(() => props.selected_product && props.questionnaire.items.indexOf(props.selected_product) === -1);
const isEditable = computed(() => props.selected_product && props.questionnaire.items.indexOf(props.selected_product) !== -1);
const editor = ref();
const dlgEditor = ref();
const dlgAddExisting = ref();
</script>
@@ -27,7 +41,7 @@ const editor = ref();
<template>
<div class="question-edit-buttons"><div>
<button class="btn btn-default"><i class="fa fa-arrows"></i></button>
<button class="btn btn-default" @click="editor.show()"><i class="fa fa-edit"></i></button>
<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>
</div></div>
@@ -48,7 +62,7 @@ const editor = ref();
</div>
<p v-if="true">
<button class="btn btn-default" @click="addExistingDatafield()"><i class="fa fa-plus"></i> Bestehendes Datenfeld hinzufügen</button>
<button class="btn btn-default" @click="dlgAddExisting.show()"><i class="fa fa-plus"></i> Bestehendes Datenfeld hinzufügen</button>
<button class="btn btn-default" @click="newDatafield()"><i class="fa fa-plus"></i> Neues Datenfeld</button>
<button class="btn btn-default" @click="addSubtitle()"><i class="fa fa-plus"></i> Zwischenüberschrift</button>
<button class="btn btn-default" @click="addTextBlock()"><i class="fa fa-plus"></i> Text</button>
@@ -57,11 +71,11 @@ const editor = ref();
</details>
<Teleport to="body">
<NativeDialog ref="editor" class="modal-card"
title="Edit questionnaire">
<NativeDialog ref="dlgEditor" class="modal-card"
:title="gettext('Edit questionnaire')">
<div class="form-group">
<label class="col-md-3 control-label">
Internal name
{{ gettext('Internal name') }}
</label>
<div class="col-md-9">
<input type="text" class="form-control" v-model="questionnaire.internal_name"/>
@@ -69,7 +83,7 @@ const editor = ref();
</div>
<div class="form-group">
<label class="col-md-3 control-label">
Visible on products
{{ gettext('Visible on products') }}
</label>
<div class="col-md-9">
<div class="checkbox" v-for="item in items">
@@ -79,8 +93,18 @@ const editor = ref();
</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="dlgEditor.close()" class="btn btn-primary pull-right"><span class="fa fa-check"></span> {{ gettext('Save and close') }}</button>
<button class="btn btn-default">Delete</button>
</NativeDialog>
<NativeDialog ref="dlgAddExisting" class="modal-card"
:title="gettext('Add existing data field')">
<div class="list-group">
<a href="javascript:" @click="addExistingDatafield(field)" v-for="field in datafields" class="list-group-item">{{ field.internal_name }}</a>
</div>
<button @click="dlgAddExisting.close()" class="btn btn-default pull-right">Cancel</button>
</NativeDialog>
</Teleport>
</template>

View File

@@ -1,6 +1,8 @@
export function i18n_any(data) {
if (!data) return null;
const preferred = document.body.getAttribute("data-pretixlocale");
if (data[preferred]) return data[preferred];
return Object.values(data)[0];
}