Beispiel #1
0
    def render(self, context):
        formset = self.form[self.fieldname].formset

        # management form
        yield from Form.from_django_form(formset.management_form,
                                         standalone=False).render(context)

        # detect internal fields like the delete-checkbox or the order-widget etc. and add them
        declared_fields = [
            f.fieldname
            for f in self.filter(lambda e, ancestors: isinstance(e, FormField))
        ]
        internal_fields = [
            field for field in formset.empty_form.fields
            if field not in declared_fields
        ]
        for field in internal_fields:
            self.append(FormField(field))

        # wrapping things with the div is a bit ugly but the quickest way to do it now
        yield f'<div id="formset_{formset.prefix}_container">'
        for form in formset:
            yield from Form.wrap_with_form(form, *self,
                                           standalone=False).render(context)
        yield "</div>"

        # empty/template form
        yield from htmlgenerator.DIV(
            htmlgenerator.DIV(
                Form.wrap_with_form(formset.empty_form,
                                    *self,
                                    standalone=False)),
            id=f"empty_{ formset.prefix }_form",
            _class="template-form",
            style="display:none;",
        ).render(context)

        # add-new-form button
        yield from htmlgenerator.DIV(
            Button(
                _("Add"),
                id=f"add_{formset.prefix}_button",
                onclick=
                f"formset_add('{ formset.prefix }', '#formset_{ formset.prefix }_container');",
                icon=Icon("add"),
                notext=True,
                small=True,
            ),
            _class="bx--form-item",
        ).render(context)
        yield from htmlgenerator.SCRIPT(
            mark_safe(
                f"""document.addEventListener("DOMContentLoaded", e => init_formset("{ formset.prefix }"));"""
            )).render(context)
def _display_email_without_subscription(email):
    modal_add = modal_add_subscription(email)
    return hg.BaseElement(
        hg.DIV(email.email, style="font-weight: bold;"),
        hg.DIV(_("No subscription yet for "), email.email),
        layout.button.Button(
            _("Add subscription"),
            buttontype="ghost",
            icon="add",
            **modal_add.openerattributes,
        ),
        modal_add,
    )
def is_interested_indicator(is_interested, is_active):
    if is_interested and is_active:
        color = "#198038"
        text = _("active")
    elif is_interested:
        color = "#e0e0e0"
        text = _("active")
    else:
        color = "#e0e0e0"
        text = _("inactive")
    return hg.DIV(
        hg.DIV("●", style=f"color: {color}; display: inline-block;"),
        hg.DIV(text, style="display: inline-block; padding-left: 8px"),
        style="display: inline-block;",
    )
Beispiel #4
0
    def __init__(
        self,
        fieldname,
        light=False,
        widgetattributes={},
        **attributes,
    ):
        self.fieldname = fieldname
        attributes["_class"] = (attributes.get("_class", "") +
                                " bx--form-item bx--text-input-wrapper")
        widgetattributes["_class"] = (
            widgetattributes.get("_class", "") +
            f" bx--text-input {'bx--text-input--light' if light else ''}")

        super().__init__(
            htmlgenerator.LABEL(_class="bx--label"),
            htmlgenerator.DIV(
                htmlgenerator.INPUT(**widgetattributes),
                _class="bx--text-input__field-wrapper",
            ),
            **attributes,
        )
        # for easier reference in the render method:
        self.label = self[0]
        self.input = self[1][0]
Beispiel #5
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",
            ),
        )
def searchperson(request):
    query = request.GET.get("q")

    highlight = CustomHighlighter(query)
    if not query or len(query) < settings.MIN_CHARACTERS_DYNAMIC_SEARCH:
        return HttpResponse("")

    query_set = (SearchQuerySet().models(models.Person).autocomplete(
        name_auto=query).filter_or(personnumber=query))

    def onclick(person):
        link = reverse_model(
            person,
            "edit",
            kwargs={"pk": person.pk},
        )
        return f"document.location = '{link}'"

    ret = _display_results(query_set, highlight, onclick)
    return HttpResponse(
        hg.DIV(
            ret,
            _class="raised",
            style=
            "margin-bottom: 1rem; padding: 16px 0 48px 48px; background-color: #fff",
        ).render({}))
