From aeb5bd829f072f413dd8683ac2656e18b3164a6c Mon Sep 17 00:00:00 2001 From: Kacper Date: Sat, 10 Jan 2026 23:03:29 +0100 Subject: [PATCH] feat: Add Init Script Indicator visibility feature for worktrees This commit introduces a new feature allowing users to toggle the visibility of the Init Script Indicator for each project. Key changes include: 1. **State Management**: Added `showInitScriptIndicatorByProject` to manage the visibility state per project. 2. **UI Components**: Implemented a checkbox in the WorktreesSection to enable or disable the Init Script Indicator, enhancing user control over the UI. 3. **BoardView Updates**: Modified the BoardView to conditionally render the Init Script Indicator based on the new visibility state. These enhancements improve the user experience by providing customizable visibility options for the Init Script Indicator, streamlining project management workflows. --- apps/ui/src/components/views/board-view.tsx | 9 +++- .../worktrees/worktrees-section.tsx | 47 ++++++++++++++++++- apps/ui/src/store/app-store.ts | 24 ++++++++++ libs/types/src/settings.ts | 2 + 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/apps/ui/src/components/views/board-view.tsx b/apps/ui/src/components/views/board-view.tsx index b4c050f6..028f7bd1 100644 --- a/apps/ui/src/components/views/board-view.tsx +++ b/apps/ui/src/components/views/board-view.tsx @@ -114,6 +114,11 @@ export function BoardView() { const pipelineConfigByProject = useAppStore((state) => state.pipelineConfigByProject); // Subscribe to worktreePanelVisibleByProject to trigger re-renders when it changes const worktreePanelVisibleByProject = useAppStore((state) => state.worktreePanelVisibleByProject); + // Subscribe to showInitScriptIndicatorByProject to trigger re-renders when it changes + const showInitScriptIndicatorByProject = useAppStore( + (state) => state.showInitScriptIndicatorByProject + ); + const getShowInitScriptIndicator = useAppStore((state) => state.getShowInitScriptIndicator); const shortcuts = useKeyboardShortcutsConfig(); const { features: hookFeatures, @@ -1577,7 +1582,9 @@ export function BoardView() { /> {/* Init Script Indicator - floating overlay for worktree init script status */} - + {getShowInitScriptIndicator(currentProject.path) && ( + + )} ); } diff --git a/apps/ui/src/components/views/settings-view/worktrees/worktrees-section.tsx b/apps/ui/src/components/views/settings-view/worktrees/worktrees-section.tsx index 8a615c58..01ff77c6 100644 --- a/apps/ui/src/components/views/settings-view/worktrees/worktrees-section.tsx +++ b/apps/ui/src/components/views/settings-view/worktrees/worktrees-section.tsx @@ -3,7 +3,16 @@ import { Label } from '@/components/ui/label'; import { Checkbox } from '@/components/ui/checkbox'; import { Button } from '@/components/ui/button'; import { ShellSyntaxEditor } from '@/components/ui/shell-syntax-editor'; -import { GitBranch, Terminal, FileCode, Save, RotateCcw, Trash2, Loader2 } from 'lucide-react'; +import { + GitBranch, + Terminal, + FileCode, + Save, + RotateCcw, + Trash2, + Loader2, + PanelBottomClose, +} from 'lucide-react'; import { cn } from '@/lib/utils'; import { apiPost, apiPut, apiDelete } from '@/lib/api-fetch'; import { toast } from 'sonner'; @@ -24,6 +33,8 @@ interface InitScriptResponse { export function WorktreesSection({ useWorktrees, onUseWorktreesChange }: WorktreesSectionProps) { const currentProject = useAppStore((s) => s.currentProject); + const getShowInitScriptIndicator = useAppStore((s) => s.getShowInitScriptIndicator); + const setShowInitScriptIndicator = useAppStore((s) => s.setShowInitScriptIndicator); const [scriptContent, setScriptContent] = useState(''); const [originalContent, setOriginalContent] = useState(''); const [scriptExists, setScriptExists] = useState(false); @@ -31,6 +42,11 @@ export function WorktreesSection({ useWorktrees, onUseWorktreesChange }: Worktre const [isSaving, setIsSaving] = useState(false); const [isDeleting, setIsDeleting] = useState(false); + // Get the current show indicator setting + const showIndicator = currentProject?.path + ? getShowInitScriptIndicator(currentProject.path) + : true; + // Check if there are unsaved changes const hasChanges = scriptContent !== originalContent; @@ -181,6 +197,35 @@ export function WorktreesSection({ useWorktrees, onUseWorktreesChange }: Worktre + {/* Show Init Script Indicator Toggle */} + {currentProject && ( +
+ { + if (currentProject?.path) { + setShowInitScriptIndicator(currentProject.path, checked === true); + } + }} + className="mt-1" + /> +
+ +

+ Display a floating panel in the bottom-right corner showing init script execution + status and output when a worktree is created. +

+
+
+ )} + {/* Separator */}
diff --git a/apps/ui/src/store/app-store.ts b/apps/ui/src/store/app-store.ts index 5479c015..974ffe87 100644 --- a/apps/ui/src/store/app-store.ts +++ b/apps/ui/src/store/app-store.ts @@ -665,6 +665,10 @@ export interface AppState { // Whether the worktree panel row is visible (default: true) worktreePanelVisibleByProject: Record; + // Init Script Indicator Visibility (per-project, keyed by project path) + // Whether to show the floating init script indicator panel (default: true) + showInitScriptIndicatorByProject: Record; + // UI State (previously in localStorage, now synced via API) /** Whether worktree panel is collapsed in board view */ worktreePanelCollapsed: boolean; @@ -1078,6 +1082,10 @@ export interface AppActions { setWorktreePanelVisible: (projectPath: string, visible: boolean) => void; getWorktreePanelVisible: (projectPath: string) => boolean; + // Init Script Indicator Visibility actions (per-project) + setShowInitScriptIndicator: (projectPath: string, visible: boolean) => void; + getShowInitScriptIndicator: (projectPath: string) => boolean; + // UI State actions (previously in localStorage, now synced via API) setWorktreePanelCollapsed: (collapsed: boolean) => void; setLastProjectDir: (dir: string) => void; @@ -1208,6 +1216,7 @@ const initialState: AppState = { codexModelsLastFetched: null, pipelineConfigByProject: {}, worktreePanelVisibleByProject: {}, + showInitScriptIndicatorByProject: {}, // UI State (previously in localStorage, now synced via API) worktreePanelCollapsed: false, lastProjectDir: '', @@ -3124,6 +3133,21 @@ export const useAppStore = create()((set, get) => ({ return get().worktreePanelVisibleByProject[projectPath] ?? true; }, + // Init Script Indicator Visibility actions (per-project) + setShowInitScriptIndicator: (projectPath, visible) => { + set({ + showInitScriptIndicatorByProject: { + ...get().showInitScriptIndicatorByProject, + [projectPath]: visible, + }, + }); + }, + + getShowInitScriptIndicator: (projectPath) => { + // Default to true (visible) if not set + return get().showInitScriptIndicatorByProject[projectPath] ?? true; + }, + // UI State actions (previously in localStorage, now synced via API) setWorktreePanelCollapsed: (collapsed) => set({ worktreePanelCollapsed: collapsed }), setLastProjectDir: (dir) => set({ lastProjectDir: dir }), diff --git a/libs/types/src/settings.ts b/libs/types/src/settings.ts index 07b4290d..7a46d4aa 100644 --- a/libs/types/src/settings.ts +++ b/libs/types/src/settings.ts @@ -595,6 +595,8 @@ export interface ProjectSettings { // UI Visibility /** Whether the worktree panel row is visible (default: true) */ worktreePanelVisible?: boolean; + /** Whether to show the init script indicator panel (default: true) */ + showInitScriptIndicator?: boolean; // Session Tracking /** Last chat session selected in this project */