Implement label rendering functionality and integrate it into worklog template; add label.js for dynamic label updates
This commit is contained in:
parent
a61b56ddf2
commit
1e05ad16ce
6 changed files with 78 additions and 3 deletions
|
|
@ -1,15 +1,28 @@
|
|||
import logging
|
||||
|
||||
from flask import Blueprint, g
|
||||
from sqlalchemy.sql import Select
|
||||
from sqlalchemy.engine import ScalarResult
|
||||
from sqlalchemy.orm import joinedload
|
||||
from sqlalchemy.sql import Select
|
||||
from typing import Iterable, Any, cast
|
||||
|
||||
main = Blueprint('main', __name__)
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
from . import inventory, user, worklog, settings, index, search, hooks
|
||||
from .. import db
|
||||
from ..ui.blueprint import get_model_class, call
|
||||
from ..ui.defaults import default_query
|
||||
|
||||
def _eager_from_fields(Model, fields: Iterable[str]):
|
||||
rels = {f.split(".", 1)[0] for f in fields if "." in f}
|
||||
opts = []
|
||||
for r in rels:
|
||||
rel_attr = getattr(Model, r, None)
|
||||
if getattr(rel_attr, "property", None) is not None:
|
||||
opts.append(joinedload(rel_attr))
|
||||
return opts
|
||||
|
||||
def _cell_cache():
|
||||
if not hasattr(g, '_cell_cache'):
|
||||
g._cell_cache = {}
|
||||
|
|
@ -22,7 +35,12 @@ def _tmpl_cache(name: str):
|
|||
|
||||
def _project_row(obj: Any, fields: Iterable[str]) -> dict[str, Any]:
|
||||
out = {"id": obj.id}
|
||||
Model = type(obj)
|
||||
allow = getattr(Model, "ui_value_allow", None)
|
||||
for f in fields:
|
||||
if allow and f not in allow:
|
||||
out[f] = None
|
||||
continue
|
||||
if "." in f:
|
||||
rel, attr = f.split(".", 1)
|
||||
relobj = getattr(obj, rel, None)
|
||||
|
|
@ -45,7 +63,8 @@ def cell(model_name: str, id_: int, field: str, default: str = ""):
|
|||
val = call(Model, 'ui_value', db.session, id_=id_, field=field)
|
||||
if val is None:
|
||||
val = default_value(db.session, Model, id_=id_, field=field)
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
log.warning(f"cell() error for {model_name} {id_} {field}: {e}")
|
||||
val = default
|
||||
if val is None:
|
||||
val = default
|
||||
|
|
@ -106,6 +125,16 @@ def table(model_name: str, fields: Iterable[str], *,
|
|||
Model = get_model_class(model_name)
|
||||
qkwargs = dict(text=(q or None), limit=int(limit), offset=int(offset),
|
||||
sort=(sort or None), direction=(direction or "asc").lower())
|
||||
extra_opts = _eager_from_fields(Model, fields)
|
||||
if extra_opts:
|
||||
if isinstance(rows_any, Select):
|
||||
rows_any = rows_any.options(*extra_opts)
|
||||
elif rows_any is None:
|
||||
original = getattr(Model, 'ui_eagerload', ())
|
||||
def dyn_opts():
|
||||
base = original() if callable(original) else original
|
||||
return tuple(base) + tuple(extra_opts)
|
||||
setattr(Model, 'ui_eagerload', dyn_opts)
|
||||
rows_any: Any = call(Model, "ui_query", db.session, **qkwargs)
|
||||
|
||||
if rows_any is None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue