From e60b91fd452d0ac88d3f8fcc2f056f5487e9a84b Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 14 Feb 2026 20:18:35 -0600 Subject: [PATCH] fix: cleanup Structure views to better match farmOS --- ...cc1565d38e7_add_structure_thumbnail_url.py | 41 +++++++++++++++ src/wuttafarm/db/model/structures.py | 8 +++ src/wuttafarm/importing/farmos.py | 4 ++ src/wuttafarm/web/views/animals.py | 7 --- src/wuttafarm/web/views/master.py | 9 ++++ src/wuttafarm/web/views/structures.py | 50 +++++++++++++++++-- 6 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 src/wuttafarm/db/alembic/versions/8cc1565d38e7_add_structure_thumbnail_url.py diff --git a/src/wuttafarm/db/alembic/versions/8cc1565d38e7_add_structure_thumbnail_url.py b/src/wuttafarm/db/alembic/versions/8cc1565d38e7_add_structure_thumbnail_url.py new file mode 100644 index 0000000..6bcd51b --- /dev/null +++ b/src/wuttafarm/db/alembic/versions/8cc1565d38e7_add_structure_thumbnail_url.py @@ -0,0 +1,41 @@ +"""add structure thumbnail url + +Revision ID: 8cc1565d38e7 +Revises: 2a49127e974b +Create Date: 2026-02-14 20:07:33.913573 + +""" + +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +import wuttjamaican.db.util + + +# revision identifiers, used by Alembic. +revision: str = "8cc1565d38e7" +down_revision: Union[str, None] = "2a49127e974b" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + + # structure + op.add_column( + "structure", sa.Column("thumbnail_url", sa.String(length=255), nullable=True) + ) + op.add_column( + "structure_version", + sa.Column( + "thumbnail_url", sa.String(length=255), autoincrement=False, nullable=True + ), + ) + + +def downgrade() -> None: + + # structure + op.drop_column("structure_version", "thumbnail_url") + op.drop_column("structure", "thumbnail_url") diff --git a/src/wuttafarm/db/model/structures.py b/src/wuttafarm/db/model/structures.py index 546c9a1..aad50d0 100644 --- a/src/wuttafarm/db/model/structures.py +++ b/src/wuttafarm/db/model/structures.py @@ -146,6 +146,14 @@ class Structure(model.Base): """, ) + thumbnail_url = sa.Column( + sa.String(length=255), + nullable=True, + doc=""" + Optional thumbnail URL for the structure. + """, + ) + farmos_uuid = sa.Column( model.UUID(), nullable=True, diff --git a/src/wuttafarm/importing/farmos.py b/src/wuttafarm/importing/farmos.py index e9167dc..d8c67b4 100644 --- a/src/wuttafarm/importing/farmos.py +++ b/src/wuttafarm/importing/farmos.py @@ -511,6 +511,7 @@ class StructureImporter(FromFarmOS, ToWutta): "notes", "archived", "image_url", + "thumbnail_url", ] def setup(self): @@ -542,6 +543,7 @@ class StructureImporter(FromFarmOS, ToWutta): notes = notes["value"] image_url = None + thumbnail_url = None if relationships := structure.get("relationships"): if image := relationships.get("image"): if image["data"]: @@ -552,6 +554,7 @@ class StructureImporter(FromFarmOS, ToWutta): "image_style_uri" ): image_url = image_style["large"] + thumbnail_url = image_style["thumbnail"] if self.farmos_4x: archived = structure["attributes"]["archived"] @@ -568,6 +571,7 @@ class StructureImporter(FromFarmOS, ToWutta): "archived": archived, "notes": notes, "image_url": image_url, + "thumbnail_url": thumbnail_url, } diff --git a/src/wuttafarm/web/views/animals.py b/src/wuttafarm/web/views/animals.py index 884c185..5758d68 100644 --- a/src/wuttafarm/web/views/animals.py +++ b/src/wuttafarm/web/views/animals.py @@ -23,8 +23,6 @@ Master view for Animals """ -from webhelpers2.html import tags - from wuttaweb.forms.schema import WuttaDictEnum from wuttafarm.db.model.animals import Animal @@ -113,11 +111,6 @@ class AnimalView(WuttaFarmMasterView): # sex g.set_enum("sex", enum.ANIMAL_SEX) - def render_grid_thumbnail(self, animal, field, value): - if animal.thumbnail_url: - return tags.image(animal.thumbnail_url, "animal thumbnail") - return None - def grid_row_class(self, animal, data, i): """ """ if animal.archived: diff --git a/src/wuttafarm/web/views/master.py b/src/wuttafarm/web/views/master.py index 9498db4..98856f6 100644 --- a/src/wuttafarm/web/views/master.py +++ b/src/wuttafarm/web/views/master.py @@ -23,6 +23,8 @@ Base class for WuttaFarm master views """ +from webhelpers2.html import tags + from wuttaweb.views import MasterView @@ -57,6 +59,13 @@ class WuttaFarmMasterView(MasterView): return context + def render_grid_thumbnail(self, obj, field, value): + if obj.thumbnail_url: + return tags.image( + obj.thumbnail_url, f"thumbnail for {self.get_model_title()}" + ) + return None + def get_xref_buttons(self, obj): url = self.get_farmos_url(obj) if url: diff --git a/src/wuttafarm/web/views/structures.py b/src/wuttafarm/web/views/structures.py index 34c6b96..018911d 100644 --- a/src/wuttafarm/web/views/structures.py +++ b/src/wuttafarm/web/views/structures.py @@ -40,11 +40,15 @@ class StructureView(WuttaFarmMasterView): farmos_refurl_path = "/assets/structure" + labels = { + "name": "Asset Name", + } + grid_columns = [ + "thumbnail", + "drupal_id", "name", "structure_type", - "is_location", - "is_fixed", "archived", ] @@ -57,14 +61,17 @@ class StructureView(WuttaFarmMasterView): form_fields = [ "name", + "notes", + "asset_type", "structure_type", "is_location", "is_fixed", - "notes", "archived", "farmos_uuid", "drupal_id", + "thumbnail_url", "image_url", + "thumbnail", "image", ] @@ -73,6 +80,14 @@ class StructureView(WuttaFarmMasterView): super().configure_grid(g) model = self.app.model + # thumbnail + g.set_renderer("thumbnail", self.render_grid_thumbnail) + g.set_label("thumbnail", "", column_only=True) + g.set_centered("thumbnail") + + # drupal_id + g.set_label("drupal_id", "ID", column_only=True) + # name g.set_link("name") @@ -94,11 +109,38 @@ class StructureView(WuttaFarmMasterView): super().configure_form(f) structure = form.model_instance + # notes + f.set_widget("notes", "notes") + + # asset_type + if self.creating: + f.remove("asset_type") + else: + f.set_default("asset_type", "Structure") + f.set_readonly("asset_type") + # structure_type f.set_node("structure_type", StructureTypeRef(self.request)) + # thumbnail_url + if self.creating or self.editing: + f.remove("thumbnail_url") + + # image_url + if self.creating or self.editing: + f.remove("image_url") + + # thumbnail + if self.creating or self.editing: + f.remove("thumbnail") + elif structure.thumbnail_url: + f.set_widget("thumbnail", ImageWidget("structure thumbnail")) + f.set_default("thumbnail", structure.thumbnail_url) + # image - if structure.image_url: + if self.creating or self.editing: + f.remove("image") + elif structure.image_url: f.set_widget("image", ImageWidget("structure image")) f.set_default("image", structure.image_url)