Beispiel #7
0
def sync_help_modal():
    return bread.layout.modal.Modal(
        _("Help"),
        _("The button below is currently the only way of getting new subcribers from the mailer into our system. Is it also the only way of getting updates for subscribers that we already have in our system. This is what happens when the button is pressed:"
          ),
        hg.DIV(
            hg.UL(
                hg.LI(
                    _("For all the Subscriptions that are in the relevant segment in the Mailer, we check whether the email address is already in BasxConnect."
                      ),
                    _class="bx--list__item",
                ),
                hg.LI(
                    _("If an email address is already in BasxConnect, the downloaded subscription will be attached to the email address and override the current values in case there are any."
                      ),
                    _class="bx--list__item",
                ),
                hg.LI(
                    _("If an email address is not yet in BasxConnect, a new person will be created with that email address."
                      ),
                    _class="bx--list__item",
                ),
                _class="bx--list--unordered",
            ),
            style="padding-left: 1rem;",
        ),
        width=8,
    )
def relationshipstab(request):
    person = get_object_or_404(Person, pk=request.resolver_match.kwargs["pk"])
    modal_from = modal_add_relationship_from(person)
    modal_to = modal_add_relationship_to(person)
    return layout.tabs.Tab(
        _("Relationships"),
        utils.grid_inside_tab(
            R(
                utils.tiling_col(
                    relationships_datatable(
                        request,
                        title=_("Relationships to person"),
                        queryset=hg.F(
                            lambda c: c["object"].relationships_from.all()),
                        primary_button=button_add_relationship_to(modal_to),
                    ),
                    modal_to,
                    hg.DIV(style="margin-top: 4rem;"),
                    relationships_datatable(
                        request,
                        title=_("Relationships from person"),
                        queryset=hg.F(
                            lambda c: c["object"].relationships_to.all()),
                        primary_button=button_add_relationship_from(
                            modal_from),
                    ),
                    modal_from,
                )), ),
    )
Beispiel #9
0
def error_layout(
    request,
    status_code: int,
    status_title: str,
    description: Union[str, hg.BaseElement],
    exception_detail: str = None,
):
    return hg.BaseElement(
        hg.H1(f"{status_code}: {status_title}", style="margin-bottom: 1rem;"),
        hg.P(
            description,
            style="margin-bottom: 1rem;",
        ),
        hg.If(
            bool(exception_detail),
            hg.BaseElement(
                hg.H4("Detail", style="margin-bottom: 1rem;"),
                hg.DIV(
                    exception_detail,
                    style=(
                        "border: 1px solid grey;"
                        "padding: 1rem;"
                        "font-family: monospace;"
                        "margin-bottom: 1rem;"
                    ),
                ),
            ),
        ),
        Button.from_link(
            Link(
                label=_("Back to homepage"),
                href=hg.F(lambda c: c["request"].META["SCRIPT_NAME"] or "/"),
            )
        ),
    )
Beispiel #10
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,
     )
Beispiel #11
0
    def __init__(
        self,
        fieldname,
        placeholder="",
        rows=None,
        cols=None,
        light=False,
        widgetattributes={},
        **attributes,
    ):
        self.fieldname = fieldname
        attributes["_class"] = attributes.get("_class", "") + " bx--form-item"

        widgetattributes["_class"] = (
            widgetattributes.get("_class", "") +
            f" bx--text-area bx--text-area--v2 {'bx--text-area--light' if light else ''}",
        )
        if rows:
            widgetattributes["rows"] = rows
        if cols:
            widgetattributes["cols"] = cols

        super().__init__(
            htmlgenerator.LABEL(_class="bx--label"),
            htmlgenerator.DIV(
                htmlgenerator.TEXTAREA(placeholder=placeholder,
                                       **widgetattributes),
                _class="bx--text-area__wrapper",
            ),
            **attributes,
        )
        # for easier reference in the render method:
        self.label = self[0]
        self.input = self[1][0]
Beispiel #12
0
 def get_layout(self):
     self.checkboxcounterid = hg.html_id(self, "checkbox-counter")
     ret = super().get_layout()
     toolbar = list(
         ret.filter(lambda e, a: getattr(e, "attributes", {}).get(
             "_class", "") == "bx--toolbar-content"))[0]
     nfilters = self._checkbox_count()
     toolbar.insert(
         -2,
         hg.DIV(
             hg.SPAN(nfilters, id=self.checkboxcounterid),
             layout.icon.Icon(
                 "close",
                 focusable="false",
                 size=15,
                 role="img",
                 onclick=
                 f"document.location = '{self.request.path}?reset=1'",
             ),
             role="button",
             _class=
             "bx--list-box__selection bx--list-box__selection--multi bx--tag--filter",
             style="margin: auto 0.5rem;" +
             (" display: none;" if nfilters == 0 else ""),
             tabindex="0",
             title=("Reset"),
         ),
     )
     return ret
Beispiel #13
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 #14
0
def _loading_indicator(resultcontainerid):
    return hg.DIV(
        Loading(small=True),
        id=hg.format("{}-indicator", resultcontainerid),
        _class="htmx-indicator",
        style="position: absolute; right: 2rem",
    )
Beispiel #15
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)
Beispiel #16
0
    def __init__(
        self,
        size="xl",
        placeholder=None,
        widgetattributes=None,
        backend=None,
        resultcontainerid=None,
        show_result_container=True,
        resultcontainer_onload_js=None,
        disabled=False,
        **kwargs,
    ):
        """
        :param SearchBackendConfig backend: Where and how to get search results
        """
        kwargs["_class"] = kwargs.get("_class", "") + f" bx--search bx--search--{size}"
        kwargs["data_search"] = True
        kwargs["role"] = "search"
        width = kwargs.get("width", None)
        if width:
            kwargs["style"] = kwargs.get("style", "") + f"width:{width};"

        widgetattributes = {
            "id": "search__" + hg.html_id(self),
            "_class": "bx--search-input",
            "type": "text",
            "placeholder": placeholder or _("Search"),
            "autocomplete": "off",
            **(widgetattributes or {}),
        }
        if backend:
            if resultcontainerid is None:
                resultcontainerid = f"search-result-{hg.html_id((self, backend.url))}"
            widgetattributes["hx_get"] = backend.url
            widgetattributes["hx_trigger"] = "changed, click, keyup changed delay:500ms"
            widgetattributes["hx_target"] = hg.format("#{}", resultcontainerid)
            widgetattributes["hx_indicator"] = hg.format(
                "#{}-indicator", resultcontainerid
            )
            widgetattributes["name"] = backend.query_parameter

        self.close_button = _close_button(resultcontainerid, widgetattributes)

        super().__init__(
            hg.DIV(
                hg.LABEL(_("Search"), _class="bx--label", _for=widgetattributes["id"]),
                hg.INPUT(**widgetattributes),
                _search_icon(),
                self.close_button,
                hg.If(backend is not None, _loading_indicator(resultcontainerid)),
                **kwargs,
            ),
            hg.If(
                backend is not None and show_result_container,
                _result_container(resultcontainerid, resultcontainer_onload_js, width),
            ),
            style=hg.If(disabled, hg.BaseElement("display: none")),
        )
Beispiel #17
0
    def full(title, datatable, primary_button, helper_text=None):
        header = [hg.H4(title)]
        if helper_text:
            header.append(
                hg.P(helper_text, _class="bx--data-table-header__description"))

        return hg.DIV(
            hg.DIV(*header, _class="bx--data-table-header"),
            hg.SECTION(
                hg.DIV(
                    hg.DIV(_class="bx--action-list"),
                    hg.DIV(
                        hg.P(
                            hg.SPAN(0, data_items_selected=True),
                            _(" items selected"),
                            _class="bx--batch-summary__para",
                        ),
                        _class="bx--batch-summary",
                    ),
                    _class="bx--batch-actions",
                    aria_label=_("Table Action Bar"),
                ),
                hg.DIV(
                    hg.DIV(Search(),
                           _class="bx--toolbar-search-container-expandable"),
                    primary_button,
                    _class="bx--toolbar-content",
                ),
                _class="bx--table-toolbar",
            ),
            datatable,
            _class="bx--data-table-container",
            data_table=True,
        )
    def __init__(
        self,
        links,
        menuiconname="overflow-menu--vertical",
        menuname=None,
        direction="bottom",
        flip=False,
        item_attributes={},
        **attributes,
    ):
        attributes["data-overflow-menu"] = True
        attributes["_class"] = attributes.get("_class",
                                              "") + " bx--overflow-menu"
        item_attributes["_class"] = (item_attributes.get("_class", "") +
                                     " bx--overflow-menu-options__option")

        menuid = hg.F(lambda c: OverflowMenu.MENUID_TEMPLATE % hg.html_id(
            c.get("row", self)))
        triggerid = hg.F(lambda c: (OverflowMenu.MENUID_TEMPLATE % hg.html_id(
            c.get("row", self))) + "-trigger")

        super().__init__(
            hg.BUTTON(
                Icon(menuiconname, size=16),
                _class="bx--overflow-menu__trigger" +
                (" bx--tooltip__trigger bx--tooltip--a11y bx--tooltip--right bx--tooltip--align-start"
                 if menuname is not None else ""),
                aria_haspopup="true",
                aria_expanded="false",
                aria_controls=menuid,
                type="button",
                id=triggerid,
            ),
            hg.DIV(
                hg.UL(
                    hg.Iterator(
                        links,
                        "link",
                        hg.LI(
                            hg.F(asoverflowbutton),
                            **item_attributes,
                        ),
                    ),
                    _class="bx--overflow-menu-options__content",
                ),
                _class="bx--overflow-menu-options" +
                (" bx--overflow-menu--flip" if flip else ""),
                tabindex="-1",
                role="menu",
                aria_labelledby=triggerid,
                data_floating_menu_direction=direction,
                id=menuid,
            ),
            **attributes,
        )
        if menuname is not None:
            self[0].insert(0, hg.SPAN(menuname, _class="bx--assistive-text"))
