The index file picker built breadcrumb targets as '/' + segments, so on a Windows drive path (C:/Users/rap) clicking a crumb browsed to '/C:/...', which the backend rejected as 'not a directory'. Only the '.. (up)' button worked.
Build drive-aware crumb targets (C:/, C:/Users) and drop the bogus unified '/' root crumb on Windows drive paths; POSIX behavior is unchanged. Add a regression test for Windows breadcrumb navigation and cleanup() for test isolation.
Signed-off-by: Zadak <rarepops@protonmail.com>
The backend /api/index-status reports status:"error" plus an error
message for failed indexing jobs, but IndexProgress treated any
non-"indexing" state as successful completion: the spinner vanished
with no feedback (e.g. after an OOM-killed indexer subprocess), the
project never appeared, and no error was shown.
Render a visible error banner (path + error text) with a Dismiss
button instead, and keep the success flow unchanged. Beyond the
original PR:
- Restore the empty-jobs guard the PR dropped: the backend keeps
finished jobs listed as "done"/"error" (handle_index_status only
skips idle slots), so an empty list mid-index only occurs on
transient state loss and must not be treated as completion.
- Route the new user-facing strings through the i18n system
(projects.indexingFailed, common.dismiss; EN + zh entries).
- Cover error banner + dismiss, success flow and the empty-jobs
guard with vitest cases on the now-exported IndexProgress.
Distilled from #549.
Refs #524
Co-authored-by: sahil-mangla <manglasahil2017@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Clicking "None" (disable all filters) clears every label and edge type,
making filteredData.nodes empty. The early return then replaced the whole
layout — including the left filter sidebar — with a centered "All nodes
filtered out / Reset Filters" message, leaving no way to re-enable
individual filters without resetting everything.
Narrow the early return to the genuinely-empty / no-data case and render
the "all filtered out" state inside the graph area instead, so the
FilterPanel and Sidebar stay mounted. As a side effect, a project with
zero nodes now correctly reads "No nodes in this project" rather than
"All nodes filtered out".
Add a regression test that disables all filters via "None" and asserts the
Filters sidebar remains in the document.
Signed-off-by: Zadak <rarepops@protonmail.com>
Two visualization gaps in the cross-repo graph view:
1. Fixed LAYOUT_GALAXY_SPACING=600 buried satellite galaxies inside the
primary cluster on any non-trivial project — a 1000-node primary
cluster has bounding radius ~1500. Added layout_radius() (max distance
from origin across all node positions) and compute the per-satellite
distance as primary_radius + sat_radius + LAYOUT_GALAXY_PAD, with the
old constant retained as a lower bound for tiny projects.
2. cross_edges was hard-coded to an empty array (TODO placeholder), so
inter-galaxy CROSS_* edges never rendered even when the matcher had
produced them. Populate from a join on the source store's CROSS_*
edges → Route node qualified_name, then resolve the canonical QN in
the linked store to get its node id. The Route QN is the cross-repo
matching contract; properties.target_function isn't unique.
Required keeping both `store` and `lp_store` open through the linked-
projects loop instead of closing them right after layout compute.
Added cbm_store_close to all early-error paths to balance the lifetime.
Frontend side:
- EdgeLines accepts an optional targetNodes prop so a single component
can render edges with source in one node array and target in another
(offset-adjusted satellite nodes).
- GraphScene renders an EdgeLines layer per linked project for its
cross_edges, using primary nodes as source and offsetNodes as target.
- GraphTab folds linked-project labels and edge types into the filter
init / enableAll / filteredData paths so cross_edges respect the
current filter state.
- Edge color palette extended with GRPC/GRAPHQL/TRPC/CROSS_* tones.
Co-authored-by: sponger94 <45746997+sponger94@users.noreply.github.com>