From 21ac610cadaf291f7e8dfcfc36befcb4a3ae0fbc Mon Sep 17 00:00:00 2001
From: Elmar Ludwig <elmar.ludwig@uni-osnabrueck.de>
Date: Mon, 10 Jun 2024 13:00:15 +0200
Subject: [PATCH] move pool search to sidebar, fixes #256

---
 VipsPlugin.php             |  1 +
 controllers/pool.php       | 52 +++++++++++++++++++++++++-------------
 lib/VipsSearchWidget.php   | 42 ++++++++++++++++++++++++++++++
 views/pool/assignments.php | 38 +++-------------------------
 views/pool/exercises.php   | 38 +++-------------------------
 5 files changed, 83 insertions(+), 88 deletions(-)
 create mode 100644 lib/VipsSearchWidget.php

diff --git a/VipsPlugin.php b/VipsPlugin.php
index 7852f8c..1ff8d7d 100644
--- a/VipsPlugin.php
+++ b/VipsPlugin.php
@@ -42,6 +42,7 @@ StudipAutoloader::addClassLookups([
     'VipsGroup'             => __DIR__ . '/lib/VipsGroup.php',
     'VipsGroupMember'       => __DIR__ . '/lib/VipsGroupMember.php',
     'VipsLtiLink'           => __DIR__ . '/lib/VipsLtiLink.php',
+    'VipsSearchWidget'      => __DIR__ . '/lib/VipsSearchWidget.php',
     'VipsSolution'          => __DIR__ . '/lib/VipsSolution.php',
     'VipsSolutionArchive'   => __DIR__ . '/lib/VipsSolutionArchive.php',
     'VipsTest'              => __DIR__ . '/lib/VipsTest.php'
diff --git a/controllers/pool.php b/controllers/pool.php
index 008ff50..f355f19 100644
--- a/controllers/pool.php
+++ b/controllers/pool.php
@@ -66,7 +66,9 @@ class PoolController extends StudipController
         $page = Request::int('page', 1);
         $size = Config::get()->ENTRIES_PER_PAGE;
 
-        $search_filter = Request::getArray('search_filter');
+        $search_filter = Request::getArray('search_filter') + ['search_string' => '', 'exercise_type' => ''];
+        $search_filter['search_string'] = Request::get('pool_search_parameter', $search_filter['search_string']);
+        $search_filter['exercise_type'] = Request::get('exercise_type', $search_filter['exercise_type']);
 
         if (Request::submitted('start_search') || Request::int('pool_search')) {
             $search_filter = [
@@ -94,6 +96,20 @@ class PoolController extends StudipController
                 ORDER BY title";
         $search = new SQLSearch($sql, _vips('Titel der Aufgabe'));
 
+        $widget = new VipsSearchWidget($this->url_for('pool/exercises', ['exercise_type' => $search_filter['exercise_type']]));
+        $widget->addNeedle(_vips('Suche'), 'pool_search', true, $search, 'function(id, name) { this.value = name; this.form.submit(); }', $search_filter['search_string']);
+        Sidebar::get()->addWidget($widget);
+
+        $widget = new SelectWidget(_vips('Aufgabentyp'), $this->url_for('pool/exercises', ['pool_search_parameter' => $search_filter['search_string']]), 'exercise_type');
+        $element = new SelectElement('', _vips('Alle Aufgabentypen'));
+        $widget->addElement($element);
+        Sidebar::get()->addWidget($widget);
+
+        foreach (Exercise::getExerciseTypes() as $type => $entry) {
+            $element = new SelectElement($type, $entry['name'], $type === $search_filter['exercise_type']);
+            $widget->addElement($element);
+        }
+
         $result = $this->getAllExercises($course_ids, $sort, $desc, $search_filter);
 
         $this->sort = $sort;
@@ -101,10 +117,7 @@ class PoolController extends StudipController
         $this->page = $page;
         $this->count = count($result);
         $this->exercises = array_slice($result, $size * ($page - 1), $size);
-
-        $this->search = $search;
         $this->search_filter = $search_filter;
-        $this->exercise_types = Exercise::getExerciseTypes();
     }
 
     /**
@@ -150,16 +163,9 @@ class PoolController extends StudipController
         $page = Request::int('page', 1);
         $size = Config::get()->ENTRIES_PER_PAGE;
 
-        $search_filter = Request::getArray('search_filter');
-
-        if (Request::submitted('start_search') || Request::int('pool_search')) {
-            $search_filter = [
-                'search_string' => Request::get('pool_search_parameter'),
-                'assignment_type' => Request::get('assignment_type')
-            ];
-        } else if (empty($search_filter) || Request::submitted('reset_search')) {
-            $search_filter = array_fill_keys(['search_string', 'assignment_type'], '');
-        }
+        $search_filter = Request::getArray('search_filter') + ['search_string' => '', 'assignment_type' => ''];
+        $search_filter['search_string'] = Request::get('pool_search_parameter', $search_filter['search_string']);
+        $search_filter['assignment_type'] = Request::get('assignment_type', $search_filter['assignment_type']);
 
         // get assignments of this user and where he/she has permission
         if ($context === 'course') {
@@ -177,18 +183,28 @@ class PoolController extends StudipController
                 ORDER BY title";
         $search = new SQLSearch($sql, _vips('Titel des Aufgabenblatts'));
 
+        $widget = new VipsSearchWidget($this->url_for('pool/assignments', ['assignment_type' => $search_filter['assignment_type']]));
+        $widget->addNeedle(_vips('Suche'), 'pool_search', true, $search, 'function(id, name) { this.value = name; this.form.submit(); }', $search_filter['search_string']);
+        Sidebar::get()->addWidget($widget);
+
+        $widget = new SelectWidget(_vips('Modus'), $this->url_for('pool/assignments', ['pool_search_parameter' => $search_filter['search_string']]), 'assignment_type');
+        $element = new SelectElement('', _vips('Beliebiger Modus'));
+        $widget->addElement($element);
+        Sidebar::get()->addWidget($widget);
+
+        foreach (VipsAssignment::getAssignmentTypes() as $type => $entry) {
+            $element = new SelectElement($type, $entry['name'], $type === $search_filter['assignment_type']);
+            $widget->addElement($element);
+        }
+
         $result = $this->getAllAssignments($course_ids, $sort, $desc, $search_filter);
 
         $this->sort = $sort;
         $this->desc = $desc;
         $this->page = $page;
         $this->count = count($result);
-
         $this->assignments = array_slice($result, $size * ($page - 1), $size);
-
-        $this->search = $search;
         $this->search_filter = $search_filter;
-        $this->assignment_types = VipsAssignment::getAssignmentTypes();
     }
 
 
diff --git a/lib/VipsSearchWidget.php b/lib/VipsSearchWidget.php
new file mode 100644
index 0000000..bd8ad33
--- /dev/null
+++ b/lib/VipsSearchWidget.php
@@ -0,0 +1,42 @@
+<?php
+/*
+ * VipsSearchWidget.php - Sidebar SearchWidget for Vips
+ * Copyright (c) 2024  Elmar Ludwig
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+class VipsSearchWidget extends SearchWidget
+{
+    /**
+     * Renders the widget.
+     *
+     * @param Array $variables Unused variables parameter
+     * @return String containing the html output of the widget
+     */
+    public function render($variables = [])
+    {
+        $needles = [];
+
+        foreach ($this->needles as $index => $needle) {
+            if ($needle['quick_search']) {
+                $quick_search = QuickSearch::get($needle['name'], $needle['quick_search']);
+                $quick_search->noSelectbox();
+                if (isset($needle['value'])) {
+                    $quick_search->defaultValue(null, $needle['value']);
+                }
+                if (isset($needle['js_func'])) {
+                    $quick_search->fireJSFunctionOnSelect($needle['js_func']);
+                }
+
+                $needle['quick_search'] = $quick_search;
+                $needles[] = $needle;
+            }
+        }
+
+        return parent::render($variables + compact('needles'));
+    }
+}
diff --git a/views/pool/assignments.php b/views/pool/assignments.php
index 28e48ce..04bf347 100644
--- a/views/pool/assignments.php
+++ b/views/pool/assignments.php
@@ -2,40 +2,8 @@
     <?= MessageBox::info(_vips('Es wurden noch keine Aufgabenblätter eingerichtet.'), [
             _vips('Auf dieser Seite finden Sie eine Übersicht über alle Aufgabenblätter in Vips, auf die Sie Zugriff haben.')
         ]) ?>
+<? elseif ($count): ?>
+    <?= $this->render_partial('pool/list_assignments') ?>
 <? else: ?>
-    <form class="default" action="<?= $controller->link_for('pool/assignments') ?>">
-        <label class="col-2">
-            <?= QuickSearch::get('pool_search', $search)
-                ->setAttributes(['autofocus' => ''])
-                ->defaultValue(null, $search_filter['search_string'])
-                ->fireJSFunctionOnSelect('function(id, name) { $(this).val(name); this.form.submit(); }')
-                ->noSelectbox()
-                ->render()
-            ?>
-        </label>
-
-        <label class="col-2">
-            <select name="assignment_type" class="inline_select" aria-label="<?= _vips('Modus auswählen') ?>">
-                <option value="">
-                    <?= _vips('Beliebiger Modus') ?>
-                </option>
-                <? foreach ($assignment_types as $type => $entry): ?>
-                    <option value="<?= $type ?>"<?= $search_filter['assignment_type'] == $type ? ' selected' : '' ?>>
-                        <?= htmlReady($entry['name']) ?>
-                    </option>
-                <? endforeach ?>
-            </select>
-        </label>
-
-        <footer style="margin: 1em 0;">
-            <?= Studip\Button::create(_vips('Suchen'), 'start_search', ['title' => _vips('Suche starten')]) ?>
-            <?= Studip\Button::create(_vips('Zurücksetzen'), 'reset_search', ['title' => _vips('Suche zurücksetzen')]) ?>
-        </footer>
-    </form>
-
-    <? if ($count): ?>
-        <?= $this->render_partial('pool/list_assignments') ?>
-    <? else: ?>
-        <?= MessageBox::info(_vips('Mit den aktuellen Sucheinstellungen sind keine Aufgabenblätter mit Zugriffsberechtigung vorhanden.')) ?>
-    <? endif ?>
+    <?= MessageBox::info(_vips('Mit den aktuellen Sucheinstellungen sind keine Aufgabenblätter mit Zugriffsberechtigung vorhanden.')) ?>
 <? endif ?>
diff --git a/views/pool/exercises.php b/views/pool/exercises.php
index c00de4d..f19786e 100644
--- a/views/pool/exercises.php
+++ b/views/pool/exercises.php
@@ -2,40 +2,8 @@
     <?= MessageBox::info(_vips('Es wurden noch keine Aufgabenblätter eingerichtet.'), [
             _vips('Auf dieser Seite finden Sie eine Übersicht über alle Aufgaben in Vips, auf die Sie Zugriff haben.')
         ]) ?>
+<? elseif ($count): ?>
+    <?= $this->render_partial('pool/list_exercises') ?>
 <? else: ?>
-    <form class="default" action="<?= $controller->link_for('pool/exercises') ?>">
-        <label class="col-2">
-            <?= QuickSearch::get('pool_search', $search)
-                ->setAttributes(['autofocus' => ''])
-                ->defaultValue(null, $search_filter['search_string'])
-                ->fireJSFunctionOnSelect('function(id, name) { $(this).val(name); this.form.submit(); }')
-                ->noSelectbox()
-                ->render()
-            ?>
-        </label>
-
-        <label class="col-2">
-            <select name="exercise_type" class="inline_select" aria-label="<?= _vips('Aufgabentyp auswählen') ?>">
-                <option value="">
-                    <?= _vips('Alle Aufgabentypen') ?>
-                </option>
-                <? foreach ($exercise_types as $type => $entry): ?>
-                    <option value="<?= $type ?>"<?= $search_filter['exercise_type'] == $type ? ' selected' : '' ?>>
-                        <?= htmlReady($entry['name']) ?>
-                    </option>
-                <? endforeach ?>
-            </select>
-        </label>
-
-        <footer style="margin: 1em 0;">
-            <?= Studip\Button::create(_vips('Suchen'), 'start_search', ['title' => _vips('Suche starten')]) ?>
-            <?= Studip\Button::create(_vips('Zurücksetzen'), 'reset_search', ['title' => _vips('Suche zurücksetzen')]) ?>
-        </footer>
-    </form>
-
-    <? if ($count): ?>
-        <?= $this->render_partial('pool/list_exercises') ?>
-    <? else: ?>
-        <?= MessageBox::info(_vips('Mit den aktuellen Sucheinstellungen sind keine Aufgaben mit Zugriffsberechtigung vorhanden.')) ?>
-    <? endif ?>
+    <?= MessageBox::info(_vips('Mit den aktuellen Sucheinstellungen sind keine Aufgaben mit Zugriffsberechtigung vorhanden.')) ?>
 <? endif ?>
-- 
GitLab