Exemplo n.º 1
0
def auth_page(content, submitname, show_cancelbutton=False):
    return hg.DIV(
        hg.DIV(
            hg.H3(hg.C("pagetitle")),
            hg.FORM(id="cancelform", action=reverse("login")),
            content,
            hg.DIV(
                hg.If(
                    show_cancelbutton,
                    layout.button.Button(
                        _("Cancel"),
                        buttontype="ghost",
                        form="cancelform",
                        type="submit",
                        style="width: 50%",
                    ),
                    hg.DIV(style="width: 50%"),
                ),
                layout.button.Button(
                    submitname, type="submit", form="authform", style="width: 50%"
                ),
                style="margin: 1rem -1rem -1rem -1rem; display: flex; height: 64px",
            ),
            style="margin: auto; width: 25rem",
            _class="bx--tile",
        ),
        style="background-image: linear-gradient(#0F62FE, #0008C9); position: absolute; left: 0; top: 0; bottom: 0; right: 0; display: flex; flex-direction: column",
    )
    def get_layout(self):
        if self.section_name:
            section_names = [self.section_name]
        else:
            section_names = self.form_class.registry.section_objects.keys()
        section_fields = {}
        for section in section_names:
            section_fields[section] = []
            for field in self.form_class.registry[section]:
                section_fields[section].append(f"{section}__{field}")

        return breadlayout.forms.Form(
            hg.C("form"),
            hg.H3(_("Global preferences")),
            Tabs(
                *[
                    Tab(
                        self.form_class.registry.section_objects[section].
                        verbose_name,
                        hg.BaseElement(*[
                            breadlayout.forms.FormField(f)
                            for f in section_fields.get(section)
                        ]),
                    ) for section in section_fields.keys()
                ],
                tabpanel_attributes={"style": "padding-left:0;"},
            ),
            breadlayout.forms.helpers.Submit(),
        )
Exemplo n.º 3
0
 def get_layout(self):
     form_fields = [layout.forms.FormField(field) for field in [*self.fields]] + [
         hg.If(
             hg.F(
                 lambda c: c["object"].person.primary_email_address
                 and c["object"].person.primary_email_address.pk != c["object"].pk
             ),
             layout.forms.FormField("is_primary"),
             "",
         ),
         hg.If(
             hg.F(
                 lambda c: apps.is_installed("basxconnect.mailer_integration")
                 and hasattr(c["object"], "subscription")
             ),
             layout.forms.FormField("propagate_change_to_mailer"),
             "",
         ),
     ]
     return layout.grid.Grid(
         hg.H3(_("Edit Email")),
         layout.grid.Row(
             layout.grid.Col(
                 layout.forms.Form(
                     hg.C("form"),
                     hg.DIV(*form_fields),
                     layout.forms.helpers.Submit(),
                 ),
                 width=4,
             )
         ),
         gutter=False,
     )
def generalsettings(request):

    if request.method == "POST":
        form = global_preference_form_builder(
            preferences=["general__organizationname"]
        )(request.POST, request.FILES)
        if form.is_valid():
            form.update_preferences()
    else:
        form = global_preference_form_builder(
            preferences=["general__organizationname"]
        )()

    return layout.grid.Grid(
        R(C(hg.H3(_("Settings")))),
        R(C(hg.H4(_("General")))),
        R(C(hg.H5(_("Information about our organization")))),
        R(
            C(
                layout.forms.Form(
                    form,
                    hg.BaseElement(F("general__organizationname")),
                    layout.forms.helpers.Submit(),
                    style="max-width: 480px",
                )
            )
        ),
        gutter=False,
    )
Exemplo n.º 5
0
def systeminformation(request):
    git_status = ""
    try:
        git_status = (
            subprocess.
            run(  # nosec because we have no user input to subprocess
                ["git", "log", "-n", "5", "--oneline"],
                capture_output=True,
                check=True).stdout.decode())
    except subprocess.SubprocessError as e:
        git_status = hg.BaseElement(
            "ERROR",
            hg.BR(),
            str(e),
            hg.BR(),
            getattr(e, "stdout", b"").decode(),
            hg.BR(),
            getattr(e, "stderr", b"").decode(),
        )

    return hg.BaseElement(
        hg.H3(_("System information")),
        hg.H4("Git log"),
        hg.PRE(hg.CODE(git_status)),
        hg.H4("PIP packages", style="margin-top: 2rem"),
        hg.UL(
            hg.Iterator(
                sorted([
                    "%s==%s" % (i.key, i.version)
                    for i in pkg_resources.working_set
                ]),
                "package",
                hg.LI(hg.C("package")),
            )),
    )
