9d43abedde
## Backend - Delete `agents/auto_claude_tools.py` (compatibility shim) - Delete `implementation_plan/main.py` (compatibility shim) - Remove `--dev` flag and `dev_mode` parameter from: - cli/main.py, cli/utils.py, cli/spec_commands.py - runners/spec_runner.py - spec/pipeline/models.py, orchestrator.py - spec/complexity.py - Remove `ClaudeSimilarityDetector` class from batch_issues.py - Remove unused `self.detector` alias ## Frontend - Remove `PROJECT_UPDATE_AUTOBUILD` IPC channel - Remove `updateProjectAutoBuild` from: - project-handlers.ts (IPC handler) - project-api.ts (preload API) - project-store.ts (store function) - project-mock.ts (mock) - Remove deprecated `appendOutput`/`clearOutputBuffer` from terminal-store - Update useTerminalEvents to use terminalBufferManager directly - Remove deprecated "Update Auto Claude" dialog from Sidebar - Remove `handleUpdate` from useProjectSettings hook ## Tests - Remove `test_dev_mode_param_ignored` test
169 lines
4.8 KiB
TypeScript
169 lines
4.8 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
import { LinearTaskImportModal } from '../LinearTaskImportModal';
|
|
import { SettingsSection } from './SettingsSection';
|
|
import { useProjectSettings, UseProjectSettingsReturn } from '../project-settings/hooks/useProjectSettings';
|
|
import { loadTasks } from '../../stores/task-store';
|
|
import { EmptyProjectState } from './common/EmptyProjectState';
|
|
import { ErrorDisplay } from './common/ErrorDisplay';
|
|
import { SectionRouter } from './sections/SectionRouter';
|
|
import { createHookProxy } from './utils/hookProxyFactory';
|
|
import type { Project } from '../../../shared/types';
|
|
|
|
export type ProjectSettingsSection = 'general' | 'claude' | 'linear' | 'github' | 'memory';
|
|
|
|
interface ProjectSettingsContentProps {
|
|
project: Project | undefined;
|
|
activeSection: ProjectSettingsSection;
|
|
isOpen: boolean;
|
|
onHookReady: (hook: UseProjectSettingsReturn | null) => void;
|
|
}
|
|
|
|
/**
|
|
* Renders project settings content based on the active section.
|
|
* Exposes hook state to parent for save coordination.
|
|
*/
|
|
export function ProjectSettingsContent({
|
|
project,
|
|
activeSection,
|
|
isOpen,
|
|
onHookReady
|
|
}: ProjectSettingsContentProps) {
|
|
// Show empty state if no project selected
|
|
if (!project) {
|
|
return (
|
|
<SettingsSection
|
|
title="No Project Selected"
|
|
description="Select a project from the dropdown above to configure its settings"
|
|
>
|
|
<EmptyProjectState />
|
|
</SettingsSection>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<ProjectSettingsContentInner
|
|
project={project}
|
|
activeSection={activeSection}
|
|
isOpen={isOpen}
|
|
onHookReady={onHookReady}
|
|
/>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Inner component that uses the project settings hook.
|
|
* Separated to ensure the hook is only called when a project is selected.
|
|
*/
|
|
function ProjectSettingsContentInner({
|
|
project,
|
|
activeSection,
|
|
isOpen,
|
|
onHookReady
|
|
}: {
|
|
project: Project;
|
|
activeSection: ProjectSettingsSection;
|
|
isOpen: boolean;
|
|
onHookReady: (hook: UseProjectSettingsReturn | null) => void;
|
|
}) {
|
|
const hook = useProjectSettings(project, isOpen);
|
|
|
|
// Keep a stable ref to the hook for the parent
|
|
const hookRef = useRef(hook);
|
|
hookRef.current = hook;
|
|
|
|
const {
|
|
settings,
|
|
setSettings,
|
|
versionInfo,
|
|
isCheckingVersion,
|
|
isUpdating,
|
|
envConfig,
|
|
isLoadingEnv,
|
|
envError,
|
|
updateEnvConfig,
|
|
showClaudeToken,
|
|
setShowClaudeToken,
|
|
showLinearKey,
|
|
setShowLinearKey,
|
|
showOpenAIKey,
|
|
setShowOpenAIKey,
|
|
showGitHubToken,
|
|
setShowGitHubToken,
|
|
expandedSections: _expandedSections,
|
|
toggleSection: _toggleSection,
|
|
gitHubConnectionStatus,
|
|
isCheckingGitHub,
|
|
isCheckingClaudeAuth,
|
|
claudeAuthStatus,
|
|
showLinearImportModal,
|
|
setShowLinearImportModal,
|
|
linearConnectionStatus,
|
|
isCheckingLinear,
|
|
handleInitialize,
|
|
handleClaudeSetup,
|
|
error
|
|
} = hook;
|
|
|
|
// Expose hook to parent for save coordination - only once when dialog opens
|
|
// We use hookRef to avoid infinite loops (hook object is recreated each render)
|
|
useEffect(() => {
|
|
if (isOpen) {
|
|
const hookProxy = createHookProxy(hookRef);
|
|
onHookReady(hookProxy);
|
|
}
|
|
return () => {
|
|
onHookReady(null);
|
|
};
|
|
}, [isOpen, onHookReady]);
|
|
|
|
return (
|
|
<>
|
|
<SectionRouter
|
|
activeSection={activeSection}
|
|
project={project}
|
|
settings={settings}
|
|
setSettings={setSettings}
|
|
versionInfo={versionInfo}
|
|
isCheckingVersion={isCheckingVersion}
|
|
isUpdating={isUpdating}
|
|
envConfig={envConfig}
|
|
isLoadingEnv={isLoadingEnv}
|
|
envError={envError}
|
|
updateEnvConfig={updateEnvConfig}
|
|
showClaudeToken={showClaudeToken}
|
|
setShowClaudeToken={setShowClaudeToken}
|
|
showLinearKey={showLinearKey}
|
|
setShowLinearKey={setShowLinearKey}
|
|
showOpenAIKey={showOpenAIKey}
|
|
setShowOpenAIKey={setShowOpenAIKey}
|
|
showGitHubToken={showGitHubToken}
|
|
setShowGitHubToken={setShowGitHubToken}
|
|
gitHubConnectionStatus={gitHubConnectionStatus}
|
|
isCheckingGitHub={isCheckingGitHub}
|
|
isCheckingClaudeAuth={isCheckingClaudeAuth}
|
|
claudeAuthStatus={claudeAuthStatus}
|
|
linearConnectionStatus={linearConnectionStatus}
|
|
isCheckingLinear={isCheckingLinear}
|
|
handleInitialize={handleInitialize}
|
|
handleClaudeSetup={handleClaudeSetup}
|
|
onOpenLinearImport={() => setShowLinearImportModal(true)}
|
|
/>
|
|
|
|
<ErrorDisplay error={error} envError={envError} />
|
|
|
|
{/* Linear Task Import Modal */}
|
|
<LinearTaskImportModal
|
|
projectId={project.id}
|
|
open={showLinearImportModal}
|
|
onOpenChange={setShowLinearImportModal}
|
|
onImportComplete={async (result) => {
|
|
// Refresh task list to show imported tasks (even on partial success)
|
|
if (result.imported > 0) {
|
|
await loadTasks(project.id);
|
|
}
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
}
|