Modal Workflows, Dialog Results & Transactional UI
The Work Orders screen of the TicketOps Console opens an ApprovalDialog for
the selected work order (WO-2002 · Repair loading dock pump), awaits it with ShowDialogAsync, and
reads one typed ApprovalDialogResult — never the dialog's controls. Only a confirmed result reaches
ApprovalService.ApplyAsync, which re-checks the rules and commits status, audit row and notification
as one transaction. Cancel, ✕ and a rejection without comments leave the work order exactly as it was.
Nothing here is deployed anywhere; it is a plain Wisej.NET 4 project that runs on your machine.
Run it
cd "LearnWisej-Samples/Production Architecture Deep Dive\Module 6\TicketOps"
dotnet run -f net10.0 --urls http://localhost:5106
Then open http://localhost:5106. (Visual Studio: open TicketOps.slnx, press F5 — the port is in
Properties/launchSettings.json.)
Requirements: .NET 10 SDK, the Wisej-4 4.1.0 NuGet package.
What to try in the Work Orders window
The dark strip under the buttons is the workflow status (Work order 2002 selected., Approval dialog open — work order 2002 untouched. …).
| Action | Path | What you should see |
|---|---|---|
| WO-2002 selected → ✓ Approve / Reject… → keep Approve, Confirm | success | the modal dialog Approve Work Order 2002; on Confirm the grid refreshes, the card reads Status: Approved by approver@ticketops …; status ● Work order WO-2002 approved. |
| ✓ Approve / Reject… → Cancel (or the title-bar ✕) | cancel = unchanged | strip Approval canceled — work order 2002 unchanged.; status ● unchanged |
| ✓ Approve / Reject… → Reject, leave comments empty, Confirm | validation inside the dialog | the hint required when rejecting appears; the dialog stays open with Comments are required when rejecting. Type a comment and Confirm → the order is rejected |
| Select an order that is already decided | domain rule | ✓ Approve / Reject… is disabled; the card shows who decided and when |
| ↻ Refresh | — | reloads the queue |
If the commit fails, nothing is applied (status, audit and notification roll back together), the details go to the log and the user sees The action could not be completed. Check the log for details.
Where things live
TicketOps/
├─ Views/WorkOrderQueue the screen: buttonReview_Click opens the dialog, awaits it, gates on DialogResult.OK + Result.Confirmed
├─ Dialogs/
│ ├─ ApprovalDialog the modal checkpoint: private controls, validation in Confirm, one public Result
│ └─ ApprovalDialogResult.cs the typed contract (Confirmed / Action / Comments) — plain data
├─ Controls/StatusBanner reusable "● state" + banner UserControl (display only)
├─ Services/ IApprovalService / ApprovalService: three gates, result → ApprovalCommand, one transaction
├─ Domain/ WorkOrder (CanDecide / Decide), ApprovalCommand (+ ApprovalRecord), OperationResult
├─ Data/ IWorkOrderRepository + IWorkOrderTransaction, InMemoryWorkOrderRepository (working-copy commit)
├─ Infrastructure/ ILog / ActivityLog (server console), AppComposition (per session, the trusted CurrentUser)
├─ Resources/Strings.cs safe user-facing messages
├─ Diagnostics/ResultHandlingTests.cs the six unit-style cases, each on its own fixture
├─ docs/ the deliverables
├─ Program.cs Wisej.NET session entry point → AppComposition
└─ Startup.cs Kestrel host (app.UseWisej())