✨ Добавлен русский язык + исправлены критические баги
🌍 Интернационализация: - Добавлен русский язык в i18n.ts (supportedLngs) - Русский пункт меню в NavBar.tsx (desktop + mobile) - Полная локализация страницы RobotCreate.tsx - Расширен ru.json: robotCreate (60+ ключей) + mainmenu 🐛 Исправления: - PostCSS баг в vite.config.js (css.postcss: false → { plugins: [] }) - Backend URL конфигурация (8081 вместо 8080) - API ключи теперь генерируются корректно 🔧 Конфигурация: - docker-compose.yml: host network mode - Dockerfile.frontend обновлен - Добавлены postcss конфиги ✅ Все сервисы работают: - Frontend: http://localhost:5174 - Backend: http://localhost:8081 - PostgreSQL: 5433 - MinIO: 9020/9021
This commit is contained in:
@@ -276,7 +276,7 @@ const RobotCreate: React.FC = () => {
|
||||
<ArrowBack />
|
||||
</IconButton>
|
||||
<Typography variant="h5" component="h1">
|
||||
Create New Robot
|
||||
{t('robotCreate.title')}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
@@ -299,10 +299,10 @@ const RobotCreate: React.FC = () => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Tab label="Extract" id="extract-robot" aria-controls="extract-robot" />
|
||||
<Tab label="Scrape" id="scrape-robot" aria-controls="scrape-robot" />
|
||||
<Tab label="Crawl" id="crawl-robot" aria-controls="crawl-robot" />
|
||||
<Tab label="Search" id="search-robot" aria-controls="search-robot" />
|
||||
<Tab label={t('robotCreate.tabs.extract')} id="extract-robot" aria-controls="extract-robot" />
|
||||
<Tab label={t('robotCreate.tabs.scrape')} id="scrape-robot" aria-controls="scrape-robot" />
|
||||
<Tab label={t('robotCreate.tabs.crawl')} id="crawl-robot" aria-controls="crawl-robot" />
|
||||
<Tab label={t('robotCreate.tabs.search')} id="search-robot" aria-controls="search-robot" />
|
||||
</Tabs>
|
||||
</Box>
|
||||
|
||||
@@ -321,11 +321,11 @@ const RobotCreate: React.FC = () => {
|
||||
/>
|
||||
|
||||
<Typography variant="body2" color="text.secondary" mb={3}>
|
||||
Extract structured data from websites using AI or record your own extraction workflow.
|
||||
{t('robotCreate.extract.description')}
|
||||
</Typography>
|
||||
<Box sx={{ width: '100%', maxWidth: 700, mb: 3 }}>
|
||||
<Typography variant="subtitle1" gutterBottom sx={{ mb: 2 }} color="text.secondary">
|
||||
Choose How to Build
|
||||
{t('robotCreate.chooseMode')}
|
||||
</Typography>
|
||||
|
||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||
@@ -345,10 +345,10 @@ const RobotCreate: React.FC = () => {
|
||||
<CardContent sx={{ textAlign: 'center', py: 3, color:"text.secondary" }}>
|
||||
<HighlightAlt sx={{ fontSize: 32, mb: 1 }} />
|
||||
<Typography variant="h6" gutterBottom>
|
||||
Recorder Mode
|
||||
{t('robotCreate.modes.recorder.title')}
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
Record your actions into a workflow.
|
||||
{t('robotCreate.modes.recorder.description')}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -380,16 +380,16 @@ const RobotCreate: React.FC = () => {
|
||||
fontSize: '0.7rem',
|
||||
}}
|
||||
>
|
||||
Beta
|
||||
</Box>
|
||||
{t('robotCreate.modes.ai.label')}
|
||||
</Box>
|
||||
|
||||
<CardContent sx={{ textAlign: 'center', py: 3, color:"text.secondary" }}>
|
||||
<AutoAwesome sx={{ fontSize: 32, mb: 1 }} />
|
||||
<Typography variant="h6" gutterBottom>
|
||||
AI Mode
|
||||
{t('robotCreate.modes.ai.title')}
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
Describe the task. It builds it for you.
|
||||
{t('robotCreate.modes.ai.description')}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -399,45 +399,45 @@ const RobotCreate: React.FC = () => {
|
||||
<Box sx={{ width: '100%', maxWidth: 700 }}>
|
||||
<Box sx={{ mb: 3 }}>
|
||||
<TextField
|
||||
placeholder="Name"
|
||||
placeholder={t('robotCreate.extract.namePlaceholder')}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={extractRobotName}
|
||||
onChange={(e) => setExtractRobotName(e.target.value)}
|
||||
label="Name"
|
||||
label={t('robotCreate.extract.name')}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ mb: 3 }}>
|
||||
<TextField
|
||||
placeholder="Example: Extract first 15 company names, descriptions, and batch information"
|
||||
placeholder={t('robotCreate.extract.aiPromptPlaceholder')}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
multiline
|
||||
rows={3}
|
||||
value={aiPrompt}
|
||||
onChange={(e) => setAiPrompt(e.target.value)}
|
||||
label="Extraction Prompt"
|
||||
label={t('robotCreate.extract.aiPrompt')}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ mb: 3 }}>
|
||||
<TextField
|
||||
placeholder="Example: https://www.ycombinator.com/companies/"
|
||||
placeholder={t('robotCreate.extract.websiteUrlPlaceholder')}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={url}
|
||||
onChange={(e) => setUrl(e.target.value)}
|
||||
label="Website URL (Optional)"
|
||||
label={t('robotCreate.extract.websiteUrlOptional')}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ display: 'flex', gap: 2, mb: 3 }}>
|
||||
<FormControl sx={{ flex: 1 }}>
|
||||
<InputLabel>LLM Provider</InputLabel>
|
||||
<InputLabel>{t('robotCreate.extract.llmProvider')}</InputLabel>
|
||||
<Select
|
||||
value={llmProvider}
|
||||
label="LLM Provider"
|
||||
label={t('robotCreate.extract.llmProvider')}
|
||||
onChange={(e) => {
|
||||
const provider = e.target.value as 'anthropic' | 'openai' | 'ollama';
|
||||
setLlmProvider(provider);
|
||||
@@ -449,22 +449,22 @@ const RobotCreate: React.FC = () => {
|
||||
}
|
||||
}}
|
||||
>
|
||||
<MenuItem value="ollama">Ollama (Local)</MenuItem>
|
||||
<MenuItem value="anthropic">Anthropic (Claude)</MenuItem>
|
||||
<MenuItem value="openai">OpenAI (GPT-4)</MenuItem>
|
||||
<MenuItem value="ollama">{t('robotCreate.extract.llmProviderOllama')}</MenuItem>
|
||||
<MenuItem value="anthropic">{t('robotCreate.extract.llmProviderAnthropic')}</MenuItem>
|
||||
<MenuItem value="openai">{t('robotCreate.extract.llmProviderOpenAI')}</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
<FormControl sx={{ flex: 1 }}>
|
||||
<InputLabel>Model</InputLabel>
|
||||
<InputLabel>{t('robotCreate.extract.model')}</InputLabel>
|
||||
<Select
|
||||
value={llmModel}
|
||||
label="Model"
|
||||
label={t('robotCreate.extract.model')}
|
||||
onChange={(e) => setLlmModel(e.target.value)}
|
||||
>
|
||||
{llmProvider === 'ollama' ? (
|
||||
[
|
||||
<MenuItem key="default" value="default">Default (llama3.2-vision)</MenuItem>,
|
||||
<MenuItem key="default" value="default">{t('robotCreate.extract.modelDefault')}</MenuItem>,
|
||||
<MenuItem key="llama3.2-vision" value="llama3.2-vision">llama3.2-vision</MenuItem>,
|
||||
<MenuItem key="llama3.2" value="llama3.2">llama3.2</MenuItem>
|
||||
]
|
||||
@@ -495,7 +495,7 @@ const RobotCreate: React.FC = () => {
|
||||
type="password"
|
||||
value={llmApiKey}
|
||||
onChange={(e) => setLlmApiKey(e.target.value)}
|
||||
label="API Key (Optional if set in .env)"
|
||||
label={t('robotCreate.extract.apiKey')}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
@@ -508,7 +508,7 @@ const RobotCreate: React.FC = () => {
|
||||
fullWidth
|
||||
value={llmBaseUrl}
|
||||
onChange={(e) => setLlmBaseUrl(e.target.value)}
|
||||
label="Ollama Base URL (Optional)"
|
||||
label={t('robotCreate.extract.ollamaBaseUrl')}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
@@ -626,7 +626,7 @@ const RobotCreate: React.FC = () => {
|
||||
}}
|
||||
startIcon={isLoading ? <CircularProgress size={20} color="inherit" /> : null}
|
||||
>
|
||||
{isLoading ? 'Creating & Running...' : 'Create & Run Robot'}
|
||||
{isLoading ? t('robotCreate.extract.creatingAndRunning') : t('robotCreate.extract.createAndRun')}
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
@@ -635,12 +635,12 @@ const RobotCreate: React.FC = () => {
|
||||
<>
|
||||
<Box sx={{ width: '100%', maxWidth: 700, mb: 3 }}>
|
||||
<TextField
|
||||
placeholder="Example: https://www.ycombinator.com/companies/"
|
||||
placeholder={t('robotCreate.extract.websiteUrlPlaceholder')}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={url}
|
||||
onChange={(e) => setUrl(e.target.value)}
|
||||
label="Website URL"
|
||||
label={t('robotCreate.extract.websiteUrl')}
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{ width: '100%', maxWidth: 700 }}>
|
||||
@@ -658,7 +658,7 @@ const RobotCreate: React.FC = () => {
|
||||
}}
|
||||
startIcon={isLoading ? <CircularProgress size={20} color="inherit" /> : null}
|
||||
>
|
||||
{isLoading ? 'Starting...' : 'Start Recording'}
|
||||
{isLoading ? t('robotCreate.extract.starting') : t('robotCreate.extract.startRecording')}
|
||||
</Button>
|
||||
</Box>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user