Custom Controls, Extensions, Widget Wrappers & Reusable Components
Custom Controls, Extensions, Widget Wrappers & Reusable Components — Build a StatusTimeline control & a chart widget.
The EnterpriseOps Command Center's Work order history screen, built out of two reusable components:
EnterpriseOps.Controls.StatusTimeline— a composedUserControlwith typed properties (Items : IList<TimelineItem>,SelectedItem,Caption,TimeFormat,SampleMode), a named server event (ItemSelected) and a design-time sample mode;EnterpriseOps.Widgets.WorkOrderChartWidget : Wisej.Web.Widget— a stable C# API in front of a third-party SVG chart, with an embedded client adapter, an embedded resource package, apointSelectedevent that becomes the named server eventSegmentClicked, and anerrorevent that becomesWidgetErrorwith a polite fallback already on screen.
Everything is in memory. No database, no network, no cloud account, nothing deployed.
Run it
cd "Module 8/EnterpriseOps"
dotnet run -f net10.0 --urls http://localhost:5208
Then open http://localhost:5208. The session is ana.ops · Manager on tenant fabrikam, on work order 2002 — the work order the walkthrough video opens (Dock door sensor fault), whose four history entries are the four entries.
The screen
WorkOrderHistoryPage (948 × 590): a blue title bar EnterpriseOps — Work order history, then one white
card with the heading lblCardTitle (Work order 2002 — history), statusTimeline (left),
chartWorkOrders (right), the note lblBanner (hidden until there is something to say), the grid
dgvSegment and the dark status bar lblStatusBar.
What to click
| Do this | Path | What you should see |
|---|---|---|
| (page load) | success | Timeline with 4 entries (grey Created, blue Assigned, amber On hold, red Escalated); chart Open 38 · On hold 22 · Escalated 12 · Done 28; status bar Work order 2002 — history loaded · StatusTimeline + WorkOrderChartWidget. |
| A timeline entry | ItemSelected | The row highlights; the status bar shows Escalated: approver m.weber · due Jun 14. |
| A chart slice (e.g. red Escalated) | SegmentClicked | Blue note SegmentClicked → "escalated" · 12 work orders shown below; the grid shows the 12 rows; status bar SegmentClicked("escalated") — named server event · grid filtered server-side. |
Block /Widgets/vendor-opschart.js in the browser's developer tools (Network → Block request URL), then reload | failure — the path | The chart renders the embedded fallback list with the same numbers; red note WidgetLoadError — vendor-opschart.js · fallback rendered · screen still works; the timeline keeps working and the error is logged server-side (System.Diagnostics.Trace). |
Other failures are handled as ordinary code: a tenant-denied read (AccessPolicy) or a segment key the
service does not know shows a red note with the correlation id; an unexpected exception shows the note and
a toast.
Where things live
EnterpriseOps/
Program.cs session composition root → UI.WorkOrderHistoryPage
Controls/ StatusTimeline.cs / .Designer.cs · TimelineItem.cs
Widgets/ WorkOrderChartWidget.cs · ChartSegment.cs · ComponentResourcePackage.cs
vendor-opschart.js · opschart.css · opschart-init.js (embedded, InitScript)
UI/ WorkOrderHistoryPage.cs / .Designer.cs
Services/ WorkOrderHistoryService.cs · ActivityTrace.cs (server log) · SessionContext.cs · CommandResult.cs · Views.cs
Security/AccessPolicy.cs Domain/ Data/
docs/ the five deliverables + event-contract.svg
The solution tree shows six projects; this sample keeps one project with folder-per-layer namespaces
that map 1:1 onto that split, so it runs with one dotnet run.