From e385df4599211522f597cd1ee2c590daad75a5c2 Mon Sep 17 00:00:00 2001 From: ali asaria <ali.asaria@gmail.com> Date: Tue, 5 Mar 2024 09:32:29 -0500 Subject: [PATCH] update autosetup and connect with more detailed steps --- package-lock.json | 8 +- package.json | 1 + src/main/main.ts | 40 +- src/main/preload.ts | 6 +- src/main/util.ts | 115 ++++- .../components/Connect/LocalConnection.tsx | 442 +++++++++++++++--- .../components/Connect/LoginModal.tsx | 14 +- 7 files changed, 522 insertions(+), 104 deletions(-) diff --git a/package-lock.json b/package-lock.json index afaeadca..4707df24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,7 @@ "requires": true, "packages": { "": { - "version": "0.1.6", + "version": "0.2.2", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -26,6 +26,7 @@ "@uppy/xhr-upload": "^3.3.2", "basic-auth": "~2.0.1", "cidr-matcher": "^2.1.1", + "command-exists": "^1.2.9", "debug": "^4.3.4", "easy-peasy": "^6.0.2", "electron-debug": "^3.2.0", @@ -7438,6 +7439,11 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" + }, "node_modules/commander": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", diff --git a/package.json b/package.json index 3e2abe12..a7dbd875 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "@uppy/xhr-upload": "^3.3.2", "basic-auth": "~2.0.1", "cidr-matcher": "^2.1.1", + "command-exists": "^1.2.9", "debug": "^4.3.4", "easy-peasy": "^6.0.2", "electron-debug": "^3.2.0", diff --git a/src/main/main.ts b/src/main/main.ts index 25153181..f15c7b78 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -23,6 +23,9 @@ import { installLocalServer, killLocalServer, executeInstallStep, + checkIfShellCommandExists, + checkIfCondaEnvironmentExists, + checkDependencies, } from './util'; // //////////// @@ -68,19 +71,42 @@ ipcMain.handle('server:InstallLocally', (event) => { }); ipcMain.handle('server:install_download', (event) => { - return executeInstallStep('download_transformer_lab'); + return executeInstallStep('download_transformer_lab', false); }); -ipcMain.handle('server:install_conda', (event) => { - return executeInstallStep('install_conda'); +ipcMain.handle('server:install_conda', async (event) => { + console.log('** Installing conda'); + await executeInstallStep('install_conda', true); + console.log('Finishing installing conda'); + return; }); -ipcMain.handle('server:install_create-conda-environment', (event) => { - return executeInstallStep('create_conda_environment'); +ipcMain.handle('server:install_create-conda-environment', async (event) => { + return executeInstallStep('create_conda_environment', true); }); -ipcMain.handle('server:install_install-dependencies', (event) => { - return executeInstallStep('install_dependencies'); +ipcMain.handle('server:install_install-dependencies', async (event) => { + return executeInstallStep('install_dependencies', true); +}); + +ipcMain.handle('server:checkIfCondaExists', async (event) => { + const r = checkIfShellCommandExists('conda'); + console.log('conda exists', r); + return r; +}); + +ipcMain.handle('server:checkIfCondaEnvironmentExists', async (event) => { + const envList = await checkIfCondaEnvironmentExists(); + console.log('envList', envList); + return envList; +}); + +ipcMain.handle('server:checkIfUvicornExists', async (event) => { + return checkIfShellCommandExists('uvicorn'); +}); + +ipcMain.handle('server:checkDependencies', async (event) => { + return await checkDependencies(); }); class AppUpdater { diff --git a/src/main/preload.ts b/src/main/preload.ts index 0728a13c..9ecb63c0 100644 --- a/src/main/preload.ts +++ b/src/main/preload.ts @@ -21,7 +21,11 @@ export type Channels = | 'server:install_download' | 'server:install_conda' | 'server:install_create-conda-environment' - | 'server:install_install-dependencies'; + | 'server:install_install-dependencies' + | 'server:checkIfCondaExists' + | 'server:checkIfCondaEnvironmentExists' + | 'server:checkIfUvicornExists' + | 'server:checkDependencies'; const electronHandler = { ipcRenderer: { diff --git a/src/main/util.ts b/src/main/util.ts index 1bb738ce..db58b94b 100644 --- a/src/main/util.ts +++ b/src/main/util.ts @@ -4,8 +4,11 @@ import path from 'path'; const fs = require('fs'); const os = require('os'); const { spawn, exec, ChildProcess } = require('child_process'); +const util = require('node:util'); +const awaitExec = util.promisify(require('node:child_process').exec); const homeDir = os.homedir(); const transformerLabDir = path.join(homeDir, '.transformerlab/src/'); +const commandExistsSync = require('command-exists').sync; var localServer: typeof ChildProcess = null; @@ -124,24 +127,104 @@ export function installLocalServer() { } } -export function executeInstallStep(argument: string) { - console.log('Downloading transformerlab-api to ~/.transformerlab/src'); +export function checkIfShellCommandExists(command: string) { + if (commandExistsSync(command)) { + return true; + } else { + return false; + } +} + +export async function checkDependencies() { + // First activate the transformerlab environment + // Then run pip list + // Then compare the output to the list of dependencies + // If any are missing, return the missing ones + // If all are present, manually check if the uvicorn command is present + const uvicornExists = checkIfShellCommandExists('uvicorn'); + const command = + 'eval "$(conda shell.bash hook)" && conda activate transformerlab && pip list --format json'; const options = { shell: '/bin/bash' }; - try { - const child = exec( - `curl https://raw.githubusercontent.com/transformerlab/transformerlab-api/main/install.sh | bash -s -- ${argument}`, - options, - (error, stdout, stderr) => { - if (error) { - console.error(`exec error: ${error}`); - return; - } - console.log(`stdout: ${stdout}`); - console.error(`stderr: ${stderr}`); - } + const { stdout, stderr } = await awaitExec(command, options).catch((err) => { + console.log('Error running pip list', err); + }); + console.log('stdout:', stdout); + console.error('stderr:', stderr); + + const pipList = JSON.parse(stdout); + const pipListNames = pipList.map((x) => x.name); + const keyDependencies = [ + 'fastapi', + 'pydantic', + 'transformers', + 'uvicorn', + 'sentencepiece', + 'torch', + 'transformers', + 'peft', + 'packaging', + 'fschat', + ]; + + //compare the list of dependencies to the keyDependencies + let missingDependencies = []; + for (let i = 0; i < keyDependencies.length; i++) { + if (!pipListNames.includes(keyDependencies[i])) { + missingDependencies.push(keyDependencies[i]); + } + } + + console.log('missingDependencies', missingDependencies); + return missingDependencies; +} + +export async function checkIfCondaEnvironmentExists() { + const options = { shell: '/bin/bash' }; + console.log('Checking if Conda environment "transformerlab" exists'); + const { stdout, stderr } = await awaitExec(`conda env list`, options).catch( + (err) => { + console.log('Error running conda env list', err); + } + ); + console.log('stdout:', stdout); + console.error('stderr:', stderr); + + // search for the string "transformerlab" in the output + if (stdout.includes('transformerlab')) { + return true; + } else { + return false; + } +} + +export async function executeInstallStep( + argument: string, + useLocalInstallSh = false +) { + const options = { shell: '/bin/bash' }; + console.log('Running install.sh ' + argument); + + if (useLocalInstallSh) { + console.log( + `Using local install.sh and running: ~/.transformerlab/src/install.sh ${argument}` ); - } catch (err) { - console.log('Failed to download Transformer Lab API', err); + const { stdout, stderr } = await awaitExec( + `~/.transformerlab/src/install.sh ${argument}`, + options + ).catch((err) => { + console.log('Error running install.sh', err); + }); + console.log('stdout:', stdout); + console.error('stderr:', stderr); + } else { + const { stdout, stderr } = await awaitExec( + `curl https://raw.githubusercontent.com/transformerlab/transformerlab-api/main/install.sh | bash -s -- ${argument}`, + options + ).catch((err) => { + console.log('Error running install.sh', err); + }); + console.log('stdout:', stdout); + console.error('stderr:', stderr); } } diff --git a/src/renderer/components/Connect/LocalConnection.tsx b/src/renderer/components/Connect/LocalConnection.tsx index 187f166d..05c533c7 100644 --- a/src/renderer/components/Connect/LocalConnection.tsx +++ b/src/renderer/components/Connect/LocalConnection.tsx @@ -34,18 +34,28 @@ function setIntervalXTimes(callback, notSuccessful, delay, repetitions) { }, delay); } +const Steps = [ + 'CHECK_IF_INSTALLED', + 'CHECK_VERSION', + 'CHECK_IF_CONDA_INSTALLED', + 'CHECK_IF_CONDA_ENVIRONMENT_EXISTS', + 'CHECK_IF_PYTHON_DEPENDENCIES_INSTALLED', + 'CHECK_IF_SERVER_RUNNING_ON_PORT_8000', + 'CHECK_FOR_IMPORTANT_PLUGINS', +]; + function CheckIfInstalled({ activeStep, setActiveStep }) { const [installStatus, setInstallStatus] = useState('notstarted'); // notstarted, pending, success, error useEffect(() => { - if (activeStep !== 1) return; + if (activeStep !== Steps.indexOf('CHECK_IF_INSTALLED')) return; (async () => { const serverIsInstalled = await window.electron.ipcRenderer.invoke( 'server:checkIfInstalledLocally' ); if (serverIsInstalled) { setInstallStatus('success'); - setActiveStep(2); + setActiveStep(Steps.indexOf('CHECK_VERSION')); } else { setInstallStatus('notstarted'); } @@ -68,38 +78,39 @@ function CheckIfInstalled({ activeStep, setActiveStep }) { {installStatus === 'error' && <Chip color="danger">Error </Chip>} <ButtonGroup variant="plain" spacing={1}> - {activeStep == 1 && installStatus == 'notstarted' && ( - <Button - variant="solid" - onClick={async () => { - await window.electron.ipcRenderer.invoke( - 'server:InstallLocally' - ); - setInstallStatus('pending'); - setIntervalXTimes( - async () => { - const serverIsInstalled = - await window.electron.ipcRenderer.invoke( - 'server:checkIfInstalledLocally' - ); - if (serverIsInstalled) { - setInstallStatus('success'); - setActiveStep(2); - return true; - } - return false; - }, - () => { - setInstallStatus('error'); - }, - 2000, - 8 - ); - }} - > - Install Transformer Lab Server API - </Button> - )} + {activeStep == Steps.indexOf('CHECK_IF_INSTALLED') && + installStatus == 'notstarted' && ( + <Button + variant="solid" + onClick={async () => { + await window.electron.ipcRenderer.invoke( + 'server:InstallLocally' + ); + setInstallStatus('pending'); + setIntervalXTimes( + async () => { + const serverIsInstalled = + await window.electron.ipcRenderer.invoke( + 'server:checkIfInstalledLocally' + ); + if (serverIsInstalled) { + setInstallStatus('success'); + setActiveStep(Steps.indexOf('CHECK_IF_INSTALLED') + 1); + return true; + } + return false; + }, + () => { + setInstallStatus('error'); + }, + 2000, + 8 + ); + }} + > + Install Transformer Lab Server API + </Button> + )} </ButtonGroup> </Stack> </> @@ -112,7 +123,7 @@ function CheckCurrentVersion({ activeStep, setActiveStep }) { const [installStatus, setInstallStatus] = useState('notstarted'); // notstarted, pending, success, error useEffect(() => { - if (activeStep !== 2) return; + if (activeStep !== Steps.indexOf('CHECK_VERSION')) return; (async () => { const ver = await window.electron.ipcRenderer.invoke( @@ -129,7 +140,7 @@ function CheckCurrentVersion({ activeStep, setActiveStep }) { setRelease(tag); if (ver === tag) { - setActiveStep(3); + setActiveStep(Steps.indexOf('CHECK_VERSION') + 1); } })(); }, [activeStep]); @@ -137,7 +148,7 @@ function CheckCurrentVersion({ activeStep, setActiveStep }) { return ( <> <Stack spacing={1}> - {activeStep >= 2 && ( + {activeStep >= Steps.indexOf('CHECK_VERSION') && ( <> <Typography level="body-sm"> Your version of Transformer Lab API is {version} @@ -152,7 +163,7 @@ function CheckCurrentVersion({ activeStep, setActiveStep }) { )} {version == release && <Chip color="success">Success!</Chip>} - {activeStep == 2 && release != '' && ( + {activeStep == Steps.indexOf('CHECK_VERSION') && release != '' && ( <ButtonGroup variant="plain" spacing={1}> <Button variant="solid" @@ -171,7 +182,7 @@ function CheckCurrentVersion({ activeStep, setActiveStep }) { if (ver === release) { setInstallStatus('success'); setVersion(ver); - setActiveStep(3); + setActiveStep(Steps.indexOf('CHECK_VERSION') + 1); return true; } return false; @@ -190,7 +201,7 @@ function CheckCurrentVersion({ activeStep, setActiveStep }) { variant="plain" size="sm" onClick={() => { - setActiveStep(3); + setActiveStep(Steps.indexOf('CHECK_VERSION') + 1); }} > Skip @@ -211,17 +222,20 @@ function RunServer({ activeStep, setActiveStep }) { } = useCheckLocalConnection(); useEffect(() => { - if (activeStep !== 3) return; + if (activeStep !== Steps.indexOf('CHECK_IF_SERVER_RUNNING_ON_PORT_8000')) + return; if (server && !serverError) { console.log('I think things are good'); - setActiveStep(4); + setActiveStep(Steps.indexOf('CHECK_IF_SERVER_RUNNING_ON_PORT_8000') + 1); return; } else { setIntervalXTimes( async () => { if (!server || serverError) return false; - setActiveStep(4); + setActiveStep( + Steps.indexOf('CHECK_IF_SERVER_RUNNING_ON_PORT_8000') + 1 + ); return true; }, () => {}, @@ -234,14 +248,14 @@ function RunServer({ activeStep, setActiveStep }) { return ( <> <Stack spacing={1}> - {activeStep >= 3 && server && !serverError && ( - <Chip color="success">Success!</Chip> - )} - {activeStep >= 3 && (!server || serverError) && ( - <Chip color="danger">Not Running</Chip> - )} + {activeStep >= Steps.indexOf('CHECK_IF_SERVER_RUNNING_ON_PORT_8000') && + server && + !serverError && <Chip color="success">Success!</Chip>} + {activeStep >= Steps.indexOf('CHECK_IF_SERVER_RUNNING_ON_PORT_8000') && + (!server || serverError) && <Chip color="danger">Not Running</Chip>} <ButtonGroup variant="plain" spacing={1}> - {activeStep == 3 && + {activeStep == + Steps.indexOf('CHECK_IF_SERVER_RUNNING_ON_PORT_8000') && (!server || serverError ? ( thinking ? ( <CircularProgress color="primary" /> @@ -257,7 +271,8 @@ function RunServer({ activeStep, setActiveStep }) { ); if (start_process?.status == 'error') { - const response_text = "Failed to start server: \n" + start_process?.message; + const response_text = + 'Failed to start server: \n' + start_process?.message; alert(response_text); setThinking(false); return; @@ -267,7 +282,11 @@ function RunServer({ activeStep, setActiveStep }) { async () => { if (!server || serverError) return false; setThinking(false); - setActiveStep(4); + setActiveStep( + Steps.indexOf( + 'CHECK_IF_SERVER_RUNNING_ON_PORT_8000' + ) + 1 + ); return true; }, () => { @@ -296,7 +315,7 @@ function CheckForPlugins({ activeStep, setActiveStep }) { const [installing, setInstalling] = useState(false); useEffect(() => { - if (activeStep !== 4) return; + if (activeStep !== Steps.indexOf('CHECK_FOR_IMPORTANT_PLUGINS')) return; (async () => { const p = await fetch( @@ -306,7 +325,7 @@ function CheckForPlugins({ activeStep, setActiveStep }) { setMissingPlugins(json); if (json.length === 0) { - setActiveStep(5); + setActiveStep(Steps.indexOf('CHECK_FOR_IMPORTANT_PLUGINS') + 1); } })(); }, [activeStep]); @@ -334,7 +353,7 @@ function CheckForPlugins({ activeStep, setActiveStep }) { {missingPlugins?.map((p) => p).join(', ')} </Typography> - {activeStep == 4 && ( + {activeStep == Steps.indexOf('CHECK_FOR_IMPORTANT_PLUGINS') && ( <ButtonGroup variant="plain" spacing={1}> <Button variant="solid" @@ -346,7 +365,7 @@ function CheckForPlugins({ activeStep, setActiveStep }) { ); setInstalling(false); setMissingPlugins([]); - setActiveStep(5); + setActiveStep(Steps.indexOf('CHECK_FOR_IMPORTANT_PLUGINS') + 1); // setIntervalXTimes( // async () => { // const p = await fetch( @@ -377,7 +396,9 @@ function CheckForPlugins({ activeStep, setActiveStep }) { <Button variant="plain" onClick={() => { - setActiveStep(5); + setActiveStep( + Steps.indexOf('CHECK_FOR_IMPORTANT_PLUGINS') + 1 + ); }} size="sm" > @@ -408,6 +429,237 @@ function ConnectToLocalServer({ activeStep, setActiveStep, tryToConnect }) { ); } +function CheckIfCondaInstalled({ activeStep, setActiveStep }) { + const [installStatus, setInstallStatus] = useState(''); // notstarted, pending, success, error + + useEffect(() => { + if (activeStep !== Steps.indexOf('CHECK_IF_CONDA_INSTALLED')) return; + + (async () => { + const condaExists = await window.electron.ipcRenderer.invoke( + 'server:checkIfCondaExists' + ); + if (condaExists) { + setInstallStatus('success'); + setActiveStep(Steps.indexOf('CHECK_IF_CONDA_INSTALLED') + 1); + } else { + setInstallStatus('notstarted'); + } + })(); + }, [activeStep]); + + return ( + <> + <Stack spacing={1}> + {installStatus == 'success' && <Chip color="success">Success!</Chip>} + {installStatus == 'pending' && <CircularProgress color="primary" />} + + {activeStep == Steps.indexOf('CHECK_IF_CONDA_INSTALLED') && + installStatus == 'notstarted' && ( + <ButtonGroup variant="plain" spacing={1}> + <Button + variant="solid" + size="sm" + startDecorator={<RotateCcwIcon size="16px" />} + onClick={async () => { + setInstallStatus('pending'); + const installConda = await window.electron.ipcRenderer.invoke( + 'server:install_conda' + ); + const condaExists = await window.electron.ipcRenderer.invoke( + 'server:checkIfCondaExists' + ); + if (condaExists) { + setInstallStatus('success'); + setActiveStep( + Steps.indexOf('CHECK_IF_CONDA_INSTALLED') + 1 + ); + return; + } + setIntervalXTimes( + async () => { + const condaExists = + await window.electron.ipcRenderer.invoke( + 'server:checkIfCondaExists' + ); + if (condaExists) { + setInstallStatus('success'); + setActiveStep( + Steps.indexOf('CHECK_IF_CONDA_INSTALLED') + 1 + ); + return true; + } + return false; + }, + () => {}, + 2000, + 8 + ); + }} + > + Install Conda + </Button> + </ButtonGroup> + )} + </Stack> + </> + ); +} + +function CheckIfCondaEnvironmentExists({ activeStep, setActiveStep }) { + const [installStatus, setInstallStatus] = useState(''); // notstarted, pending, success, error + + useEffect(() => { + if (activeStep !== Steps.indexOf('CHECK_IF_CONDA_ENVIRONMENT_EXISTS')) + return; + + (async () => { + const condaExists = await window.electron.ipcRenderer.invoke( + 'server:checkIfCondaEnvironmentExists' + ); + if (condaExists) { + setInstallStatus('success'); + setActiveStep(Steps.indexOf('CHECK_IF_CONDA_ENVIRONMENT_EXISTS') + 1); + } else { + setInstallStatus('notstarted'); + } + })(); + }, [activeStep]); + + return ( + <> + <Stack spacing={1}> + {installStatus == 'success' && <Chip color="success">Success!</Chip>} + {installStatus == 'pending' && <CircularProgress color="primary" />} + + {activeStep == Steps.indexOf('CHECK_IF_CONDA_ENVIRONMENT_EXISTS') && + installStatus == 'notstarted' && ( + <ButtonGroup variant="plain" spacing={1}> + <Button + variant="solid" + size="sm" + startDecorator={<RotateCcwIcon size="16px" />} + onClick={async () => { + setInstallStatus('pending'); + const installConda = await window.electron.ipcRenderer.invoke( + 'server:install_create-conda-environment' + ); + const condaExists = await window.electron.ipcRenderer.invoke( + 'server:checkIfCondaEnvironmentExists' + ); + if (condaExists) { + setInstallStatus('success'); + setActiveStep( + Steps.indexOf('CHECK_IF_CONDA_ENVIRONMENT_EXISTS') + 1 + ); + return; + } + setIntervalXTimes( + async () => { + const condaExists = + await window.electron.ipcRenderer.invoke( + 'server:checkIfCondaEnvironmentExists' + ); + if (condaExists) { + setInstallStatus('success'); + setActiveStep( + Steps.indexOf('CHECK_IF_CONDA_ENVIRONMENT_EXISTS') + 1 + ); + return true; + } + return false; + }, + () => {}, + 2000, + 8 + ); + }} + > + Create "transformerlab" Conda Environment + </Button> + </ButtonGroup> + )} + </Stack> + </> + ); +} + +function CheckDependencies({ activeStep, setActiveStep }) { + const [installStatus, setInstallStatus] = useState(''); // notstarted, pending, success, error + const [missingDependencies, setMissingDependencies] = useState([]); + + useEffect(() => { + if (activeStep !== Steps.indexOf('CHECK_IF_PYTHON_DEPENDENCIES_INSTALLED')) + return; + + (async () => { + const missingDependencies = await window.electron.ipcRenderer.invoke( + 'server:checkDependencies' + ); + if (missingDependencies.length == 0) { + setInstallStatus('success'); + setActiveStep( + Steps.indexOf('CHECK_IF_PYTHON_DEPENDENCIES_INSTALLED') + 1 + ); + } else { + setMissingDependencies(missingDependencies); + setInstallStatus('notstarted'); + } + })(); + }, [activeStep]); + + return ( + <> + <Stack spacing={1}> + {installStatus == 'success' && <Chip color="success">Success!</Chip>} + {installStatus == 'pending' && <CircularProgress color="primary" />} + {missingDependencies.length > 0 && installStatus == 'notstarted' && ( + <Typography level="body-sm" color="warning"> + Many dependencies are missing including:{' '} + <Typography level="body-sm" color="warning"> + {missingDependencies.join(', ')} ... + </Typography> + </Typography> + )} + + {activeStep == + Steps.indexOf('CHECK_IF_PYTHON_DEPENDENCIES_INSTALLED') && + installStatus == 'notstarted' && ( + <ButtonGroup variant="plain" spacing={1}> + <Button + variant="solid" + size="sm" + startDecorator={<RotateCcwIcon size="16px" />} + onClick={async () => { + setInstallStatus('pending'); + const installDependencies = + await window.electron.ipcRenderer.invoke( + 'server:install_install-dependencies' + ); + + const missingDependencies = + await window.electron.ipcRenderer.invoke( + 'server:checkDependencies' + ); + if (missingDependencies.length == 0) { + setInstallStatus('success'); + setActiveStep( + Steps.indexOf('CHECK_IF_PYTHON_DEPENDENCIES_INSTALLED') + + 1 + ); + return; + } + }} + > + Install Dependencies + </Button> + </ButtonGroup> + )} + </Stack> + </> + ); +} + function InstallStep({ children, thisStep, title, activeStep, setActiveStep }) { return ( <Step @@ -429,21 +681,33 @@ function InstallStep({ children, thisStep, title, activeStep, setActiveStep }) { } function InstallStepper({ setServer }) { - const [activeStep, setActiveStep] = useState(1); // 0, 1, 2 + const [activeStep, setActiveStep] = useState( + Steps.indexOf('CHECK_IF_INSTALLED') + ); // 0, 1, 2 function tryToConnect() { const fullServer = 'http://' + 'localhost' + ':' + '8000' + '/'; window.TransformerLab = {}; window.TransformerLab.API_URL = fullServer; - setActiveStep(1); + setActiveStep(Steps.indexOf('CHECK_IF_INSTALLED')); setServer(fullServer); } return ( - <> - <Stepper orientation="vertical"> + <Sheet + sx={{ + display: 'flex', + flexDirection: 'column', + overflow: 'hidden', + height: '100%', + }} + > + <Stepper + orientation="vertical" + sx={{ display: 'flex', overflow: 'auto' }} + > {/* Active Step: {activeStep} */} <InstallStep - thisStep={1} + thisStep={Steps.indexOf('CHECK_IF_INSTALLED')} title="Check if Server is Installed at ~/.transformerlab/" activeStep={activeStep} setActiveStep={setActiveStep} @@ -454,7 +718,7 @@ function InstallStepper({ setServer }) { /> </InstallStep> <InstallStep - thisStep={2} + thisStep={Steps.indexOf('CHECK_VERSION')} title="Check Current Version" activeStep={activeStep} setActiveStep={setActiveStep} @@ -465,7 +729,40 @@ function InstallStepper({ setServer }) { /> </InstallStep> <InstallStep - thisStep={3} + thisStep={Steps.indexOf('CHECK_IF_CONDA_INSTALLED')} + title="Check if Conda is Installed" + activeStep={activeStep} + setActiveStep={setActiveStep} + > + <CheckIfCondaInstalled + activeStep={activeStep} + setActiveStep={setActiveStep} + /> + </InstallStep> + <InstallStep + thisStep={Steps.indexOf('CHECK_IF_CONDA_ENVIRONMENT_EXISTS')} + title="Check if Conda Environment 'transformerlab' Exists" + activeStep={activeStep} + setActiveStep={setActiveStep} + > + <CheckIfCondaEnvironmentExists + activeStep={activeStep} + setActiveStep={setActiveStep} + /> + </InstallStep> + <InstallStep + thisStep={Steps.indexOf('CHECK_IF_PYTHON_DEPENDENCIES_INSTALLED')} + title="Check if Python Dependencies are Installed" + activeStep={activeStep} + setActiveStep={setActiveStep} + > + <CheckDependencies + activeStep={activeStep} + setActiveStep={setActiveStep} + /> + </InstallStep> + <InstallStep + thisStep={Steps.indexOf('CHECK_IF_SERVER_RUNNING_ON_PORT_8000')} title="Check if Server is Running Locally on Port 8000" activeStep={activeStep} setActiveStep={setActiveStep} @@ -473,7 +770,7 @@ function InstallStepper({ setServer }) { <RunServer activeStep={activeStep} setActiveStep={setActiveStep} /> </InstallStep> <InstallStep - thisStep={4} + thisStep={Steps.indexOf('CHECK_FOR_IMPORTANT_PLUGINS')} title="Check for Important Plugins" activeStep={activeStep} setActiveStep={setActiveStep} @@ -491,25 +788,18 @@ function InstallStepper({ setServer }) { color="success" onClick={tryToConnect} startDecorator={<PlayIcon />} - sx={{ width: '100%', mt: 2 }} - disabled={activeStep !== 5} + sx={{ width: '100%', mt: 2, flex: 1, display: 'flex' }} + disabled={activeStep !== Steps.length} > Connect </Button> } - </> + </Sheet> ); } function LocalConnection({ setServer }) { - return ( - <Sheet sx={{ overflowY: 'auto' }}> - {/* {serverError - ? `Server is not running` + serverError && serverError.status - : 'Server is connected'} */} - <InstallStepper setServer={setServer} /> - </Sheet> - ); + return <InstallStepper setServer={setServer} />; } export default LocalConnection; diff --git a/src/renderer/components/Connect/LoginModal.tsx b/src/renderer/components/Connect/LoginModal.tsx index 3b41a075..f5d53e99 100644 --- a/src/renderer/components/Connect/LoginModal.tsx +++ b/src/renderer/components/Connect/LoginModal.tsx @@ -96,12 +96,12 @@ export default function LoginModal({ aria-labelledby="basic-modal-dialog-title" aria-describedby="basic-modal-dialog-description" sx={{ - top: '10vh', // Sit 20% from the top of the screen + top: '5vh', // Sit 20% from the top of the screen margin: 'auto', transform: 'translateX(-50%)', // This undoes the default translateY that centers vertically width: '55vw', maxWidth: '700px', - maxHeight: '70vh', + maxHeight: '90vh', }} > <Tabs @@ -115,7 +115,15 @@ export default function LoginModal({ <Tab>Remote Connection</Tab> {/* <Tab value="SSH">Connect via SSH</Tab> */} </TabList> - <TabPanel value={0} sx={{ p: 2, overflowY: 'auto' }}> + <TabPanel + value={0} + sx={{ + p: 2, + overflowY: 'hidden', + display: 'flex', + flexDirection: 'column', + }} + > <LocalConnection setServer={setServer} /> </TabPanel> <TabPanel value={1} sx={{ p: 2 }}> -- GitLab