Beispiel #1
0
    def get_layout(self):
        if hasattr(self, "layout") and self.layout is not None:
            ret = self.layout
        else:
            formfields = filter_fieldlist(
                self.model,
                [f for f in self.fields if isinstance(f, str)] if self.fields else None,
                for_form=True,
            )
            ret = hg.BaseElement()
            for field in self.fields or formfields:
                if field in formfields:
                    ret.append(breadlayout.forms.FormField(field))
                else:
                    ret.append(field)

        if self.ajax_urlparameter in self.request.GET:
            return breadlayout.forms.Form(hg.C("form"), ret)

        # wrap with form will add a submit button
        return hg.DIV(
            header(),
            breadlayout.tile.Tile(
                breadlayout.forms.Form(
                    hg.C("form"), ret, breadlayout.forms.helpers.Submit()
                ),
                _class="theme-white",
            ),
        )
Beispiel #2
0
class TaskResultBrowseView(BrowseView):
    columns = [
        DataTableColumn(
            layout.ObjectFieldLabel("task_id", TaskResult),
            hg.DIV(hg.C("row.task_id"), ),
            "task_id",
        ),
        DataTableColumn(
            layout.ObjectFieldLabel("task_name", TaskResult),
            hg.DIV(hg.C("row.task_name"), ),
            "task_name",
        ),
        DataTableColumn(
            _("Date Created"),
            hg.DIV(hg.C("row.date_created"), ),
            "date_created",
        ),
        DataTableColumn(
            _("Date Completed"),
            hg.DIV(hg.C("row.date_done"), ),
            "date_done",
        ),
        "status",
        "worker",
        "content_type",
        DataTableColumn(
            _("Metadata"),
            hg.DIV(hg.C("row.meta"), ),
        ),
    ]
    rowclickaction = BrowseView.gen_rowclickaction("read")
    title = "Background Jobs"
Beispiel #3
0
 def get_layout(self):
     return hg.If(
         hg.C("validlink"),
         auth_page(
             layout.forms.Form(
                 hg.C("form"),
                 layout.forms.FormField(
                     "new_password1",
                     inputelement_attrs={"_class": "field-02-background"},
                     style="width: 100%",
                 ),
                 layout.forms.FormField(
                     "new_password2",
                     inputelement_attrs={"_class": "field-02-background"},
                 ),
                 id="authform",
             ),
             _("Change password"),
         ),
         auth_page(
             hg.BaseElement(
                 hg.FORM(id="authform", action=reverse("login")),
                 layout.notification.InlineNotification(
                     _("Invalid password reset link"),
                     _(
                         "The password reset link was invalid, possibly because it has already been used. Please request a new password reset."
                     ),
                     kind="error",
                     lowcontrast=True,
                     style="margin-bottom: 4rem",
                 ),
             ),
             _("Back to Login"),
         ),
     )
def personal_data():
    displayed_fields = [
        utils.display_field_label_and_value(field)
        for field in [
            "salutation",
            "title",
            "name",
            "first_name",
            "last_name",
            "date_of_birth",
            "profession",
        ]
    ] + [
        hg.If(
            hg.C("object.deceased"),
            display_label_and_value(
                ObjectFieldLabel("deceased"),
                hg.If(hg.C("object.deceased"), _("Yes"), _("No")),
            ),
        ),
        hg.If(
            hg.C("object.deceased"),
            utils.display_field_label_and_value("decease_date"),
        ),
    ]
    return utils.tile_col_edit_modal_displayed_fields(
        _("Personal Data"),
        models.NaturalPerson,
        "ajax_edit_personal_data",
        Icon("user--profile"),
        displayed_fields,
    )
