Add survey question drag-sort and backend assets
- Frontend editor: drag-to-sort questions with dedicated sort assets/JS - Backend list/search refinements for tl_survey and tl_survey_content - Repository helpers for survey/question/editor queries - Translations and AI handover notes update
This commit is contained in:
@@ -188,6 +188,7 @@ final class MemberSurveyEditController extends AbstractFrontendModuleController
|
||||
$template->set('questionForms', $questionFormViews);
|
||||
$template->set('newQuestionForm', $newQuestionFormView);
|
||||
$template->set('questions', $questions);
|
||||
$template->set('canQuestionReorder', !$structureLocked && count($questions) > 1);
|
||||
$conditionOverview = $this->surveyConditionRepository->findOverviewBySurvey((int) $survey->id);
|
||||
|
||||
$template->set('conditions', $this->buildJumpRuleOverview($questions, $conditionOverview));
|
||||
@@ -279,6 +280,11 @@ final class MemberSurveyEditController extends AbstractFrontendModuleController
|
||||
$this->addFlash('success', 'Die Frage wurde gelöscht.');
|
||||
}
|
||||
|
||||
if ('reorder-questions' === $action) {
|
||||
$this->surveyEditorService->reorderQuestions($survey, $this->parseQuestionOrder($request));
|
||||
$this->addFlash('success', 'Die neue Reihenfolge der Fragen wurde gespeichert.');
|
||||
}
|
||||
|
||||
if ('delete-condition' === $action) {
|
||||
$this->surveyEditorService->deleteCondition($survey, $itemId);
|
||||
$this->addFlash('success', 'Die Bedingung wurde gelöscht.');
|
||||
@@ -290,6 +296,23 @@ final class MemberSurveyEditController extends AbstractFrontendModuleController
|
||||
return new RedirectResponse($this->buildEditUrl($model, $request, (int) $survey->id));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<int>
|
||||
*/
|
||||
private function parseQuestionOrder(Request $request): array
|
||||
{
|
||||
$rawOrder = trim((string) $request->request->get('question_order', ''));
|
||||
|
||||
if ('' === $rawOrder) {
|
||||
throw new \RuntimeException('Die neue Reihenfolge der Fragen fehlt.');
|
||||
}
|
||||
|
||||
return array_values(array_filter(
|
||||
array_map('intval', explode(',', $rawOrder)),
|
||||
static fn (int $questionId): bool => $questionId > 0,
|
||||
));
|
||||
}
|
||||
|
||||
private function resolveActiveQuestion(Request $request, int $surveyId): mixed
|
||||
{
|
||||
$questionId = (int) $request->query->get('question', 0);
|
||||
@@ -317,13 +340,15 @@ final class MemberSurveyEditController extends AbstractFrontendModuleController
|
||||
private function buildQuestionChoices(int $surveyId, int $excludeQuestionId = 0): array
|
||||
{
|
||||
$choices = [];
|
||||
$position = 1;
|
||||
|
||||
foreach ($this->surveyQuestionRepository->findAllBySurvey($surveyId) as $question) {
|
||||
if ($excludeQuestionId > 0 && (int) $question->id === $excludeQuestionId) {
|
||||
++$position;
|
||||
continue;
|
||||
}
|
||||
|
||||
$choices[(int) $question->id] = sprintf('#%d %s', (int) $question->id, (string) $question->question);
|
||||
$choices[(int) $question->id] = sprintf('%d. %s', $position++, (string) $question->question);
|
||||
}
|
||||
|
||||
return $choices;
|
||||
|
||||
@@ -90,9 +90,8 @@ final class MemberSurveyListController extends AbstractFrontendModuleController
|
||||
{
|
||||
$surveyId = (int) $request->request->get('item_id', 0);
|
||||
$action = (string) $request->request->get('_survey_action');
|
||||
$token = (string) $request->request->get('_token');
|
||||
|
||||
if ($surveyId <= 0 || !$this->isCsrfTokenValid($action.'-'.$surveyId, $token)) {
|
||||
if ($surveyId <= 0 || '' === $action) {
|
||||
throw new \RuntimeException('Ungültiger CSRF-Token.');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user