Appearance
Dashboard Viewer Component Documentation
File: src/pages/private/admin/analytics/partial/metaBase.svelte
Overview
This component displays a dashboard in an iframe, handling loading states, errors, and initial empty states. It communicates with a GraphQL API to fetch dashboard URLs and manages the display lifecycle.
Module Script (GraphQL Query)
ts
async function getDashboard(startDate: string, endDate: string, dashboardId: number) {
const { data, error } = await query<any>(`
query dashboardUrl(
$dashboardId: Long!
$expirySeconds: Int!
$parameters: String!
) {
dashboardUrl(
expirySeconds: $expirySeconds
dashboardId: $dashboardId
parameters: $parameters
)
}
`, {
_id: uniqueId("q"),
dashboardId,
expirySeconds: 3000, // 50 minutes expiry
parameters: JSON.stringify({
start_date: startDate,
end_date: endDate
})
});
if (error) {
return { success: false, message: error?.message || error };
}
return {
success: true,
data: data?.dashboardUrl
};
}Component Script
Props
ts
export let filterData = {
startDate: string | null,
endDate: string | null,
dashboard: string | null
};
export let functionToCall: (() => {
startDate: string,
endDate: string,
dashboardId: number
}) | null;State Variables
ts
let src: string = ""; // iframe source URL
let isLoading: boolean = false;
let hasError: boolean = false;
let isInitialized: boolean = true;Methods
ts
async function loadData(startDate: string, endDate: string, dashboardId: number) {
try {
isInitialized = false;
isLoading = true;
hasError = false;
const ret = await getDashboard(startDate, endDate, dashboardId);
if (!ret.success) {
hasError = true;
isLoading = false;
return;
}
src = ret.data;
hasError = false;
} catch (error) {
console.error("Error setting iframe source:", error);
hasError = true;
} finally {
functionToCall = null; // Reset after loading
isLoading = false;
}
}UI States
1. Loading State
svelte
<div class="absolute inset-0 flex items-center justify-center bg-gray-100">
<div class="text-center">
<svg class="animate-spin h-12 w-12 text-blue-500 mx-auto">...</svg>
<p class="mt-4 text-gray-600">Loading dashboard...</p>
</div>
</div>2. Error State
svelte
<div class="absolute inset-0 flex items-center justify-center bg-gray-100">
<div class="text-center p-4 bg-red-50 rounded-lg">
<svg class="h-12 w-12 text-red-500 mx-auto">...</svg>
<p class="mt-4 text-red-600">Failed to load dashboard</p>
<button
on:click={() => (isLoading = true)}
class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
>
Retry
</button>
</div>
</div>3. Initial State (No Filters Selected)
svelte
<div class="flex flex-col items-center justify-center h-full bg-gray-50 rounded-lg shadow-md p-8">
<svg class="h-14 w-14 text-blue-400 mb-4">...</svg>
<p class="text-gray-600 text-lg font-medium text-center">
Please select filters to view the dashboard.
</p>
<p class="text-gray-400 text-sm mt-2 text-center">
Choose a date range to get started.
</p>
</div>4. Dashboard Display
svelte
<iframe
{src}
frameborder="0"
class="w-full h-full"
title="Dashboard"
on:load={() => (isLoading = false)}
on:error={() => {
hasError = true;
isLoading = false;
}}
/>Lifecycle Management
Initialization:
- Starts in
isInitializedstate showing placeholder content - Waits for
functionToCallto be set by parent component
- Starts in
Data Loading:
- Triggered in
afterUpdatewhenfunctionToCallis available - Shows loading spinner during API request
- Handles success/error cases appropriately
- Triggered in
Error Recovery:
- Provides retry button in error state
- Resets loading state on iframe load/error events
Usage Example
svelte
<script>
import MetaBase from "./metaBase.svelte";
let filterData = {
startDate: "2023-01-01",
endDate: "2023-12-31",
dashboard: "sales"
};
function getDashboardParams() {
return {
startDate: filterData.startDate,
endDate: filterData.endDate,
dashboardId: 123 // Would typically map from filterData.dashboard
};
}
</script>
<MetaBase
{filterData}
functionToCall={getDashboardParams}
/>Dependencies
lodash/fpforuniqueIdfunction- Custom
queryfunction for GraphQL operations - Svelte lifecycle functions (
afterUpdate)
Error Handling
GraphQL Errors:
- Catches and displays API errors
- Sets error state for UI feedback
Loading Errors:
- Handles iframe loading errors
- Provides retry mechanism
Validation:
- Requires both dates to be set before loading
- Maintains clean state transitions
Accessibility Features
Loading States:
- Clear visual feedback during loading
- Accessible spinner animation
Error States:
- High contrast error display
- Clear error message and recovery option
Iframe:
- Proper title attribute
- Handles load/error events