mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-05 16:10:43 +00:00
### **PR Type** Enhancement, Bug fix ___ ### **Description** - Add tabbed RUM event details drawer - Centralize RUM event formatting utilities - Improve sidebar filtering and null safety - Sync dashboard chart zoom to time range ___ ### Diagram Walkthrough ```mermaid flowchart LR A["RUM Session Viewer UI"] B["Event detail drawer tabs (Overview/Network/Attributes)"] C["Shared formatter composable (`useEventFormatters`)"] D["Network resources list from related events"] E["Clipboard copy + JSON highlighting"] F["Dashboards emit `update:dateTime` on zoom"] G["Sidebar event type filter behavior"] H["Session email null-safety"] A -- "refactor + UX" --> B B -- "uses" --> C B -- "derives" --> D B -- "adds" --> E A -- "interactions" --> F A -- "filtering" --> G A -- "stability" --> H ``` <details> <summary><h3> File Walkthrough</h3></summary> <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>14 files</summary><table> <tr> <td><strong>useEventFormatters.ts</strong><dd><code>Add shared formatting helpers for RUM events</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-d301f514502d418578addfb8a9332f18193ec77414fe2de5f86584eaccf89a43">+88/-0</a> </td> </tr> <tr> <td><strong>LogsHighLighting.vue</strong><dd><code>Import highlighting stylesheet via scoped SCSS</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-4ef4ac0444004add270de4da30fa39bafd95bd7f1c408d28cf6737655fc152eb">+4/-2</a> </td> </tr> <tr> <td><strong>EventDetailDrawerContent.vue</strong><dd><code>Redesign drawer with tabs, copy, network</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-e31bfc4c2d218ac4beaa9110939974f0461a818a7d5d169279e2ff58dec8136c">+479/-353</a></td> </tr> <tr> <td><strong>EventDetailsSection.vue</strong><dd><code>Add reusable key-value section renderer</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-eb9d64194e4354ce8babdb843029087b4d0813100046f6de6fd2605816eede58">+67/-0</a> </td> </tr> <tr> <td><strong>EventTypeBadge.vue</strong><dd><code>Add reusable event type badge component</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-78d3b36f54018d0cc31a0ed96800588bacb5b3f6e608803f32e704e576d89001">+49/-0</a> </td> </tr> <tr> <td><strong>KeyValueRow.vue</strong><dd><code>Add reusable labeled key-value row component</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-978f05f4c50530f6d772579c54478e1aef10b7f7b066f2769e9d34c62c488895">+53/-0</a> </td> </tr> <tr> <td><strong>PerformanceMetrics.vue</strong><dd><code>Add wrapper component for performance metrics</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-7c9e28cabc9dd4189346dadc26dcb4def95a9265557144e99128a9f3b951c21e">+60/-0</a> </td> </tr> <tr> <td><strong>ActionPerformanceMetrics.vue</strong><dd><code>Add action performance metric cards and statuses</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-cd6683a885104c9e5074ab1c2b97bed5275cffa688da905f539bef98efdb4ec8">+98/-0</a> </td> </tr> <tr> <td><strong>ErrorPerformanceMetrics.vue</strong><dd><code>Add error performance metric cards and statuses</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-1fc102647ba527cfd553f4c0fd723f1b72fabbd85bad7518e0a826a09d858442">+76/-0</a> </td> </tr> <tr> <td><strong>MetricCard.vue</strong><dd><code>Add generic metric card with formatting</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-3666ababe7e5a472c88da967ba6e5e632dfd907abb8555a6bb4baeabc0215e32">+168/-0</a> </td> </tr> <tr> <td><strong>ResourcePerformanceMetrics.vue</strong><dd><code>Add resource timing breakdown metric cards</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-9dfcf79c8b3c1b1c0e43bc8e65c90a6cd6b75c84b7de8250f18ba985ef36ad55">+128/-0</a> </td> </tr> <tr> <td><strong>ViewPerformanceMetrics.vue</strong><dd><code>Add web vitals and view metric cards</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-0ddb74b6ef8bdb8656c47fb4065e4add8ba853f5834fbf3e59087623b054aa2b">+172/-0</a> </td> </tr> <tr> <td><strong>ErrorsDashboard.vue</strong><dd><code>Emit zoom events to update time range</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-46138c05241c5e0911a0feba39a21dbb8452453c0e26a1d00c3493cc579f07b2">+8/-0</a> </td> </tr> <tr> <td><strong>WebVitalsDashboard.vue</strong><dd><code>Emit zoom events and support dateTime updates</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-bbb15649f6ecf4b2968a8173091ef8b2a21bfe39bff8e08f91566bca189cca09">+9/-1</a> </td> </tr> </table></details></td></tr><tr><td><strong>Miscellaneous</strong></td><td><details><summary>1 files</summary><table> <tr> <td><strong>zincutils.ts</strong><dd><code>Adjust formatting and utility function style</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-d3d59688cccdcc6c84ebe88b698c6910030abecc3125f4c0ef81b0df023699ba">+26/-14</a> </td> </tr> </table></details></td></tr><tr><td><strong>Bug fix</strong></td><td><details><summary>2 files</summary><table> <tr> <td><strong>PlayerEventsSidebar.vue</strong><dd><code>Improve multiselect UX and filtering logic</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-a7d04eb87cd7588ba4811d79c6d32696a58d737a24931258329be4f96cee7610">+39/-10</a> </td> </tr> <tr> <td><strong>SessionViewer.vue</strong><dd><code>Guard session email access with optional chaining</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10329/files#diff-9f7a183be1e2cfcb3c3c852c059f66003dd4f3f586421b012e1b835724929ca1">+1/-1</a> </td> </tr> </table></details></td></tr></tr></tbody></table> </details> ___
89 lines
2.5 KiB
TypeScript
89 lines
2.5 KiB
TypeScript
/**
|
|
* Event Formatters Composable
|
|
* ============================
|
|
* Reusable formatting utilities for RUM events
|
|
*/
|
|
|
|
import { date } from "quasar";
|
|
import { formatDuration } from "@/utils/zincutils";
|
|
|
|
export function useEventFormatters() {
|
|
/**
|
|
* Format timestamp to readable date string
|
|
*/
|
|
const formatTimestamp = (timestamp: number): string => {
|
|
if (!timestamp) return "N/A";
|
|
return date.formatDate(
|
|
Math.floor(timestamp),
|
|
"MMM DD, YYYY HH:mm:ss.SSS Z",
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Format ID (currently pass-through, can be enhanced)
|
|
*/
|
|
const formatId = (id: string): string => {
|
|
if (!id) return "";
|
|
return id;
|
|
};
|
|
|
|
/**
|
|
* Get status icon based on HTTP status code
|
|
*/
|
|
const getStatusIcon = (statusCode: number): string => {
|
|
if (!statusCode) return "help";
|
|
if (statusCode >= 200 && statusCode < 300) return "check_circle";
|
|
if (statusCode >= 300 && statusCode < 400) return "info";
|
|
if (statusCode >= 400 && statusCode < 500) return "warning";
|
|
return "error";
|
|
};
|
|
|
|
/**
|
|
* Get status color based on HTTP status code
|
|
*/
|
|
const getStatusColor = (statusCode: number): string => {
|
|
if (!statusCode) return "grey";
|
|
if (statusCode >= 200 && statusCode < 300) return "positive";
|
|
if (statusCode >= 300 && statusCode < 400) return "info";
|
|
if (statusCode >= 400 && statusCode < 500) return "warning";
|
|
return "negative";
|
|
};
|
|
|
|
/**
|
|
* Format resource duration (microseconds or milliseconds)
|
|
*/
|
|
const formatResourceDuration = (
|
|
duration: number,
|
|
fromMicroseconds = false,
|
|
): string => {
|
|
if (!duration) return "N/A";
|
|
const durationInMs = fromMicroseconds ? duration / 1000000 : duration / 1000;
|
|
return formatDuration(durationInMs);
|
|
};
|
|
|
|
/**
|
|
* Get event type CSS classes
|
|
*/
|
|
const getEventTypeClass = (type: string): string => {
|
|
const classes: { [key: string]: string } = {
|
|
error:
|
|
"tw:bg-red-100 tw:text-red-700 tw:border tw:border-solid tw:border-red-300",
|
|
action:
|
|
"tw:bg-blue-100 tw:text-blue-700 tw:border tw:border-solid tw:border-blue-300",
|
|
view: "tw:bg-green-100 tw:text-green-700 tw:border tw:border-solid tw:border-green-300",
|
|
resource:
|
|
"tw:bg-purple-100 tw:text-purple-700 tw:border tw:border-solid tw:border-purple-300",
|
|
};
|
|
return classes[type] || "tw:bg-grey-100 tw:text-grey-700";
|
|
};
|
|
|
|
return {
|
|
formatTimestamp,
|
|
formatId,
|
|
getStatusIcon,
|
|
getStatusColor,
|
|
formatResourceDuration,
|
|
getEventTypeClass,
|
|
};
|
|
}
|