Exemplo n.º 6
0
    def __init__(
        self,
        title,
        subtitle,
        kind="info",
        lowcontrast=False,
        hideclosebutton=False,
        hidetimestamp=False,
        **attributes,
    ):
        """
        kind: can be one of "error" "info", "info-square", "success", "warning", "warning-alt"
        """
        assert (
            kind in KIND_ICON_MAPPING
        ), f"kind '{kind}' does not exists, must be one of {KIND_ICON_MAPPING.keys()}"
        self.hidetimestamp = hidetimestamp

        attributes["data-notification"] = True
        attributes["_class"] = (
            attributes.get("_class", "")
            + f" bx--toast-notification bx--toast-notification--{kind}"
        )
        if lowcontrast:
            attributes["_class"] += "  bx--toast-notification--low-contrast"
        attributes["role"] = "alert"

        timestampelem = (
            [
                htmlgenerator.P(
                    _("Time stamp "), _class="bx--toast-notification__caption"
                )
            ]
            if not hidetimestamp
            else []
        )
        children = [
            Icon(
                KIND_ICON_MAPPING[kind],
                size=20,
                _class="bx--toast-notification__icon",
            ),
            htmlgenerator.DIV(
                htmlgenerator.H3(title, _class="bx--toast-notification__title"),
                htmlgenerator.P(subtitle, _class="bx--toast-notification__subtitle"),
                *timestampelem,
                _class="bx--toast-notification__details",
            ),
        ]
        if not hideclosebutton:
            children.append(
                htmlgenerator.BUTTON(
                    Icon("close", size=20, _class="bx--toast-notification__close-icon"),
                    data_notification_btn=True,
                    _class="bx--toast-notification__close-button",
                    aria_label="close",
                )
            )
        super().__init__(*children, **attributes)
Exemplo n.º 7
0
def personsettings(request):
    ret = layout.grid.Grid(R(C(hg.H3(_("Persons")))), gutter=False)
    for vocabulary in Vocabulary.objects.all():
        ret.append(
            R(
                C(generate_term_datatable(vocabulary.name, vocabulary.slug)),
                style="margin-bottom: 2rem",
            ))
    return ret
Exemplo n.º 8
0
def header():

    editbutton = breadlayout.button.Button(
        _("Edit"),
        buttontype="ghost",
        icon="edit",
        notext=True,
    ).as_href(ModelHref.from_object(hg.C("object"), "edit"))
    readbutton = breadlayout.button.Button(
        _("Read"),
        buttontype="ghost",
        icon="view",
        notext=True,
    ).as_href(ModelHref.from_object(hg.C("object"), "read"))

    deletebutton = breadlayout.button.Button(
        _("Delete"),
        buttontype="tertiary",
        icon="trash-can",
        notext=True,
        style="border-color: red; background-color: inherit",
    ).as_href(ModelHref.from_object(hg.C("object"), "delete"))
    deletebutton[1].attributes["style"] = "fill: red; color: red;"

    copybutton = breadlayout.button.Button(
        _("Copy"),
        buttontype="ghost",
        icon="copy",
        notext=True,
    ).as_href(ModelHref.from_object(hg.C("object"), "copy"))

    return hg.DIV(
        hg.H3(
            hg.If(
                hg.C("object"),
                hg.BaseElement(
                    hg.SPAN(hg.C("object")),
                    hg.SPAN(
                        hg.If(
                            hg.C("request").resolver_match.url_name.endswith(".read"),
                            editbutton,
                            readbutton,
                        ),
                        copybutton,
                        breadlayout.button.PrintPageButton(buttontype="ghost"),
                        deletebutton,
                        _class="no-print",
                        style="margin-bottom: 1rem; margin-left: 1rem",
                        width=3,
                    ),
                ),
                hg.SPAN(hg.format(_("Add {}"), hg.C("view").model._meta.verbose_name)),
            ),
        ),
        style="padding-top: 1rem",
    )
