Skip to content
Snippets Groups Projects
Commit 54cebe0b authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

Document layout.py with some additional fixes

parent 05519acb
No related branches found
No related tags found
No related merge requests found
import uuid
"""Re-implementation of django-material's form layout mechanics.
This implementation provides a drop-in replacement for django-material's
Layout, Row, and Fieldset classes, which allow rendering into a JSON schema.
cf. http://docs.viewflow.io/material_forms.html
"""
from abc import ABC
from dataclasses import dataclass
from typing import Union
from typing import Optional, Union
from django.utils.text import slugify
class LayoutNode(ABC):
"""Abstract node in a form layout."""
def __init__(self, *elements):
self.elements = elements
def build_schema(self, schema, form_fields) -> dict:
"""Render this node into a JSON schema fragment."""
props = {}
for field in self.elements:
if isinstance(field, LayoutNode):
# Recurse and add fragment of the sub-node
built_schema = field.build_schema(schema, form_fields)
props.update(built_schema["properties"])
else:
# Add verbatim field
props[field] = schema.generate_field(form_fields[field])
return {"properties": props}
@dataclass
class _Section:
"""Visual section in a form."""
codename: str
title: str
description: str = None
description: Optional[str] = None
class Row(LayoutNode):
"""Visual row in a form."""
def build_schema(self, schema, form_fields):
row_name = "row-" + str(uuid.uuid4())
"""Render this row as a JSON schema fragment."""
row_name = f"row-{id(self)}"
fields = super().build_schema(schema, form_fields)["properties"]
for k in fields.keys():
fields[k]["x-options"] = {
"fieldColProps": {
"cols": 12,
"md": ""
}
}
# Make row responsive by extending each field to full width on smaller viewports
fields[k].setdefault("x-options", {}).setdefault("fieldColProps", {}).update({"cols": 12, "md": ""})
return {
"properties": {
row_name: {
......@@ -50,15 +63,18 @@ class Row(LayoutNode):
class Fieldset(LayoutNode):
"""Visual set of fields in a form."""
def __init__(self, name: Union[tuple[str, str], str], *elements):
super().__init__(*elements)
codename = str(slugify(name))
if type(name) == tuple:
self.section = _Section(codename, *map(str, name))
if isinstance(name, tuple):
self.section = _Section(codename, *name)
else:
self.section = _Section(codename, str(name))
self.section = _Section(codename, name)
def build_schema(self, schema, form_fields) -> dict:
"""Render this fieldset as a JSON schema fragment."""
section = schema.generate_section(self.section)
section["properties"].update(super().build_schema(schema, form_fields)["properties"])
return {
......@@ -69,4 +85,4 @@ class Fieldset(LayoutNode):
class Layout(LayoutNode):
...
"""Full form layout as the root node."""
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment