コード例 #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)
コード例 #2
0
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,
    )
コード例 #3
0
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;",
    )
コード例 #4
0
ファイル: text_input.py プロジェクト: tpokorra/bread
    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]
コード例 #5
0
ファイル: util.py プロジェクト: basxsoftwareassociation/bread
    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",
            ),
        )
コード例 #6
0
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({}))
コード例 #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,
    )
コード例 #8
0
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,
                )), ),
    )
コード例 #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 "/"),
            )
        ),
    )
コード例 #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,
     )
コード例 #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]
コード例 #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
コード例 #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;",
    )
コード例 #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",
    )
コード例 #15
0
ファイル: notification.py プロジェクト: tpokorra/bread
    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)
コード例 #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")),
        )
コード例 #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,
        )
コード例 #18
0
    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"))
コード例 #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",
         ),
     )
コード例 #20
0
ファイル: util.py プロジェクト: basxsoftwareassociation/bread
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",
    )
コード例 #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",
         ),
     )
コード例 #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"))
コード例 #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"),
             ),
         ),
     )
コード例 #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)],
    )
コード例 #25
0
 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,
     )
コード例 #26
0
 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",
     )
コード例 #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;",
    )
コード例 #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)
コード例 #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))
コード例 #30
0
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"),
            )),
    )