Exemplo n.º 9
0
 def get_context_data(self, *args, **kwargs):
     layout = hg.BaseElement(
         hg.H3(_("Add %s") % pretty_modelname(self.model), ),
         self._get_layout_cached(),
     )
     return {
         **super().get_context_data(*args, **kwargs),
         "layout": layout,
         "pagetitle": _("Add %s") % pretty_modelname(self.model),
     }
 def get_layout(self):
     return layout.grid.Grid(
         hg.H3(_("Edit Relationship")),
         layout.grid.Row(
             layout.grid.Col(
                 layout.forms.Form(
                     hg.C("form"), hg.DIV(*formfields), layout.forms.helpers.Submit()
                 ),
                 width=4,
             )
         ),
         gutter=False,
     )
Exemplo n.º 11
0
    def get_layout(self):
        modelclass = self.object.model.model_class()
        if modelclass is None:
            return layout.notification.InlineNotification(
                _("Error"),
                f"Model '{self.object.model}' does no longer exist.",
                kind="error",
            )
        column_helper = layout.get_attribute_description_modal(modelclass)

        only_template, only_definition = self.object.missing_variables()
        warnings = hg.BaseElement()
        if only_template:
            warnings.append(
                layout.notification.InlineNotification(
                    _("Variables in document but not defined below: "),
                    f"{', '.join(only_template)}",
                    kind="warning",
                ))
        if only_definition:
            warnings.append(
                layout.notification.InlineNotification(
                    _("Variables defined below but not used in document: "),
                    f"{', '.join(only_definition)}",
                    kind="warning",
                ))

        F = layout.forms.FormField
        ret = hg.BaseElement(
            hg.H3(self.object),
            warnings,
            layout.forms.Form(
                hg.C("form"),
                F("name"),
                F("file"),
                layout.forms.FormsetField.as_datatable(
                    "variables",
                    ["name", "value"],
                    formsetfield_kwargs={"extra": 1},
                ),
                column_helper,
                layout.button.Button(
                    _("Help"),
                    buttontype="ghost",
                    style="margin-top: 1rem",
                    **column_helper.openerattributes,
                ),
                layout.forms.helpers.Submit(),
            ),
        )
        return ret
Exemplo n.º 12
0
def editperson_head(request):
    return hg.BaseElement(
        R(
            C(
                hg.H3(
                    hg.SPAN(
                        hg.C("object"),
                        style=hg.If(hg.C("object.deleted"),
                                    "text-decoration: line-through"),
                    ),
                    editperson_toolbar(request),
                ),
                width=12,
            ),
            style="padding-top: 1rem",
        ), )
Exemplo n.º 13
0
    def preview(self):
        columns = []
        for column in self.columns.all():
            columns.append(
                DataTableColumn(column.header,
                                layout.FC(f"row.{column.column}")))
        qs = self.queryset
        if qs is None:
            return hg.BaseElement("Model does no longer exists!")

        return hg.BaseElement(
            hg.HR(),
            hg.H3(_("Preview"), style="margin-top: 1rem"),
            layout.datatable.DataTable.from_queryset(qs[:25],
                                                     columns=columns,
                                                     primary_button=""),
        )
 def get_layout(self):
     if self.ajax_urlparameter in self.request.GET:
         return layout.forms.Form(hg.C("form"), hg.BaseElement(*formfields))
     else:
         return layout.grid.Grid(
             hg.H3(_("Add Relationship")),
             layout.grid.Row(
                 layout.grid.Col(
                     layout.forms.Form(
                         hg.C("form"),
                         hg.DIV(*formfields),
                     ),
                     width=4,
                 )
             ),
             gutter=False,
         )
Exemplo n.º 15
0
def mailer_synchronization_view(request):
    if request.method == "POST":
        try:
            sync_result = synchronize(settings.MAILER)
            notification = bread.layout.components.notification.InlineNotification(
                _("Sychronization successful"),
                _("Synchronized with mailer segment containing %s contacts. %s new persons were added to BasxConnect."
                  ) % (
                      sync_result.total_synchronized_persons,
                      sync_result.persons.filter(
                          sync_status=SynchronizationPerson.NEW).count(),
                  ),
                kind="success",
            )
        except Exception:
            notification = bread.layout.components.notification.InlineNotification(
                "Error",
                f"An error occured during synchronization. {traceback.format_exc()}",
                kind="error",
            )
    else:
        notification = None

    help_modal = sync_help_modal()
    return hg.BaseElement(
        Form(
            forms.Form(),
            bread.layout.grid.Grid(
                hg.H3(_("Synchronization of Email Subcriptions")),
                notification,
                gutter=False,
            ),
            help_modal,
            layout.forms.helpers.Submit(_("Download subscriptions"),
                                        style="display: inline-block;"),
            layout.button.Button(
                _("Help"),
                buttontype="ghost",
                style="margin-left: 1rem",
                icon="help",
                **help_modal.openerattributes,
            ),
        ),
        display_previous_execution(request),
    )
