# Tasks: Implement Blazor UI ## Phase 1: Project Configuration - [x] 001: Verify JdeScoping.Client project configuration - Location: `NEW/src/JdeScoping.Client/JdeScoping.Client.csproj` - Verify: Radzen.Blazor, SignalR.Client packages referenced - Validation: `dotnet build` succeeds - [x] 002: Configure _Imports.razor - Location: `NEW/src/JdeScoping.Client/_Imports.razor` - Add: Radzen, SignalR, Models, Services namespaces - Validation: Namespace imports resolve - [x] 003: Update App.razor with routing - Location: `NEW/src/JdeScoping.Client/App.razor` - Add: CascadingAuthenticationState, AuthorizeRouteView - Validation: Router configuration compiles - [x] 004: Configure Program.cs service registration - Location: `NEW/src/JdeScoping.Client/Program.cs` - Add: Radzen services, Auth services, Application services - Validation: Application starts without DI errors - [x] 005: Add JS interop file for file downloads - Location: `NEW/src/JdeScoping.Client/wwwroot/js/interop.js` - Add: downloadFileFromStream, downloadFileFromUrl functions - Validation: JS file loads in browser ## Phase 2: Models - [x] 006: Create ValidCombination model - Location: `NEW/src/JdeScoping.Client/Models/ValidCombination.cs` - Source: `OLD/WebInterface/Scripts/model/models.js` (ValidCombination definitions) - Include: All 16 search type combinations with filter flags - Validation: GetAll() returns 16 items - [x] 007: Create LoginModel - Location: `NEW/src/JdeScoping.Client/Models/LoginModel.cs` - Properties: Username (required), Password (required) - Include: DataAnnotations validation attributes - Validation: Validation fails for empty fields - [x] 008: Create SearchViewModel - Location: `NEW/src/JdeScoping.Client/Models/SearchViewModel.cs` - Properties: ID, Name, UserName, Status, SubmitDT, StartDT, EndDT, Criteria - Validation: Model compiles with all properties - [x] 009: Create SearchCriteriaViewModel - Location: `NEW/src/JdeScoping.Client/Models/SearchCriteriaViewModel.cs` - Properties: MinimumDT, MaximumDT, all filter collections, ExtractMisData - Validation: Model compiles with all properties - [x] 010: Create filter item ViewModels - Location: `NEW/src/JdeScoping.Client/Models/` - Files: ItemViewModel, ProfitCenterViewModel, WorkCenterViewModel, OperatorViewModel, WorkOrderViewModel, ComponentLotViewModel, PartOperationViewModel - Validation: All models compile - [x] 011: Create SignalR message models - Location: `NEW/src/JdeScoping.Client/Models/` - Files: SearchUpdate.cs, StatusUpdate.cs - Validation: Records compile - [x] 012: Create DataUpdateViewModel - Location: `NEW/src/JdeScoping.Client/Models/DataUpdateViewModel.cs` - Properties: StartDT, EndDT, record counts for each table, WasSuccessful - Validation: Model compiles ## Phase 3: Authentication Services - [x] 013: Create ITokenStorageService interface - Location: `NEW/src/JdeScoping.Client/Auth/ITokenStorageService.cs` - Methods: GetTokenAsync, SetTokenAsync, RemoveTokenAsync - Validation: Interface compiles - [x] 014: Create TokenStorageService - Location: `NEW/src/JdeScoping.Client/Auth/TokenStorageService.cs` - Implementation: localStorage via IJSRuntime - Validation: Can store/retrieve/remove token - [x] 015: Create AuthStateProvider - Location: `NEW/src/JdeScoping.Client/Auth/AuthStateProvider.cs` - Implementation: Parse JWT claims, manage auth state - Methods: GetAuthenticationStateAsync, NotifyAuthenticationStateChangedAsync, LogoutAsync - Validation: Auth state changes propagate to components - [x] 016: Create IAuthService interface - Location: `NEW/src/JdeScoping.Client/Services/IAuthService.cs` - Methods: LoginAsync, LogoutAsync - Validation: Interface compiles - [x] 017: Create AuthService - Location: `NEW/src/JdeScoping.Client/Services/AuthService.cs` - Implementation: Call /api/auth/login, store token - Returns: AuthResult with Success, ErrorMessage, Token - Validation: Login flow works with mock endpoint ## Phase 4: SignalR Service - [x] 018: Create IHubConnectionService interface - Location: `NEW/src/JdeScoping.Client/Services/IHubConnectionService.cs` - Methods: StartAsync, StopAsync, GetCachedStatusAsync - Events: OnSearchUpdate, OnStatusUpdate - Validation: Interface compiles - [x] 019: Create HubConnectionService - Location: `NEW/src/JdeScoping.Client/Services/HubConnectionService.cs` - Implementation: HubConnectionBuilder with auto-reconnect - Subscribe: searchUpdate, statusUpdate events - Validation: Connects to /hubs/status, receives events ## Phase 5: API Client Services - [x] 020: Create ISearchService interface - Location: `NEW/src/JdeScoping.Client/Services/ISearchService.cs` - Methods: GetUserSearchesAsync, GetSearchAsync, CopySearchAsync, SaveSearchAsync, GetQueueAsync, DownloadResultsAsync - Validation: Interface compiles - [x] 021: Create SearchService - Location: `NEW/src/JdeScoping.Client/Services/SearchService.cs` - Implementation: HttpClient calls to /api/search endpoints - Include: Error handling, logging - Validation: Service compiles, handles errors gracefully - [x] 022: Create ILookupService interface - Location: `NEW/src/JdeScoping.Client/Services/ILookupService.cs` - Methods: FindItemsAsync, FindProfitCentersAsync, FindWorkCentersAsync, FindOperatorsAsync - Validation: Interface compiles - [x] 023: Create LookupService - Location: `NEW/src/JdeScoping.Client/Services/LookupService.cs` - Implementation: HttpClient calls to /api/lookup endpoints - Validation: Service compiles - [x] 024: Create IFileService interface - Location: `NEW/src/JdeScoping.Client/Services/IFileService.cs` - Methods: DownloadTemplateAsync, DownloadPartNumberTemplateAsync, UploadAsync - Validation: Interface compiles - [x] 025: Create FileService - Location: `NEW/src/JdeScoping.Client/Services/FileService.cs` - Implementation: File download via JS interop, upload via RadzenUpload - Validation: Download triggers browser save dialog - [x] 026: Create IRefreshStatusService interface - Location: `NEW/src/JdeScoping.Client/Services/IRefreshStatusService.cs` - Methods: GetRefreshStatusAsync(minDT, maxDT) - Validation: Interface compiles - [x] 027: Create RefreshStatusService - Location: `NEW/src/JdeScoping.Client/Services/RefreshStatusService.cs` - Implementation: HttpClient calls to /api/refresh-status - Validation: Service compiles ## Phase 6: Layout Components - [x] 028: Create MainLayout.razor - Location: `NEW/src/JdeScoping.Client/Layout/MainLayout.razor` - Structure: RadzenLayout with Header, Body, Footer - Include: AuthorizeView for user display, logout button - Validation: Layout renders header, content, footer - [x] 029: Create LoadingIndicator component - Location: `NEW/src/JdeScoping.Client/Components/Shared/LoadingIndicator.razor` - Structure: RadzenProgressBarCircular with optional message - Validation: Component renders centered spinner ## Phase 7: Authentication Pages - [x] 030: Create Login.razor - Location: `NEW/src/JdeScoping.Client/Pages/Login.razor` - Route: /login - Structure: RadzenCard with EditForm, username/password fields - Features: Validation, error display, loading state, redirect on success - Validation: Login form submits and redirects - [x] 031: Create NotAuthorized.razor - Location: `NEW/src/JdeScoping.Client/Pages/NotAuthorized.razor` - Route: /not-authorized - Structure: RadzenAlert with error message, navigation buttons - Validation: Page displays resource URL from query string - [x] 032: Create RedirectToLogin component - Location: `NEW/src/JdeScoping.Client/Components/Shared/RedirectToLogin.razor` - Implementation: NavigateTo /login with returnUrl - Validation: Unauthorized access redirects to login ## Phase 8: Search List Page - [x] 033: Create Searches.razor (Search List) - Location: `NEW/src/JdeScoping.Client/Pages/Searches.razor` - Routes: / and /searches - Structure: RadzenDataGrid with Name, Submitted, Status columns - Features: New Search button, Queue button, status badges - SignalR: Subscribe to searchUpdate, update grid in real-time - Validation: Grid displays user's searches, updates on SignalR events ## Phase 9: Search Create/Edit Page - [x] 034: Create SearchEdit.razor (main page) - Location: `NEW/src/JdeScoping.Client/Pages/SearchEdit.razor` - Routes: /search/create, /search/{Id:int} - Structure: Search details panel, conditional filter panels - Features: Search type dropdown, read-only mode, Copy button, Submit button - SignalR: Subscribe to searchUpdate for current search - Validation: Form loads, validates, submits correctly ## Phase 10: Filter Panel Components - [x] 035: Create TimeSpanFilterPanel.razor - Location: `NEW/src/JdeScoping.Client/Components/FilterPanels/TimeSpanFilterPanel.razor` - Structure: Min/Max date pickers - Business rules: Min >= 2002-11-01, Max <= today, Max >= Min - Validation: Date constraints enforced - [x] 036: Create WorkOrderFilterPanel.razor - Location: `NEW/src/JdeScoping.Client/Components/FilterPanels/WorkOrderFilterPanel.razor` - Structure: Upload/Download/Clear buttons, data grid - Features: Excel upload parsing, template download - Validation: Upload populates grid, Clear empties grid - [x] 037: Create ItemNumberFilterPanel.razor - Location: `NEW/src/JdeScoping.Client/Components/FilterPanels/ItemNumberFilterPanel.razor` - Structure: Autocomplete with Add button, data grid - Features: Search with 3+ chars, prevent duplicates - Validation: Autocomplete returns results, Add works - [x] 038: Create ProfitCenterFilterPanel.razor - Location: `NEW/src/JdeScoping.Client/Components/FilterPanels/ProfitCenterFilterPanel.razor` - Structure: Autocomplete with Add button, data grid - Validation: Same pattern as ItemNumber panel - [x] 039: Create WorkCenterFilterPanel.razor - Location: `NEW/src/JdeScoping.Client/Components/FilterPanels/WorkCenterFilterPanel.razor` - Structure: Autocomplete with Add button, data grid - Validation: Same pattern as ItemNumber panel - [x] 040: Create OperatorFilterPanel.razor - Location: `NEW/src/JdeScoping.Client/Components/FilterPanels/OperatorFilterPanel.razor` - Structure: Autocomplete with Add button, data grid - Properties: AddressNumber, UserID, FullName - Validation: Displays all three properties in dropdown - [x] 041: Create ComponentLotFilterPanel.razor - Location: `NEW/src/JdeScoping.Client/Components/FilterPanels/ComponentLotFilterPanel.razor` - Structure: Upload/Download/Clear buttons, data grid - Properties: LotNumber, ItemNumber - Validation: Two-column display in grid - [x] 042: Create PartOperationFilterPanel.razor - Location: `NEW/src/JdeScoping.Client/Components/FilterPanels/PartOperationFilterPanel.razor` - Structure: Upload/Download/Clear buttons, data grid - Properties: ItemNumber, OperationNumber, MisNumber, MisRevision - Validation: Four-column display in grid ## Phase 11: Search Queue Page - [x] 043: Create SearchQueue.razor - Location: `NEW/src/JdeScoping.Client/Pages/SearchQueue.razor` - Route: /search/queue - Structure: Processor status panel, data grid of all queued searches - SignalR: Subscribe to statusUpdate, searchUpdate - Features: Remove completed searches from grid - Validation: Grid shows all users' searches, status panel updates ## Phase 12: Refresh Status Page - [x] 044: Create RefreshStatus.razor - Location: `NEW/src/JdeScoping.Client/Pages/RefreshStatus.razor` - Route: /refresh-status - Structure: Date filter panel, data grid with record counts - Features: Default to last 7 days, Filter button, WasSuccessful badges - Validation: Grid displays sync history, filtering works ## Phase 13: Styling and Polish - [x] 045: Update wwwroot/css/app.css - Location: `NEW/src/JdeScoping.Client/wwwroot/css/app.css` - Add: Custom styles for badges, cards, loading states - Validation: Styles applied consistently - [x] 046: Update index.html - Location: `NEW/src/JdeScoping.Client/wwwroot/index.html` - Add: Radzen CSS reference, JS interop script reference - Validation: Radzen styles load correctly ## Phase 14: Verification - [x] 047: Verify all pages render - Navigate to each route, verify content loads - Validation: No console errors, all pages accessible - [x] 048: Verify form validation - Test Login form, Search Create form with invalid data - Validation: Validation messages display correctly - [x] 049: Verify SignalR connection - Check browser console for connection logs - Validation: Connection established, reconnects on disconnect - [x] 050: Run solution build - Command: `dotnet build NEW/JdeScoping.sln` - Validation: No errors or warnings - [x] 051: Run OpenSpec validation - Command: `openspec validate implement-blazor-ui --strict` - Validation: No validation errors