Beispiel #19
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 #20
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 #21
0
 def get_layout(self):
     fields = hg.BaseElement(
         *[layout.forms.FormField(f) for f in self.object.active_fields()]
     )
     return hg.BaseElement(
         hg.H1(self.object, style="margin-bottom: 2rem"),
         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 #22
0
    def __init__(
        self,
        item_iterator,
        iteratorclass=htmlgenerator.Iterator,
        menuname=None,
        direction="bottom",
        flip=False,
        item_attributes={},
        **attributes,
    ):
        # making the class inline seems better, I think we can enforce scoping the type to this instance of OverflowMenu
        class MenuItemValueProvider(htmlgenerator.ValueProvider):
            attributename = "item"

        """item_iterator: an iterable which contains bread.menu.Action objects where the onclick value is what will be passed to the onclick attribute of the menu-item (and therefore should be javascript, e.g. "window.location.href='/home'"). All three item_iterator in the tuple can be lazy objects
        iteratorclass: If the Iterator needs additional values in order to generate item_iterator it can be customized and passed here"""
        attributes["data-overflow-menu"] = True
        attributes["_class"] = attributes.get("_class",
                                              "") + " bx--overflow-menu"
        menuid = f"overflow-menu-{hash(id(self))}"
        super().__init__(
            htmlgenerator.BUTTON(
                Icon("overflow-menu--vertical", size=16),
                _class="bx--overflow-menu__trigger" +
                (" bx--tooltip__trigger bx--tooltip--a11y bx--tooltip--right bx--tooltip--align-start"
                 if menuname is not None else ""),
                aria_haspopup="true",
                aria_expanded="false",
                aria_controls=menuid,
                _id=f"{menuid}-trigger",
            ),
            htmlgenerator.DIV(
                htmlgenerator.UL(
                    iteratorclass(
                        item_iterator,
                        MenuItemValueProvider.Binding(OverflowMenuItem)(
                            MenuItemValueProvider, **item_attributes),
                        MenuItemValueProvider,
                    ),
                    _class="bx--overflow-menu-options__content",
                ),
                _class="bx--overflow-menu-options" +
                (" bx--overflow-menu--flip" if flip else ""),
                tabindex="-1",
                role="menu",
                aria_labelledby=f"{menuid}-trigger",
                data_floating_menu_direction=direction,
                id=menuid,
            ),
            **attributes,
        )
        if menuname is not None:
            self[0].insert(
                0, htmlgenerator.SPAN(menuname, _class="bx--assistive-text"))
Beispiel #23
0
 def __init__(self, helptext, disabled=False):
     super().__init__(
         helptext,
         hg.DIV(
             helptext,
             _class=hg.BaseElement(
                 "bx--form__helper-text",
                 hg.If(disabled, " bx--form__helper-text--disabled"),
             ),
         ),
     )
Beispiel #24
0
def maintainance_package_layout(request):
    PYPI_API = "https://pypi.python.org/pypi/{}/json"
    PACKAGE_NAMES = ("basx-bread", "basxconnect", "htmlgenerator")

    package_current = []
    package_latest = []
    for package_name in PACKAGE_NAMES:
        current_version = pkg_resources.get_distribution(package_name).version
        newer_version = _("unable to load")

        # load the latest package info from the PyPI API
        pkg_info_req = requests.get(PYPI_API.format(package_name))
        if pkg_info_req.status_code == requests.codes.ok:
            newer_version = pkg_info_req.json()["info"]["version"]

        package_current.append(current_version)
        package_latest.append(newer_version)

    return DataTable(
        columns=[
            DataTableColumn(
                header=_("Package"),
                cell=hg.DIV(hg.C("row.package_name")),
            ),
            DataTableColumn(
                header=_("Current"),
                cell=hg.DIV(hg.C("row.package_current")),
            ),
            DataTableColumn(
                header=_("Latest"),
                cell=(hg.DIV(hg.C("row.package_latest"))),
            ),
        ],
        row_iterator=[{
            "package_name": pkg_name,
            "package_current": pkg_current,
            "package_latest": pkg_latest,
        }
                      for pkg_name, pkg_current, pkg_latest in zip(
                          PACKAGE_NAMES, package_current, package_latest)],
    )
 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 asbutton(self):
     return hg.DIV(
         hg.SPAN(self.email, style="margin-right: 0.25rem"),
         hg.SPAN(style="flex-grow: 1"),
         button.Button(
             icon="email",
             onclick=f"window.location = 'mailto:{self.email}';",
             buttontype="ghost",
             _class="bx--overflow-menu",
         ),
         style="display: flex; flex-wrap: nowrap; align-items: center",
     )
Beispiel #27
0
def display_label_and_value(label, value):
    return R(
        C(
            hg.DIV(
                label,
                style="font-weight: bold;",
            ),
            width=6,
        ),
        C(value),
        style="padding-bottom: 1.5rem;",
    )
Beispiel #28
0
def active_toggle():
    toggle = layout.toggle.Toggle(None,
                                  _("Inactive"),
                                  _("Active"),
                                  style="margin-top:-1rem; margin-bottom:0;")
    toggle.input.attributes["id"] = "person_active_toggle2"
    toggle.input.attributes["hx_trigger"] = "change"
    toggle.input.attributes["hx_post"] = hg.F(lambda c: reverse_lazy(
        "core.person.togglestatus", args=[c["object"].pk]))
    toggle.input.attributes["checked"] = hg.F(lambda c: c["object"].active)
    toggle.label.attributes["_for"] = toggle.input.attributes["id"]
    return hg.DIV(toggle)
Beispiel #29
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_postal_address
                 and c["object"].person.primary_postal_address.pk != c["object"].pk
             ),
             layout.forms.FormField("is_primary"),
             "",
         )
     ]
     return hg.DIV(layout.components.forms.Form(hg.C("form"), *form_fields))
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"),
            )),
    )