Exemplo n.º 16
0
def maintenancesettings(request):
    # Add the view's header
    ret = layout.grid.Grid(R(C(hg.H3(_("Maintenance")))), gutter=False)

    # Add the Package Information modal
    ret.append(
        R(
            C(
                hg.H4(_("Packages")),
                maintainance_package_layout(request),
            ),
            C(
                hg.H4(_("Optimize database")),
                maintenance_database_optimization(request),
                hg.H4(_("Rebuild search index"), _style="margin-top: 3rem;"),
                maintenance_search_reindex(request),
            ),
        ))

    return ret
Exemplo n.º 17
0
def bulk_tag_operation_view(request):
    operation = request.GET["operation"]
    initial = request.GET.get("new-tag")
    if operation not in ["add", "remove"]:
        return HttpResponseBadRequest("invalid GET parameter 'operation'")

    class PersonList(forms.Form):
        persons = forms.ModelMultipleChoiceField(
            queryset=models.Person.objects.all())

    personlist = PersonList(request.GET)
    if personlist.is_valid():
        persons = [person.pk for person in personlist.cleaned_data["persons"]]
    else:
        return HttpResponseBadRequest("invalid GET parameter 'persons'")

    class BulkTagOperationForm(forms.Form):
        tag = forms.ModelChoiceField(
            queryset=models.Term.objects.filter(vocabulary__slug="tag"),
            required=True,
            initial=initial,
        )

    if request.method == "POST":
        form = BulkTagOperationForm(request.POST)
        if form.is_valid():
            tag = form.cleaned_data.get("tag")
            for person in models.Person.objects.filter(pk__in=persons):
                if operation == "add":
                    person.tags.add(tag)
                else:
                    person.tags.remove(tag)
                person.save()
            return HttpResponseRedirect(reverse_model(models.Person, "browse"))

    form = BulkTagOperationForm()
    count = len(persons)
    if operation == "add":
        header = ngettext_lazy(
            "Add tag to %(count)d person",
            "Add tag to %(count)d persons",
            count,
        ) % {
            "count": count
        }
    else:
        header = ngettext_lazy(
            "Remove tag from %(count)d person",
            "Remove tag from %(count)d persons",
            count,
        ) % {
            "count": count
        }
    tags_vocabulary_id = (getattr(
        Vocabulary.objects.filter(slug="tag").first(), "id", "") or "")
    return bread.layout.forms.Form(
        form,
        hg.H3(header),
        hg.DIV(
            hg.DIV(bread.layout.forms.FormField("tag")),
            hg.If(
                operation == "add",
                hg.DIV(
                    modal_with_trigger(
                        Modal.with_ajax_content(
                            heading=_("Create new tag"),
                            url=reverse_model(
                                Term,
                                "ajax_add",
                                query={
                                    "vocabulary":
                                    tags_vocabulary_id,
                                    "asajax":
                                    True,
                                    "next":
                                    mark_safe(
                                        reverse_model(
                                            models.Person,
                                            "bulk-tag-operation",
                                            query={
                                                "operation": operation,
                                                "persons": persons,
                                            },
                                        )),
                                },
                            ),
                            submitlabel=_("Save"),
                        ),
                        Button,
                        _("Create new tag"),
                        buttontype="ghost",
                        style="margin-bottom: 2rem;",
                        icon="add",
                    ), ),
            ),
            style="display:flex;align-items:end;",
        ),
        layout.forms.helpers.Submit(_("Submit")),
    )