Beispiel #5
0
def person_metadata(model):
    return tiling_col(
        # we need this to take exactly as much space as a real header
        hg.DIV("", style="margin-bottom:3.25rem;"),
        display_field_label_and_value("personnumber"),
        display_field_label_and_value("maintype"),
        display_field_label_and_value("type"),
        display_label_and_value(_("Status"), active_toggle()),
        display_label_and_value(
            _("Changed"),
            hg.BaseElement(
                ObjectFieldValue("history.first.history_date.date"),
                " / ",
                hg.C("object.history.first.history_user"),
            ),
        ),
        display_label_and_value(
            _("Created"),
            hg.BaseElement(
                ObjectFieldValue("history.last.history_date.date"),
                " / ",
                hg.C("object.history.last.history_user"),
            ),
        ),
        open_modal_popup_button(
            _("Meta data"), model,
            f"{model._meta.model_name}_ajax_edit_metadata"),
        style="border-left: none;",
    )
Beispiel #6
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)

        F = layout.forms.FormField

        fieldstable = layout.forms.FormsetField.as_datatable(
            "columns",
            ["header", "column", "sortingname"],
            formsetfield_kwargs={
                "extra": 1,
                "can_order": True,
            },
        )
        fieldstable[0][1].insert(
            0,
            layout.button.Button(_("Help"),
                                 buttontype="ghost",
                                 **column_helper.openerattributes),
        )
        fieldstable.append(hg.DIV(style="height: 1rem"))
        ret = hg.BaseElement(
            views.header(),
            layout.forms.Form(
                hg.C("form"),
                hg.DIV(
                    _("Base model"),
                    ": ",
                    hg.C("object.model"),
                    style="margin: 2rem 0 2rem 0",
                ),
                F("name"),
                F(
                    "filter",
                    inputelement_attrs={"rows": 1},
                    style="width: 100%",
                ),
                fieldstable,
                layout.tile.ExpandableTile(
                    hg.H4(_("Extended settings")),
                    hg.DIV(
                        F("custom_queryset"),
                        F("pagination"),
                    ),
                ),
                layout.forms.helpers.Submit(style="margin-top: 1rem"),
                column_helper,
            ),
            hg.C("object.preview"),
        )
        return ret
def display_sync_persons(sync_status):
    return hg.Iterator(
        hg.F(lambda c: c["row"].persons.filter(sync_status=sync_status)),
        "person",
        hg.DIV(
            hg.format(
                "{} {} <{}>",
                hg.C("person.first_name"),
                hg.C("person.last_name"),
                hg.C("person.email"),
            )),
    )
 def __init__(self, platform, company, searchbar, actions=(), *args, **kwargs):
     super().__init__(
         hg.If(
             HasBreadCookieValue("sidenav-hidden", "true"),
             variable_size_header_part(hg.BaseElement(), company, searchbar, "5rem"),
             variable_size_header_part(
                 hg.SPAN(platform, _class="bx--header__name--prefix"),
                 company,
                 searchbar,
                 "18rem",
             ),
         ),
         hg.DIV(
             hg.If(
                 hg.F(lambda c: c["request"].user.is_authenticated),
                 hg.A(
                     hg.SPAN(
                         hg.C("request.user.get_username"),
                         _class="bx--header__name--prefix",
                     ),
                     _class="bx--header__name",
                     href=reverse("userprofile"),
                     title=hg.C("request.user.get_username"),
                     style="padding: 0; margin-right: 1rem",
                 ),
             ),
             hg.If(
                 hg.F(lambda c: c["request"].user.is_authenticated),
                 hg.BUTTON(
                     Icon(
                         "logout",
                         size=20,
                         _class="bx--navigation-menu-panel-expand-icon",
                         aria_hidden="true",
                     ),
                     Icon(
                         "logout",
                         size=20,
                         _class="bx--navigation-menu-panel-collapse-icon",
                         aria_hidden="true",
                     ),
                     _class="bx--header__menu-trigger bx--header__action",
                     title=_("Logout"),
                     data_navigation_menu_panel_label_expand=_("Logout"),
                     data_navigation_menu_panel_label_collapse=_("Close"),
                     onclick=f"document.location = '{reverse('logout')}'",
                 ),
             ),
             _class="bx--header__global",
         ),
         _class="bx--header",
         data_header=True,
     )
