- React 19 with TypeScript
- Functional components with hooks
- Modern CSS with responsive design
- Accessibility-first approach
- Main app: frontend/jwst-frontend/src/App.tsx
- Components:
- JwstDataDashboard.tsx - Main dashboard with grid, list, grouped, and lineage views
- MastSearch.tsx - MAST portal search interface with progress tracking
- ImageViewer.tsx - FITS image viewer with color maps, stretch controls, and PNG export
- Types:
- JwstDataTypes.ts - Core data types, lineage types, processing levels
- MastTypes.ts - MAST search/import types, progress tracking
- Utilities:
- fitsUtils.ts - FITS file type detection and classification
- colormaps.ts - Color maps for FITS visualization
- Services:
- apiClient.ts - Core HTTP client with error handling
- ApiError.ts - Custom error class for API errors
- jwstDataService.ts - JWST data CRUD operations
- mastService.ts - MAST search and import operations
- index.ts - Service re-exports
- Styles:
- App.css - Global styles
- JwstDataDashboard.css - Dashboard and lineage view styles
- MastSearch.css - MAST search and progress styles
- FitsViewer.css - FITS viewer styles
- ImageViewer.css - Image viewer modal styles
- Package config: frontend/jwst-frontend/package.json
- Use TypeScript interfaces for all data models
- Implement proper error handling and loading states
- Use semantic HTML with proper accessibility attributes
- Follow React best practices (hooks, functional components)
- Use CSS classes for styling (no inline styles)
- Implement responsive design for mobile compatibility
- App: Root component with data fetching and error handling
- JwstDataDashboard: Main dashboard with multiple view modes:
- Grid view: Card-based display
- List view: Compact table format
- Grouped view: By data type
- Lineage view: Tree hierarchy showing processing levels (L1→L2a→L2b→L3)
- Tag filtering: Dedicated tag dropdown plus clickable tag pills on cards
- FITS type badges: Visual indicators for image vs table files
- Refresh Metadata button: Re-fetch MAST metadata for all imports
- MastSearch: MAST portal integration with:
- Search by target, coordinates, observation, or program
- Bulk import with progress tracking
- Byte-level progress display (speed, ETA, per-file status)
- Resume capability for interrupted downloads
- ImageViewer: FITS image viewer with:
- Multiple color maps (grayscale, hot, cool, rainbow, viridis, plasma, magma, inferno)
- Stretch controls (linear, log, sqrt, asinh, zscale) with histogram visualization
- Zoom and pan controls
- Pixel coordinate display with WCS conversion
- PNG export with current visualization settings
- Header metadata display in sidebar
- Graceful handling of non-image FITS files
- CompositeWizard: RGB composite workflow with:
- Per-channel image assignment and independent stretch/levels/curve controls
- WCS-aware channel alignment for accurate RGB registration
- Live composite preview during channel tuning
- Final export step with overall image-viewer-style stretch/levels controls applied post-stack
- Types:
- JwstDataModel, ImageMetadata, SensorMetadata, ProcessingResult
- LineageResponse, LineageFileInfo
- ProcessingLevels, ProcessingLevelLabels, ProcessingLevelColors
- MastSearchResult, MastImportResponse, ImportJobStatus
- FileProgressInfo, ResumableJobSummary, MetadataRefreshResponse
- ImageMetadata now includes: wavelengthRange, calibrationLevel, proposalId, proposalPi, observationTitle
- Utilities:
- getFitsFileInfo(): Classify FITS files by suffix (image vs table)
- isFitsViewable(): Check if FITS file is viewable
- calculateZScale(): Optimal display limits for FITS data
- getColorMap(): Color map lookup tables
- Backend API base URL: http://localhost:5001 (configured in
config/api.ts) - Use service layer for all API calls (never use fetch directly in components)
- Services provide:
- Consistent error handling via
ApiErrorclass - Automatic JSON parsing and error extraction
- TypeScript typing for request/response
- Clean separation of concerns
- Consistent error handling via
// Import services
import { jwstDataService, mastService, ApiError } from '../services';
// Fetch data
const data = await jwstDataService.getAll(includeArchived);
// Handle errors
try {
await mastService.startImport({ obsId });
} catch (err) {
if (ApiError.isApiError(err)) {
console.error(`API Error ${err.status}: ${err.message}`);
}
}jwstDataService:
getAll(includeArchived?)- Fetch all data recordsupload(file, dataType, description?, tags?)- Upload a fileprocess(dataId, algorithm, parameters?)- Trigger processingarchive(dataId)/unarchive(dataId)- Archive operationsgetDeletePreview(obsId)/deleteObservation(obsId)- Delete operationsscanAndImportMastFiles()- Bulk import from disk
mastService:
searchByTarget(params, signal?)- Search by target namesearchByCoordinates(params, signal?)- Search by RA/DecsearchByObservation(params, signal?)- Search by obs IDsearchByProgram(params, signal?)- Search by program IDstartImport(params)- Start import jobgetImportProgress(jobId)- Poll progresscancelImport(jobId)- Cancel jobresumeImport(jobId)- Resume failed jobimportFromExisting(obsId)- Import from downloaded filesrefreshMetadataAll()- Refresh all MAST metadata
compositeService:
generateNChannelPreview(channels, size, overall?)- Generate N-channel composite previewexportNChannelComposite(channels, format, quality, width, height, overall?)- Export N-channel compositegenerateNChannelComposite(request)- Full N-channel composite generation
mosaicService:
generateMosaic(params)- Generate WCS-aligned mosaicgenerateAndSaveMosaic(params)- Generate and save mosaic to libraryexportMosaic(params)- Async mosaic export via job queuesaveMosaic(params)- Async save-to-library via job queuegetFootprint(dataIds)- Compute WCS footprint polygons
discoveryService:
getFeaturedTargets()- Get curated featured targets listsuggestRecipes(observations)- Get composite recipe suggestions
semanticSearchService:
search(query, topK?, minScore?)- Natural language search over FITS metadatagetIndexStatus()- Get semantic index health
analysisService:
getRegionStatistics(params)- Compute region statisticsdetectSources(params)- Detect astronomical sourcesgetTableInfo(dataId)- Get FITS table HDU metadatagetTableData(params)- Get paginated table datagetSpectralData(dataId, hduIndex?)- Get spectral column arrays
authService:
login(username, password)- Login and get tokensregister(username, password)- Create accountrefreshToken(refreshToken)- Refresh access tokenlogout()- Revoke refresh token
signalRService:
connect(accessToken)- Connect to job progress hubsubscribeToJob(jobId, callbacks)- Subscribe to job eventsdisconnect()- Disconnect from hub
- Current theme: "Sunset Galaxy" gradient background
- Use consistent spacing and typography
- Implement loading spinners for async operations
- Provide clear error messages and retry options
- Use status indicators for processing states
- Implement search and filtering functionality
- Use proper ARIA labels and roles
- Implement keyboard navigation
- Provide alt text for images
- Use semantic HTML elements
- Ensure sufficient color contrast