Exemplo n.º 18
0
def generate_wizard_form(wizardview, wizardtitle, steptitle, formlayout):
    """
    title: Title of the current page
    steps: list of 2-tuples with (step_title, status) where status must be one of ["incomplete", "complete", "current"]
    """

    # needs to be rendered in view of type NamedUrlSessionWizardView in order to work correctly
    def go_back_url(context):
        url = reverse(
            context["request"].resolver_match.view_name,
            kwargs={"step": context["wizard"]["steps"].prev},
        )
        return f"document.location='{url}'"

    steps = []
    for i, (step, formclass) in enumerate(wizardview.get_form_list().items()):
        status = "incomplete"
        if i < wizardview.steps.index:
            status = "complete"
        if step == wizardview.steps.current:
            status = "current"
        steps.append((formclass.title, status))

    return hg.BaseElement(
        hg.H3(wizardtitle),
        hg.H4(steptitle),
        layout.progress_indicator.ProgressIndicator(
            steps,
            style="margin-bottom: 2rem",
        ),
        layout.forms.Form(
            hg.C("wizard.form"),
            layout.forms.Form(
                hg.C("wizard.management_form"),
                layout.forms.FormField("current_step",
                                       form="wizard.management_form"),
                standalone=False,
            ),
            formlayout,
            hg.DIV(
                hg.DIV(
                    hg.If(
                        hg.C("wizard.steps.prev"),
                        layout.button.Button(
                            _("Back"),
                            buttontype="secondary",
                            onclick=hg.F(go_back_url),
                        ),
                    ),
                    hg.If(
                        hg.F(lambda c: c["wizard"]["steps"].last == c["wizard"]
                             ["steps"].current),
                        layout.button.Button(_("Complete"),
                                             type="submit",
                                             style="margin-left: 1rem"),
                        layout.button.Button(_("Continue"),
                                             type="submit",
                                             style="margin-left: 1rem"),
                    ),
                ),
                style="align-items: flex-end",
                _class="bx--form-item",
            ),
        ),
    )
Exemplo n.º 19
0
def relationshipssettings(request):
    return layout.grid.Grid(
        R(C(hg.H3(_("Relationships")))),
        R(
            C(
                layout.datatable.DataTable.from_queryset(
                    RelationshipType.objects.all(),
                    columns=["name"],
                    primary_button=layout.button.Button.from_link(
                        Link(
                            href=ModelHref(
                                RelationshipType,
                                "add",
                                query={
                                    "next":
                                    reverse(
                                        "basxconnect.core.views.settings_views.relationshipssettings"
                                    )
                                },
                            ),
                            label=_("Add %s") %
                            pretty_modelname(RelationshipType),
                        ),
                        icon=layout.icon.Icon("add", size=20),
                    ),
                    rowactions=[
                        Link(
                            label=_("Edit"),
                            href=ModelHref(
                                RelationshipType,
                                "edit",
                                kwargs={"pk": hg.C("row.pk")},
                                query={
                                    "next":
                                    reverse(
                                        "basxconnect.core.views.settings_views.relationshipssettings"
                                    )
                                },
                            ),
                            iconname="edit",
                        ),
                        Link(
                            label=_("Delete"),
                            href=ModelHref(
                                RelationshipType,
                                "delete",
                                kwargs={"pk": hg.C("row.pk")},
                                query={
                                    "next":
                                    reverse(
                                        "basxconnect.core.views.settings_views.relationshipssettings"
                                    )
                                },
                            ),
                            iconname="trash-can",
                        ),
                    ],
                    backurl=reverse(
                        "basxconnect.core.views.settings_views.relationshipssettings"
                    ),
                ), )),
        gutter=False,
    )
