updated apps
This commit is contained in:
@@ -131,6 +131,10 @@ def _build_task_summary(
|
||||
"nfc_tag_id": task_data.get("nfc_tag_id"),
|
||||
# v2.20 (#83): unit for `reading`-type tasks; values live in history.
|
||||
"reading_unit": task_data.get("reading_unit"),
|
||||
# Spare parts: consumption links ([{part_id, quantity}]) and, on an
|
||||
# auto-created "buy" reminder, the owning part marker ({part_id}).
|
||||
"consumes_parts": task_data.get("consumes_parts"),
|
||||
"part_ref": task_data.get("part_ref"),
|
||||
"priority": task_data.get("priority", "normal"),
|
||||
# v2.10.0 archive: archived_at is the persisted timestamp (None = active);
|
||||
# `archived` is the convenience bool the frontend filters on; reason is
|
||||
@@ -229,12 +233,44 @@ def _build_object_response(hass: HomeAssistant, entry: ConfigEntry, coordinator_
|
||||
|
||||
tasks = [_build_task_summary(hass, tid, tdata, ct_tasks.get(tid), object_slug) for tid, tdata in tasks_data.items()]
|
||||
|
||||
# (roadmap P2) attached-document count for the objects-table paperclip badge.
|
||||
# (roadmap P2) attached-document count for the objects-table paperclip badge,
|
||||
# plus a per-task count so each task row can carry its own document badge.
|
||||
from .. import DOCUMENT_STORE_KEY
|
||||
|
||||
doc_store = hass.data.get(DOMAIN, {}).get(DOCUMENT_STORE_KEY)
|
||||
object_id = obj_data.get("id", "")
|
||||
document_count = len(doc_store.for_object(object_id)) if doc_store is not None and object_id else 0
|
||||
object_docs = doc_store.for_object(object_id) if doc_store is not None and object_id else []
|
||||
document_count = len(object_docs)
|
||||
task_doc_counts: dict[str, int] = {}
|
||||
for _doc in object_docs:
|
||||
for _tid in _doc.get("task_ids") or []:
|
||||
task_doc_counts[_tid] = task_doc_counts.get(_tid, 0) + 1
|
||||
for _task in tasks:
|
||||
_task["document_count"] = task_doc_counts.get(_task["id"], 0)
|
||||
|
||||
# Spare parts: full definition + merged stock + the derived helpers the
|
||||
# panel renders (is_low, resolved shopping URL). EVERY persisted field is
|
||||
# exposed (#50 field-completeness class).
|
||||
from ..const import CONF_PART_SEARCH_URL_TEMPLATE, CONF_PARTS
|
||||
from ..helpers.global_options import get_global_options
|
||||
from ..helpers.i18n import normalize_language
|
||||
from ..helpers.parts import part_is_low, resolve_shopping_url
|
||||
|
||||
rd_parts = getattr(entry, "runtime_data", None)
|
||||
part_store = getattr(rd_parts, "store", None) if rd_parts else None
|
||||
search_template = get_global_options(hass).get(CONF_PART_SEARCH_URL_TEMPLATE)
|
||||
lang = normalize_language(hass)
|
||||
parts_payload = []
|
||||
for part in (entry.data.get(CONF_PARTS) or {}).values():
|
||||
stock = part_store.get_part_stock(part["id"]) if part_store else None
|
||||
parts_payload.append(
|
||||
{
|
||||
**part,
|
||||
"stock": stock,
|
||||
"is_low": part_is_low(part, stock),
|
||||
"shopping_url": resolve_shopping_url(part, search_template, lang),
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"entry_id": entry.entry_id,
|
||||
@@ -274,15 +310,15 @@ def _build_object_response(hass: HomeAssistant, entry: ConfigEntry, coordinator_
|
||||
"document_count": document_count,
|
||||
},
|
||||
"tasks": tasks,
|
||||
"parts": parts_payload,
|
||||
}
|
||||
|
||||
|
||||
def _get_global_entry(hass: HomeAssistant) -> ConfigEntry | None:
|
||||
"""Get the global config entry."""
|
||||
for entry in hass.config_entries.async_entries(DOMAIN):
|
||||
if entry.unique_id == GLOBAL_UNIQUE_ID:
|
||||
return entry
|
||||
return None
|
||||
"""Get the global config entry (thin re-export of the shared helper)."""
|
||||
from ..helpers.global_options import get_global_entry
|
||||
|
||||
return get_global_entry(hass)
|
||||
|
||||
|
||||
def _load_object_entry(
|
||||
@@ -434,6 +470,21 @@ def async_register_commands(hass: HomeAssistant) -> None:
|
||||
ws_unarchive_object,
|
||||
ws_update_object,
|
||||
)
|
||||
from .parts import (
|
||||
ws_create_part,
|
||||
ws_delete_part,
|
||||
ws_restock_part,
|
||||
ws_update_part,
|
||||
)
|
||||
from .problem_sensors import (
|
||||
ws_adopt_problem_sensors,
|
||||
ws_discover_problem_sensors,
|
||||
)
|
||||
from .saved_views import (
|
||||
ws_delete_saved_view,
|
||||
ws_list_saved_views,
|
||||
ws_save_saved_view,
|
||||
)
|
||||
from .tags import ws_list_tags
|
||||
from .tasks import (
|
||||
ws_archive_task,
|
||||
@@ -486,6 +537,10 @@ def async_register_commands(hass: HomeAssistant) -> None:
|
||||
websocket_api.async_register_command(hass, ws_reset_task)
|
||||
websocket_api.async_register_command(hass, ws_snooze_task)
|
||||
websocket_api.async_register_command(hass, ws_postpone_task)
|
||||
websocket_api.async_register_command(hass, ws_create_part)
|
||||
websocket_api.async_register_command(hass, ws_update_part)
|
||||
websocket_api.async_register_command(hass, ws_delete_part)
|
||||
websocket_api.async_register_command(hass, ws_restock_part)
|
||||
websocket_api.async_register_command(hass, ws_update_history_entry)
|
||||
websocket_api.async_register_command(hass, ws_get_templates)
|
||||
websocket_api.async_register_command(hass, ws_export_data)
|
||||
@@ -494,6 +549,11 @@ def async_register_commands(hass: HomeAssistant) -> None:
|
||||
websocket_api.async_register_command(hass, ws_export_objects_csv)
|
||||
websocket_api.async_register_command(hass, ws_import_csv)
|
||||
websocket_api.async_register_command(hass, ws_import_json)
|
||||
websocket_api.async_register_command(hass, ws_discover_problem_sensors)
|
||||
websocket_api.async_register_command(hass, ws_adopt_problem_sensors)
|
||||
websocket_api.async_register_command(hass, ws_list_saved_views)
|
||||
websocket_api.async_register_command(hass, ws_save_saved_view)
|
||||
websocket_api.async_register_command(hass, ws_delete_saved_view)
|
||||
websocket_api.async_register_command(hass, ws_get_groups)
|
||||
websocket_api.async_register_command(hass, ws_create_group)
|
||||
websocket_api.async_register_command(hass, ws_update_group)
|
||||
|
||||
Reference in New Issue
Block a user