mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-07-25 23:18:06 -04:00
BE+FE: change log
This commit is contained in:
@@ -777,12 +777,12 @@ def api_devices_totals(payload=None):
|
||||
@validate_request(
|
||||
operation_id="get_device_history_filters",
|
||||
summary="Get Device History Filter Values",
|
||||
description="Return distinct changedBy and changedColumn values available in DevicesHistory. Optionally scope to a single device with ?devGuid=<guid>.",
|
||||
description="Return distinct changedBy and changedColumn values available in DevicesHistory. Optionally scope to a single device with ?devGUID=<guid>.",
|
||||
tags=["devices"],
|
||||
auth_callable=is_authorized
|
||||
)
|
||||
def api_devices_history_filters(payload=None):
|
||||
dev_guid = request.args.get("devGuid") or None
|
||||
dev_guid = request.args.get("devGUID") or None
|
||||
filters = DevicesHistoryInstance().get_available_filter_values(devGUID=dev_guid)
|
||||
return jsonify({"success": True, "data": filters})
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ from .graphql_helpers import ( # noqa: E402 [flake8 lint suppression]
|
||||
apply_common_pagination,
|
||||
apply_plugin_filters,
|
||||
apply_events_filters,
|
||||
extract_paging
|
||||
)
|
||||
from models.device_history_instance import DevicesHistoryInstance # noqa: E402
|
||||
|
||||
@@ -65,72 +66,98 @@ def _to_graphql_history(groups):
|
||||
|
||||
|
||||
class Query(ObjectType):
|
||||
# --- DEVICES ---
|
||||
devices = Field(DeviceResult, options=PageQueryOptionsInput())
|
||||
|
||||
# --- DEVICE HISTORY ---
|
||||
deviceHistoryGrouped = Field(
|
||||
DeviceHistoryResult,
|
||||
devGuid=String(required=True, description="Device GUID to fetch history for"),
|
||||
devGUID=String(required=False, description="Device GUID to fetch history for"),
|
||||
changedColumn=String(description="Filter to groups containing this field change"),
|
||||
changedBy=String(description="Filter to a specific attribution source"),
|
||||
limit=graphene.Int(description="Max grouped events to return (default 50)"),
|
||||
offset=graphene.Int(description="Grouped-event offset for pagination (default 0)"),
|
||||
options=PageQueryOptionsInput(description="Paging, sorting, filtering options"),
|
||||
)
|
||||
|
||||
allDeviceHistoryGrouped = Field(
|
||||
DeviceHistoryResult,
|
||||
changedColumn=String(description="Filter to groups containing this field change"),
|
||||
changedBy=String(description="Filter to a specific attribution source"),
|
||||
limit=graphene.Int(description="Max grouped events to return (default 100)"),
|
||||
offset=graphene.Int(description="Grouped-event offset for pagination (default 0)"),
|
||||
)
|
||||
def resolve_deviceHistoryGrouped(
|
||||
self,
|
||||
info,
|
||||
devGUID=None,
|
||||
changedColumn=None,
|
||||
changedBy=None,
|
||||
options=None):
|
||||
"""
|
||||
Return grouped device history.
|
||||
|
||||
def resolve_deviceHistoryGrouped(self, info, devGuid, changedColumn=None,
|
||||
changedBy=None, limit=50, offset=0):
|
||||
If `devGUID` is provided, results are restricted to a single device.
|
||||
If omitted, history across all devices is returned.
|
||||
|
||||
This resolver supports:
|
||||
- Optional filtering by device GUID, change column, and attribution source
|
||||
- Pagination via `options` (page/limit/offset)
|
||||
- Sorting at the grouped event level
|
||||
- Full-text search across history fields (if enabled in backend)
|
||||
|
||||
Internally:
|
||||
- Raw history rows are fetched from the database
|
||||
- Rows are grouped in Python by (timestamp, changedBy, devGUID)
|
||||
- Sorting is applied to grouped events
|
||||
- Pagination is applied after grouping
|
||||
|
||||
Args:
|
||||
info: GraphQL execution context
|
||||
devGUID (str | None): Optional device GUID filter
|
||||
changedColumn (str | None): Filter to only events containing this column
|
||||
changedBy (str | None): Filter by attribution source
|
||||
options (PageQueryOptionsInput | None): Paging, sorting, and search options
|
||||
|
||||
Returns:
|
||||
DeviceHistoryResult: Grouped history events and total count
|
||||
"""
|
||||
try:
|
||||
mylog("none", f"[HISTORY] unified resolver devGUID={devGUID} changedColumn={changedColumn} changedBy={changedBy}")
|
||||
|
||||
h = DevicesHistoryInstance()
|
||||
groups = h.get_grouped_history(
|
||||
devGUID=devGuid,
|
||||
changedColumn=changedColumn,
|
||||
changedBy=changedBy,
|
||||
limit=limit,
|
||||
offset=offset,
|
||||
)
|
||||
total = h.get_total_group_count(
|
||||
devGUID=devGuid,
|
||||
changedColumn=changedColumn,
|
||||
changedBy=changedBy,
|
||||
)
|
||||
paging = extract_paging(options)
|
||||
|
||||
if devGUID:
|
||||
groups = h.get_grouped_history(
|
||||
devGUID=devGUID,
|
||||
changedColumn=changedColumn,
|
||||
changedBy=changedBy,
|
||||
limit=paging["limit"],
|
||||
offset=paging["offset"],
|
||||
sort=paging["sort"],
|
||||
search=paging["search"],
|
||||
)
|
||||
|
||||
total = h.get_total_group_count(
|
||||
devGUID=devGUID,
|
||||
changedColumn=changedColumn,
|
||||
changedBy=changedBy,
|
||||
)
|
||||
else:
|
||||
groups = h.get_all_grouped_history(
|
||||
changedColumn=changedColumn,
|
||||
changedBy=changedBy,
|
||||
limit=paging["limit"],
|
||||
offset=paging["offset"],
|
||||
sort=paging["sort"],
|
||||
search=paging["search"],
|
||||
)
|
||||
|
||||
total = h.get_total_group_count(
|
||||
changedColumn=changedColumn,
|
||||
changedBy=changedBy,
|
||||
)
|
||||
|
||||
return DeviceHistoryResult(
|
||||
history=_to_graphql_history(groups),
|
||||
count=total,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
mylog("none", f"[graphql] resolve_deviceHistoryGrouped error: {e}")
|
||||
mylog("none", f"[graphql] unified resolver error: {e}")
|
||||
return DeviceHistoryResult(history=[], count=0)
|
||||
|
||||
def resolve_allDeviceHistoryGrouped(self, info, changedColumn=None,
|
||||
changedBy=None, limit=100, offset=0):
|
||||
try:
|
||||
h = DevicesHistoryInstance()
|
||||
groups = h.get_all_grouped_history(
|
||||
changedColumn=changedColumn,
|
||||
changedBy=changedBy,
|
||||
limit=limit,
|
||||
offset=offset,
|
||||
)
|
||||
total = h.get_total_group_count(
|
||||
changedColumn=changedColumn,
|
||||
changedBy=changedBy,
|
||||
)
|
||||
return DeviceHistoryResult(
|
||||
history=_to_graphql_history(groups),
|
||||
count=total,
|
||||
)
|
||||
except Exception as e:
|
||||
mylog("none", f"[graphql] resolve_allDeviceHistoryGrouped error: {e}")
|
||||
return DeviceHistoryResult(history=[], count=0)
|
||||
# --- DEVICES ---
|
||||
devices = Field(DeviceResult, options=PageQueryOptionsInput())
|
||||
|
||||
def resolve_devices(self, info, options=None):
|
||||
# mylog('none', f'[graphql_schema] resolve_devices: {self}')
|
||||
|
||||
@@ -139,3 +139,29 @@ def apply_events_filters(data, options):
|
||||
]
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def extract_paging(options):
|
||||
if not options:
|
||||
return {
|
||||
"page": 1,
|
||||
"limit": 50,
|
||||
"offset": 0,
|
||||
"sort": [],
|
||||
"search": None
|
||||
}
|
||||
|
||||
page = getattr(options, "page", 1) or 1
|
||||
limit = getattr(options, "limit", 50) or 50
|
||||
search = getattr(options, "search", None)
|
||||
sort = getattr(options, "sort", []) or []
|
||||
|
||||
offset = (page - 1) * limit
|
||||
|
||||
return {
|
||||
"page": page,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
"sort": sort,
|
||||
"search": search
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ from graphene import (
|
||||
|
||||
class SortOptionsInput(InputObjectType):
|
||||
field = String()
|
||||
order = String()
|
||||
order = String() # direction asc, desc
|
||||
|
||||
|
||||
class FilterOptionsInput(InputObjectType):
|
||||
@@ -20,8 +20,8 @@ class FilterOptionsInput(InputObjectType):
|
||||
|
||||
class PageQueryOptionsInput(InputObjectType):
|
||||
page = Int()
|
||||
limit = Int()
|
||||
sort = List(SortOptionsInput)
|
||||
limit = Int() # pageSize
|
||||
sort = List(SortOptionsInput) # sorting
|
||||
search = String()
|
||||
status = String()
|
||||
filters = List(FilterOptionsInput)
|
||||
|
||||
Reference in New Issue
Block a user