def tags():
    return tile_with_icon(
        Icon("tag--group"),
        hg.H4(_("Tags")),
        hg.Iterator(hg.F(lambda c: c["object"].tags.all()), "i",
                    Tag(hg.C("i"))),
        open_modal_popup_button(
            _("Edit Tags"),
            hg.C("object").person_ptr,
            "ajax_edit_tags",
        ),
    )
 def management_form(self):
     # the management form is required for Django formsets
     return hg.BaseElement(
         # management forms, for housekeeping of inline forms
         hg.F(lambda c: Form(
             c[self.formname][self.fieldname].formset.management_form,
             *[
                 FormField(
                     f, no_wrapper=True, no_label=True, no_helptext=True)
                 for f in c[self.formname][self.fieldname].formset.
                 management_form.fields
             ],
             standalone=False,
         )),
         # Empty form as template for new entries. The script tag works very well
         # for this since we need a single, raw, unescaped HTML string
         hg.SCRIPT(
             Form(
                 hg.C(f"{self.formname}.{self.fieldname}.formset.empty_form"
                      ),
                 hg.WithContext(
                     self.content,
                     **{
                         DEFAULT_FORMSET_CONTEXTNAME:
                         hg.
                         C(f"{self.formname}.{self.fieldname}.formset.empty_form"
                           )
                     },
                 ),
                 standalone=False,
             ),
             id=hg.BaseElement(
                 "empty_",
                 hg.C(f"{self.formname}.{self.fieldname}.formset.prefix"),
                 "_form",
             ),
             type="text/plain",
         ),
         hg.SCRIPT(
             mark_safe(
                 "document.addEventListener('DOMContentLoaded', e => init_formset('"
             ),
             hg.C(f"{self.formname}.{self.fieldname}.formset.prefix"),
             mark_safe("'));"),
         ),
         hg.SPAN(onload=hg.BaseElement(
             mark_safe("init_formset('"),
             hg.C(f"{self.formname}.{self.fieldname}.formset.prefix"),
             mark_safe("');"),
         ), ),
     )
Beispiel #11
0
def tile_with_datatable(model, queryset, columns, request):
    modal = layout.modal.Modal.with_ajax_content(
        _("Add"),
        ModelHref(
            model,
            "add",
            query=hg.F(lambda c: {
                "person": c["object"].pk,
                "asajax": True
            }),
        ),
        submitlabel=_("Save"),
    )
    return tiling_col(
        layout.datatable.DataTable.from_queryset(
            queryset,
            model=model,
            prevent_automatic_sortingnames=True,
            columns=columns,
            rowactions=[
                Link(
                    href=ModelHref(
                        model,
                        "edit",
                        kwargs={"pk": hg.C("row.pk")},
                        query={"next": request.get_full_path()},
                    ),
                    iconname="edit",
                    label=_("Edit"),
                ),
                Link(
                    href=ModelHref(
                        model,
                        "delete",
                        kwargs={"pk": hg.C("row.pk")},
                        query={"next": request.get_full_path()},
                    ),
                    iconname="trash-can",
                    label=_("Delete"),
                ),
            ],
            primary_button=layout.button.Button(_("Add"),
                                                buttontype="primary",
                                                **modal.openerattributes),
            style="border-top: none;",
        ),
        modal,
    )
Beispiel #12
0
 def get_layout(self):
     R = layout.grid.Row
     C = layout.grid.Col
     F = layout.forms.FormField
     return layout.grid.Grid(
         layout.components.forms.Form(
             hg.C("form"),
             R(C(F("salutation"))),
             R(C(F("title"))),
             R(
                 C(
                     F("name"),
                     width=10,
                     breakpoint="lg",
                 ),
                 C(
                     F("autogenerate_displayname"),
                     width=6,
                     breakpoint="lg",
                     style="align-self: flex-end;",
                 ),
             ),
             R(C(F("first_name"))),
             R(C(F("last_name"))),
             R(C(F("date_of_birth"))),
             R(C(F("profession"))),
             R(C(F("deceased"))),
             R(C(F("decease_date"))),
         )
     )
Beispiel #13
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",
        ), )
