diff --git a/src/App.tsx b/src/App.tsx index 4ad3c8f..e721b0c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -26,7 +26,7 @@ import { KernelPage } from './pages/Kernel'; import { VersionManagementPage } from './pages/VersionManagementPage'; import { OAuthManagementPage } from './pages/ManagementPages'; import { AgentsPage } from './pages/AgentsPage'; -import { EasyModePage, type EasyModeDestination } from './pages/EasyModePage'; +import { EasyModePage } from './pages/EasyModePage'; import { UsageRecordsPage } from './pages/UsageRecordsPage'; import { languageOptions, useI18n } from './i18n'; import { AppUpdateDialog, AppUpdateProvider, useAppUpdate } from './appUpdate'; @@ -228,10 +228,6 @@ function AppContent() { setActive(pageId); }; - const openPage = (pageId: EasyModeDestination) => { - setActive(pageId); - }; - const openContact = async () => { try { await invoke('open_external_url', { url: CONTACT_URL }); @@ -423,7 +419,7 @@ function AppContent() {
{isAlwaysAvailablePage(activePage.id) || coreRunning ? ( activePage.id === 'easy' ? ( - + ) : ( ) diff --git a/src/i18n/ja.ts b/src/i18n/ja.ts index ff7a018..15bf80e 100644 --- a/src/i18n/ja.ts +++ b/src/i18n/ja.ts @@ -35,57 +35,31 @@ export const jaOverrides = { 'app.close.exiting': '終了しています...', 'app.close.exit': 'アプリを終了', 'app.close.remember': 'この選択を記憶', - 'easyMode.eyebrow': 'クイックスタート', - 'easyMode.title': '3 ステップで最初のエージェントを接続', - 'easyMode.description': '認証方法を選び、接続を完了してから、モデルを普段使うエージェントクライアントに接続します。', - 'easyMode.reset': '最初からやり直す', 'easyMode.steps.label': '接続ウィザードの手順', - 'easyMode.step': 'ステップ {number}', - 'easyMode.step1.title': '認証方法を選択', - 'easyMode.step1.description': '既存のアカウントでログインするか、サードパーティ API キーを直接入力します。', - 'easyMode.step1.selectHint': 'まず方法を 1 つ選びます。選択後、対応する設定手順に進みます。', - 'easyMode.step1.selectFirst': '先に OAuth または API 接続を選択してください', - 'easyMode.step1.continue': '次へ:接続を完了', - 'easyMode.step1.hint': '迷ったら、公式アカウントを使い API キーを管理したくない場合は OAuth を選んでください。', - 'easyMode.step2.title': 'モデル接続を完了', - 'easyMode.step2.description': 'ログインまたは API 接続を完了し、保存して次へ進みます。', - 'easyMode.step2.openTitle': 'まず上の設定を完了してください', - 'easyMode.step2.returnHint': 'ボタンで設定ページを開きます。完了後、左側の「簡易モード」をクリックしてここに戻り、完了を確認してください。', - 'easyMode.step2.doneHint': '接続設定が終わったら次へ進みます', - 'easyMode.step2.complete': '接続完了、次へ', - 'easyMode.step2.next': '完了しました。エージェントを接続', - 'easyMode.selectedPath': '選択中の方法', - 'easyMode.changePath': '方法を変更', + 'easyMode.overview.coreTitle': '使い方', + 'easyMode.overview.providerTitle': 'モデルを接続', + 'easyMode.overview.agentTitle': 'エージェントを接続', + 'easyMode.provider.oauthFit': '公式アカウントとブラウザー認証向け', + 'easyMode.provider.apiFit': 'サードパーティプラットフォームの API 向け', 'easyMode.oauth.title': 'OAuth ログイン', 'easyMode.oauth.description': 'API キーを手動でコピーせず、ブラウザーで認証します。', - 'easyMode.oauth.step1': 'OAuth ページを開き、ログインするサービスを選びます。', - 'easyMode.oauth.step2': '「ログインを開始」をクリックし、ブラウザーで認証します。', - 'easyMode.oauth.step3': 'ソフトウェアに戻り、ログイン状態が完了したことを確認します。', - 'easyMode.oauth.action': 'OAuth ログインを開く', 'easyMode.api.title': 'API 接続', - 'easyMode.api.description': 'サードパーティまたはセルフホストサービスの Base URL と API キーを入力します。', - 'easyMode.api.step1': 'API 接続を開き、右上の「追加」をクリックします。', - 'easyMode.api.step2': '備考、Base URL、API キーを入力してモデルを取得します。', - 'easyMode.api.step3': '接続を保存し、少なくとも 1 つのモデルが利用可能なことを確認します。', - 'easyMode.api.action': 'API 接続を設定', - 'easyMode.step3.title': 'エージェントを接続', - 'easyMode.step3.description': '使用するクライアントを選び、モデル設定を適用して会話を始めます。', - 'easyMode.step3.ready': '準備完了', - 'easyMode.step3.cardTitle': 'CPA をローカルエージェントに接続', - 'easyMode.step3.cardDescription': 'エージェントページがインストール済みのクライアントを検出し、CPA の接続設定を書き込みます。', + 'easyMode.api.description': 'サードパーティプラットフォームから提供された Base URL と API キーを入力します。', + 'easyMode.step3.cardTitle': 'CPA をエージェントクライアントに接続', + 'easyMode.step3.cardDescription': 'インストール済みのクライアントとモデルを選び、CPA の接続設定を書き込みます。', 'easyMode.step3.step1': 'エージェント設定を開き、インストール済みのクライアントを選びます。', - 'easyMode.step3.step2': 'モデルを選びます。Codex では OAuth 設定も利用できます。', + 'easyMode.step3.step2': '利用するモデルを選びます。', 'easyMode.step3.step3': '「設定変更を適用」をクリックし、CLI またはアプリを起動します。', - 'easyMode.step3.action': 'エージェント設定を開く', - 'easyMode.step3.back': '前の手順に戻る', - 'easyMode.step3.note': '設定後は対応する CLI またはアプリを起動して利用できます。', - 'easyMode.core.title': '先に CPA コアを起動', - 'easyMode.core.description': 'OAuth、API 接続、エージェント設定にはコアの実行が必要です。', - 'easyMode.core.action': 'コア制御を開く', - 'easyMode.core.ready': 'コア実行中', - 'easyMode.core.waiting': 'コアを待機中', - 'easyMode.core.blocked': '設定ページを開く前にコアを起動してください。', - 'easyMode.footer': '設定後は左側の機能メニューから詳細を管理できます。', + 'easyMode.guide.title': '使い方', + 'easyMode.guide.description': 'OAuth ログインまたは API 接続を選び、モデルを接続してから、利用可能なモデルをエージェントクライアントに適用します。', + 'easyMode.guide.step1Title': 'モデル接続方法を選ぶ', + 'easyMode.guide.step1Description': 'ログイン可能なアカウントがある場合は OAuth、サードパーティプラットフォームの Base URL と API キーがある場合は API 接続を利用できます。', + 'easyMode.guide.step2Title': 'モデルを接続', + 'easyMode.guide.step2Description': 'OAuth ではアカウント認証を行います。API 接続ではサードパーティプラットフォームの Base URL と API キーを入力します。保存後はエージェント設定へ進めます。', + 'easyMode.guide.step3Title': 'エージェントクライアントに接続', + 'easyMode.guide.step3Description': 'インストール済みのエージェントクライアントと利用可能なモデルを選び、設定を適用すると利用を開始できます。', + 'easyMode.navigation.back': '前へ', + 'easyMode.navigation.next': '次へ', 'error.render.title': 'ページの描画中にエラーが発生しました', 'error.unknown': '不明なエラー', 'error.reload': 'ページを再読み込み', diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index fcd0bbc..1e52680 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -35,57 +35,31 @@ export const en: Record = { 'app.close.exiting': 'Exiting...', 'app.close.exit': 'Exit App', 'app.close.remember': 'Remember this choice', - 'easyMode.eyebrow': 'Quick start', - 'easyMode.title': 'Connect your first agent in three steps', - 'easyMode.description': 'Choose an authentication method, finish the connection, then link a model to your favorite agent client.', - 'easyMode.reset': 'Start over', 'easyMode.steps.label': 'Connection wizard steps', - 'easyMode.step': 'Step {number}', - 'easyMode.step1.title': 'Choose authentication', - 'easyMode.step1.description': 'Sign in to an existing account, or enter a third-party API key directly.', - 'easyMode.step1.selectHint': 'Choose one method first. You will then enter the matching setup step.', - 'easyMode.step1.selectFirst': 'Choose OAuth or API Access first', - 'easyMode.step1.continue': 'Next: finish the connection', - 'easyMode.step1.hint': 'Not sure? Choose OAuth when you have an official account and do not want to manage an API key.', - 'easyMode.step2.title': 'Finish the model connection', - 'easyMode.step2.description': 'Complete the sign-in or add an API connection, then save it to continue.', - 'easyMode.step2.openTitle': 'Complete the setup above first', - 'easyMode.step2.returnHint': 'Open the setup page with the button. When finished, click “Easy Mode” in the left sidebar to return here and confirm completion.', - 'easyMode.step2.doneHint': 'Continue after the connection is configured', - 'easyMode.step2.complete': 'Connection complete, next step', - 'easyMode.step2.next': 'I am done, connect an agent', - 'easyMode.selectedPath': 'Selected method', - 'easyMode.changePath': 'Change method', + 'easyMode.overview.coreTitle': 'How to use', + 'easyMode.overview.providerTitle': 'Connect a model', + 'easyMode.overview.agentTitle': 'Connect an agent', + 'easyMode.provider.oauthFit': 'Best for official accounts and browser authorization', + 'easyMode.provider.apiFit': 'Best for APIs provided by third-party platforms', 'easyMode.oauth.title': 'OAuth Sign-In', 'easyMode.oauth.description': 'Authorize in your browser without copying an API key manually.', - 'easyMode.oauth.step1': 'Open OAuth and choose the service you want to sign in to.', - 'easyMode.oauth.step2': 'Click “Start Sign-In” and finish authorization in the browser.', - 'easyMode.oauth.step3': 'Return here and confirm the sign-in status is completed.', - 'easyMode.oauth.action': 'Open OAuth Sign-In', 'easyMode.api.title': 'API Access', - 'easyMode.api.description': 'Enter a Base URL and API key for a third-party or self-hosted service.', - 'easyMode.api.step1': 'Open API Access and click “Add” in the upper-right.', - 'easyMode.api.step2': 'Enter a remark, Base URL, and API key, then fetch models.', - 'easyMode.api.step3': 'Save the connection and confirm that at least one model is available.', - 'easyMode.api.action': 'Configure API Access', - 'easyMode.step3.title': 'Connect an agent', - 'easyMode.step3.description': 'Choose the client you use and apply one model configuration to start chatting.', - 'easyMode.step3.ready': 'Ready', - 'easyMode.step3.cardTitle': 'Connect CPA to a local agent client', - 'easyMode.step3.cardDescription': 'The agent page detects installed clients and writes the CPA connection settings for you.', + 'easyMode.api.description': 'Enter the Base URL and API key provided by a third-party platform.', + 'easyMode.step3.cardTitle': 'Connect CPA to an agent client', + 'easyMode.step3.cardDescription': 'Choose an installed client and model here, then write the CPA connection settings.', 'easyMode.step3.step1': 'Open Agent Configuration and choose an installed client.', - 'easyMode.step3.step2': 'Choose a model; Codex can also use the OAuth configuration.', + 'easyMode.step3.step2': 'Choose the model you want to use.', 'easyMode.step3.step3': 'Click “Apply Configuration Changes”, then launch the CLI or App.', - 'easyMode.step3.action': 'Open Agent Configuration', - 'easyMode.step3.back': 'Back to previous step', - 'easyMode.step3.note': 'After configuration, launch the matching CLI or App to start.', - 'easyMode.core.title': 'Start the CPA core first', - 'easyMode.core.description': 'OAuth, API access, and agent configuration need the core to be running.', - 'easyMode.core.action': 'Open Core Control', - 'easyMode.core.ready': 'Core is running', - 'easyMode.core.waiting': 'Waiting for core', - 'easyMode.core.blocked': 'Start the core before opening a configuration page.', - 'easyMode.footer': 'After setup, use the navigation on the left to manage more details.', + 'easyMode.guide.title': 'How to use', + 'easyMode.guide.description': 'Choose OAuth sign-in or API Access first. After the model is connected, apply an available model to an agent client.', + 'easyMode.guide.step1Title': 'Choose a model connection', + 'easyMode.guide.step1Description': 'Use OAuth when an account can sign in, or API Access when you have a Base URL and API key from a third-party platform.', + 'easyMode.guide.step2Title': 'Connect the model', + 'easyMode.guide.step2Description': 'OAuth opens the account authorization flow. API Access asks for the Base URL and API key from the third-party platform. After saving, continue to agent configuration.', + 'easyMode.guide.step3Title': 'Connect an agent client', + 'easyMode.guide.step3Description': 'Choose an installed agent client and an available model, then apply the configuration to start using it.', + 'easyMode.navigation.back': 'Previous', + 'easyMode.navigation.next': 'Next', 'error.render.title': 'Something went wrong while rendering this page', 'error.unknown': 'Unknown error', 'error.reload': 'Reload Page', diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index 28ff5bd..05f0f76 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -33,57 +33,31 @@ export const zhCN = { 'app.close.exiting': '正在退出...', 'app.close.exit': '退出程序', 'app.close.remember': '记住选项', - 'easyMode.eyebrow': '新手引导', - 'easyMode.title': '三步接入你的第一个智能体', - 'easyMode.description': '先选择认证方式,再完成接入,最后把模型连接到常用的智能体客户端。', - 'easyMode.reset': '重新开始', 'easyMode.steps.label': '接入向导步骤', - 'easyMode.step': '第 {number} 步', - 'easyMode.step1.title': '选择认证方式', - 'easyMode.step1.description': '你可以登录已有账号,也可以直接填入第三方 API 密钥。', - 'easyMode.step1.selectHint': '先选择一种方式。选定后,再进入对应的配置步骤。', - 'easyMode.step1.selectFirst': '请先选择 OAuth 或 API 接入', - 'easyMode.step1.continue': '下一步:完成接入', - 'easyMode.step1.hint': '不知道选哪种?有官方账号并希望免填密钥时,优先选择 OAuth。', - 'easyMode.step2.title': '完成模型接入', - 'easyMode.step2.description': '按提示完成认证或新增 API 接入,保存后即可继续。', - 'easyMode.step2.openTitle': '先完成上面的配置', - 'easyMode.step2.returnHint': '点击按钮打开配置页面。完成后,点击左侧“简易模式”返回这里,再确认已完成。', - 'easyMode.step2.doneHint': '完成配置后再继续下一步', - 'easyMode.step2.complete': '已完成接入,下一步', - 'easyMode.step2.next': '我已完成,连接智能体', - 'easyMode.selectedPath': '当前选择', - 'easyMode.changePath': '更换方式', + 'easyMode.overview.coreTitle': '使用指导', + 'easyMode.overview.providerTitle': '接入模型', + 'easyMode.overview.agentTitle': '连接智能体', + 'easyMode.provider.oauthFit': '适合官方账号和浏览器授权', + 'easyMode.provider.apiFit': '适合使用第三方平台提供的 API', 'easyMode.oauth.title': 'OAuth 登录', 'easyMode.oauth.description': '通过浏览器授权,不需要手动复制 API 密钥。', - 'easyMode.oauth.step1': '打开 OAuth 页面,选择要登录的服务。', - 'easyMode.oauth.step2': '点击“开始登录”,在浏览器中完成授权。', - 'easyMode.oauth.step3': '回到软件,确认登录状态显示为已完成。', - 'easyMode.oauth.action': '去 OAuth 登录', 'easyMode.api.title': 'API 接入', - 'easyMode.api.description': '填入 Base URL 和 API 密钥,适合第三方或自建服务。', - 'easyMode.api.step1': '打开 API 接入页面,点击右上角“新增”。', - 'easyMode.api.step2': '填写备注、Base URL 和 API 密钥,然后获取模型。', - 'easyMode.api.step3': '保存接入,并确认至少有一个模型可用。', - 'easyMode.api.action': '去配置 API', - 'easyMode.step3.title': '连接智能体', - 'easyMode.step3.description': '选择你正在使用的客户端,应用一个模型配置即可开始对话。', - 'easyMode.step3.ready': '准备就绪', - 'easyMode.step3.cardTitle': '把 CPA 接入本地智能体客户端', - 'easyMode.step3.cardDescription': '智能体页面会自动检测已安装的客户端,并为它写入 CPA 所需的连接配置。', + 'easyMode.api.description': '填写第三方平台提供的 Base URL 和 API 密钥。', + 'easyMode.step3.cardTitle': '将 CPA 连接到智能体客户端', + 'easyMode.step3.cardDescription': '在这里可以选择已安装的客户端和模型,并写入 CPA 所需的连接配置。', 'easyMode.step3.step1': '打开智能体配置,选择一个已安装的客户端。', - 'easyMode.step3.step2': '选择模型;Codex 还可以选择是否使用 OAuth 配置。', + 'easyMode.step3.step2': '选择要使用的模型。', 'easyMode.step3.step3': '点击“应用配置修改”,然后启动 CLI 或 App。', - 'easyMode.step3.action': '打开智能体配置', - 'easyMode.step3.back': '返回上一步', - 'easyMode.step3.note': '配置完成后,就可以从对应的 CLI 或 App 启动。', - 'easyMode.core.title': '先启动 CPA 内核', - 'easyMode.core.description': 'OAuth、API 接入和智能体配置都需要内核运行。', - 'easyMode.core.action': '前往内核控制', - 'easyMode.core.ready': '内核运行中', - 'easyMode.core.waiting': '等待内核', - 'easyMode.core.blocked': '启动内核后才能打开配置页面。', - 'easyMode.footer': '完成接入后,可直接使用左侧功能入口管理更多细节。', + 'easyMode.guide.title': '使用指导', + 'easyMode.guide.description': '先确定使用 OAuth 登录还是 API 接入,模型接入后,再把可用模型应用到智能体客户端。', + 'easyMode.guide.step1Title': '选择模型接入方式', + 'easyMode.guide.step1Description': '已有可登录账号时可以使用 OAuth;持有第三方平台提供的 Base URL 和 API 密钥时,可以使用 API 接入。', + 'easyMode.guide.step2Title': '接入模型', + 'easyMode.guide.step2Description': 'OAuth 会打开账号授权流程;API 接入需要填写第三方平台提供的 Base URL 和 API 密钥。保存后即可继续配置智能体。', + 'easyMode.guide.step3Title': '连接智能体客户端', + 'easyMode.guide.step3Description': '从已安装的智能体客户端中选择一个客户端和模型,应用配置后即可开始使用。', + 'easyMode.navigation.back': '上一步', + 'easyMode.navigation.next': '下一步', 'error.render.title': '页面渲染出现异常', 'error.unknown': '未知错误', 'error.reload': '重新加载页面', diff --git a/src/pages/EasyModePage.tsx b/src/pages/EasyModePage.tsx index 3f56bd5..3411be8 100644 --- a/src/pages/EasyModePage.tsx +++ b/src/pages/EasyModePage.tsx @@ -1,136 +1,97 @@ -import { useEffect, useState } from 'react'; -import { useCoreRuntime } from '../coreRuntime'; +import { useState } from 'react'; import { useI18n } from '../i18n'; - -export type EasyModeDestination = 'home' | 'oauth' | 'api' | 'agents'; +import { ApiAccessPage } from './ApiAccessPage'; +import { AgentsPage } from './AgentsPage'; +import { OAuthLoginPage } from './ManagementPages'; type AuthMethod = 'oauth' | 'api'; -type EasyModeStep = 1 | 2 | 3; - -type SavedEasyModeState = { - authMethod: AuthMethod | null; - step: EasyModeStep; -}; +type SetupStep = 1 | 2 | 3; +type SetupView = SetupStep | 'oauth' | 'api' | 'agents'; const EASY_MODE_STATE_KEY = 'easy-cli-proxy-api.easy-mode.state'; -const defaultState: SavedEasyModeState = { - authMethod: null, - step: 1, -}; - -function readSavedState(): SavedEasyModeState { +function readSavedAuthMethod(): AuthMethod { try { const raw = window.localStorage.getItem(EASY_MODE_STATE_KEY); - if (!raw) return defaultState; - const parsed = JSON.parse(raw) as Partial; - const authMethod = parsed.authMethod === 'oauth' || parsed.authMethod === 'api' - ? parsed.authMethod - : null; - const step = parsed.step === 2 || parsed.step === 3 ? parsed.step : 1; - return { authMethod, step: authMethod ? step : 1 }; + if (!raw) return 'oauth'; + const parsed = JSON.parse(raw) as { authMethod?: unknown }; + return parsed.authMethod === 'api' ? 'api' : 'oauth'; } catch { - return defaultState; + return 'oauth'; } } -function saveState(state: SavedEasyModeState) { +function saveAuthMethod(authMethod: AuthMethod) { try { - window.localStorage.setItem(EASY_MODE_STATE_KEY, JSON.stringify(state)); + window.localStorage.setItem(EASY_MODE_STATE_KEY, JSON.stringify({ authMethod })); } catch { - // Keep the wizard usable when persistent storage is unavailable. + // Keep the selection in memory when persistent storage is unavailable. } } -export function EasyModePage({ - onOpenPage, -}: { - onOpenPage: (page: EasyModeDestination) => void; -}) { +export function EasyModePage() { const { t } = useI18n(); - const { status: coreStatus } = useCoreRuntime(); - const [wizardState, setWizardState] = useState(readSavedState); - const coreRunning = Boolean(coreStatus?.running); + const [authMethod, setAuthMethod] = useState(readSavedAuthMethod); + const [view, setView] = useState(1); - useEffect(() => { - saveState(wizardState); - }, [wizardState]); - - const chooseAuthMethod = (authMethod: AuthMethod) => { - setWizardState((current) => ({ ...current, authMethod, step: 1 })); + const chooseAuthMethod = (method: AuthMethod) => { + setAuthMethod(method); + saveAuthMethod(method); }; - const goToStep = (step: EasyModeStep) => { - if (!wizardState.authMethod && step !== 1) return; - setWizardState((current) => ({ ...current, step })); + const openSelectedProvider = () => { + setView(authMethod); }; - const resetWizard = () => setWizardState(defaultState); - - const openAuthPage = () => { - if (!coreRunning || !wizardState.authMethod) return; - onOpenPage(wizardState.authMethod); + const openAgentSummary = () => { + setView(3); + }; + + const openAgentConfiguration = () => { + setView('agents'); + }; + + const previousView: SetupView | null = view === 2 + ? 1 + : view === 'oauth' || view === 'api' + ? 2 + : view === 3 + ? authMethod + : view === 'agents' + ? 3 + : null; + const continueSetup = () => { + if (view === 1) setView(2); + else if (view === 2) openSelectedProvider(); + else if (view === 'oauth' || view === 'api') openAgentSummary(); + else if (view === 3) openAgentConfiguration(); }; - const authTitle = wizardState.authMethod === 'oauth' - ? t('easyMode.oauth.title') - : t('easyMode.api.title'); - const authAction = wizardState.authMethod === 'oauth' - ? t('easyMode.oauth.action') - : t('easyMode.api.action'); - const authSteps = wizardState.authMethod === 'oauth' - ? [t('easyMode.oauth.step1'), t('easyMode.oauth.step2'), t('easyMode.oauth.step3')] - : [t('easyMode.api.step1'), t('easyMode.api.step2'), t('easyMode.api.step3')]; const stepTitles = [ - t('easyMode.step1.title'), - t('easyMode.step2.title'), - t('easyMode.step3.title'), + t('easyMode.overview.coreTitle'), + t('easyMode.overview.providerTitle'), + t('easyMode.overview.agentTitle'), ]; return (
-
-
- {t('easyMode.eyebrow')} -

{t('easyMode.title')}

-

{t('easyMode.description')}

-
- -
- - {!coreRunning ? ( -
-
- {t('easyMode.core.title')} -

{t('easyMode.core.description')}

-
- -
- ) : null} - -
+
{stepTitles.map((title, index) => { - const step = (index + 1) as EasyModeStep; - const active = wizardState.step === step; - const complete = wizardState.step > step; - const locked = !wizardState.authMethod && step > 1; + const step = (index + 1) as SetupStep; + const active = step === 1 + ? view === 1 + : step === 2 + ? view === 2 || view === 'oauth' || view === 'api' + : view === 3 || view === 'agents'; return ( @@ -138,119 +99,94 @@ export function EasyModePage({ })}
- {wizardState.step === 1 ? ( +
+ {previousView !== null ? ( + + ) : null} + {view !== 'agents' ? ( + + ) : null} +
+ + {view === 1 ? (
- 1
-

{t('easyMode.step1.title')}

-

{t('easyMode.step1.description')}

+

{t('easyMode.guide.title')}

+

{t('easyMode.guide.description')}

-

{t('easyMode.step1.selectHint')}

+
+
+ {t('easyMode.guide.step1Title')} +

{t('easyMode.guide.step1Description')}

+
+
+ {t('easyMode.guide.step2Title')} +

{t('easyMode.guide.step2Description')}

+
+
+ {t('easyMode.guide.step3Title')} +

{t('easyMode.guide.step3Description')}

+
+
+
+ ) : null} + {view === 2 ? ( +
-
- -
- - {wizardState.authMethod - ? t('easyMode.selectedPath') + `:${authTitle}` - : t('easyMode.step1.selectFirst')} - -
) : null} - {wizardState.step === 2 && wizardState.authMethod ? ( -
-
- 2 -
-

{t('easyMode.step2.title')}

-

{t('easyMode.step2.description')}

-
+ {view === 'oauth' || view === 'api' ? ( +
+
+ {view === 'oauth' ? : }
- -
- {t('easyMode.selectedPath')} - {authTitle} - -
- -
-
- {t('easyMode.step2.openTitle')} -

{t('easyMode.step2.returnHint')}

-
- -
- -
    - {authSteps.map((item, index) => ( -
  1. - {index + 1} -

    {item}

    -
  2. - ))} -
- -
- {t('easyMode.step2.doneHint')} - -
- {!coreRunning ?

{t('easyMode.core.blocked')}

: null}
) : null} - {wizardState.step === 3 && wizardState.authMethod ? ( + {view === 3 ? (
-
- 3 -
-

{t('easyMode.step3.title')}

-

{t('easyMode.step3.description')}

-
-
-
{t('easyMode.step3.cardTitle')}

{t('easyMode.step3.cardDescription')}

- {t('easyMode.step3.ready')}
    @@ -258,22 +194,16 @@ export function EasyModePage({
  1. 2

    {t('easyMode.step3.step2')}

  2. 3

    {t('easyMode.step3.step3')}

- -
- {t('easyMode.step3.note')} -
- - -
-
) : null} -
{t('easyMode.footer')}
+ {view === 'agents' ? ( +
+
+ +
+
+ ) : null}
); } diff --git a/src/styles.css b/src/styles.css index bd16553..61d0077 100644 --- a/src/styles.css +++ b/src/styles.css @@ -10038,42 +10038,6 @@ body.table-col-resizing * { margin-inline: auto; } -.simple-mode-header { - display: flex; - align-items: flex-start; - justify-content: space-between; - gap: 20px; -} - -.simple-mode-header > div { - min-width: 0; -} - -.simple-mode-eyebrow { - color: var(--ui-accent-strong); - font-size: var(--font-size-label); - font-weight: 800; -} - -.simple-mode-header h1 { - margin: 7px 0 6px; - color: var(--theme-2d2a26); - font-size: clamp(25px, 3vw, 34px); - line-height: 1.15; -} - -.simple-mode-header p { - max-width: 680px; - margin: 0; - color: var(--theme-5f5a53); - line-height: var(--line-height-body); -} - -.simple-mode-reset { - flex: none; - min-height: 38px; -} - .simple-mode-core-alert { display: flex; align-items: center; @@ -10115,7 +10079,7 @@ body.table-col-resizing * { .simple-mode-progress-item { display: grid; - grid-template-columns: auto minmax(0, 1fr); + grid-template-columns: minmax(0, 1fr); align-items: center; gap: 9px; min-width: 0; @@ -10144,30 +10108,6 @@ body.table-col-resizing * { box-shadow: 0 4px 12px var(--ui-accent-shadow); } -.simple-mode-progress-number, -.simple-mode-task-number { - display: grid; - place-items: center; - border-radius: 999px; - font-weight: 800; -} - -.simple-mode-progress-number { - width: 28px; - height: 28px; - border: 1px solid var(--theme-d5d2cb); - background: var(--theme-faf9f5); - color: var(--theme-716b61); -} - -.simple-mode-progress-item.active .simple-mode-progress-number, -.simple-mode-progress-item.complete .simple-mode-progress-number { - border-color: var(--ui-accent); - background: var(--ui-accent); - color: #ffffff; -} - -.simple-mode-progress-item small, .simple-mode-progress-item strong { display: block; min-width: 0; @@ -10176,12 +10116,6 @@ body.table-col-resizing * { white-space: nowrap; } -.simple-mode-progress-item small { - margin-bottom: 2px; - color: var(--theme-7a746c); - font-size: var(--font-size-caption); -} - .simple-mode-progress-item strong { color: var(--theme-2d2a26); font-size: var(--font-size-body); @@ -10199,15 +10133,6 @@ body.table-col-resizing * { gap: 11px; } -.simple-mode-task-number { - flex: none; - width: 31px; - height: 31px; - border-radius: 8px; - background: var(--ui-accent); - color: #ffffff; -} - .simple-mode-task-heading h2 { margin: 0; color: var(--theme-2d2a26); @@ -10226,6 +10151,43 @@ body.table-col-resizing * { font-weight: 650; } +.simple-mode-guide-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 12px; +} + +.simple-mode-guide-card { + display: grid; + align-content: start; + gap: 7px; + min-width: 0; + min-height: 170px; + padding: 15px; + border: 1px solid var(--theme-e3e1db); + border-radius: 10px; + background: var(--theme-faf9f5); +} + +.simple-mode-guide-label { + color: var(--ui-accent-strong); + font-size: var(--font-size-caption); + font-weight: 800; +} + +.simple-mode-guide-card > strong { + color: var(--theme-2d2a26); + font-size: var(--font-size-section); +} + +.simple-mode-guide-card > p { + flex: 1; + margin: 0; + color: var(--theme-5f5a53); + font-size: var(--font-size-label); + line-height: var(--line-height-body); +} + .simple-mode-choice-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); @@ -10268,6 +10230,12 @@ body.table-col-resizing * { line-height: var(--line-height-body); } +.simple-mode-choice small { + color: var(--theme-7a746c); + font-size: var(--font-size-caption); + line-height: var(--line-height-body); +} + .simple-mode-task-footer { display: flex; align-items: center; @@ -10350,13 +10318,6 @@ body.table-col-resizing * { background: var(--theme-f1f8f1); } -.simple-mode-ready-label { - flex: none; - color: var(--theme-2f6b3a); - font-size: var(--font-size-label); - font-weight: 800; -} - .simple-mode-checklist { display: grid; gap: 11px; @@ -10391,6 +10352,23 @@ body.table-col-resizing * { line-height: var(--line-height-body); } +.simple-mode-guide-list li > div { + display: grid; + gap: 3px; + min-width: 0; +} + +.simple-mode-guide-list strong { + color: var(--theme-2d2a26); + font-size: var(--font-size-body); +} + +.simple-mode-guide-list p { + margin: 0; + color: var(--theme-5f5a53); + font-size: var(--font-size-label); +} + .simple-mode-warning { margin: -6px 0 0; color: var(--theme-9f2d20); @@ -10403,24 +10381,72 @@ body.table-col-resizing * { gap: 8px; } -.simple-mode-footer { - padding: 0 0 8px; - color: var(--theme-7a746c); - font-size: var(--font-size-label); +.simple-mode-embedded-task { + display: grid; + gap: 16px; + padding: clamp(18px, 2.5vw, 24px); +} + +.simple-mode-embedded-heading { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 16px; +} + +.simple-mode-embedded-heading > div:first-child { + display: flex; + align-items: flex-start; + gap: 11px; + min-width: 0; +} + +.simple-mode-embedded-heading h2 { + margin: 0; + color: var(--theme-2d2a26); + font-size: var(--font-size-panel-title); +} + +.simple-mode-embedded-heading p { + margin: 4px 0 0; + color: var(--theme-5f5a53); line-height: var(--line-height-body); - text-align: center; +} + +.simple-mode-embedded-content { + min-width: 0; + padding: 18px; + border: 1px solid var(--theme-e3e1db); + border-radius: 10px; + background: var(--theme-faf9f5); + container-type: inline-size; + container-name: workspace; +} + +.simple-mode-embedded-content > .page { + max-width: none; +} + +.simple-mode-flow-navigation { + display: flex; + align-items: center; + justify-content: flex-start; + gap: 8px; + padding-bottom: 14px; + border-bottom: 1px solid var(--theme-e3e1db); +} + +.simple-mode-flow-navigation > button { + min-width: 96px; + min-height: 40px; + white-space: nowrap; +} + +.simple-mode-flow-navigation > .primary-button { + margin-left: auto; } @media (max-width: 680px) { - .simple-mode-header { - flex-direction: column; - gap: 13px; - } - - .simple-mode-reset { - width: 100%; - } - .simple-mode-core-alert, .simple-mode-action-card, .simple-mode-task-footer { @@ -10436,7 +10462,8 @@ body.table-col-resizing * { } .simple-mode-progress, - .simple-mode-choice-grid { + .simple-mode-choice-grid, + .simple-mode-guide-grid { grid-template-columns: 1fr; } @@ -10462,4 +10489,39 @@ body.table-col-resizing * { .simple-mode-actions button { width: 100%; } + + .simple-mode-embedded-heading { + align-items: stretch; + flex-direction: column; + } + + .simple-mode-embedded-heading .text-button { + width: 100%; + margin-left: 0; + text-align: left; + } + + .simple-mode-embedded-content { + padding: 10px; + } + + .simple-mode-flow-navigation { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; + } + + .simple-mode-flow-navigation > button { + width: 100%; + margin-left: 0; + } + + .simple-mode-flow-navigation > .secondary-button:only-child { + grid-column: 1; + } + + .simple-mode-flow-navigation > .primary-button:only-child { + grid-column: 2; + } + }