fix: adress pr comments

This commit is contained in:
Kacper
2026-01-16 21:05:58 +01:00
parent 6237f1a0fe
commit c0d64bc994
5 changed files with 48 additions and 33 deletions

View File

@@ -56,19 +56,23 @@ export function GitHubIssuesView() {
// Combine all issues for filtering
const allIssues = useMemo(() => [...openIssues, ...closedIssues], [openIssues, closedIssues]);
// Apply filter to issues
// Apply filter to issues - now returns matched issues directly for better performance
const filterResult = useIssuesFilter(allIssues, filterState, cachedValidations);
// Filter issues based on matched results
const filteredOpenIssues = useMemo(
() => openIssues.filter((issue) => filterResult.matchedIssueNumbers.has(issue.number)),
[openIssues, filterResult.matchedIssueNumbers]
);
const filteredClosedIssues = useMemo(
() => closedIssues.filter((issue) => filterResult.matchedIssueNumbers.has(issue.number)),
[closedIssues, filterResult.matchedIssueNumbers]
);
// Separate filtered issues by state - this is O(n) but now only done once
// since filterResult.matchedIssues already contains the filtered issues
const { filteredOpenIssues, filteredClosedIssues } = useMemo(() => {
const open: typeof openIssues = [];
const closed: typeof closedIssues = [];
for (const issue of filterResult.matchedIssues) {
if (issue.state.toLowerCase() === 'open') {
open.push(issue);
} else {
closed.push(issue);
}
}
return { filteredOpenIssues: open, filteredClosedIssues: closed };
}, [filterResult.matchedIssues]);
// Filter state change handlers
const handleStateFilterChange = useCallback((stateFilter: IssuesStateFilter) => {

View File

@@ -20,6 +20,11 @@ import { cn } from '@/lib/utils';
import type { IssuesStateFilter } from '../types';
import { ISSUES_STATE_FILTER_OPTIONS } from '../types';
/** Maximum number of labels to display before showing "+N more" in normal layout */
const VISIBLE_LABELS_LIMIT = 3;
/** Maximum number of labels to display before showing "+N more" in compact layout */
const VISIBLE_LABELS_LIMIT_COMPACT = 2;
interface IssuesFilterControlsProps {
/** Current state filter value */
stateFilter: IssuesStateFilter;
@@ -156,21 +161,27 @@ export function IssuesFilterControls({
{/* Selected Labels Display - shown on separate row */}
{hasSelectedLabels && (
<div className="flex items-center gap-1 flex-wrap">
{selectedLabels.slice(0, compact ? 2 : 3).map((label) => (
<Badge
key={label}
variant="outline"
size="sm"
className="gap-1 cursor-pointer hover:bg-destructive/10 hover:border-destructive/50"
onClick={() => handleLabelToggle(label)}
>
{label}
<X className="h-2.5 w-2.5" />
</Badge>
))}
{selectedLabels.length > (compact ? 2 : 3) && (
{selectedLabels
.slice(0, compact ? VISIBLE_LABELS_LIMIT_COMPACT : VISIBLE_LABELS_LIMIT)
.map((label) => (
<Badge
key={label}
variant="outline"
size="sm"
className="gap-1 cursor-pointer hover:bg-destructive/10 hover:border-destructive/50"
onClick={() => handleLabelToggle(label)}
>
{label}
<X className="h-2.5 w-2.5" />
</Badge>
))}
{selectedLabels.length >
(compact ? VISIBLE_LABELS_LIMIT_COMPACT : VISIBLE_LABELS_LIMIT) && (
<Badge variant="muted" size="sm">
+{selectedLabels.length - (compact ? 2 : 3)} more
+
{selectedLabels.length -
(compact ? VISIBLE_LABELS_LIMIT_COMPACT : VISIBLE_LABELS_LIMIT)}{' '}
more
</Badge>
)}
</div>

View File

@@ -200,8 +200,9 @@ export function useIssuesFilter(
// Normalize search query for case-insensitive matching
const normalizedQuery = searchQuery.toLowerCase().trim();
// Filter issues based on all criteria
const matchedIssueNumbers = new Set<number>();
// Filter issues based on all criteria - return matched issues directly
// This eliminates the redundant O(n) filtering operation in the consuming component
const matchedIssues: GitHubIssue[] = [];
for (const issue of issues) {
// All conditions must be true for a match
@@ -214,17 +215,17 @@ export function useIssuesFilter(
matchesValidationStatus(issue, validationStatusFilter, cachedValidations);
if (matchesAllFilters) {
matchedIssueNumbers.add(issue.number);
matchedIssues.push(issue);
}
}
return {
matchedIssueNumbers,
matchedIssues,
availableLabels,
availableAssignees,
availableMilestones,
hasActiveFilter,
matchedCount: matchedIssueNumbers.size,
matchedCount: matchedIssues.length,
};
}, [
issues,

View File

@@ -72,8 +72,8 @@ export interface IssuesFilterState {
* Result of applying filters to the issues list
*/
export interface IssuesFilterResult {
/** Set of issue numbers that match the current filters */
matchedIssueNumbers: Set<number>;
/** Array of GitHubIssue objects that match the current filters */
matchedIssues: GitHubIssue[];
/** Available labels from all issues (for filter dropdown population) */
availableLabels: string[];
/** Available assignees from all issues (for filter dropdown population) */

View File

@@ -2,7 +2,6 @@ export { useAutoMode } from './use-auto-mode';
export { useBoardBackgroundSettings } from './use-board-background-settings';
export { useElectronAgent } from './use-electron-agent';
export { useGuidedPrompts } from './use-guided-prompts';
export { useIssuesFilter } from '@/components/views/github-issues-view/hooks/use-issues-filter';
export { useKeyboardShortcuts } from './use-keyboard-shortcuts';
export { useMessageQueue } from './use-message-queue';
export { useOSDetection, type OperatingSystem, type OSDetectionResult } from './use-os-detection';