Beispiel #14
0
    def get_layout(self):
        fields = hg.BaseElement(
            *[
                layout.forms.FormField(f)
                for f in utils.filter_fieldlist(self.model, ["__all__"], for_form=True)
            ]
        )

        return hg.BaseElement(
            hg.H1(self.object, style="margin-bottom: 2rem"),
            hg.DIV(
                layout.button.Button(
                    "Edit",
                    **layout.aslink_attributes(
                        layout.objectaction(self.object, "edit")
                    ),
                ),
                views.layoutasreadonly(
                    hg.DIV(
                        hg.DIV(
                            layout.forms.Form(
                                hg.C("form"), fields, layout.forms.helpers.Submit()
                            ),
                            style="padding: 1rem",
                        ),
                        hg.DIV(
                            self.object.as_svg(),
                            style="width: 40%; border: 1px solid gray",
                        ),
                        style="display: flex;",
                    )
                ),
            ),
        )
Beispiel #15
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 display_previous_execution(request):
    return R(
        C(
            layout.datatable.DataTable.from_queryset(
                SynchronizationResult.objects.order_by(
                    "-sync_completed_datetime"),
                columns=[
                    "total_synchronized_persons",
                    "sync_completed_datetime",
                    DataTableColumn(
                        _("Newly added to BasxConnect"),
                        display_sync_persons(SynchronizationPerson.NEW),
                    ),
                ],
                title=_("Previous Executions"),
                primary_button="",
                rowactions=[
                    Link(
                        href=ModelHref(
                            SynchronizationResult,
                            "delete",
                            kwargs={"pk": hg.C("row.pk")},
                            query={"next": request.get_full_path()},
                        ),
                        iconname="trash-can",
                        label=_("Delete"),
                    )
                ],
            ),
            width=16,
        ))
Beispiel #17
0
def generate_term_datatable(title, vocabulary_slug):
    """Helper function to display a table for all terms of a certain term, currently always returns to the personsettings view"""
    # TODO: make the backurl dynamic to return to current view (needs correct handling in the DataTable code)

    cat = Vocabulary.objects.filter(slug=vocabulary_slug).first() or ""
    return layout.datatable.DataTable.from_queryset(
        Term.objects.filter(vocabulary__slug=vocabulary_slug),
        columns=["term"],
        title=title,
        primary_button=layout.button.Button.from_link(
            Link(
                href=ModelHref(Term,
                               "add",
                               query={"vocabulary": cat.id},
                               return_to_current=True),
                label=_("Add %s") % pretty_modelname(Term),
            ),
            icon=layout.icon.Icon("add", size=20),
        ),
        prevent_automatic_sortingnames=True,
        rowclickaction=BrowseView.gen_rowclickaction("edit",
                                                     return_to_current=True),
        rowactions=[
            Link(
                label=_("Delete"),
                href=ModelHref.from_object(hg.C("row"),
                                           "delete",
                                           return_to_current=True),
                iconname="trash-can",
            )
        ],
        backurl=reverse(
            "basxconnect.core.views.settings_views.personsettings"),
    )
    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(),
        )
Beispiel #19
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")),
            )),
    )
Beispiel #20
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",
    )
Beispiel #21
0
 def get_layout(self):
     return auth_page(
         layout.forms.Form(
             hg.C("form"),
             hg.A(
                 _("Lost password?"),
                 href=reverse("password_reset"),
                 style="display: block; text-align: right; font-size: 0.75rem",
             ),
             layout.forms.FormField(
                 fieldname="username",
                 form="form",
                 inputelement_attrs={"_class": "field-02-background"},
                 style="width: 100%",
             ),
             layout.forms.FormField(
                 fieldname="password",
                 form="form",
                 inputelement_attrs={"_class": "field-02-background"},
                 style="width: 100%",
             ),
             id="authform",
         ),
         _("Login"),
     )
