SIGN IN SIGN UP

Feature/sidebar inspector (#4485)

* feat(visualization): migrate attribute sidebar to sidebarInspector feature

- new features/sidebarInspector: right-side Inspector drawer following the
  feature architecture (signals, OnPush, DaisyUI/Tailwind, no SCSS/Material,
  ngrx confined to stores/ and selectors/)
- header with parent path + highlighted node name, copy-path button,
  external node link, and folder file counts incl. delta counts
- METRIC MAPPING section showing area/height/color/edge metric names with
  global min-max ranges, inverted color marker, and edge in/out counts;
  color block hidden in delta mode like the metrics bar
- METRICS list with severity-colored bars sized by each value's position
  in its global range, respecting higher-is-better metric directions
- visibility derived from selectedBuildingId state (auto open/close,
  manual close via button), exposed through the feature facade
- delete legacy ui/attributeSideBar and isAttributeSideBarVisible service;
  update codeMap, legendPanel, and screenshot service consumers
- relocate shared Metric/Edge types to state/selectors/primaryMetrics
- drop the sigma/median attribute-type toggle (accepted regression)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(visualization): show node values and share-of-map bars in inspector

Review feedback on the sidebarInspector feature:

- METRIC MAPPING blocks now show the selected node's value for each mapped
  metric instead of the global min-max range; buildings show their direct
  values, folders the aggregated values of the contained files (same
  decorated data the METRICS list uses)
- metric bars now visualize the value's share of the whole map: value
  divided by the root aggregate, so a building with 100 rloc in a
  1,000-rloc map fills 10%; folders show their share of the project;
  severity thirds (direction-aware) apply to that share and metrics
  missing on the root render a neutral full bar
- closing the inspector with the x button now deselects the building or
  folder in the 3D scene (ThreeSceneService.clearSelection + re-render);
  visibility is derived purely from the selected node, the manual-close
  flag is gone

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(visualization): group empty inspector metrics in collapsible, grey bars

- metrics with empty (zero/missing) values render an empty bar instead of
  a full near-black one and are grouped greyed-out in a collapsed
  'Empty metrics (N)' section below the metrics with values
- neutral severity fill (degenerate map totals) changed from bg-neutral
  to bg-base-content/30 so it reads as grey rather than black

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(visualization): add map/range comparison toggle for inspector metric bars

- segmented 'map | range' control in the METRICS header switches the bar
  denominator between share-of-map (value / root aggregate, default) and
  position within the file-level min/max range of the metric
- the metric rows selector precomputes both bar variants (mapBar/rangeBar)
  so switching modes is purely presentational
- the chosen mode is a session-only signal in InspectorComparisonModeService

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(visualization): align legend and view cube with inspector width

The legend panel, legend button, and view cube shifted by the legacy
sidebar width (350px) when a building was selected, leaving a gap next
to the 320px inspector. Offsets now match the inspector's w-80 width.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(visualization): add type badges to inspector header, pin sections

- remove the 'selected' chip; below the node name two badges now show the
  node type (file/folder) and, for folders, the contained file count;
  delta file counts render next to the badges in delta mode
- node type is derived from NodeType instead of the children heuristic
- header and METRIC MAPPING are pinned at the top of the drawer; only the
  METRICS section scrolls

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(visualization): remove dead primaryMetricsSelector and updateAttributeType

Post-review cleanup of code orphaned by the attribute sidebar migration:

- delete state/selectors/primaryMetrics/{primaryMetrics.selector,metric,edge}.ts
  and the selector spec - the value-based selector's last consumer was the
  deleted legacy sidebar; metricsBar only uses primaryMetricNames.selector
- delete the updateAttributeType action, its reducer branch, the
  fileSettingsActions entry, and its reducer spec case - its only
  dispatcher was the removed sigma/median attribute-type toggle

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(visualization): address inspector review nits

- clear the copy-feedback timeout on header destroy via DestroyRef
- single-source the inspector width as --cc-inspector-width (20rem) in
  tailwind.css; the drawer host, legend panel/button, and view cube
  offsets all derive from it instead of three hardcoded pixel values
- correct plan frontmatter (state: complete, branch: feature/sidebar-inspector)

The delta number format (locale formatting instead of legacy's forced
one decimal) stays as an intentional change, consistent with all other
numbers in the inspector.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(visualization): keep zero-value metrics with deltas out of the empty group

In delta mode a metric that dropped to 0 (e.g. value 0, delta -20) was
classified as empty and hidden in the collapsed 'Empty metrics' group,
hiding its delta. Rows now count as empty only when they have neither a
value nor a delta.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(visualization): split inspector header and metrics list templates

- extract four presentational components, each with its own spec:
  inspectorNodePath (parent path + name + link), inspectorNodeBadges
  (type/file-count badges + delta counts), inspectorComparisonToggle
  (map|range segmented control), inspectorEmptyMetrics (collapsible
  empty-metrics group); all data-testids preserved
- make isEmptyMetricValue explicit (value === undefined || value === 0 ||
  NaN) instead of !value - treating 0 as empty is intentional, zero-valued
  metrics belong in the collapsed Empty group and rows with deltas are
  protected by isEmptyMetricRow

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Christian Hühn <christian.huehn@maibornwolff.de>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
C
Christian Hühn committed
2ee15949254b45283bc1d430930a52b5aa0fe972
Parent: 8274b8d
Committed by GitHub <noreply@github.com> on 6/11/2026, 11:59:45 AM