Component Architecture - gaulatti/autostrada-frontend GitHub Wiki

Overview

The Autostrada frontend follows a structured component hierarchy designed for modularity, reusability, and maintainability. This document outlines the main component categories and their relationships.

Component Types

1. Layout Components

Layout components define the overall structure of the application and provide consistent framing for content pages.

  • Layout: The root component in root.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

2. Page Components

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

3. Shared UI Components

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

4. Domain-Specific Components

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

Component Communication

Components in Autostrada communicate through several patterns:

  1. Props Passing: Direct parent-to-child communication
  2. Redux State: Global state management for cross-component data sharing
  3. Custom Hooks: Encapsulated logic and state management
  4. Context API: For theme settings and other cross-cutting concerns

Key Custom Hooks

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

Component Styling

Styling follows a hybrid approach:

  1. Tailwind CSS: Utility classes for most styling needs
  2. Radix UI Themes: Themeable UI components with consistent styling
  3. CSS Modules: For component-specific styles that need more complex CSS

Best Practices

When working with components in Autostrada:

  1. Keep components focused: Each component should fulfill a single responsibility
  2. Prioritize composition: Compose complex UIs from simpler components
  3. Minimize prop drilling: Use context or state management for deeply nested data
  4. Document with JSDoc: All components should have proper documentation
  5. Use TypeScript interfaces: Define clear prop interfaces for each component
  6. Test key components: Ensure critical UI elements have proper test coverage

Examples

Page Component Example

// 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;

Custom Hook Example

// 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'
  });
};
⚠️ **GitHub.com Fallback** ⚠️