Component Architecture - gaulatti/autostrada-frontend GitHub Wiki
The Autostrada frontend follows a structured component hierarchy designed for modularity, reusability, and maintainability. This document outlines the main component categories and their relationships.
Layout components define the overall structure of the application and provide consistent framing for content pages.
-
Layout
: The root component inroot.tsx
that handles the HTML structure, theme, and Redux provider wrapping -
AppSidebar
: The collapsible sidebar navigation component -
SiteHeader
: The top header bar with title, user info, and actions -
TeamSwitcher
: UI for switching between different teams and projects
Page components represent complete views rendered at specific routes. These are organized in the pages
directory by domain area:
-
Scans: Components for visualizing and managing performance scans
-
pulses
: Real-time scanning results -
heartbeats
: Individual scan result details -
platforms
: Platform-specific performance data -
providers
: Provider management interfaces -
projects
: Project configuration and management
-
-
Targets: Components for monitoring specific targets
-
clusters
: Groups of related URLs -
urls
: Individual URL monitoring
-
-
Auth: Authentication-related pages
-
login
: Login interface -
logout
: Logout confirmation -
callback
: OAuth callback handling
-
Reusable UI elements found in the components
directory:
-
Data Display
-
Table
: Data table with sorting and pagination - Charts: Various visualization components
-
Breadcrumbs
: Navigation breadcrumb trail
-
-
User Input
-
DatePickerWithRange
: Date range selection component - Form controls and input components
-
-
Feedback
-
OverlaySpinner
: Loading indicator - Modal dialogs and notifications
-
Components that implement business logic for specific features:
-
Metrics
-
CoreWebVitals
: Components for displaying CWV metrics -
Grades
: Performance grade visualization -
OverallGrade
: Summary performance grading
-
-
Dashboard
-
PerformantClusters
: High-performing cluster visualization -
PerformantUrls
: High-performing URL visualization -
StableUrls
: Stability metric visualization -
SummaryCards
: Performance summary cards
-
Components in Autostrada communicate through several patterns:
- Props Passing: Direct parent-to-child communication
- Redux State: Global state management for cross-component data sharing
- Custom Hooks: Encapsulated logic and state management
- Context API: For theme settings and other cross-cutting concerns
The application leverages custom hooks to abstract complex logic:
-
useAPI
: Handles API communication with error handling and loading states -
useAuthStatus
: Provides authentication state -
useDarkMode
: Manages theme preferences -
useFeatureFlags
: Controls feature availability -
useRandom
: Generates consistent random values for stable rendering -
useSSE
: Manages server-sent events for real-time updates
Styling follows a hybrid approach:
- Tailwind CSS: Utility classes for most styling needs
- Radix UI Themes: Themeable UI components with consistent styling
- CSS Modules: For component-specific styles that need more complex CSS
When working with components in Autostrada:
- Keep components focused: Each component should fulfill a single responsibility
- Prioritize composition: Compose complex UIs from simpler components
- Minimize prop drilling: Use context or state management for deeply nested data
- Document with JSDoc: All components should have proper documentation
- Use TypeScript interfaces: Define clear prop interfaces for each component
- Test key components: Ensure critical UI elements have proper test coverage
// Example of a typical page component structure
import { Flex } from '@radix-ui/themes';
import { useTranslation } from 'react-i18next';
import { Breadcrumbs, type BreadcrumbItem } from '~/components/breadcrumbs';
import { SiteHeader } from '~/components/header';
import { DataTable } from './list.table';
const Page = () => {
const { t } = useTranslation();
const breadcrumbItems: BreadcrumbItem[] = [
{ title: t('navigation.home'), link: '/' },
{ title: t('scans.platforms'), link: '/platforms' },
];
return (
<>
<SiteHeader title={t('scans.platforms')} />
<Flex className='m-6' gap='3' direction='column'>
<Breadcrumbs items={breadcrumbItems} />
<DataTable />
</Flex>
</>
);
};
export default Page;
// Example of a custom hook pattern
import { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { selectFeatureFlags } from '~/state/selectors';
export const useFeatureFlags = () => {
const flags = useSelector(selectFeatureFlags);
return (flagId: string) => ({
isEnabled: () => flags[flagId]?.enabled ?? false,
getVariant: () => flags[flagId]?.variant ?? 'default'
});
};