Skip to main content

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 composed UserControl with 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, a pointSelected event that becomes the named server event SegmentClicked, and an error event that becomes WidgetError with 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 thisPathWhat you should see
(page load)successTimeline 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 entryItemSelectedThe row highlights; the status bar shows Escalated: approver m.weber · due Jun 14.
A chart slice (e.g. red Escalated)SegmentClickedBlue 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 reloadfailure — the pathThe 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.