mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-05-31 17:35:30 +08:00
fix: remove project dependency from settings controller and onboarding
This commit is contained in:
@@ -11,7 +11,6 @@ import {
|
|||||||
createInitialProviderStatuses,
|
createInitialProviderStatuses,
|
||||||
gitEmailPattern,
|
gitEmailPattern,
|
||||||
readErrorMessageFromResponse,
|
readErrorMessageFromResponse,
|
||||||
selectedProject,
|
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
type OnboardingProps = {
|
type OnboardingProps = {
|
||||||
@@ -279,7 +278,6 @@ export default function Onboarding({ onComplete }: OnboardingProps) {
|
|||||||
isOpen={Boolean(activeLoginProvider)}
|
isOpen={Boolean(activeLoginProvider)}
|
||||||
onClose={() => setActiveLoginProvider(null)}
|
onClose={() => setActiveLoginProvider(null)}
|
||||||
provider={activeLoginProvider}
|
provider={activeLoginProvider}
|
||||||
project={selectedProject}
|
|
||||||
onComplete={handleLoginComplete}
|
onComplete={handleLoginComplete}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,17 +1,9 @@
|
|||||||
import { IS_PLATFORM } from '../../../constants/config';
|
|
||||||
import type { CliProvider, ProviderStatusMap } from './types';
|
import type { CliProvider, ProviderStatusMap } from './types';
|
||||||
|
|
||||||
export const cliProviders: CliProvider[] = ['claude', 'cursor', 'codex', 'gemini'];
|
export const cliProviders: CliProvider[] = ['claude', 'cursor', 'codex', 'gemini'];
|
||||||
|
|
||||||
export const gitEmailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
export const gitEmailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||||
|
|
||||||
export const selectedProject = {
|
|
||||||
name: 'default',
|
|
||||||
displayName: 'default',
|
|
||||||
fullPath: IS_PLATFORM ? '/workspace' : '',
|
|
||||||
path: IS_PLATFORM ? '/workspace' : '',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createInitialProviderStatuses = (): ProviderStatusMap => ({
|
export const createInitialProviderStatuses = (): ProviderStatusMap => ({
|
||||||
claude: { authenticated: false, email: null, loading: true, error: null },
|
claude: { authenticated: false, email: null, loading: true, error: null },
|
||||||
cursor: { authenticated: false, email: null, loading: true, error: null },
|
cursor: { authenticated: false, email: null, loading: true, error: null },
|
||||||
|
|||||||
@@ -1,21 +1,12 @@
|
|||||||
import { ExternalLink, KeyRound, X } from 'lucide-react';
|
import { ExternalLink, KeyRound, X } from 'lucide-react';
|
||||||
import StandaloneShell from '../../standalone-shell/view/StandaloneShell';
|
import StandaloneShell from '../../standalone-shell/view/StandaloneShell';
|
||||||
import { IS_PLATFORM } from '../../../constants/config';
|
import { DEFAULT_PROJECT_FOR_EMPTY_SHELL, IS_PLATFORM } from '../../../constants/config';
|
||||||
import type { CliProvider } from '../types';
|
import type { CliProvider } from '../types';
|
||||||
|
|
||||||
type LoginModalProject = {
|
|
||||||
name?: string;
|
|
||||||
displayName?: string;
|
|
||||||
fullPath?: string;
|
|
||||||
path?: string;
|
|
||||||
[key: string]: unknown;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ProviderLoginModalProps = {
|
type ProviderLoginModalProps = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
provider?: CliProvider;
|
provider?: CliProvider;
|
||||||
project?: LoginModalProject | null;
|
|
||||||
onComplete?: (exitCode: number) => void;
|
onComplete?: (exitCode: number) => void;
|
||||||
customCommand?: string;
|
customCommand?: string;
|
||||||
isAuthenticated?: boolean;
|
isAuthenticated?: boolean;
|
||||||
@@ -56,23 +47,10 @@ const getProviderTitle = (provider: CliProvider) => {
|
|||||||
return 'Gemini CLI Configuration';
|
return 'Gemini CLI Configuration';
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizeProject = (project?: LoginModalProject | null) => {
|
|
||||||
const normalizedName = project?.name || 'default';
|
|
||||||
const normalizedFullPath = project?.fullPath ?? project?.path ?? (IS_PLATFORM ? '/workspace' : '');
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: normalizedName,
|
|
||||||
displayName: project?.displayName || normalizedName,
|
|
||||||
fullPath: normalizedFullPath,
|
|
||||||
path: project?.path ?? normalizedFullPath,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function ProviderLoginModal({
|
export default function ProviderLoginModal({
|
||||||
isOpen,
|
isOpen,
|
||||||
onClose,
|
onClose,
|
||||||
provider = 'claude',
|
provider = 'claude',
|
||||||
project = null,
|
|
||||||
onComplete,
|
onComplete,
|
||||||
customCommand,
|
customCommand,
|
||||||
isAuthenticated = false,
|
isAuthenticated = false,
|
||||||
@@ -83,7 +61,6 @@ export default function ProviderLoginModal({
|
|||||||
|
|
||||||
const command = getProviderCommand({ provider, customCommand, isAuthenticated });
|
const command = getProviderCommand({ provider, customCommand, isAuthenticated });
|
||||||
const title = getProviderTitle(provider);
|
const title = getProviderTitle(provider);
|
||||||
const shellProject = normalizeProject(project);
|
|
||||||
|
|
||||||
const handleComplete = (exitCode: number) => {
|
const handleComplete = (exitCode: number) => {
|
||||||
onComplete?.(exitCode);
|
onComplete?.(exitCode);
|
||||||
@@ -158,7 +135,7 @@ export default function ProviderLoginModal({
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<StandaloneShell project={shellProject} command={command} onComplete={handleComplete} minimal={true} />
|
<StandaloneShell project={DEFAULT_PROJECT_FOR_EMPTY_SHELL} command={command} onComplete={handleComplete} minimal={true} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import type {
|
|||||||
NotificationPreferencesState,
|
NotificationPreferencesState,
|
||||||
ProjectSortOrder,
|
ProjectSortOrder,
|
||||||
SettingsMainTab,
|
SettingsMainTab,
|
||||||
SettingsProject,
|
|
||||||
} from '../types/types';
|
} from '../types/types';
|
||||||
|
|
||||||
type ThemeContextValue = {
|
type ThemeContextValue = {
|
||||||
@@ -34,7 +33,6 @@ type ThemeContextValue = {
|
|||||||
type UseSettingsControllerArgs = {
|
type UseSettingsControllerArgs = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
initialTab: string;
|
initialTab: string;
|
||||||
projects: SettingsProject[];
|
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -166,20 +164,6 @@ const mapCliServersToMcpServers = (servers: McpCliServer[] = []): McpServer[] =>
|
|||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
const getDefaultProject = (projects: SettingsProject[]): SettingsProject => {
|
|
||||||
if (projects.length > 0) {
|
|
||||||
return projects[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
const cwd = typeof process !== 'undefined' && process.cwd ? process.cwd() : '';
|
|
||||||
return {
|
|
||||||
name: 'default',
|
|
||||||
displayName: 'default',
|
|
||||||
fullPath: cwd,
|
|
||||||
path: cwd,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const toResponseJson = async <T>(response: Response): Promise<T> => response.json() as Promise<T>;
|
const toResponseJson = async <T>(response: Response): Promise<T> => response.json() as Promise<T>;
|
||||||
|
|
||||||
const createEmptyClaudePermissions = (): ClaudePermissionsState => ({
|
const createEmptyClaudePermissions = (): ClaudePermissionsState => ({
|
||||||
@@ -204,7 +188,7 @@ const createDefaultNotificationPreferences = (): NotificationPreferencesState =>
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export function useSettingsController({ isOpen, initialTab, projects, onClose }: UseSettingsControllerArgs) {
|
export function useSettingsController({ isOpen, initialTab }: UseSettingsControllerArgs) {
|
||||||
const { isDarkMode, toggleDarkMode } = useTheme() as ThemeContextValue;
|
const { isDarkMode, toggleDarkMode } = useTheme() as ThemeContextValue;
|
||||||
const closeTimerRef = useRef<number | null>(null);
|
const closeTimerRef = useRef<number | null>(null);
|
||||||
|
|
||||||
@@ -242,7 +226,6 @@ export function useSettingsController({ isOpen, initialTab, projects, onClose }:
|
|||||||
|
|
||||||
const [showLoginModal, setShowLoginModal] = useState(false);
|
const [showLoginModal, setShowLoginModal] = useState(false);
|
||||||
const [loginProvider, setLoginProvider] = useState<ActiveLoginProvider>('');
|
const [loginProvider, setLoginProvider] = useState<ActiveLoginProvider>('');
|
||||||
const [selectedProject, setSelectedProject] = useState<SettingsProject | null>(null);
|
|
||||||
|
|
||||||
const [claudeAuthStatus, setClaudeAuthStatus] = useState<AuthStatus>(DEFAULT_AUTH_STATUS);
|
const [claudeAuthStatus, setClaudeAuthStatus] = useState<AuthStatus>(DEFAULT_AUTH_STATUS);
|
||||||
const [cursorAuthStatus, setCursorAuthStatus] = useState<AuthStatus>(DEFAULT_AUTH_STATUS);
|
const [cursorAuthStatus, setCursorAuthStatus] = useState<AuthStatus>(DEFAULT_AUTH_STATUS);
|
||||||
@@ -724,9 +707,8 @@ export function useSettingsController({ isOpen, initialTab, projects, onClose }:
|
|||||||
|
|
||||||
const openLoginForProvider = useCallback((provider: AgentProvider) => {
|
const openLoginForProvider = useCallback((provider: AgentProvider) => {
|
||||||
setLoginProvider(provider);
|
setLoginProvider(provider);
|
||||||
setSelectedProject(getDefaultProject(projects));
|
|
||||||
setShowLoginModal(true);
|
setShowLoginModal(true);
|
||||||
}, [projects]);
|
}, []);
|
||||||
|
|
||||||
const handleLoginComplete = useCallback((exitCode: number) => {
|
const handleLoginComplete = useCallback((exitCode: number) => {
|
||||||
if (exitCode !== 0 || !loginProvider) {
|
if (exitCode !== 0 || !loginProvider) {
|
||||||
@@ -945,7 +927,6 @@ export function useSettingsController({ isOpen, initialTab, projects, onClose }:
|
|||||||
showLoginModal,
|
showLoginModal,
|
||||||
setShowLoginModal,
|
setShowLoginModal,
|
||||||
loginProvider,
|
loginProvider,
|
||||||
selectedProject,
|
|
||||||
handleLoginComplete,
|
handleLoginComplete,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,12 +66,10 @@ function Settings({ isOpen, onClose, projects = [], initialTab = 'agents' }: Set
|
|||||||
showLoginModal,
|
showLoginModal,
|
||||||
setShowLoginModal,
|
setShowLoginModal,
|
||||||
loginProvider,
|
loginProvider,
|
||||||
selectedProject,
|
|
||||||
handleLoginComplete,
|
handleLoginComplete,
|
||||||
} = useSettingsController({
|
} = useSettingsController({
|
||||||
isOpen,
|
isOpen,
|
||||||
initialTab,
|
initialTab,
|
||||||
projects,
|
|
||||||
onClose,
|
onClose,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -219,7 +217,6 @@ function Settings({ isOpen, onClose, projects = [], initialTab = 'agents' }: Set
|
|||||||
isOpen={showLoginModal}
|
isOpen={showLoginModal}
|
||||||
onClose={() => setShowLoginModal(false)}
|
onClose={() => setShowLoginModal(false)}
|
||||||
provider={loginProvider || 'claude'}
|
provider={loginProvider || 'claude'}
|
||||||
project={selectedProject}
|
|
||||||
onComplete={handleLoginComplete}
|
onComplete={handleLoginComplete}
|
||||||
isAuthenticated={isAuthenticated}
|
isAuthenticated={isAuthenticated}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -3,3 +3,15 @@
|
|||||||
* Indicates if the app is running in Platform mode (hosted) or OSS mode (self-hosted)
|
* Indicates if the app is running in Platform mode (hosted) or OSS mode (self-hosted)
|
||||||
*/
|
*/
|
||||||
export const IS_PLATFORM = import.meta.env.VITE_IS_PLATFORM === 'true';
|
export const IS_PLATFORM = import.meta.env.VITE_IS_PLATFORM === 'true';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For empty shell instances where no project is provided,
|
||||||
|
* we use a default project object to ensure the shell can still function.
|
||||||
|
* This prevents errors related to missing project data.
|
||||||
|
*/
|
||||||
|
export const DEFAULT_PROJECT_FOR_EMPTY_SHELL = {
|
||||||
|
name: 'default',
|
||||||
|
displayName: 'default',
|
||||||
|
fullPath: IS_PLATFORM ? '/workspace' : '',
|
||||||
|
path: IS_PLATFORM ? '/workspace' : '',
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user