Beispiel #22
0
def editperson_toolbar(request):
    deletebutton = layout.button.Button(
        _("Delete"),
        buttontype="ghost",
        icon="trash-can",
        notext=True,
        **layout.aslink_attributes(
            hg.F(lambda c: layout.objectaction(c["object"], "delete"))),
    )
    restorebutton = layout.button.Button(
        _("Restore"),
        buttontype="ghost",
        icon="undo",
        notext=True,
        **layout.aslink_attributes(
            hg.F(lambda c: layout.objectaction(
                c["object"], "delete", query={"restore": True}))),
    )
    copybutton = layout.button.Button(
        _("Copy"),
        buttontype="ghost",
        icon="copy",
        notext=True,
        **layout.aslink_attributes(
            hg.F(lambda c: layout.objectaction(c["object"], "copy"))),
    )

    return hg.SPAN(
        hg.If(hg.C("object.deleted"), restorebutton, deletebutton),
        copybutton,
        layout.button.PrintPageButton(buttontype="ghost"),
        _class="no-print",
        style="margin-bottom: 1rem; margin-left: 1rem",
        width=3,
    )
def profile_field_checkbox(fieldname):
    return layout.forms.widgets.Checkbox(
        label=layout.ObjectFieldLabel(fieldname),
        inputelement_attrs={
            "checked": hg.C(f"object.{fieldname}"),
            "disabled": True
        },
    )
 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,
         )
Beispiel #25
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",
    )
Beispiel #26
0
 def deletelink(return_to_current=True):
     return Link(
         href=ModelHref.from_object(hg.C("row"),
                                    "delete",
                                    return_to_current=return_to_current),
         label=_("Delete"),
         iconname="delete",
     )
def relationships_datatable(request, queryset, primary_button, title):
    return layout.datatable.DataTable.from_queryset(
        queryset,
        model=Relationship,
        title=title,
        prevent_automatic_sortingnames=True,
        columns=[
            person_in_relationship(
                "Person A",
                "person_a",
                lambda relationship: relationship.person_a,
            ),
            "type",
            person_in_relationship(
                "Person B",
                "person_b",
                lambda relationship: relationship.person_b,
            ),
            "start_date",
            "end_date",
        ],
        rowactions=[
            Link(
                href=ModelHref(
                    Relationship,
                    "edit",
                    kwargs={"pk": hg.C("row.pk")},
                    query={"next": request.get_full_path()},
                ),
                iconname="edit",
                label=_("Edit"),
            ),
            Link(
                href=ModelHref(
                    Relationship,
                    "delete",
                    kwargs={"pk": hg.C("row.pk")},
                    query={"next": request.get_full_path()},
                ),
                iconname="trash-can",
                label=_("Delete"),
            ),
        ],
        primary_button=primary_button,
    )
Beispiel #28
0
 def __init__(self, errors):
     super().__init__(
         errors,
         hg.DIV(
             hg.UL(hg.Iterator(errors or (), "error",
                               hg.LI(hg.C("error")))),
             _class="bx--form-requirement",
         ),
     )
Beispiel #29
0
 def editlink(return_to_current=True, **attributes):
     return Link(
         href=ModelHref.from_object(hg.C("row"),
                                    "edit",
                                    return_to_current=return_to_current),
         label=_("Edit"),
         iconname="edit",
         attributes=attributes,
     )
 def __init__(
     self,
     label=None,
     help_text=None,
     errors=None,
     inputelement_attrs=None,
     boundfield=None,
     **attributes,
 ):
     inputelement_attrs = inputelement_attrs or {}
     super().__init__(
         hg.FIELDSET(
             label,
             hg.DIV(
                 hg.Iterator(
                     boundfield.subwidgets,
                     "radiobutton",
                     RadioButton(
                         label=Label(hg.C("radiobutton").data["label"]),
                         inputelement_attrs=_combine_lazy_dict(
                             _combine_lazy_dict(
                                 inputelement_attrs,
                                 {
                                     "name":
                                     hg.C("radiobutton").data["name"],
                                     "value":
                                     hg.C("radiobutton").data["value"],
                                     "checked":
                                     hg.C("radiobutton").data["selected"],
                                 },
                             ),
                             hg.C("radiobutton").data["attrs"],
                         ),
                     ),
                 ),
                 _class=
                 "bx--radio-button-group  bx--radio-button-group--vertical",
             ),
             data_invalid=hg.If(getattr(errors, "condition", False), True),
         ),
         help_text,
         errors,
         **attributes,
     )