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 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 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 render(self, context): if not hasattr(self, "model") and hasattr(self, "object"): self.model = self.object yield str(pretty_modelname(self.model, self.plural))
def from_queryset( queryset, # column behaviour columns: Iterable[Union[str, "DataTableColumn"]] = (), prevent_automatic_sortingnames=False, # row behaviour rowvariable="row", rowactions: Iterable[Link] = (), rowactions_dropdown=False, rowclickaction=None, # bulkaction behaviour bulkactions: Iterable[Link] = (), checkbox_for_bulkaction_name="_selected", # toolbar configuration title=None, primary_button: Optional[Button] = None, settingspanel: Any = None, pagination_config: Optional[PaginationConfig] = None, search_urlparameter: Optional[str] = None, model=None, # required if queryset is Lazy **kwargs, ): """TODO: Write Docs!!!! Yeah yeah, on it already... :param settingspanel: A panel which will be opened when clicking on the "Settings" button of the datatable, usefull e.g. for showing filter options. Currently only one button and one panel are supported. More buttons and panels could be interesting but may to over- engineered because it is a rare case and it is not difficutl to add another button by modifying the datatable after creation. """ if not isinstance(queryset, hg.Lazy): model = queryset.model if model is None: raise ValueError( "Argument for 'model' must be given if 'queryset' is of type hg.Lazy" ) columns = columns or filter_fieldlist(model, ["__all__"]) title = title or pretty_modelname(model, plural=True) if primary_button is None: primary_button = Button.from_link( Link( href=ModelHref(model, "add"), label=_("Add %s") % pretty_modelname(model), permissions=[ f"{model._meta.app_label}.add_{model._meta.model_name}" ], ), icon=Icon("add", size=20), ) if rowactions_dropdown: objectactions_menu: hg.HTMLElement = OverflowMenu( rowactions, flip=True, item_attributes={"_class": "bx--table-row--menu-option"}, ) else: objectactions_menu = hg.DIV( hg.Iterator( rowactions, "link", hg.F(lambda c: Button.from_link( c["link"], notext=True, small=True, buttontype="ghost", _class="bx--overflow-menu", ) if isinstance(c["link"], Link) else c["link"]), ), style="display: flex; justify-content: flex-end;", ) column_definitions: List[DataTableColumn] = [] for col in columns: if not (isinstance(col, DataTableColumn) or isinstance(col, str)): raise ValueError( f"Argument 'columns' needs to be of a List[str] or a List[DataTableColumn], but found {col}" ) td_attributes: Optional[dict] = None if rowclickaction and getattr(col, "enable_row_click", True): assert isinstance(rowclickaction, Link), "rowclickaction must be of type Link" td_attributes = { **aslink_attributes(rowclickaction.href), **(rowclickaction.attributes or {}), } # convert simple string (modelfield) to column definition if isinstance(col, str): col = DataTableColumn.from_modelfield( col, model, prevent_automatic_sortingnames, rowvariable, td_attributes=td_attributes, ) else: if td_attributes: col = col._replace( td_attributes=td_attributes) # type: ignore column_definitions.append(col) return DataTable( column_definitions + ([ DataTableColumn( "", objectactions_menu, td_attributes=hg.F( lambda c: { "_class": "bx--table-column-menu" if rowactions_dropdown else "" }), th_attributes=hg.F( lambda c: {"_class": "bx--table-column-menu"}), ) ] if rowactions else []), # querysets are cached, the call to all will make sure a new query is used in every request hg.F(lambda c: queryset), **kwargs, ).with_toolbar( title, helper_text=hg.format( "{} {}", hg.F(lambda c: len(hg.resolve_lazy(queryset, c)) if pagination_config is None else pagination_config. paginator.count), model._meta.verbose_name_plural, ), primary_button=primary_button, bulkactions=bulkactions, pagination_config=pagination_config, checkbox_for_bulkaction_name=checkbox_for_bulkaction_name, search_urlparameter=search_urlparameter, settingspanel=settingspanel, )
def edit_heading(model: type): return _("Edit %s") % pretty_modelname(model)
def maintype(self): return pretty_modelname(get_concrete_instance(self))