3
0
Fork 0

fix: render datetimes with tooltip showing time delta from now

This commit is contained in:
Lance Edgar 2025-12-29 14:20:20 -06:00
parent ca20fdfd03
commit 0619f070c7
6 changed files with 17 additions and 37 deletions

View file

@ -274,7 +274,7 @@ class WuttaDateTimeWidget(DateTimeInputWidget):
if not cstruct: if not cstruct:
return "" return ""
dt = datetime.datetime.fromisoformat(cstruct) dt = datetime.datetime.fromisoformat(cstruct)
return self.app.render_datetime(dt) return self.app.render_datetime(dt, html=True)
return super().serialize(field, cstruct, **kw) return super().serialize(field, cstruct, **kw)

View file

@ -2041,7 +2041,7 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
grid.set_renderer('foo', 'datetime') grid.set_renderer('foo', 'datetime')
""" """
dt = getattr(obj, key) dt = getattr(obj, key)
return self.app.render_datetime(dt) return self.app.render_datetime(dt, html=True)
def render_enum(self, obj, key, value, enum=None): def render_enum(self, obj, key, value, enum=None):
""" """

View file

@ -25,7 +25,6 @@ Base Logic for Master Views
""" """
# pylint: disable=too-many-lines # pylint: disable=too-many-lines
import datetime
import logging import logging
import os import os
import threading import threading
@ -1280,7 +1279,6 @@ class MasterView(View): # pylint: disable=too-many-public-methods
# issued_at # issued_at
g.set_label("issued_at", "Changed") g.set_label("issued_at", "Changed")
g.set_renderer("issued_at", self.render_issued_at)
g.set_link("issued_at") g.set_link("issued_at")
g.set_sort_defaults("issued_at", "desc") g.set_sort_defaults("issued_at", "desc")
@ -1390,7 +1388,7 @@ class MasterView(View): # pylint: disable=too-many-public-methods
"instance_title": instance_title, "instance_title": instance_title,
"instance_url": self.get_action_url("versions", instance), "instance_url": self.get_action_url("versions", instance),
"transaction": txn, "transaction": txn,
"changed": self.render_issued_at(txn, None, None), "changed": self.app.render_datetime(txn.issued_at, html=True),
"version_diffs": version_diffs, "version_diffs": version_diffs,
"show_prev_next": True, "show_prev_next": True,
"prev_url": prev_url, "prev_url": prev_url,
@ -1421,14 +1419,6 @@ class MasterView(View): # pylint: disable=too-many-public-methods
.all() .all()
) )
def render_issued_at( # pylint: disable=missing-function-docstring,unused-argument
self, txn, key, value
):
dt = txn.issued_at
dt = dt.replace(tzinfo=datetime.timezone.utc)
dt = dt.astimezone(None)
return self.app.render_datetime(dt)
############################## ##############################
# autocomplete methods # autocomplete methods
############################## ##############################
@ -2025,22 +2015,17 @@ class MasterView(View): # pylint: disable=too-many-public-methods
fmt = f"${{:0,.{scale}f}}" fmt = f"${{:0,.{scale}f}}"
return fmt.format(value) return fmt.format(value)
def grid_render_datetime(self, record, key, value, fmt=None): def grid_render_datetime( # pylint: disable=empty-docstring
""" self, record, key, value, fmt=None
Custom grid value renderer for ):
:class:`~python:datetime.datetime` fields. """ """
warnings.warn(
"MasterView.grid_render_datetime() is deprecated; "
"please use app.render_datetime() directly instead",
DeprecationWarning,
stacklevel=2,
)
:param fmt: Optional format string to use instead of the
default: ``'%Y-%m-%d %I:%M:%S %p'``
To use this feature for your grid::
grid.set_renderer('my_datetime_field', self.grid_render_datetime)
# you can also override format
grid.set_renderer('my_datetime_field', self.grid_render_datetime,
fmt='%Y-%m-%d %H:%M:%S')
"""
# nb. get new value since the one provided will just be a # nb. get new value since the one provided will just be a
# (json-safe) *string* if the original type was datetime # (json-safe) *string* if the original type was datetime
value = record[key] value = record[key]

View file

@ -81,9 +81,6 @@ class UpgradeView(MasterView): # pylint: disable=abstract-method
# description # description
g.set_link("description") g.set_link("description")
# created
g.set_renderer("created", self.grid_render_datetime)
# created_by # created_by
g.set_link("created_by") g.set_link("created_by")
Creator = orm.aliased(model.User) # pylint: disable=invalid-name Creator = orm.aliased(model.User) # pylint: disable=invalid-name
@ -96,9 +93,6 @@ class UpgradeView(MasterView): # pylint: disable=abstract-method
# status # status
g.set_renderer("status", self.grid_render_enum, enum=enum.UpgradeStatus) g.set_renderer("status", self.grid_render_enum, enum=enum.UpgradeStatus)
# executed
g.set_renderer("executed", self.grid_render_datetime)
# executed_by # executed_by
g.set_link("executed_by") g.set_link("executed_by")
Executor = orm.aliased(model.User) # pylint: disable=invalid-name Executor = orm.aliased(model.User) # pylint: disable=invalid-name

View file

@ -207,7 +207,8 @@ class TestWuttaDateTimeWidget(WebTestCase):
# input data (from schema type) is always "local, zone-aware, isoformat" # input data (from schema type) is always "local, zone-aware, isoformat"
dt = datetime.datetime(2024, 12, 12, 13, 49, tzinfo=tzlocal) dt = datetime.datetime(2024, 12, 12, 13, 49, tzinfo=tzlocal)
result = widget.serialize(field, dt.isoformat()) result = widget.serialize(field, dt.isoformat())
self.assertEqual(result, "2024-12-12 13:49-0500") self.assertTrue(result.startswith('<span title="'))
self.assertIn("2024-12-12 13:49-0500", result)
class TestWuttaMoneyInputWidget(WebTestCase): class TestWuttaMoneyInputWidget(WebTestCase):

View file

@ -1681,8 +1681,8 @@ class TestGrid(WebTestCase):
dt = datetime.datetime(2024, 12, 12, 13, 44) dt = datetime.datetime(2024, 12, 12, 13, 44)
obj = MagicMock(dt=dt) obj = MagicMock(dt=dt)
result = grid.render_datetime(obj, "dt", str(dt)) result = grid.render_datetime(obj, "dt", str(dt))
self.assertEqual(result, "2024-12-12 05:44-0800") self.assertTrue(result.startswith('<span title="'))
self.assertNotEqual(result, str(dt)) self.assertIn("2024-12-12 05:44-0800", result)
def test_render_vue_tag(self): def test_render_vue_tag(self):
grid = self.make_grid(columns=["foo", "bar"]) grid = self.make_grid(columns=["foo", "bar"])