Progress Tracking
This document explains how the application provides user-friendly progress feedback during long-running operations and API calls.
Overview
The application includes a comprehensive system for providing visual feedback to users during operations that take time to complete. This helps users understand what's happening and prevents them from thinking the application is frozen.
Components
ProgressService (src/app/services/progress.service.ts)
Manages the global progress state and UI feedback.
Key Features:
- Manages progress bar visibility and messages
- Integrates with cold start detection
- Provides smooth transitions between different states
- Supports both automatic and manual progress control
Usage:
// Inject the service
constructor(private progressService: ProgressService) {}
// Start progress with cold start detection
this.progressService.startProgress('Connecting to server...').subscribe(() => {
// Cold start detection completed, proceed with actual work
this.performActualWork();
});
// Update progress manually
this.progressService.updateProgress('Processing data...', 75);
// Complete progress
this.progressService.completeProgress('Operation completed!');
GlobalProgressComponent (src/app/components/global-progress/global-progress.component.ts)
Displays the global progress bar at the top of the application.
Features:
- Fixed position at the top of the screen
- Shows progress messages and cold start indicators
- Animated transitions and visual feedback
- Automatically appears/disappears based on progress state
GrpcWrapperService (src/app/services/grpc-wrapper.service.ts)
Provides utility methods for wrapping gRPC calls with progress tracking.
Usage:
// Inject the service
constructor(private grpcWrapper: GrpcWrapperService) {}
// Wrap a gRPC call with progress tracking
const grpcCall = this.client.someMethod(request, null);
this.grpcWrapper.wrapWithProgress(
grpcCall,
'Loading data...',
'Data loaded successfully'
).subscribe({
next: (result) => {
// Handle success
},
error: (error) => {
// Handle error
}
});
Integration Examples
1. Basic gRPC Call with Progress
// Before (no progress tracking)
async getData(): Promise<any> {
const request = new GetDataRequest();
return this.client.getData(request, null);
}
// After (with progress tracking)
getDataWithProgress(): Observable<any> {
const request = new GetDataRequest();
const grpcCall = this.client.getData(request, null);
return this.grpcWrapper.wrapWithProgress(
grpcCall,
'Loading data...',
'Data loaded successfully'
);
}
2. Using Decorators (Advanced)
import { withProgress } from '../decorators/with-progress.decorator';
export class MyService {
constructor(private progressService: ProgressService) {}
@withProgress('Loading user data...', 'User data loaded')
async getUserData(userId: string): Promise<any> {
// Your gRPC call here
const request = new GetUserRequest();
request.setUserId(userId);
return this.client.getUser(request, null);
}
}
3. Manual Progress Control
// Start progress
this.progressService.startProgress('Initializing...').subscribe(() => {
// Cold start detection completed
this.progressService.updateProgress('Processing step 1...', 25);
// Do some work
this.doWork().then(() => {
this.progressService.updateProgress('Processing step 2...', 50);
// More work
this.doMoreWork().then(() => {
this.progressService.completeProgress('All done!');
});
});
});
Testing
A demo component is available at src/app/components/progress-demo/progress-demo.component.ts that demonstrates progress tracking functionality:
- Progress tracking scenarios
- Manual progress control
- gRPC wrapper usage
To test the demo, add a route to your application:
// In app.routes.ts
{
path: 'progress-demo',
component: ProgressDemoComponent
}
Best Practices
- Use the wrapper service for most gRPC calls to get automatic progress tracking
- Provide meaningful messages that explain what's happening to the user
- Handle errors gracefully - the progress service will automatically hide the progress bar on errors
- Don't overuse - only show progress for operations that take more than a few hundred milliseconds
- Test with real scenarios - ensure progress messages match actual operation duration
Troubleshooting
Progress bar not showing
- Check that
ProgressServiceis injected in your component/service - Verify that
GlobalProgressComponentis included in your app component - Check browser console for any errors
gRPC wrapper errors
- Make sure
GrpcWrapperServiceis injected in your service - Verify that the gRPC call returns a Promise
- Check that error handling is properly implemented
Architecture
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Component │ │ ProgressService │ │GrpcWrapperService│
│ │───▶│ │───▶│ │
│ - User Action │ │ - State Mgmt │ │ - gRPC Wrapping │
│ - API Call │ │ - Progress Ctrl │ │ - Error Handling│
└─────────────────┘ └──────────────────┘ └─────────────────┘
│
▼
┌──────────────────┐
│GlobalProgressComp│
│ │
│ - UI Display │
│ - Animations │
└──────────────────┘
This architecture provides a clean separation of concerns while ensuring that all operations can benefit from progress tracking and user feedback.