Indenting and Nesting Items
Nesting groups related items together and creates a parent row whose total sums its children's totals.
The Rules
- Max indent level: 6 (7 levels total).
Tabindents;Shift+Taboutdents.- Indenting assigns the nearest previous row at the same or lower level as the parent.
Worked Example
Start with a flat list:
1 Site Preparation
2 Excavation
3 Backfill
Select rows 2 and 3, press Tab:
1 Site Preparation
2 Excavation
3 Backfill
Row 1 becomes the parent. Its TotalWithChildren now sums lines 2 and 3.
Header vs Mixed Parent
Row 1 in the example has Qty = 0 and no resource — it's a pure header. A parent can also have its own quantity and rate, in which case TX1 adds that to the children's total. This is allowed but unusual. Recommended pattern: keep parents as pure headers.
Reordering
Alt+↑ / ↓moves selected rows up or down among siblings.- Dragging a row onto another row re-parents it.
- Drag-and-drop respects the max indent level and blocks invalid moves.
Collapsing
Click the chevron to collapse a parent. The expand state persists across sessions via the project's DirectCostHierarchyStateJson field.
What Rolls Up
| Aggregate | Source |
|---|---|
TotalWithChildren | Σ of all descendants' TotalWithChildren + own DirectTotal. |
RateWithChildren | TotalWithChildren / Quantity — only meaningful if the parent has its own Qty. |
| Sell Total (parent) | Computed per-row by the sell-rate pipeline, not re-summed. |
Warning — Performance
Changing a deep-nested row triggers a bubble-up notification to every ancestor. Large hierarchies (thousands of items) should be debounced — the engine does this with NotifyAncestorsOfTotalChange() to avoid re-rendering on every keystroke.