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 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, )
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 "/"), ) ), )
def contributions_tab(request): person = get_object_or_404(Person, pk=request.resolver_match.kwargs["pk"]) return layout.tabs.Tab( _("Contributions"), utils.grid_inside_tab( R( utils.tiling_col( layout.datatable.DataTable.from_queryset( person.contributions.all(), columns=[ "_import.date", "date", "note", "debitaccount", "creditaccount", "amount_formatted", ], title="", primary_button=layout.button.Button.from_link( Link( href=ModelHref(Contribution, "add", query={"person": person.id}), label=_("Add %s") % pretty_modelname(Contribution), ), icon=layout.icon.Icon("add", size=20), ), backurl=request.get_full_path(), prevent_automatic_sortingnames=True, )))), )
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, )
class VocabularyBrowseView(BrowseView): rowactions = [ BrowseView.editlink(), Link( href=ModelHref(Term, "browse", query={"vocabulary_slug": hg.C("row").slug}), label=_("Terms of vocabulary"), iconname="tree-view--alt", ), ]
from bread import menu, views from bread.contrib.document_templates.models import DocumentTemplate from bread.contrib.document_templates.views import ( DocumentTemplateEditView, generate_document, ) from bread.utils import Link, autopath, default_model_paths, model_urlname, urls urlpatterns = [ *default_model_paths( DocumentTemplate, browseview=views.BrowseView._with( rowclickaction=views.BrowseView.gen_rowclickaction("edit")), editview=DocumentTemplateEditView, readview=DocumentTemplateEditView, addview=views.AddView._with(fields=["name", "model", "file"]), ), autopath(generate_document, model_urlname(DocumentTemplate, "generate_document")), ] menu.registeritem( menu.Item( Link( href=urls.reverse_model(DocumentTemplate, "browse"), label="Document Templates", iconname="document--blank", ), menu.Group("Document Templates", iconname="document--blank"), ))
def relationshipssettings(request): return layout.grid.Grid( R(C(hg.H3(_("Relationships")))), R( C( layout.datatable.DataTable.from_queryset( RelationshipType.objects.all(), columns=["name"], primary_button=layout.button.Button.from_link( Link( href=ModelHref( RelationshipType, "add", query={ "next": reverse( "basxconnect.core.views.settings_views.relationshipssettings" ) }, ), label=_("Add %s") % pretty_modelname(RelationshipType), ), icon=layout.icon.Icon("add", size=20), ), rowactions=[ Link( label=_("Edit"), href=ModelHref( RelationshipType, "edit", kwargs={"pk": hg.C("row.pk")}, query={ "next": reverse( "basxconnect.core.views.settings_views.relationshipssettings" ) }, ), iconname="edit", ), Link( label=_("Delete"), href=ModelHref( RelationshipType, "delete", kwargs={"pk": hg.C("row.pk")}, query={ "next": reverse( "basxconnect.core.views.settings_views.relationshipssettings" ) }, ), iconname="trash-can", ), ], backurl=reverse( "basxconnect.core.views.settings_views.relationshipssettings" ), ), )), gutter=False, )
def confirm_delete_email(request, pk: int): email = models.Email.objects.get(id=pk) enable_delete_mailer_contact_checkbox = apps.is_installed( "basxconnect.mailer_integration") and hasattr(email, "subscription") fields = [] if enable_delete_mailer_contact_checkbox: from basxconnect.mailer_integration.settings import MAILER class DeleteMailerSubscriptionForm(forms.Form): delete_mailer_contact = django.forms.BooleanField( label=_("Delete linked %s subscription as well") % MAILER.name(), required=False, ) fields.append("delete_mailer_contact") if request.method == "POST": form = DeleteMailerSubscriptionForm(request.POST) if form.is_valid(): person = email.person if enable_delete_mailer_contact_checkbox and form.cleaned_data.get( "delete_mailer_contact"): try: from basxconnect.mailer_integration.settings import MAILER MAILER.delete_person(email.email) except Exception: logging.error( "tried to delete person from mailer but failed") email.delete() person.refresh_from_db() person.save() return HttpResponseRedirect( reverse_model(person, "read", kwargs={"pk": person.pk})) else: form = DeleteMailerSubscriptionForm() else: if request.method == "POST": form = forms.Form(request.POST) if form.is_valid(): email.delete() return HttpResponseRedirect( reverse_model(email.person, "read", kwargs={"pk": email.person.pk})) else: form = forms.Form() return layout.render( request, import_string(settings.DEFAULT_PAGE_LAYOUT)( menu.main, Form( form, hg.BaseElement( hg.H3(_("Delete email %s") % email.email), *(bread.layout.forms.FormField(field) for field in fields), ), hg.DIV( Button.from_link( Link( href=reverse_model(email.person, "read", kwargs={"pk": email.person.pk}), label=_("Cancel"), iconname=None, ), buttontype="tertiary", ), hg.DIV(style="width: 1rem"), *layout.forms.helpers.Submit(_("Confirm")), style="display: flex; ", ), ), ), )