""" Web UI Lambda. Serves a simple HTML dashboard for viewing work orders and comments. Accessed via Lambda Function URL. """ import json import os from html import escape as esc import boto3 dynamodb = boto3.resource("dynamodb") WORK_ORDERS_TABLE = os.environ.get("WORK_ORDERS_TABLE", "WorkOrders") COMMENTS_TABLE = os.environ.get("COMMENTS_TABLE", "WorkOrderComments") def get_work_orders(limit=500): table = dynamodb.Table(WORK_ORDERS_TABLE) items = [] response = table.scan() items.extend(response.get("Items", [])) while "LastEvaluatedKey" in response: response = table.scan(ExclusiveStartKey=response["LastEvaluatedKey"]) items.extend(response.get("Items", [])) items.sort(key=lambda x: x.get("updated_at", ""), reverse=True) return items[:limit] def get_comments(work_order_id): table = dynamodb.Table(COMMENTS_TABLE) items = [] kwargs = { "KeyConditionExpression": "work_order_id = :woid", "ExpressionAttributeValues": {":woid": work_order_id}, } response = table.query(**kwargs) items.extend(response.get("Items", [])) while "LastEvaluatedKey" in response: response = table.query(**kwargs, ExclusiveStartKey=response["LastEvaluatedKey"]) items.extend(response.get("Items", [])) items.sort(key=lambda x: x.get("created_at", ""), reverse=True) return items def render_badge(value, color_map): if not value: value = "unknown" color = color_map.get(value.lower(), "#9ca3af") label = esc(value.replace("_", " ").title()) return f'{label}' STATUS_COLORS = { "new": "#3b82f6", "assigned": "#8b5cf6", "in_progress": "#f59e0b", "on_hold": "#6b7280", "completed": "#10b981", "cancelled": "#ef4444", "unknown": "#9ca3af", } RECORD_TYPE_COLORS = { "new_work_order": "#3b82f6", "comment": "#8b5cf6", "update": "#f59e0b", "cancellation": "#ef4444", "unknown": "#9ca3af", } def render_work_order_detail(wo, events): events_html = "" if events: for e in events: record_type = e.get("record_type", "unknown") commenter = esc(e.get("commenter", "")) created = esc(e.get("created_at", "")) text = esc(e.get("text", "")) badge = render_badge(record_type, RECORD_TYPE_COLORS) commenter_str = ( f"{commenter} — " if commenter else "" ) border_colors = { "new_work_order": "#3b82f6", "comment": "#8b5cf6", "update": "#f59e0b", "cancellation": "#ef4444", } border = border_colors.get(record_type, "#94a3b8") events_html += f"""
No events yet.
' wo_id = esc(wo.get("work_order_id", "")) fields = [ ("Description", esc(wo.get("description", "")) or None), ("Status", render_badge(wo.get("wo_status", "unknown"), STATUS_COLORS)), ( "Record Type", render_badge(wo.get("record_type", "unknown"), RECORD_TYPE_COLORS), ), ("Site Code", esc(wo.get("site_code", "")) or None), ("Building", esc(wo.get("building", "")) or None), ("Address", esc(wo.get("address", "")) or None), ("Severity", esc(wo.get("severity", "")) or None), ("Priority", esc(wo.get("priority", "")) or None), ("Due Date", esc(wo.get("due_date", "")) or None), ("Date Reported", esc(wo.get("date_reported", "")) or None), ("Scheduled Start", esc(wo.get("scheduled_start", "")) or None), ("Assigned To", esc(wo.get("assigned_to", "")) or None), ("Created", esc(wo.get("created_at", "")) or None), ("Last Updated", esc(wo.get("updated_at", "")) or None), ] details_html = "" for label, value in fields: if value: details_html += f"""