def confirm_delete_email(request, pk: int):
    email = models.Email.objects.get(id=pk)
    enable_delete_mailer_contact_checkbox = apps.is_installed(
        "basxconnect.mailer_integration") and hasattr(email, "subscription")

    fields = []
    if enable_delete_mailer_contact_checkbox:

        from basxconnect.mailer_integration.settings import MAILER

        class DeleteMailerSubscriptionForm(forms.Form):
            delete_mailer_contact = django.forms.BooleanField(
                label=_("Delete linked %s subscription as well") %
                MAILER.name(),
                required=False,
            )

        fields.append("delete_mailer_contact")

        if request.method == "POST":
            form = DeleteMailerSubscriptionForm(request.POST)
            if form.is_valid():
                person = email.person
                if enable_delete_mailer_contact_checkbox and form.cleaned_data.get(
                        "delete_mailer_contact"):
                    try:
                        from basxconnect.mailer_integration.settings import MAILER

                        MAILER.delete_person(email.email)
                    except Exception:
                        logging.error(
                            "tried to delete person from mailer but failed")

                email.delete()
                person.refresh_from_db()
                person.save()
                return HttpResponseRedirect(
                    reverse_model(person, "read", kwargs={"pk": person.pk}))
        else:
            form = DeleteMailerSubscriptionForm()
    else:
        if request.method == "POST":
            form = forms.Form(request.POST)
            if form.is_valid():
                email.delete()
                return HttpResponseRedirect(
                    reverse_model(email.person,
                                  "read",
                                  kwargs={"pk": email.person.pk}))
        else:
            form = forms.Form()

    return layout.render(
        request,
        import_string(settings.DEFAULT_PAGE_LAYOUT)(
            menu.main,
            Form(
                form,
                hg.BaseElement(
                    hg.H3(_("Delete email %s") % email.email),
                    *(bread.layout.forms.FormField(field) for field in fields),
                ),
                hg.DIV(
                    Button.from_link(
                        Link(
                            href=reverse_model(email.person,
                                               "read",
                                               kwargs={"pk": email.person.pk}),
                            label=_("Cancel"),
                            iconname=None,
                        ),
                        buttontype="tertiary",
                    ),
                    hg.DIV(style="width: 1rem"),
                    *layout.forms.helpers.Submit(_("Confirm")),
                    style="display: flex; ",
                ),
            ),
        ),
    )
