Skip to content

refactor: centralise duplicate frontend helpers#197

Merged
NotYuSheng merged 5 commits intomainfrom
feature/network-filter-shared-utils
Apr 14, 2026
Merged

refactor: centralise duplicate frontend helpers#197
NotYuSheng merged 5 commits intomainfrom
feature/network-filter-shared-utils

Conversation

@NotYuSheng
Copy link
Copy Markdown
Owner

Summary

  • Extracts shared network filter/label utilities (applyNetworkFilters, buildActiveFilterLabels, edgeMatchesLegendKey, toggleSet) so NetworkDiagramPage, ComparePage, and AnalysisPage all use the same logic
  • Removes inline copies of formatBytes, parseDateTime, confidenceLevel, buildDeviceSignals scattered across pages and popup components
  • Adds useClickOutside utility hook to replace identical useEffect patterns in both classification popups

Changes

Removed duplicate Was in Now lives in
parseDateTime timelineService.ts utils/dateUtils.ts
formatBytes NetworkDiagramPage, ComparePage utils/formatters
toggleSet NetworkDiagramPage, ComparePage features/network/constants.ts
edgeMatchesLegendKey ComparePage networkService.ts
Edge filter logic ComparePage inline useMemo networkService.applyNetworkFilters()
confidenceLevel Both classification popups utils/deviceType.ts
buildDeviceSignals Both classification popups utils/deviceType.ts
Click-outside useEffect Both classification popups utils/useClickOutside.ts (new)

Net: −235 lines added, +95 lines → −140 lines of duplicated code.

Test plan

  • Network Diagram page: filters (protocol, node type, IP, port, risks, app, L7, category, etc.) all still work
  • Compare page: same filters work; per-file source toggle still hides/shows edges
  • Report download: active filter labels and node-limit note appear correctly in generated PDF
  • Both classification popups close on outside click
  • Confidence bar and device signals display correctly in both popups
  • Timeline page loads without errors

🤖 Generated with Claude Code

NotYuSheng and others added 2 commits April 13, 2026 18:02
Move duplicated edge-filter logic into applyNetworkFilters() in
networkService.ts and duplicated filter-label building into
buildActiveFilterLabels() in constants.ts. Both AnalysisPage and
NetworkDiagramPage now call the shared helpers, eliminating the
divergence risk flagged in review.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- parseDateTime: remove copy in timelineService, import from dateUtils
- formatBytes: remove copies in NetworkDiagramPage + ComparePage, import from utils/formatters
- toggleSet: remove copies in NetworkDiagramPage + ComparePage, export from network/constants
- edgeMatchesLegendKey: remove copy in ComparePage, import from networkService
- applyNetworkFilters: remove inline filter block in ComparePage, call shared helper (hiddenSources pre-filter kept inline as it is compare-specific)
- confidenceLevel + buildDeviceSignals: remove copies in both classification popups, export from utils/deviceType
- useClickOutside: new shared hook in utils/, replaces duplicate useEffect in both classification popups

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request centralizes and refactors network filtering logic, device classification utilities, and common UI behaviors into shared services and hooks, significantly reducing code duplication across the Analysis, Compare, and Network Diagram pages. Feedback was provided regarding a performance bottleneck in the IP filtering logic within networkService.ts, where replacing a nested loop with a Set-based lookup would improve efficiency as the graph size increases.

Comment thread frontend/src/features/network/services/networkService.ts Outdated
NotYuSheng and others added 2 commits April 14, 2026 21:04
- Fix LLM connection errors being swallowed by generic 500 handler by re-throwing LlmException and ContextLengthExceededException directly in StoryService
- Show friendly LLM unreachable message on frontend for non-502 LLM errors
- Hide Device Type filter section when no device-classified nodes are present
- Hide Node Types section when no node/device types are present
- Remove nav-tabs underline on Analysis page
- Fix card header corners not rounding in dark mode with overflow: hidden

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@NotYuSheng
Copy link
Copy Markdown
Owner Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request centralizes network filtering logic, device classification utilities, and UI components across the frontend, including the introduction of a useClickOutside hook and consolidated filtering functions in networkService.ts. Backend updates improve exception handling for LLM-related errors. Feedback identifies a performance bottleneck in the centralized filtering logic that could be optimized from $O(N \cdot E)$ to $O(N + E)$ using a Set. Additionally, the reviewer recommends fully adopting the new filtering function in NetworkDiagramPage and refining the error detection logic in StoryPage.tsx to avoid overly broad string matching.

Comment thread frontend/src/features/network/services/networkService.ts Outdated
Comment thread frontend/src/pages/NetworkDiagram/NetworkDiagramPage.tsx
Comment thread frontend/src/pages/Story/StoryPage.tsx Outdated
- Replace O(N×E) fe.some() loop with a Set-based lookup for IP filter
  node visibility in applyNetworkFilters
- Remove overly broad substring matching for LLM errors in StoryPage;
  rely solely on HTTP 502 now that backend correctly propagates LlmException

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@NotYuSheng NotYuSheng merged commit 1f4b3b6 into main Apr 14, 2026
@NotYuSheng NotYuSheng deleted the feature/network-filter-shared-utils branch April 14, 2026 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant