From 3435b4714e594588d1f9c1e14a9a75dc20efd1f4 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sun, 15 Feb 2026 13:38:11 -0600 Subject: [PATCH] feat: convert structure assets to use common base/mixin --- ...52_use_shared_base_for_structure_assets.py | 236 ++++++++++++++++++ src/wuttafarm/db/model/__init__.py | 2 +- src/wuttafarm/db/model/structures.py | 91 +------ src/wuttafarm/importing/farmos.py | 56 ++--- src/wuttafarm/web/menus.py | 10 +- src/wuttafarm/web/views/__init__.py | 1 - src/wuttafarm/web/views/assets.py | 2 + src/wuttafarm/web/views/farmos/structures.py | 6 +- src/wuttafarm/web/views/structure_types.py | 118 --------- src/wuttafarm/web/views/structures.py | 202 ++++++++------- 10 files changed, 385 insertions(+), 339 deletions(-) create mode 100644 src/wuttafarm/db/alembic/versions/34ec51d80f52_use_shared_base_for_structure_assets.py delete mode 100644 src/wuttafarm/web/views/structure_types.py diff --git a/src/wuttafarm/db/alembic/versions/34ec51d80f52_use_shared_base_for_structure_assets.py b/src/wuttafarm/db/alembic/versions/34ec51d80f52_use_shared_base_for_structure_assets.py new file mode 100644 index 0000000..4be383f --- /dev/null +++ b/src/wuttafarm/db/alembic/versions/34ec51d80f52_use_shared_base_for_structure_assets.py @@ -0,0 +1,236 @@ +"""use shared base for Structure Assets + +Revision ID: 34ec51d80f52 +Revises: d882682c82f9 +Create Date: 2026-02-15 13:19:18.814523 + +""" + +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +import wuttjamaican.db.util + + +# revision identifiers, used by Alembic. +revision: str = "34ec51d80f52" +down_revision: Union[str, None] = "d882682c82f9" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + + # asset_structure + op.create_table( + "asset_structure", + sa.Column("structure_type_uuid", wuttjamaican.db.util.UUID(), nullable=False), + sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False), + sa.ForeignKeyConstraint( + ["structure_type_uuid"], + ["structure_type.uuid"], + name=op.f("fk_asset_structure_structure_type_uuid_structure_type"), + ), + sa.ForeignKeyConstraint( + ["uuid"], ["asset.uuid"], name=op.f("fk_asset_structure_uuid_asset") + ), + sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset_structure")), + ) + op.create_table( + "asset_structure_version", + sa.Column( + "structure_type_uuid", + wuttjamaican.db.util.UUID(), + autoincrement=False, + nullable=True, + ), + sa.Column( + "uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False + ), + sa.Column( + "transaction_id", sa.BigInteger(), autoincrement=False, nullable=False + ), + sa.Column("end_transaction_id", sa.BigInteger(), nullable=True), + sa.Column("operation_type", sa.SmallInteger(), nullable=False), + sa.PrimaryKeyConstraint( + "uuid", "transaction_id", name=op.f("pk_asset_structure_version") + ), + ) + op.create_index( + op.f("ix_asset_structure_version_end_transaction_id"), + "asset_structure_version", + ["end_transaction_id"], + unique=False, + ) + op.create_index( + op.f("ix_asset_structure_version_operation_type"), + "asset_structure_version", + ["operation_type"], + unique=False, + ) + op.create_index( + "ix_asset_structure_version_pk_transaction_id", + "asset_structure_version", + ["uuid", sa.literal_column("transaction_id DESC")], + unique=False, + ) + op.create_index( + "ix_asset_structure_version_pk_validity", + "asset_structure_version", + ["uuid", "transaction_id", "end_transaction_id"], + unique=False, + ) + op.create_index( + op.f("ix_asset_structure_version_transaction_id"), + "asset_structure_version", + ["transaction_id"], + unique=False, + ) + + # structure + op.drop_index( + op.f("ix_structure_version_end_transaction_id"), table_name="structure_version" + ) + op.drop_index( + op.f("ix_structure_version_operation_type"), table_name="structure_version" + ) + op.drop_index( + op.f("ix_structure_version_pk_transaction_id"), table_name="structure_version" + ) + op.drop_index( + op.f("ix_structure_version_pk_validity"), table_name="structure_version" + ) + op.drop_index( + op.f("ix_structure_version_transaction_id"), table_name="structure_version" + ) + op.drop_table("structure_version") + op.drop_table("structure") + + +def downgrade() -> None: + + # structure + op.create_table( + "structure", + sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False), + sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=False), + sa.Column("archived", sa.BOOLEAN(), autoincrement=False, nullable=False), + sa.Column( + "structure_type_uuid", sa.UUID(), autoincrement=False, nullable=False + ), + sa.Column("is_location", sa.BOOLEAN(), autoincrement=False, nullable=False), + sa.Column("is_fixed", sa.BOOLEAN(), autoincrement=False, nullable=False), + sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column( + "image_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True + ), + sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True), + sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column( + "thumbnail_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True + ), + sa.ForeignKeyConstraint( + ["structure_type_uuid"], + ["structure_type.uuid"], + name=op.f("fk_structure_structure_type_uuid_structure_type"), + ), + sa.PrimaryKeyConstraint("uuid", name=op.f("pk_structure")), + sa.UniqueConstraint( + "drupal_id", + name=op.f("uq_structure_drupal_id"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + sa.UniqueConstraint( + "farmos_uuid", + name=op.f("uq_structure_farmos_uuid"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + sa.UniqueConstraint( + "name", + name=op.f("uq_structure_name"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + ) + op.create_table( + "structure_version", + sa.Column("uuid", sa.UUID(), autoincrement=False, nullable=False), + sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True), + sa.Column("archived", sa.BOOLEAN(), autoincrement=False, nullable=True), + sa.Column("structure_type_uuid", sa.UUID(), autoincrement=False, nullable=True), + sa.Column("is_location", sa.BOOLEAN(), autoincrement=False, nullable=True), + sa.Column("is_fixed", sa.BOOLEAN(), autoincrement=False, nullable=True), + sa.Column("notes", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column( + "image_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True + ), + sa.Column("farmos_uuid", sa.UUID(), autoincrement=False, nullable=True), + sa.Column("drupal_id", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("transaction_id", sa.BIGINT(), autoincrement=False, nullable=False), + sa.Column( + "end_transaction_id", sa.BIGINT(), autoincrement=False, nullable=True + ), + sa.Column("operation_type", sa.SMALLINT(), autoincrement=False, nullable=False), + sa.Column( + "thumbnail_url", sa.VARCHAR(length=255), autoincrement=False, nullable=True + ), + sa.PrimaryKeyConstraint( + "uuid", "transaction_id", name=op.f("pk_structure_version") + ), + ) + op.create_index( + op.f("ix_structure_version_transaction_id"), + "structure_version", + ["transaction_id"], + unique=False, + ) + op.create_index( + op.f("ix_structure_version_pk_validity"), + "structure_version", + ["uuid", "transaction_id", "end_transaction_id"], + unique=False, + ) + op.create_index( + op.f("ix_structure_version_pk_transaction_id"), + "structure_version", + ["uuid", sa.literal_column("transaction_id DESC")], + unique=False, + ) + op.create_index( + op.f("ix_structure_version_operation_type"), + "structure_version", + ["operation_type"], + unique=False, + ) + op.create_index( + op.f("ix_structure_version_end_transaction_id"), + "structure_version", + ["end_transaction_id"], + unique=False, + ) + + # asset_structure + op.drop_index( + op.f("ix_asset_structure_version_transaction_id"), + table_name="asset_structure_version", + ) + op.drop_index( + "ix_asset_structure_version_pk_validity", table_name="asset_structure_version" + ) + op.drop_index( + "ix_asset_structure_version_pk_transaction_id", + table_name="asset_structure_version", + ) + op.drop_index( + op.f("ix_asset_structure_version_operation_type"), + table_name="asset_structure_version", + ) + op.drop_index( + op.f("ix_asset_structure_version_end_transaction_id"), + table_name="asset_structure_version", + ) + op.drop_table("asset_structure_version") + op.drop_table("asset_structure") diff --git a/src/wuttafarm/db/model/__init__.py b/src/wuttafarm/db/model/__init__.py index 94592f2..5b1625a 100644 --- a/src/wuttafarm/db/model/__init__.py +++ b/src/wuttafarm/db/model/__init__.py @@ -32,7 +32,7 @@ from .users import WuttaFarmUser # wuttafarm proper models from .assets import AssetType, Asset, AssetParent from .land import LandType, LandAsset -from .structures import StructureType, Structure +from .structures import StructureType, StructureAsset from .animals import AnimalType, AnimalAsset from .groups import Group from .logs import LogType, ActivityLog diff --git a/src/wuttafarm/db/model/structures.py b/src/wuttafarm/db/model/structures.py index aad50d0..8c5371c 100644 --- a/src/wuttafarm/db/model/structures.py +++ b/src/wuttafarm/db/model/structures.py @@ -28,6 +28,8 @@ from sqlalchemy import orm from wuttjamaican.db import model +from wuttafarm.db.model.assets import AssetMixin, add_asset_proxies + class StructureType(model.Base): """ @@ -74,38 +76,19 @@ class StructureType(model.Base): return self.name or "" -class Structure(model.Base): +class StructureAsset(AssetMixin, model.Base): """ Represents a structure from farmOS """ - __tablename__ = "structure" + __tablename__ = "asset_structure" __versioned__ = {} __wutta_hint__ = { - "model_title": "Structure", - "model_title_plural": "Structures", + "model_title": "Structure Asset", + "model_title_plural": "Structure Assets", + "farmos_asset_type": "structure", } - uuid = model.uuid_column() - - name = sa.Column( - sa.String(length=100), - nullable=False, - unique=True, - doc=""" - Name for the structure. - """, - ) - - archived = sa.Column( - sa.Boolean(), - nullable=False, - default=False, - doc=""" - Whether the structure is archived. - """, - ) - structure_type_uuid = model.uuid_fk_column("structure_type.uuid", nullable=False) structure_type = orm.relationship( "StructureType", @@ -114,63 +97,5 @@ class Structure(model.Base): """, ) - is_location = sa.Column( - sa.Boolean(), - nullable=False, - doc=""" - Whether the structure is considered a location. - """, - ) - is_fixed = sa.Column( - sa.Boolean(), - nullable=False, - doc=""" - Whether the structure location is fixed. - """, - ) - - notes = sa.Column( - sa.Text(), - nullable=True, - doc=""" - Arbitrary notes for the structure. - """, - ) - - image_url = sa.Column( - sa.String(length=255), - nullable=True, - doc=""" - Optional image URL for the structure. - """, - ) - - 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, - unique=True, - doc=""" - UUID for the structure within farmOS. - """, - ) - - drupal_id = sa.Column( - sa.Integer(), - nullable=True, - unique=True, - doc=""" - Drupal internal ID for the structure. - """, - ) - - def __str__(self): - return self.name or "" +add_asset_proxies(StructureAsset) diff --git a/src/wuttafarm/importing/farmos.py b/src/wuttafarm/importing/farmos.py index fadb43e..4410023 100644 --- a/src/wuttafarm/importing/farmos.py +++ b/src/wuttafarm/importing/farmos.py @@ -100,7 +100,7 @@ class FromFarmOSToWuttaFarm(FromFarmOSHandler, ToWuttaFarmHandler): importers["LandType"] = LandTypeImporter importers["LandAsset"] = LandAssetImporter importers["StructureType"] = StructureTypeImporter - importers["Structure"] = StructureImporter + importers["StructureAsset"] = StructureAssetImporter importers["AnimalType"] = AnimalTypeImporter importers["AnimalAsset"] = AnimalAssetImporter importers["Group"] = GroupImporter @@ -613,17 +613,18 @@ class LogTypeImporter(FromFarmOS, ToWutta): } -class StructureImporter(FromFarmOS, ToWutta): +class StructureAssetImporter(AssetImporterBase): """ - farmOS API → WuttaFarm importer for Structures + farmOS API → WuttaFarm importer for Structure Assets """ - model_class = model.Structure + model_class = model.StructureAsset supported_fields = [ "farmos_uuid", "drupal_id", - "name", + "asset_type", + "asset_name", "structure_type_uuid", "is_location", "is_fixed", @@ -631,6 +632,7 @@ class StructureImporter(FromFarmOS, ToWutta): "archived", "image_url", "thumbnail_url", + "parents", ] def setup(self): @@ -652,46 +654,20 @@ class StructureImporter(FromFarmOS, ToWutta): structure_type = self.structure_types_by_id.get(structure_type_id) if not structure_type: log.warning( - "invalid structure_type '%s' for farmOS Structure: %s", + "invalid structure_type '%s' for farmOS Structure Asset: %s", structure_type_id, structure, ) return None - if notes := structure["attributes"]["notes"]: - notes = notes["value"] - - image_url = None - thumbnail_url = None - if relationships := structure.get("relationships"): - if image := relationships.get("image"): - if image["data"]: - image = self.farmos_client.resource.get_id( - "file", "file", image["data"][0]["id"] - ) - if image_style := image["data"]["attributes"].get( - "image_style_uri" - ): - image_url = image_style["large"] - thumbnail_url = image_style["thumbnail"] - - if self.farmos_4x: - archived = structure["attributes"]["archived"] - else: - archived = structure["attributes"]["status"] == "archived" - - return { - "farmos_uuid": UUID(structure["id"]), - "drupal_id": structure["attributes"]["drupal_internal__id"], - "name": structure["attributes"]["name"], - "structure_type_uuid": structure_type.uuid, - "is_location": structure["attributes"]["is_location"], - "is_fixed": structure["attributes"]["is_fixed"], - "archived": archived, - "notes": notes, - "image_url": image_url, - "thumbnail_url": thumbnail_url, - } + data = self.normalize_asset(structure) + data.update( + { + "asset_type": "structure", + "structure_type_uuid": structure_type.uuid, + } + ) + return data class StructureTypeImporter(FromFarmOS, ToWutta): diff --git a/src/wuttafarm/web/menus.py b/src/wuttafarm/web/menus.py index 9625af0..a7aa4b2 100644 --- a/src/wuttafarm/web/menus.py +++ b/src/wuttafarm/web/menus.py @@ -59,17 +59,17 @@ class WuttaFarmMenuHandler(base.MenuHandler): "route": "land_assets", "perm": "land_assets.list", }, + { + "title": "Structure", + "route": "structure_assets", + "perm": "structure_assets.list", + }, {"type": "sep"}, { "title": "Groups", "route": "groups", "perm": "groups.list", }, - { - "title": "Structures", - "route": "structures", - "perm": "structures.list", - }, {"type": "sep"}, { "title": "Animal Types", diff --git a/src/wuttafarm/web/views/__init__.py b/src/wuttafarm/web/views/__init__.py index 3963014..e44c16e 100644 --- a/src/wuttafarm/web/views/__init__.py +++ b/src/wuttafarm/web/views/__init__.py @@ -44,7 +44,6 @@ def includeme(config): config.include("wuttafarm.web.views.asset_types") config.include("wuttafarm.web.views.assets") config.include("wuttafarm.web.views.land") - config.include("wuttafarm.web.views.structure_types") config.include("wuttafarm.web.views.structures") config.include("wuttafarm.web.views.animals") config.include("wuttafarm.web.views.groups") diff --git a/src/wuttafarm/web/views/assets.py b/src/wuttafarm/web/views/assets.py index 81fd093..c4bb792 100644 --- a/src/wuttafarm/web/views/assets.py +++ b/src/wuttafarm/web/views/assets.py @@ -241,6 +241,8 @@ class AssetMasterView(WuttaFarmMasterView): route = "farmos_animals.view" elif asset.asset_type == "land": route = "farmos_land_assets.view" + elif asset.asset_type == "structure": + route = "farmos_structures.view" if route: buttons.append( diff --git a/src/wuttafarm/web/views/farmos/structures.py b/src/wuttafarm/web/views/farmos/structures.py index 618c2fa..550f432 100644 --- a/src/wuttafarm/web/views/farmos/structures.py +++ b/src/wuttafarm/web/views/farmos/structures.py @@ -211,8 +211,8 @@ class StructureView(FarmOSMasterView): ] if wf_structure := ( - session.query(model.Structure) - .filter(model.Structure.farmos_uuid == structure["uuid"]) + session.query(model.StructureAsset) + .filter(model.StructureAsset.farmos_uuid == structure["uuid"]) .first() ): buttons.append( @@ -220,7 +220,7 @@ class StructureView(FarmOSMasterView): f"View {self.app.get_title()} record", primary=True, url=self.request.route_url( - "structures.view", uuid=wf_structure.uuid + "structure_assets.view", uuid=wf_structure.uuid ), icon_left="eye", ) diff --git a/src/wuttafarm/web/views/structure_types.py b/src/wuttafarm/web/views/structure_types.py deleted file mode 100644 index f9d9bf0..0000000 --- a/src/wuttafarm/web/views/structure_types.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- coding: utf-8; -*- -################################################################################ -# -# WuttaFarm --Web app to integrate with and extend farmOS -# Copyright © 2026 Lance Edgar -# -# This file is part of WuttaFarm. -# -# WuttaFarm is free software: you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free Software -# Foundation, either version 3 of the License, or (at your option) any later -# version. -# -# WuttaFarm is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along with -# WuttaFarm. If not, see . -# -################################################################################ -""" -Master view for Structure Types -""" - -from wuttafarm.db.model.structures import StructureType, Structure -from wuttafarm.web.views import WuttaFarmMasterView - - -class StructureTypeView(WuttaFarmMasterView): - """ - Master view for Structure Types - """ - - model_class = StructureType - route_prefix = "structure_types" - url_prefix = "/structure-types" - - grid_columns = [ - "name", - ] - - sort_defaults = "name" - - filter_defaults = { - "name": {"active": True, "verb": "contains"}, - } - - form_fields = [ - "name", - "farmos_uuid", - "drupal_id", - ] - - has_rows = True - row_model_class = Structure - rows_viewable = True - - row_grid_columns = [ - "name", - "is_location", - "is_fixed", - "archived", - ] - - rows_sort_defaults = "name" - - def configure_grid(self, grid): - g = grid - super().configure_grid(g) - - # name - g.set_link("name") - - def get_xref_buttons(self, structure_type): - buttons = super().get_xref_buttons(structure_type) - - if structure_type.farmos_uuid: - buttons.append( - self.make_button( - "View farmOS record", - primary=True, - url=self.request.route_url( - "farmos_structure_types.view", uuid=structure_type.farmos_uuid - ), - icon_left="eye", - ) - ) - - return buttons - - def get_row_grid_data(self, structure_type): - model = self.app.model - session = self.Session() - return session.query(model.Structure).filter( - model.Structure.structure_type == structure_type - ) - - def configure_row_grid(self, grid): - g = grid - super().configure_row_grid(g) - - # name - g.set_link("name") - - def get_row_action_url_view(self, structure, i): - return self.request.route_url("structures.view", uuid=structure.uuid) - - -def defaults(config, **kwargs): - base = globals() - - StructureTypeView = kwargs.get("StructureTypeView", base["StructureTypeView"]) - StructureTypeView.defaults(config) - - -def includeme(config): - defaults(config) diff --git a/src/wuttafarm/web/views/structures.py b/src/wuttafarm/web/views/structures.py index 018911d..5745658 100644 --- a/src/wuttafarm/web/views/structures.py +++ b/src/wuttafarm/web/views/structures.py @@ -23,44 +23,136 @@ Master view for Structures """ -from wuttafarm.db.model.structures import Structure from wuttafarm.web.views import WuttaFarmMasterView +from wuttafarm.web.views.assets import AssetMasterView +from wuttafarm.db.model import StructureType, StructureAsset from wuttafarm.web.forms.schema import StructureTypeRef from wuttafarm.web.forms.widgets import ImageWidget -class StructureView(WuttaFarmMasterView): +class StructureTypeView(WuttaFarmMasterView): """ - Master view for Structures + Master view for Structure Types """ - model_class = Structure - route_prefix = "structures" - url_prefix = "/structures" - - farmos_refurl_path = "/assets/structure" - - labels = { - "name": "Asset Name", - } + model_class = StructureType + route_prefix = "structure_types" + url_prefix = "/structure-types" grid_columns = [ - "thumbnail", - "drupal_id", "name", - "structure_type", - "archived", ] sort_defaults = "name" filter_defaults = { "name": {"active": True, "verb": "contains"}, - "archived": {"active": True, "verb": "is_false"}, } form_fields = [ "name", + "farmos_uuid", + "drupal_id", + ] + + has_rows = True + row_model_class = StructureAsset + rows_viewable = True + + row_grid_columns = [ + "asset_name", + "is_location", + "is_fixed", + "archived", + ] + + rows_sort_defaults = "asset_name" + + def configure_grid(self, grid): + g = grid + super().configure_grid(g) + + # name + g.set_link("name") + + def get_xref_buttons(self, structure_type): + buttons = super().get_xref_buttons(structure_type) + + if structure_type.farmos_uuid: + buttons.append( + self.make_button( + "View farmOS record", + primary=True, + url=self.request.route_url( + "farmos_structure_types.view", uuid=structure_type.farmos_uuid + ), + icon_left="eye", + ) + ) + + return buttons + + def get_row_grid_data(self, structure_type): + model = self.app.model + session = self.Session() + return ( + session.query(model.StructureAsset) + .join(model.Asset) + .filter(model.StructureAsset.structure_type == structure_type) + ) + + def configure_row_grid(self, grid): + g = grid + super().configure_row_grid(g) + model = self.app.model + + # asset_name + g.set_link("asset_name") + g.set_sorter("asset_name", model.Asset.asset_name) + g.set_filter("asset_name", model.Asset.asset_name) + + # is_location + g.set_renderer("is_location", "boolean") + g.set_sorter("is_location", model.Asset.is_location) + g.set_filter("is_location", model.Asset.is_location) + + # is_fixed + g.set_renderer("is_fixed", "boolean") + g.set_sorter("is_fixed", model.Asset.is_fixed) + g.set_filter("is_fixed", model.Asset.is_fixed) + + # archived + g.set_renderer("archived", "boolean") + g.set_sorter("archived", model.Asset.archived) + g.set_filter("archived", model.Asset.archived) + + def get_row_action_url_view(self, structure, i): + return self.request.route_url("structure_assets.view", uuid=structure.uuid) + + +class StructureAssetView(AssetMasterView): + """ + Master view for Structures + """ + + model_class = StructureAsset + route_prefix = "structure_assets" + url_prefix = "/asset/structures" + + farmos_refurl_path = "/assets/structure" + + grid_columns = [ + "thumbnail", + "drupal_id", + "asset_name", + "structure_type", + "parents", + "archived", + ] + + form_fields = [ + "asset_name", + "parents", "notes", "asset_type", "structure_type", @@ -80,17 +172,6 @@ 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") - # structure_type g.set_joiner("structure_type", lambda q: q.join(model.StructureType)) g.set_sorter("structure_type", model.StructureType.name) @@ -98,78 +179,23 @@ class StructureView(WuttaFarmMasterView): "structure_type", model.StructureType.name, label="Structure Type Name" ) - def grid_row_class(self, structure, data, i): - """ """ - if structure.archived: - return "has-background-warning" - return None - def configure_form(self, form): f = form 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 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) - - def get_farmos_url(self, structure): - return self.app.get_farmos_url(f"/asset/{structure.drupal_id}") - - def get_xref_buttons(self, structure): - buttons = super().get_xref_buttons(structure) - - if structure.farmos_uuid: - buttons.append( - self.make_button( - "View farmOS record", - primary=True, - url=self.request.route_url( - "farmos_structures.view", uuid=structure.farmos_uuid - ), - icon_left="eye", - ) - ) - - return buttons - def defaults(config, **kwargs): base = globals() - StructureView = kwargs.get("StructureView", base["StructureView"]) - StructureView.defaults(config) + StructureTypeView = kwargs.get("StructureTypeView", base["StructureTypeView"]) + StructureTypeView.defaults(config) + + StructureAssetView = kwargs.get("StructureAssetView", base["StructureAssetView"]) + StructureAssetView.defaults(config) def includeme(config):