feat(playground): redesign provisioning frontend as command center - #32
Merged
Merged
Conversation
- Replace the Blazor template (Bootstrap, sidebar, 4 separate pages) with a single-screen dark Command Center sharing the lambda playground's design language - Add MessageFlowNotifier: in-process events from the publish action and the SQS handler drive instant feed updates and sequential pipeline pulses; the header shows measured publish-to-store latency - Render a live SVG pipeline (Frontend -> SNS -> SQS -> handler -> DynamoDB, plus passive S3 node when the stack provisions a bucket) with real-state badges: SQS waiting count, handler in-flight count, DynamoDB item count - Add "Simulate chat" (scripted 10-message conversation through the real pipeline) and a "slow handler" demo toggle (~2s per message, poller concurrency 2) so queue backlog and drain become visible during bursts - Add config drawer with stack outputs, LocalStack options, and corrected client endpoint display (LocalStack edge instead of the misleading regional AWS endpoint) - Rework DynamoDB browser: table picker, raw attribute view, truncation with tooltips, auto-refresh with tab-hidden pause - Switch to MapStaticAssets with fingerprinted assets, fixing stale-CSS browser caching caused by UseStaticFiles sending no Cache-Control - Update the provisioning README for the new UI and remove the superpowers spec/plan working documents
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR refactors the provisioning playground Frontend into a single-screen “Command Center” experience, adding live pipeline visualization and in-process UI updates while removing the older multi-page navigation UX.
Changes:
- Introduces an in-process message flow notifier + demo toggles (slow handler) and wires them through the message handler and UI.
- Replaces older pages/navigation with a Command Center home page and new panels (publish bar, pipeline, chat feed, DynamoDB browser, config drawer).
- Overhauls the frontend styling/assets and updates provisioning README to describe the new UI.
Reviewed changes
Copilot reviewed 27 out of 30 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| playground/provisioning/README.md | Updates documentation to match the new Command Center UI and flows. |
| playground/provisioning/LocalStack.Provisioning.Frontend/wwwroot/js/visibility.js | Adds a small JS helper for tab visibility detection. |
| playground/provisioning/LocalStack.Provisioning.Frontend/wwwroot/app.css | Replaces the default styling with a dark Command Center theme and component styles. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Services/TimeFormatting.cs | Adds relative time formatting helper for message timestamps. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Services/MessageFlowNotifier.cs | Adds an in-process event hub for publish/store flow events used by UI. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Services/EndpointDisplay.cs | Adds UI-friendly endpoint display logic (LocalStack edge vs AWS regional). |
| playground/provisioning/LocalStack.Provisioning.Frontend/Services/DemoOptions.cs | Adds demo runtime toggles shared between UI and handler (slow handler). |
| playground/provisioning/LocalStack.Provisioning.Frontend/Program.cs | Registers new services, tweaks SQS poller concurrency, switches to static-assets mapping. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Handlers/ChatMessageHandler.cs | Adds slow-handler simulation and emits “stored” flow events to the notifier. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/_Imports.razor | Adds new namespaces for Command Center components and services. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/Shared/DynamoDBTableViewer.razor | Reworks table viewer into a DynamoDB browser panel with auto-refresh and visibility pausing. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/Routes.razor | Removes FocusOnNavigate behavior from routing. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/Pages/Home.razor | Replaces the default home page with the Command Center layout and drawer toggles. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/Layout/MainLayout.razor | Simplifies layout to render the new single-screen experience without sidebar/nav. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/CommandCenter/PublishBar.razor | Adds publish bar + scripted simulation + slow-handler toggle UI. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/CommandCenter/PipelinePanel.razor | Adds live pipeline SVG with pulsing segments and queue depth badges. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/CommandCenter/MessagesPanel.razor | Adds live chat message feed with reconciliation scanning and visibility pausing. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/CommandCenter/ConfigDrawer.razor | Adds drawer to display AppHost stack outputs and client endpoints. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/App.razor | Switches to static assets mapping and inline favicon; adds ImportMap usage. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/Pages/MessagePublisher.razor | Removes the legacy message publisher page in favor of the Command Center. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/Pages/DynamoDBLocalTest.razor | Removes the legacy DynamoDB test page in favor of the Command Center. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/Pages/AppHostConfiguration.razor | Removes the legacy AppHost configuration page in favor of the drawer. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/Layout/NavMenu.razor | Removes the legacy navigation menu. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/Layout/NavMenu.razor.css | Removes legacy nav menu styles. |
| playground/provisioning/LocalStack.Provisioning.Frontend/Components/Layout/MainLayout.razor.css | Removes legacy layout/sidebar styles. |
| docs/superpowers/specs/2026-07-08-lambda-frontend-redesign-design.md | Removes unrelated lambda redesign design doc from this PR’s diff. |
| docs/superpowers/plans/2026-07-08-lambda-frontend-redesign.md | Removes unrelated lambda redesign implementation plan from this PR’s diff. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+30
to
+39
| internal sealed class MessageFlowNotifier | ||
| { | ||
| public event EventHandler<MessageFlowEventArgs>? FlowEvent; | ||
|
|
||
| public void NotifyPublished(string recipient) => | ||
| FlowEvent?.Invoke(this, new MessageFlowEventArgs(MessageFlowStage.Published, recipient, null, null, DateTimeOffset.UtcNow)); | ||
|
|
||
| public void NotifyStored(string messageId, string recipient, string message) => | ||
| FlowEvent?.Invoke(this, new MessageFlowEventArgs(MessageFlowStage.Stored, recipient, message, messageId, DateTimeOffset.UtcNow)); | ||
| } |
Comment on lines
+7
to
+13
| var reference = now ?? DateTimeOffset.UtcNow; | ||
| var seconds = Math.Round((reference - timestamp).TotalSeconds); | ||
|
|
||
| if (seconds < 5) | ||
| { | ||
| return "just now"; | ||
| } |
Comment on lines
+1
to
+3
| export function isHidden() { | ||
| return document.hidden; | ||
| } |
Comment on lines
+80
to
+91
| private async Task<bool> IsTabHiddenAsync() | ||
| { | ||
| try | ||
| { | ||
| _visibilityModule ??= await Js.InvokeAsync<IJSObjectReference>("import", "./js/visibility.js"); | ||
| return await _visibilityModule.InvokeAsync<bool>("isHidden"); | ||
| } | ||
| catch (JSException) | ||
| { | ||
| return false; | ||
| } | ||
| } |
Comment on lines
+120
to
131
| private async Task<bool> IsTabHiddenAsync() | ||
| { | ||
| if (string.IsNullOrEmpty(TableName)) | ||
| try | ||
| { | ||
| HasError = true; | ||
| ErrorMessage = "TableName parameter is required"; | ||
| IsLoading = false; | ||
| return; | ||
| _visibilityModule ??= await Js.InvokeAsync<IJSObjectReference>("import", "./js/visibility.js"); | ||
| return await _visibilityModule.InvokeAsync<bool>("isHidden"); | ||
| } | ||
| catch (JSException) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| await RefreshAsync(); | ||
| } |
Comment on lines
+124
to
+132
| try | ||
| { | ||
| var response = await DynamoDb.ScanAsync(new ScanRequest { TableName = _tableName }); | ||
|
|
||
| var records = response.Items | ||
| .Select(ToRecord) | ||
| .OrderByDescending(record => record.Timestamp) | ||
| .Take(MaxItems) | ||
| .ToList(); |
Comment on lines
1
to
5
| <Router AppAssembly="@typeof(Program).Assembly"> | ||
| <Found Context="routeData"> | ||
| <RouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)" /> | ||
| <FocusOnNavigate RouteData="@routeData" Selector="h1" /> | ||
| </Found> | ||
| </Router> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📝 Description
What does this PR do?
Rebuilds
playground/provisioning/LocalStack.Provisioning.Frontendfrom the untouched Blazor/Bootstrap template into a single-screen dark Command Center, matching the design language of the lambda playground's Command Center (#31):MessageFlowNotifiersingleton connects the publish action and the SQSChatMessageHandler(which runs in the same process) to the UI — new messages appear in the feed instantly and the header shows measured publish-to-store latency; a 10 s reconciliation scan picks up external writes.ApproximateNumberOfMessages), handler in-flight count (ApproximateNumberOfMessagesNotVisible), DynamoDB item count — every number is read from the source, nothing resets on page refresh.dynamodb.us-west-2.amazonaws.comtext (fromDetermineServiceOperationEndpoint, which ignores the LocalStack ServiceURL) and the empty SQS endpoint.MapStaticAssets+ fingerprinted assets replacingUseStaticFiles, fixing stale-CSS browser caching (no Cache-Control was sent).docs/.Both AppHosts (CDK and CloudFormation) keep working unchanged; healthcheck endpoints and AWS.Messaging configuration are untouched apart from the poller concurrency option.
Related Issue(s):
🔄 Type of Change
🎯 Aspire Compatibility
🧪 Testing
How has this been tested?
UseLocalStack())Playwright-driven end-to-end verification on the CDK AppHost: publish → sequential pipeline pulses; instant feed insert (<2 s, event-driven); CLI
put-itemreconciliation within 10 s; queue backlog visibly building (0 → 6) and draining with the slow-handler toggle; config drawer endpoint correctness; zero console errors; no page-level horizontal overflow at 1512/1280/900 px. CloudFormation AppHost smoke-tested with the same frontend. Unit test suite: 486/486 passing. Build with warnings-as-errors: 0 warnings. Slopwatch: 0 issues.Test Environment:
📚 Documentation
✅ Code Quality Checklist
🔍 Additional Notes
Breaking Changes: None — playground-only change; both AppHosts run unchanged.
Performance Impact: SQS
GetQueueAttributespolled every 2 s and DynamoDB scanned every 10 s by the UI (demo-scale, LocalStack-local). PollerMaxNumberOfConcurrentMessageslowered to 2 for the backlog demo.Dependencies: No new packages.
🎯 Reviewer Focus Areas
📸 Screenshots/Examples
Single screen: publish bar → live pipeline with real-state badges → chat feed + DynamoDB browser. Try it: run either provisioning AppHost, open the Frontend endpoint, enable "slow handler", hit "Simulate chat", and watch the queue badge climb and drain.
By submitting this pull request, I confirm that:
🤖 Generated with Claude Code