Production Readiness & Capstone
An
unfamiliar third-party widget (VendorHeatmap, a calendar heatmap — not Kendo, not DevExtreme) is integrated as a
reusable HeatmapWidget : Wisej.Web.Widget wrapper with server calls, events, postback data loading,
bounded background updates (Application.StartTask → Call → Application.Update) and a create/dispose test —
all on one "IntegrationLab — Operations Dashboard" page with the Module 1 TemperatureGauge beside it.
Nothing here is deployed anywhere; it is a plain Wisej.NET 4 project that runs on your machine.
Run it
cd "LearnWisej-Samples/Application Integration Course/Module 10/IntegrationLab"
dotnet run -f net10.0 --urls http://localhost:5080
Then open http://localhost:5080. (Visual Studio: open IntegrationLab.slnx, press F5.)
Requirements: .NET 10 SDK, the Wisej-4 4.1.0 NuGet package.
dotnet build -nologo -v q passes; warning CS7022 (Program.Main ignored) is expected.
What to try in the Operations Dashboard
The four tiles on top are Widgets live, Requests/min, Errors and Disposed cleanly.
| Action | What you should see |
|---|---|
| (page load) | the heatmap fetches …&action=load from its postback endpoint and draws 7 × 24 cells; Widgets live 2, Requests/min 1 |
| click a cell | CellSelected in C#; the banner shows the server value for that cell |
| ▶ Start / ■ Stop live updates | every 1500 ms the background task sends new cells (Call setCells) and a new gauge value in one Application.Update(page); bounded to 40 pushes; stops when the page closes |
| Highlight peak | the server finds the max cell in its copy of the data and calls highlight(day, hour); one cell pulses |
| Reload data | Call reload() → the client fetches the endpoint again |
| Cell count | await CallAsync("getCellCount") → toast "The client widget holds 168 cells." |
| Create/dispose ×25 | 25 heatmaps created and disposed in the Create/dispose test box; EvalAsync reads the adapter's counters → tile Disposed cleanly 25/25, vendor instances alive = 1 |
Any adapter or vendor failure arrives as one error event: the banner names it and the Errors tile counts it.
The adapter's guard clause turns a missing vendor script into "VendorHeatmap not loaded — check Packages order."
Where things live
IntegrationLab/
├─ Controls/
│ ├─ HeatmapWidget.cs the capstone wrapper: typed properties, postback endpoint, calls, events, pinned versions
│ ├─ HeatmapEventArgs.cs CellSelected / DataLoaded / LoadFailed payloads (data, never behavior)
│ ├─ TemperatureGauge.cs the Module 1 wrapper, reused on the dashboard (fed by the same background task)
│ └─ GaugeEventArgs.cs gauge payloads
├─ Data/
│ ├─ HeatmapCell.cs the only shape that crosses the wire
│ └─ LoadSampleService.cs deterministic load data: endpoint page, live batches, design-time sample
├─ Services/
│ └─ LiveUpdateService.cs Application.StartTask loop → Application.Update(page); bounded, disposal-aware
├─ wwwroot/
│ ├─ vendor-heatmap.js/.css the "unfamiliar" VendorHeatmap 1.2.0 library (Packages)
│ ├─ heatmap-init.js client adapter (InitScript, embedded): guard clause, _wire(), update, dispose, calls
│ ├─ temperature-gauge.js Module 1 adapter (embedded)
│ └─ vendor-gauge.js VendorGauge (Package)
├─ docs/ the four deliverables
├─ OperationsPage.cs / .Designer.cs IntegrationLab — Operations Dashboard
├─ Program.cs Application.MainPage = new OperationsPage()
└─ Startup.cs Kestrel host (app.UseWisej(), static files)