3
0
Fork 0

Compare commits

...

6 commits

7 changed files with 142 additions and 86 deletions

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# wuttaweb -- Web App for Wutta Framework # wuttaweb -- Web App for Wutta Framework
# Copyright © 2024-2025 Lance Edgar # Copyright © 2024-2026 Lance Edgar
# #
# This file is part of Wutta Framework. # This file is part of Wutta Framework.
# #
@ -30,6 +30,12 @@ import logging
import warnings import warnings
from collections import namedtuple, OrderedDict from collections import namedtuple, OrderedDict
try:
from enum import EnumType
except ImportError: # pragma: no cover
# nb. python < 3.11
from enum import EnumMeta as EnumType
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy import orm from sqlalchemy import orm
@ -763,7 +769,7 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
:param key: Name of column. :param key: Name of column.
:param enum: Instance of :class:`python:enum.Enum`. :param enum: Instance of :class:`python:enum.Enum`, or a dict.
""" """
self.enums[key] = enum self.enums[key] = enum
self.set_renderer(key, self.render_enum, enum=enum) self.set_renderer(key, self.render_enum, enum=enum)
@ -2050,7 +2056,7 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
See also :meth:`set_enum()`. See also :meth:`set_enum()`.
:param enum: Enum class for the field. This should be an :param enum: Enum class for the field. This should be an
instance of :class:`~python:enum.Enum`. instance of :class:`~python:enum.Enum` or else a dict.
To use this feature for your grid:: To use this feature for your grid::
@ -2061,13 +2067,27 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
TWO = 2 TWO = 2
THREE = 3 THREE = 3
grid.set_enum('my_enum_field', MyEnum) grid.set_enum("my_enum_field", MyEnum)
Or, perhaps more common::
myenum = {
1: "ONE",
2: "TWO",
3: "THREE",
}
grid.set_enum("my_enum_field", myenum)
""" """
if enum: if enum:
raw_value = obj[key]
if raw_value: if isinstance(enum, EnumType):
if raw_value := obj[key]:
return raw_value.value return raw_value.value
if isinstance(enum, dict):
return enum.get(value, value)
return value return value
def render_percent( # pylint: disable=unused-argument def render_percent( # pylint: disable=unused-argument

View file

@ -7,6 +7,7 @@
</%def> </%def>
<%def name="tool_panel_execution()"> <%def name="tool_panel_execution()">
% if master.executable:
<wutta-tool-panel heading="Execution"> <wutta-tool-panel heading="Execution">
% if batch.executed: % if batch.executed:
<b-notification :closable="false"> <b-notification :closable="false">
@ -87,6 +88,7 @@
% endif % endif
% endif % endif
</wutta-tool-panel> </wutta-tool-panel>
% endif
</%def> </%def>
<%def name="modify_vue_vars()"> <%def name="modify_vue_vars()">

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# wuttaweb -- Web App for Wutta Framework # wuttaweb -- Web App for Wutta Framework
# Copyright © 2024-2025 Lance Edgar # Copyright © 2024-2026 Lance Edgar
# #
# This file is part of Wutta Framework. # This file is part of Wutta Framework.
# #
@ -32,7 +32,7 @@ import markdown
from sqlalchemy import orm from sqlalchemy import orm
from wuttaweb.views import MasterView from wuttaweb.views import MasterView
from wuttaweb.forms.schema import UserRef from wuttaweb.forms.schema import UserRef, WuttaDictEnum
from wuttaweb.forms.widgets import BatchIdWidget from wuttaweb.forms.widgets import BatchIdWidget
@ -147,6 +147,9 @@ class BatchMasterView(MasterView):
# description # description
g.set_link("description") g.set_link("description")
# status_code
g.set_enum("status_code", self.model_class.STATUS)
def render_batch_id( # pylint: disable=empty-docstring,unused-argument def render_batch_id( # pylint: disable=empty-docstring,unused-argument
self, batch, key, value self, batch, key, value
): ):
@ -191,6 +194,7 @@ class BatchMasterView(MasterView):
if self.creating: if self.creating:
f.remove("status_code") f.remove("status_code")
else: else:
f.set_node("status_code", WuttaDictEnum(self.request, batch.STATUS))
f.set_readonly("status_code") f.set_readonly("status_code")
# created # created
@ -441,7 +445,7 @@ class BatchMasterView(MasterView):
g.set_renderer("status_code", self.render_row_status) g.set_renderer("status_code", self.render_row_status)
# tool button - create row # tool button - create row
if not batch.executed and self.has_perm("create_row"): if self.rows_creatable and not batch.executed and self.has_perm("create_row"):
button = self.make_button( button = self.make_button(
f"New {self.get_row_model_title()}", f"New {self.get_row_model_title()}",
primary=True, primary=True,

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# wuttaweb -- Web App for Wutta Framework # wuttaweb -- Web App for Wutta Framework
# Copyright © 2024-2025 Lance Edgar # Copyright © 2024-2026 Lance Edgar
# #
# This file is part of Wutta Framework. # This file is part of Wutta Framework.
# #
@ -3514,6 +3514,11 @@ class MasterView(View): # pylint: disable=too-many-public-methods
if hasattr(cls, "model_title"): if hasattr(cls, "model_title"):
return cls.model_title return cls.model_title
if model_class := cls.get_model_class():
if hasattr(model_class, "__wutta_hint__"):
if model_title := model_class.__wutta_hint__.get("model_title"):
return model_title
return cls.get_model_name() return cls.get_model_name()
@classmethod @classmethod
@ -3532,6 +3537,13 @@ class MasterView(View): # pylint: disable=too-many-public-methods
if hasattr(cls, "model_title_plural"): if hasattr(cls, "model_title_plural"):
return cls.model_title_plural return cls.model_title_plural
if model_class := cls.get_model_class():
if hasattr(model_class, "__wutta_hint__"):
if model_title_plural := model_class.__wutta_hint__.get(
"model_title_plural"
):
return model_title_plural
model_title = cls.get_model_title() model_title = cls.get_model_title()
return f"{model_title}s" return f"{model_title}s"

View file

@ -96,7 +96,9 @@ class PersonView(MasterView): # pylint: disable=abstract-method
f.remove("full_name") f.remove("full_name")
# users # users
if self.viewing: if self.creating or self.editing:
f.remove("users")
elif self.viewing:
f.set_grid("users", self.make_users_grid(person)) f.set_grid("users", self.make_users_grid(person))
def make_users_grid(self, person): def make_users_grid(self, person):

View file

@ -1602,15 +1602,30 @@ class TestGrid(WebTestCase):
grid = self.make_grid(columns=["foo", "bar"]) grid = self.make_grid(columns=["foo", "bar"])
obj = {"status": None} obj = {"status": None}
# null # true enum, null
value = grid.render_enum(obj, "status", None, enum=enum.UpgradeStatus) value = grid.render_enum(obj, "status", None, enum=enum.UpgradeStatus)
self.assertIsNone(value) self.assertIsNone(value)
# normal # true enum, normal value
obj["status"] = enum.UpgradeStatus.SUCCESS obj["status"] = enum.UpgradeStatus.SUCCESS
value = grid.render_enum(obj, "status", "SUCCESS", enum=enum.UpgradeStatus) value = grid.render_enum(obj, "status", "SUCCESS", enum=enum.UpgradeStatus)
self.assertEqual(value, "success") self.assertEqual(value, "success")
# dict enum
statuses = {
enum.UpgradeStatus.SUCCESS.name: "success",
enum.UpgradeStatus.FAILURE.name: "failure",
}
# dict enum, null
value = grid.render_enum(obj, "status", None, enum=statuses)
self.assertIsNone(value)
# true enum, normal value
obj["status"] = enum.UpgradeStatus.SUCCESS.value
value = grid.render_enum(obj, "status", "SUCCESS", enum=statuses)
self.assertEqual(value, "success")
def test_render_percent(self): def test_render_percent(self):
grid = self.make_grid(columns=["foo", "bar"]) grid = self.make_grid(columns=["foo", "bar"])
obj = MagicMock() obj = MagicMock()

View file

@ -442,6 +442,7 @@ class TestBatchMasterView(WebTestCase):
mod.BatchMasterView, mod.BatchMasterView,
model_class=MockBatch, model_class=MockBatch,
route_prefix="mock_batches", route_prefix="mock_batches",
rows_creatable=True,
create=True, create=True,
): ):
with patch.object( with patch.object(