From 783f4026a5f7daa45631b34785667f79aacfbe56 Mon Sep 17 00:00:00 2001 From: Sebastian Diaz Date: Thu, 23 May 2024 16:02:50 +0200 Subject: [PATCH] Add searchable and sortable flow cell column --- cg/server/admin.py | 29 +++++++++++++++++++++++++++-- cg/store/models.py | 17 ++++++++++++++++- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/cg/server/admin.py b/cg/server/admin.py index f573e13dae..43822f7375 100644 --- a/cg/server/admin.py +++ b/cg/server/admin.py @@ -8,10 +8,11 @@ from flask_admin.contrib.sqla import ModelView from flask_dance.contrib.google import google from markupsafe import Markup +from sqlalchemy.orm import aliased from cg.constants.constants import NG_UL_SUFFIX, CaseActions, DataDelivery, Workflow from cg.server.ext import db -from cg.store.models import Sample +from cg.store.models import RunDevice, Sample from cg.utils.flask.enum import SelectEnumField @@ -459,11 +460,35 @@ class IlluminaFlowCellView(BaseView): "has_backup", ) column_formatters = { - "flow_cell": view_flow_cell_internal_id, + "flow_cell": lambda v, c, m, p: m.flow_cell, } column_default_sort = ("sequenced_at", True) column_filters = ["sequencer_type", "sequencer_name", "data_availability"] column_editable_list = ["data_availability"] + column_searchable_list = ["flow_cell", "sequencer_type", "sequencer_name"] + column_sortable_list = ["flow_cell", "sequenced_at", "sequencer_type", "sequencer_name"] + + def scaffold_sortable_columns(self): + columns = super(IlluminaFlowCellView, self).scaffold_sortable_columns() + columns["flow_cell"] = "flow_cell" + return columns + + def scaffold_search(self, search_term): + if not search_term: + return None + + # Generate the base query + query = super(IlluminaFlowCellView, self).scaffold_search(search_term) + + # Add a search for the hybrid property 'flow_cell' + device_alias = aliased(RunDevice) + flow_cell_search = ( + self.session.query(self.model) + .join(device_alias, self.model.device) + .filter(device_alias.internal_id.ilike(f"%{search_term}%")) + ) + + return query.union(flow_cell_search) class OrganismView(BaseView): diff --git a/cg/store/models.py b/cg/store/models.py index 2c8fa860b9..aad408b104 100644 --- a/cg/store/models.py +++ b/cg/store/models.py @@ -12,10 +12,12 @@ Numeric, String, Table, + select, ) from sqlalchemy import Text as SLQText from sqlalchemy import UniqueConstraint, orm, types -from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column +from sqlalchemy.ext.hybrid import hybrid_property +from sqlalchemy.orm import DeclarativeBase, Mapped, aliased, mapped_column from sqlalchemy.orm.attributes import InstrumentedAttribute from cg.constants import DataDelivery, FlowCellStatus, Priority, Workflow @@ -1049,6 +1051,19 @@ class IlluminaSequencingRun(InstrumentRun): __mapper_args__ = {"polymorphic_identity": DeviceType.ILLUMINA} + @hybrid_property + def flow_cell(self): + return self.device.internal_id if self.device else None + + @flow_cell.expression + def flow_cell(cls): + device_alias = aliased(RunDevice) + return ( + select(device_alias.internal_id) + .where(device_alias.id == cls.device_id) + .scalar_subquery() + ) + class SampleRunMetrics(Base): """Parent model for the different types of sample run metrics."""