Skip to content

Commit 6deb1c2

Browse files
authored
feat: filter by project in sidebar (#101)
1 parent 1649b2e commit 6deb1c2

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

src/renderer/components/ui/sidebar/SidebarContent.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { buildTreeLines, getAllNodeIds } from "@components/ui/sidebar/Utils";
44
import { useAuthStore } from "@features/auth/stores/authStore";
55
import { useAudioRecorder } from "@features/recordings/hooks/useAudioRecorder";
66
import { useRecordings } from "@features/recordings/hooks/useRecordings";
7+
import { useTasks } from "@features/tasks/hooks/useTasks";
8+
import { useTaskStore } from "@features/tasks/stores/taskStore";
79
import { ArrowsInSimpleIcon, ArrowsOutSimpleIcon } from "@phosphor-icons/react";
810
import { Box, Flex, IconButton, Tooltip } from "@radix-ui/themes";
911
import type { Task } from "@shared/types";
@@ -21,6 +23,9 @@ export const SidebarContent: React.FC = () => {
2123
const { setCliMode } = useLayoutStore();
2224
const { saveRecording } = useRecordings();
2325
const { startRecording, stopRecording } = useAudioRecorder(saveRecording);
26+
const { isLoading } = useTasks();
27+
const activeFilters = useTaskStore((state) => state.activeFilters);
28+
const setActiveFilters = useTaskStore((state) => state.setActiveFilters);
2429
const [userName, setUserName] = useState<string>("Loading...");
2530
const [hoveredLineIndex, setHoveredLineIndex] = useState<number | null>(null);
2631

@@ -89,14 +94,24 @@ export const SidebarContent: React.FC = () => {
8994
setCliMode("task");
9095
};
9196

97+
const handleProjectClick = (repository: string) => {
98+
const newActiveFilters = { ...activeFilters };
99+
newActiveFilters.repository = [{ value: repository, operator: "is" }];
100+
setActiveFilters(newActiveFilters);
101+
handleNavigate("task-list", "Tasks");
102+
};
103+
92104
const menuData = useSidebarMenuData({
93105
userName,
94106
activeTab,
107+
isLoading,
108+
activeFilters,
95109
onNavigate: handleNavigate,
96110
onTaskClick: handleTaskClick,
97111
onCreateTask: handleCreateTask,
98112
onStartRecording: handleStartRecording,
99113
onStopRecording: handleStopRecording,
114+
onProjectClick: handleProjectClick,
100115
});
101116

102117
const treeLines = buildTreeLines([menuData], "", "", expandedNodes, 0);

src/renderer/components/ui/sidebar/UseSidebarMenuData.tsx

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { TreeNode } from "@components/ui/sidebar/Types";
22
import { useTasks } from "@features/tasks/hooks/useTasks";
3+
import type { ActiveFilters } from "@features/tasks/stores/taskStore";
34
import {
45
CheckCircleIcon,
56
CircleIcon,
@@ -16,6 +17,8 @@ import type { TabState, Task } from "@shared/types";
1617
interface UseSidebarMenuDataProps {
1718
userName: string;
1819
activeTab: TabState | undefined;
20+
isLoading: boolean;
21+
activeFilters: ActiveFilters;
1922
onNavigate: (
2023
type: "task-list" | "recordings" | "notetaker" | "settings",
2124
title: string,
@@ -24,6 +27,7 @@ interface UseSidebarMenuDataProps {
2427
onCreateTask: () => void;
2528
onStartRecording: () => void;
2629
onStopRecording: () => void;
30+
onProjectClick: (repository: string) => void;
2731
}
2832

2933
function getStatusIcon(status?: string) {
@@ -52,9 +56,12 @@ function getStatusIcon(status?: string) {
5256
export function useSidebarMenuData({
5357
userName,
5458
activeTab,
59+
isLoading,
60+
activeFilters,
5561
onNavigate,
5662
onTaskClick,
5763
onCreateTask,
64+
onProjectClick,
5865
}: UseSidebarMenuDataProps): TreeNode {
5966
const { data: allTasks = [] } = useTasks();
6067
const relevantTasks = allTasks
@@ -64,6 +71,24 @@ export function useSidebarMenuData({
6471
)
6572
.slice(0, 10);
6673

74+
const repositoryMap = new Map<string, { fullPath: string; name: string }>();
75+
for (const task of allTasks) {
76+
const { organization, repository } = task.repository_config || {};
77+
if (organization && repository) {
78+
const fullPath = `${organization}/${repository}`;
79+
repositoryMap.set(fullPath, { fullPath, name: repository });
80+
}
81+
}
82+
83+
const repositories = Array.from(repositoryMap.values()).sort((a, b) =>
84+
a.name.localeCompare(b.name),
85+
);
86+
const activeRepositoryFilters = activeFilters.repository || [];
87+
const activeRepositoryValue =
88+
activeRepositoryFilters.length === 1
89+
? activeRepositoryFilters[0].value
90+
: null;
91+
6792
return {
6893
label: userName,
6994
children: [
@@ -138,11 +163,17 @@ export function useSidebarMenuData({
138163
{
139164
label: "Projects",
140165
icon: <FolderIcon size={12} />,
141-
children: [
142-
{ label: "Array" },
143-
{ label: "posthog" },
144-
{ label: "agent" },
145-
],
166+
children: isLoading
167+
? [{ label: "Loading..." }]
168+
: repositories.length > 0
169+
? repositories.map(
170+
(repo): TreeNode => ({
171+
label: repo.name,
172+
action: () => onProjectClick(repo.fullPath),
173+
isActive: activeRepositoryValue === repo.fullPath,
174+
}),
175+
)
176+
: [{ label: "No projects found" }],
146177
},
147178
],
148179
};

0 commit comments

Comments
 (0)