diff --git a/src/renderer/src/components/Sidebar.tsx b/src/renderer/src/components/Sidebar.tsx index c119b3f..e964a85 100644 --- a/src/renderer/src/components/Sidebar.tsx +++ b/src/renderer/src/components/Sidebar.tsx @@ -212,15 +212,14 @@ function Sidebar({ apps, userName, userEmail, userRole, userCreatedAt, userLastL {collapsed &&
} {/* 네비게이션 아이템 */} - {apps.map((item) => { - const unavailable = item.canLaunch === false || item.canView === false + {apps.filter((item) => item.canView !== false).map((item) => { + const unavailable = item.canLaunch === false return (
{ - if (unavailable) return onAppChange(item.appKey) }} title={collapsed ? item.displayName : undefined} diff --git a/src/renderer/src/pages/Dashboard.tsx b/src/renderer/src/pages/Dashboard.tsx index c9bc018..dfb452e 100644 --- a/src/renderer/src/pages/Dashboard.tsx +++ b/src/renderer/src/pages/Dashboard.tsx @@ -213,11 +213,11 @@ function Dashboard({ authSession, onSessionUpdate, onLogout }: DashboardProps): if (cancelled || !payload?.apps?.length) return setApps(payload.apps) const currentApp = payload.apps.find((app) => app.appKey === activeApp) - const currentAppAvailable = currentApp?.canLaunch !== false && currentApp?.canView !== false - const firstAvailableApp = payload.apps.find((app) => app.canView !== false && app.canLaunch !== false) + const currentAppAvailable = currentApp?.canView !== false + const firstAvailableApp = payload.apps.find((app) => app.canView !== false) const lastLaunchedAppKey = window.localStorage.getItem(LAST_LAUNCHED_APP_STORAGE_KEY) const lastLaunchedApp = lastLaunchedAppKey - ? payload.apps.find((app) => app.appKey === lastLaunchedAppKey && app.canView !== false && app.canLaunch !== false) + ? payload.apps.find((app) => app.appKey === lastLaunchedAppKey && app.canView !== false) : undefined if (!initialAppSelectionDoneRef.current) { @@ -286,8 +286,9 @@ function Dashboard({ authSession, onSessionUpdate, onLogout }: DashboardProps): installation = { installed: false, version: null, path: null } } - if (IS_DEV && appConfig.devAppPath && installation.installed) { + if (IS_DEV && appConfig.devAppPath) { if (!cancelled) { + setInstalledOverrides((prev) => prev[activeApp] === undefined ? prev : { ...prev, [activeApp]: true }) setAppStatus({ appKey: activeApp, displayName: appConfig.displayName, @@ -688,7 +689,6 @@ function Dashboard({ authSession, onSessionUpdate, onLogout }: DashboardProps): 공지사항
- {appNotices.length}건
{appNotices.map((n, i) => ( diff --git a/src/renderer/src/pages/LoginForm.tsx b/src/renderer/src/pages/LoginForm.tsx index 6a91cc8..efc7dd5 100644 --- a/src/renderer/src/pages/LoginForm.tsx +++ b/src/renderer/src/pages/LoginForm.tsx @@ -329,6 +329,31 @@ function LoginForm({ onLogin, onGoSignup, onGoPasswordReset, onLoadingChange }: } } + const retryTailscaleAndContinue = async (): Promise => { + if (!pendingTailscaleConfirm) return + const pending = pendingTailscaleConfirm + setTailscaleInstalling(true) + setError('') + + try { + await ensureLauncherTailscale(pending.email, pending.password) + setPendingTailscaleConfirm(null) + setLoading(true) + onLoadingChange(true) + await completeLogin(pending.session, pending.email, pending.keepLogin, Date.now()) + } catch (retryError) { + setPendingTailscaleConfirm({ + ...pending, + reason: retryError instanceof TailscaleInstallRequiredError ? 'install-required' : 'connection-failed', + message: retryError instanceof Error ? retryError.message : 'Tailscale 연결에 실패했습니다.', + }) + } finally { + setTailscaleInstalling(false) + setLoading(false) + onLoadingChange(false) + } + } + const installTailscaleAndContinue = async (): Promise => { if (!pendingTailscaleConfirm || !window.launcherTailscale?.install) return const pending = pendingTailscaleConfirm @@ -452,7 +477,7 @@ function LoginForm({ onLogin, onGoSignup, onGoPasswordReset, onLoadingChange }:

{pendingTailscaleConfirm.reason === 'install-required' ? 'Autonomy Studio는 플랫폼 연결을 위해 Tailscale을 사용합니다. 설치를 진행하려면 관리자 권한이 필요합니다.' - : '플랫폼 원격 제어 연결을 설정하지 못했습니다. 로그인은 계속 진행할 수 있지만, 원격 플랫폼 연결 기능은 제한될 수 있습니다.'} + : 'Tailscale은 설치되어 있지만 연결 정보를 가져오거나 서버에 접속하는 과정에서 실패했습니다. 잠시 후 다시 시도할 수 있습니다.'}

@@ -474,17 +499,18 @@ function LoginForm({ onLogin, onGoSignup, onGoPasswordReset, onLoadingChange }: type="button" onClick={() => void installTailscaleAndContinue()} className="h-9 cursor-pointer rounded-md border border-[#5588ff] bg-[#5588ff] px-4 text-[12px] font-bold text-white transition hover:bg-[#4778ea] disabled:cursor-default disabled:opacity-60" - disabled={tailscaleInstalling} + disabled={tailscaleInstalling || !window.launcherTailscale?.install} > {tailscaleInstalling ? '설치 중...' : '설치'} ) : ( )}