From df1dc6ccab413f5c0a96993e57533631501e33fb Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Thu, 31 Dec 2020 15:46:21 +0100
Subject: [PATCH] Add layout builder for preferences to build rows

---
 aleksis/core/util/forms.py | 32 ++++++++++++++++++++++++++++++++
 aleksis/core/views.py      |  5 +++++
 2 files changed, 37 insertions(+)
 create mode 100644 aleksis/core/util/forms.py

diff --git a/aleksis/core/util/forms.py b/aleksis/core/util/forms.py
new file mode 100644
index 000000000..7a0442449
--- /dev/null
+++ b/aleksis/core/util/forms.py
@@ -0,0 +1,32 @@
+from collections import OrderedDict
+
+from material import Layout, Row
+
+
+def preference_layout_builder(form_base_class, section=None):
+    """
+    Return a django-material Layout object for the given form_base_class.
+
+    :param form_base_class: A Form class used as the base. Must have a ``registry` attribute
+    :param section: A section where the layout builder will load preferences
+    """
+    registry = form_base_class.registry
+    if section:
+        # Try to use section param
+        preferences_obj = registry.preferences(section=section)
+
+    else:
+        # display all preferences in the form
+        preferences_obj = registry.preferences()
+
+    rows = OrderedDict()
+
+    for preference in preferences_obj:
+        row_name = preference.get("row", preference.identifier())
+        rows.setdefault(row_name, [])
+        rows[row_name].append(preference.identifier())
+
+    rows_material = []
+    for fields in rows.values():
+        rows_material.append(Row(*fields))
+    return Layout(*rows_material)
diff --git a/aleksis/core/views.py b/aleksis/core/views.py
index ff23d83fd..93bc5e5de 100644
--- a/aleksis/core/views.py
+++ b/aleksis/core/views.py
@@ -75,6 +75,7 @@ from .tables import (
 from .util import messages
 from .util.apps import AppConfig
 from .util.core_helpers import objectgetter_optional
+from .util.forms import preference_layout_builder
 
 
 @permission_required("core.view_dashboard")
@@ -545,6 +546,10 @@ def preferences(
     # Build final form from dynamic-preferences
     form_class = preference_form_builder(form_class, instance=instance, section=section)
 
+    # Get layout
+    layout = preference_layout_builder(form_class, section=section)
+    form_class.layout = layout
+
     if request.method == "POST":
         form = form_class(request.POST, request.FILES or None)
         if form.is_valid():
-- 
GitLab