feat: enhance folder navigation and team section UI

- Implemented synthetic group creation for new folders in `DashboardView`, allowing navigation to projects without existing sessions.
- Added `headerExtra` prop to `CollapsibleTeamSection` for inline elements, improving UI flexibility.
- Updated `TeamDetailView` to include a notification button for the `claude-notifications-go` plugin, enhancing user experience with desktop notifications.
This commit is contained in:
iliya 2026-02-24 16:10:15 +02:00 committed by Илия
parent a30f8ab879
commit 33b41ef5d5
3 changed files with 53 additions and 5 deletions

View file

@ -315,11 +315,35 @@ const NewProjectCard = (): React.JSX.Element => {
return;
}
// Still no match — open the folder in file manager as fallback
const result = await api.openPath(selectedPath, undefined, true);
if (!result.success) {
logger.error('Failed to open folder:', result.error);
}
// Still no match — create a synthetic group for this new folder and navigate to it.
// This allows launching teams in projects that don't have Claude sessions yet.
const encodedId = selectedPath.replace(/[/\\]/g, '-');
const folderName = selectedPath.split('/').filter(Boolean).pop() ?? selectedPath;
const now = Date.now();
const syntheticGroup: RepositoryGroup = {
id: encodedId,
identity: null,
worktrees: [
{
id: encodedId,
path: selectedPath,
name: folderName,
isMainWorktree: true,
source: 'unknown',
sessions: [],
createdAt: now,
},
],
name: folderName,
mostRecentSession: undefined,
totalSessions: 0,
};
useStore.setState((state) => ({
repositoryGroups: [syntheticGroup, ...state.repositoryGroups],
}));
navigateToMatch({ repoId: encodedId, worktreeId: encodedId });
} catch (error) {
logger.error('Error selecting folder:', error);
}

View file

@ -8,6 +8,8 @@ interface CollapsibleTeamSectionProps {
badge?: string | number;
/** Secondary badge (e.g. unread count). Shown next to main badge when defined. */
secondaryBadge?: number;
/** Extra element rendered inline after badges (e.g. notification icon). */
headerExtra?: React.ReactNode;
defaultOpen?: boolean;
forceOpen?: boolean;
action?: React.ReactNode;
@ -18,6 +20,7 @@ export const CollapsibleTeamSection = ({
title,
badge,
secondaryBadge,
headerExtra,
defaultOpen = true,
forceOpen,
action,
@ -58,6 +61,7 @@ export const CollapsibleTeamSection = ({
{secondaryBadge} new
</Badge>
)}
{headerExtra}
</div>
{action && <div className="relative z-10 flex shrink-0 items-center">{action}</div>}
</div>

View file

@ -18,6 +18,7 @@ import { useStore } from '@renderer/store';
import { buildTaskCountsByOwner } from '@renderer/utils/pathNormalize';
import { toMessageKey } from '@renderer/utils/teamMessageKey';
import {
Bell,
CheckCheck,
GitBranch,
Pencil,
@ -832,6 +833,25 @@ export const TeamDetailView = ({ teamName }: TeamDetailViewProps): React.JSX.Ele
secondaryBadge={
filteredMessages.length > 0 && messagesUnreadCount > 0 ? messagesUnreadCount : undefined
}
headerExtra={
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
className="pointer-events-auto rounded p-0.5 text-[var(--color-text-muted)] transition-colors hover:text-[var(--color-text-secondary)]"
onClick={(e) => {
e.stopPropagation();
void window.electronAPI.openExternal(
'https://github.com/777genius/claude-notifications-go'
);
}}
>
<Bell size={12} />
</button>
</TooltipTrigger>
<TooltipContent side="top">Desktop notifications plugin</TooltipContent>
</Tooltip>
}
defaultOpen
action={
<div className="flex items-center gap-2 pl-2">