Exemplo n.º 21
0
def componentpreview(request):
    class ConfigForm(forms.Form):
        with_label = forms.BooleanField(required=False)
        with_helptext = forms.BooleanField(required=False)
        with_errors = forms.BooleanField(required=False)
        disabled = forms.BooleanField(required=False)

    CHOICES = (
        ("choice1", "Choice 1"),
        ("choice2", "Choice 2"),
        ("choice3", "Choice 3"),
        ("choice4", "Choice 4"),
    )

    widgets = {
        forms.TextInput: (forms.CharField, {
            "widget": forms.TextInput
        }),
        forms.NumberInput: (forms.DecimalField, {
            "widget": forms.NumberInput
        }),
        forms.EmailInput: (forms.EmailField, {
            "widget": forms.EmailInput
        }),
        forms.URLInput: (forms.URLField, {
            "widget": forms.URLInput
        }),
        forms.PasswordInput: (forms.CharField, {
            "widget": forms.PasswordInput
        }),
        forms.HiddenInput: (forms.CharField, {
            "widget": forms.HiddenInput
        }),
        forms.DateInput: (forms.DateField, {
            "widget": forms.DateInput
        }),
        forms.DateTimeInput: (forms.DateTimeField, {
            "widget": forms.DateTimeInput
        }),
        forms.TimeInput: (forms.TimeField, {
            "widget": forms.TimeInput
        }),
        forms.Textarea: (forms.CharField, {
            "widget": forms.Textarea
        }),
        forms.CheckboxInput: (forms.BooleanField, {
            "widget": forms.CheckboxInput
        }),
        forms.Select: (forms.ChoiceField, {
            "widget": forms.Select,
            "choices": CHOICES
        }),
        forms.NullBooleanSelect: (
            forms.NullBooleanField,
            {
                "widget": forms.NullBooleanSelect
            },
        ),
        forms.SelectMultiple: (
            forms.MultipleChoiceField,
            {
                "widget": forms.SelectMultiple,
                "choices": CHOICES
            },
        ),
        forms.RadioSelect: (
            forms.ChoiceField,
            {
                "widget": forms.RadioSelect,
                "choices": CHOICES
            },
        ),
        forms.CheckboxSelectMultiple: (
            forms.ChoiceField,
            {
                "widget": forms.CheckboxSelectMultiple,
                "choices": CHOICES
            },
        ),
        forms.FileInput: (forms.FileField, {
            "widget": forms.FileInput
        }),
        forms.ClearableFileInput: (
            forms.FileField,
            {
                "widget": forms.ClearableFileInput
            },
        ),
    }

    HELPTEXT = "This is a piece of helptext, maximized for helpfulness"
    ERRORS = [
        "This is an example of an error",
        "This is a second errors, but actually none of them are real errors, so do not worry",
    ]

    def nicefieldname(cls):
        return re.sub(r"(?<!^)(?=[A-Z])", "_", cls.__name__)

    configform = ConfigForm(request.GET)
    if not configform.is_valid() or not request.GET:
        config = configform.initial
    config = configform.cleaned_data

    Form = type(
        "Form",
        (forms.Form, ),
        {
            nicefieldname(widget): field[0](
                **field[1],
                **({
                    "help_text": HELPTEXT
                } if config["with_helptext"] else {}),
                disabled=config["disabled"])
            for widget, field in widgets.items()
        },
    )

    return hg.BaseElement(
        hg.STYLE(
            hg.mark_safe("""
                #backtotopBtn {
                    position: fixed;
                    right: 0;
                    bottom: 0;
                    z-index: 999;
                    margin-right: 3rem;
                    margin-bottom: 3rem;
                    border-radius: 50%;
                }
                """)),
        layout.button.Button.from_link(
            Link(href="#", label=_("Back to top")),
            buttontype="secondary",
            icon="arrow--up",
            notext=True,
            id="backtotopBtn",
        ),
        tabs.Tabs(
            tabs.Tab(
                _("Layout"),
                layout.componentpreview.layout(request),
            ),
            tabs.Tab(
                _("Informational"),
                layout.componentpreview.informational(request),
            ),
            tabs.Tab(
                _("Interactive"),
                layout.componentpreview.interactive(request),
            ),
            tabs.Tab(
                _("Datatable"),
                layout.componentpreview.datatable_layout(request),
            ),
            tabs.Tab(
                _("Form"),
                hg.BaseElement(
                    hg.H3(_("Widget preview")),
                    layout.grid.Grid(
                        layout.grid.Row(
                            layout.grid.Col(
                                hg.H4(_("Widgets")),
                                layout.forms.Form(
                                    Form(), *[
                                        F(
                                            nicefieldname(w),
                                            no_label=not config["with_label"],
                                            errors=ERRORS
                                            if config["with_errors"] else None,
                                        ) for w in widgets.keys()
                                    ]),
                            ),
                            layout.grid.Col(
                                hg.H4(_("Configure preview")),
                                layout.forms.Form(
                                    configform,
                                    F("with_label"),
                                    F("with_helptext"),
                                    F("with_errors"),
                                    F("disabled"),
                                    layout.forms.helpers.Submit(_("Apply")),
                                    method="GET",
                                ),
                            ),
                        ),
                        R(
                            C(
                                hg.H3(_("Tooltips")),
                                hg.H4(_("Definition tooltip")),
                                hg.DIV(
                                    layout.components.tooltip.
                                    DefinitionTooltip(
                                        "Definition tooltip (left aligned)",
                                        "Brief definition of the dotted, underlined word above.",
                                        align="left",
                                    )),
                                hg.DIV(
                                    layout.components.tooltip.
                                    DefinitionTooltip(
                                        "Definition tooltip (center aligned)",
                                        "Brief definition of the dotted, underlined word above.",
                                        align="center",
                                    )),
                                hg.DIV(
                                    layout.components.tooltip.
                                    DefinitionTooltip(
                                        "Definition tooltip (right aligned)",
                                        "Brief definition of the dotted, underlined word above.",
                                        align="right",
                                    )),
                                hg.H4(_("Icon tooltip")),
                                hg.DIV(
                                    layout.components.tooltip.IconTooltip(
                                        "Help", ),
                                    layout.components.tooltip.IconTooltip(
                                        "Filter",
                                        icon=Icon("filter"),
                                    ),
                                    layout.components.tooltip.IconTooltip(
                                        "Email",
                                        icon="email",
                                    ),
                                ),
                                hg.H4(_("Interactive tooltip")),
                                hg.DIV(
                                    layout.components.tooltip.
                                    InteractiveTooltip(
                                        label="Tooltip label",
                                        body=(_(
                                            "This is some tooltip text. This box shows the maximum amount of text that should "
                                            "appear inside. If more room is needed please use a modal instead."
                                        )),
                                        heading="Heading within a Tooltip",
                                        button=(layout.components.button.
                                                Button("Button")),
                                        link=Link(href="#", label="link"),
                                    ), ),
                            ), ),
                    ),
                ),
            ),
        ),
    )

    return hg.BaseElement()