Skip to main content

Complex Data Widgets

An editable grid (WorkOrderGrid : Widget, Kendo-style DataSource → the widget's postback URL) and a read-only pivot (WorkOrderPivot : Widget, DevExtreme-style CustomStore → a [WebMethod] on the page) feed the same vendor-free server contractGridOperationRequest, GridDataController.Handle(action, …), WorkOrderStore. Two vendors, one pattern.

The "vendor" libraries are small stand-ins written in the style of the real ones (VendorGrid, VendorPivot); nothing is fetched from a CDN. Nothing here is deployed anywhere; it is a plain Wisej.NET 4 project on this machine.

Run it

cd "LearnWisej-Samples/Application Integration Course/Module 9/IntegrationLab"
dotnet run -f net10.0 --urls http://localhost:5079

Then open http://localhost:5079. (Visual Studio: open IntegrationLab.slnx, press F5 — the launch profile already uses port 5079.)

Requirements: .NET 10 SDK, the Wisej-4 4.1.0 NuGet package. dotnet build -nologo -v q passes with the expected CS7022 warning only.

What to try on the "IntegrationLab — Data Widgets" page

Everything happens in the two widgets; the Remote operations card on the right lists each operation and event as it reaches the server.

GestureWhat you should see
(page load)← JS→.NET load {skip:0,take:20} → 200 (20/150) and ← JS→.NET LoadPivot (WebMethod) {…} → 200 (5×4, N cells)
the grid's ‹ › pagerload {skip:20,take:20} → 200 (20/150) (remote paging)
a click on a column headerload {…,sort:"status asc"} → 200 (remote sort); click again for desc
double-click a cell, edit, EnterrowUpdated {rowKey:"WO-1043",changes:{status:"Closed"}} (+ toast), then update {…} → 200 WO-1043 saved
type abc into an Hours cellupdate {…} → 400 hours must be a number …, then error {phase:"update",status:400,…} and an error toast
+ Add row, fill in, savecreate {"values":{…}} → 200 → WO-1151, followed by a reload
a row's ✕destroy {"rowKey":"WO-1010"} → 200 WO-1010 removed (149 left)
click a grid cell / a pivot cellcellClick {rowKey,field,value} / cellClick {rowKey,columnKey,value}

Where things live

IntegrationLab/
├─ Contracts/
│ ├─ GridOperationRequest.cs Skip / Take / Sort[] / Filter[] (+ SortDescriptor, FilterDescriptor)
│ ├─ GridOperationResult.cs Rows / Total / Skip / Take
│ ├─ RowOperationRequests.cs RowUpdateRequest { RowKey, Changes } · RowInsertRequest { Values } · RowDeleteRequest { RowKey }
│ ├─ PivotContracts.cs PivotRequest { RowField, ColumnField, Measure } · PivotResult · PivotCell
│ ├─ OperationResult.cs Status / Body / Summary · DataContractException(400|404)
│ ├─ WidgetEventArgs.cs CellClickEventArgs · RowUpdatedEventArgs · PivotCellClickEventArgs · DataWidgetErrorEventArgs · TraceEventArgs
│ └─ JsonCodec.cs camelCase JSON in/out, JsonElement / DynamicObject normalization
├─ Data/
│ ├─ WorkOrder.cs the row: id, asset, status, priority, assignee, hours, site
│ ├─ WorkOrderStore.cs in-memory store: Load / Insert / Update / Delete / Pivot with all validation
│ └─ GridDataController.cs Handle(action, args, body) — the one handler both entry points call
├─ Widgets/
│ ├─ WorkOrderGrid.cs typed properties, WebRequest (postback) handler, CellClick / RowUpdated events
│ ├─ GridColumn.cs typed column definition
│ └─ WorkOrderPivot.cs JSON-options prototype, CellClick / DataLoaded events
├─ wwwroot/
│ ├─ grid-init.js client adapter: Kendo-style DataSource → postback URL (embedded InitScript)
│ ├─ pivot-init.js client adapter: DevExtreme-style CustomStore → App.MainPage.LoadPivotAsync (embedded InitScript)
│ ├─ vendor-grid.js / .css the "third-party" editable grid (Package)
│ └─ vendor-pivot.js / .css the "third-party" read-only pivot (Package)
├─ docs/ the four deliverables
├─ MainPage.cs / .Designer.cs the lab page (Application.MainPage), [WebMethod] LoadPivot
├─ Program.cs Wisej.NET session entry point
└─ Startup.cs Kestrel host (app.UseWisej())