fix bus and translate to eus
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@ -23,7 +23,7 @@ function App() {
|
||||
Team Planner
|
||||
</Typography>
|
||||
<Typography variant="body1" color="text.secondary">
|
||||
Backlog management for your team
|
||||
Управление бэклогом идей команды
|
||||
</Typography>
|
||||
</Box>
|
||||
<Button
|
||||
@ -31,7 +31,7 @@ function App() {
|
||||
startIcon={<Add />}
|
||||
onClick={() => setCreateModalOpen(true)}
|
||||
>
|
||||
New Idea
|
||||
Новая идея
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
|
||||
@ -18,17 +18,17 @@ import { useCreateIdea } from '../../hooks/useIdeas';
|
||||
import type { CreateIdeaDto, IdeaStatus, IdeaPriority } from '../../types/idea';
|
||||
|
||||
const statusOptions: { value: IdeaStatus; label: string }[] = [
|
||||
{ value: 'backlog', label: 'Backlog' },
|
||||
{ value: 'todo', label: 'To Do' },
|
||||
{ value: 'in_progress', label: 'In Progress' },
|
||||
{ value: 'done', label: 'Done' },
|
||||
{ value: 'backlog', label: 'Бэклог' },
|
||||
{ value: 'todo', label: 'К выполнению' },
|
||||
{ value: 'in_progress', label: 'В работе' },
|
||||
{ value: 'done', label: 'Готово' },
|
||||
];
|
||||
|
||||
const priorityOptions: { value: IdeaPriority; label: string }[] = [
|
||||
{ value: 'low', label: 'Low' },
|
||||
{ value: 'medium', label: 'Medium' },
|
||||
{ value: 'high', label: 'High' },
|
||||
{ value: 'critical', label: 'Critical' },
|
||||
{ value: 'low', label: 'Низкий' },
|
||||
{ value: 'medium', label: 'Средний' },
|
||||
{ value: 'high', label: 'Высокий' },
|
||||
{ value: 'critical', label: 'Критичный' },
|
||||
];
|
||||
|
||||
const initialFormData: CreateIdeaDto = {
|
||||
@ -76,17 +76,17 @@ export function CreateIdeaModal() {
|
||||
fullWidth
|
||||
>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<DialogTitle>Create New Idea</DialogTitle>
|
||||
<DialogTitle>Новая идея</DialogTitle>
|
||||
<DialogContent>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, mt: 1 }}>
|
||||
{createIdea.isError && (
|
||||
<Alert severity="error">
|
||||
Failed to create idea. Please try again.
|
||||
Не удалось создать идею. Попробуйте снова.
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<TextField
|
||||
label="Title"
|
||||
label="Название"
|
||||
value={formData.title}
|
||||
onChange={(e) => handleChange('title', e.target.value)}
|
||||
required
|
||||
@ -94,7 +94,7 @@ export function CreateIdeaModal() {
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label="Description"
|
||||
label="Описание"
|
||||
value={formData.description}
|
||||
onChange={(e) => handleChange('description', e.target.value)}
|
||||
multiline
|
||||
@ -103,10 +103,10 @@ export function CreateIdeaModal() {
|
||||
|
||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel>Status</InputLabel>
|
||||
<InputLabel>Статус</InputLabel>
|
||||
<Select
|
||||
value={formData.status}
|
||||
label="Status"
|
||||
label="Статус"
|
||||
onChange={(e) => handleChange('status', e.target.value)}
|
||||
>
|
||||
{statusOptions.map((opt) => (
|
||||
@ -118,10 +118,10 @@ export function CreateIdeaModal() {
|
||||
</FormControl>
|
||||
|
||||
<FormControl fullWidth>
|
||||
<InputLabel>Priority</InputLabel>
|
||||
<InputLabel>Приоритет</InputLabel>
|
||||
<Select
|
||||
value={formData.priority}
|
||||
label="Priority"
|
||||
label="Приоритет"
|
||||
onChange={(e) => handleChange('priority', e.target.value)}
|
||||
>
|
||||
{priorityOptions.map((opt) => (
|
||||
@ -134,57 +134,57 @@ export function CreateIdeaModal() {
|
||||
</Box>
|
||||
|
||||
<TextField
|
||||
label="Module"
|
||||
label="Модуль"
|
||||
value={formData.module}
|
||||
onChange={(e) => handleChange('module', e.target.value)}
|
||||
placeholder="e.g., Auth, Dashboard, API"
|
||||
placeholder="например: Авторизация, Дашборд, API"
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label="Target Audience"
|
||||
label="Целевая аудитория"
|
||||
value={formData.targetAudience}
|
||||
onChange={(e) => handleChange('targetAudience', e.target.value)}
|
||||
placeholder="Who is this for?"
|
||||
placeholder="Для кого это?"
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label="Pain Point"
|
||||
label="Боль"
|
||||
value={formData.pain}
|
||||
onChange={(e) => handleChange('pain', e.target.value)}
|
||||
multiline
|
||||
rows={2}
|
||||
placeholder="What problem does this solve?"
|
||||
placeholder="Какую проблему это решает?"
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label="AI Role"
|
||||
label="Роль AI"
|
||||
value={formData.aiRole}
|
||||
onChange={(e) => handleChange('aiRole', e.target.value)}
|
||||
multiline
|
||||
rows={2}
|
||||
placeholder="How can AI help with this?"
|
||||
placeholder="Как AI может помочь с этим?"
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label="Verification Method"
|
||||
label="Способ проверки"
|
||||
value={formData.verificationMethod}
|
||||
onChange={(e) =>
|
||||
handleChange('verificationMethod', e.target.value)
|
||||
}
|
||||
multiline
|
||||
rows={2}
|
||||
placeholder="How to verify this is done?"
|
||||
placeholder="Как проверить, что это готово?"
|
||||
/>
|
||||
</Box>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={handleClose}>Cancel</Button>
|
||||
<Button onClick={handleClose}>Отмена</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
disabled={!formData.title || createIdea.isPending}
|
||||
>
|
||||
{createIdea.isPending ? 'Creating...' : 'Create'}
|
||||
{createIdea.isPending ? 'Создание...' : 'Создать'}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</form>
|
||||
|
||||
@ -15,18 +15,18 @@ import { useModulesQuery } from '../../hooks/useIdeas';
|
||||
import type { IdeaStatus, IdeaPriority } from '../../types/idea';
|
||||
|
||||
const statusOptions: { value: IdeaStatus; label: string }[] = [
|
||||
{ value: 'backlog', label: 'Backlog' },
|
||||
{ value: 'todo', label: 'To Do' },
|
||||
{ value: 'in_progress', label: 'In Progress' },
|
||||
{ value: 'done', label: 'Done' },
|
||||
{ value: 'cancelled', label: 'Cancelled' },
|
||||
{ value: 'backlog', label: 'Бэклог' },
|
||||
{ value: 'todo', label: 'К выполнению' },
|
||||
{ value: 'in_progress', label: 'В работе' },
|
||||
{ value: 'done', label: 'Готово' },
|
||||
{ value: 'cancelled', label: 'Отменено' },
|
||||
];
|
||||
|
||||
const priorityOptions: { value: IdeaPriority; label: string }[] = [
|
||||
{ value: 'low', label: 'Low' },
|
||||
{ value: 'medium', label: 'Medium' },
|
||||
{ value: 'high', label: 'High' },
|
||||
{ value: 'critical', label: 'Critical' },
|
||||
{ value: 'low', label: 'Низкий' },
|
||||
{ value: 'medium', label: 'Средний' },
|
||||
{ value: 'high', label: 'Высокий' },
|
||||
{ value: 'critical', label: 'Критичный' },
|
||||
];
|
||||
|
||||
export function IdeasFilters() {
|
||||
@ -52,7 +52,7 @@ export function IdeasFilters() {
|
||||
>
|
||||
<TextField
|
||||
size="small"
|
||||
placeholder="Search ideas..."
|
||||
placeholder="Поиск идей..."
|
||||
value={searchValue}
|
||||
onChange={(e) => setSearchValue(e.target.value)}
|
||||
sx={{ minWidth: 200 }}
|
||||
@ -68,16 +68,16 @@ export function IdeasFilters() {
|
||||
/>
|
||||
|
||||
<FormControl size="small" sx={{ minWidth: 120 }}>
|
||||
<InputLabel>Status</InputLabel>
|
||||
<InputLabel>Статус</InputLabel>
|
||||
<Select<IdeaStatus | ''>
|
||||
value={filters.status ?? ''}
|
||||
label="Status"
|
||||
label="Статус"
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
setFilter('status', val === '' ? undefined : val);
|
||||
}}
|
||||
>
|
||||
<MenuItem value="">All</MenuItem>
|
||||
<MenuItem value="">Все</MenuItem>
|
||||
{statusOptions.map((opt) => (
|
||||
<MenuItem key={opt.value} value={opt.value}>
|
||||
{opt.label}
|
||||
@ -87,16 +87,16 @@ export function IdeasFilters() {
|
||||
</FormControl>
|
||||
|
||||
<FormControl size="small" sx={{ minWidth: 120 }}>
|
||||
<InputLabel>Priority</InputLabel>
|
||||
<InputLabel>Приоритет</InputLabel>
|
||||
<Select<IdeaPriority | ''>
|
||||
value={filters.priority ?? ''}
|
||||
label="Priority"
|
||||
label="Приоритет"
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
setFilter('priority', val === '' ? undefined : val);
|
||||
}}
|
||||
>
|
||||
<MenuItem value="">All</MenuItem>
|
||||
<MenuItem value="">Все</MenuItem>
|
||||
{priorityOptions.map((opt) => (
|
||||
<MenuItem key={opt.value} value={opt.value}>
|
||||
{opt.label}
|
||||
@ -106,13 +106,13 @@ export function IdeasFilters() {
|
||||
</FormControl>
|
||||
|
||||
<FormControl size="small" sx={{ minWidth: 120 }}>
|
||||
<InputLabel>Module</InputLabel>
|
||||
<InputLabel>Модуль</InputLabel>
|
||||
<Select
|
||||
value={filters.module ?? ''}
|
||||
label="Module"
|
||||
label="Модуль"
|
||||
onChange={(e) => setFilter('module', e.target.value || undefined)}
|
||||
>
|
||||
<MenuItem value="">All</MenuItem>
|
||||
<MenuItem value="">Все</MenuItem>
|
||||
{modules.map((module) => (
|
||||
<MenuItem key={module} value={module}>
|
||||
{module}
|
||||
@ -130,7 +130,7 @@ export function IdeasFilters() {
|
||||
setSearchValue('');
|
||||
}}
|
||||
>
|
||||
Clear
|
||||
Сбросить
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
@ -82,6 +82,7 @@ export function EditableCell({
|
||||
onKeyDown={handleKeyDown}
|
||||
autoFocus
|
||||
sx={{ minWidth: 100 }}
|
||||
MenuProps={{ disablePortal: true }}
|
||||
>
|
||||
{options.map((opt) => (
|
||||
<MenuItem key={opt.value} value={opt.value}>
|
||||
|
||||
@ -62,7 +62,7 @@ export function IdeasTable() {
|
||||
if (isError) {
|
||||
return (
|
||||
<Box sx={{ p: 4, textAlign: 'center' }}>
|
||||
<Typography color="error">Failed to load ideas</Typography>
|
||||
<Typography color="error">Не удалось загрузить идеи</Typography>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@ -137,9 +137,9 @@ export function IdeasTable() {
|
||||
}}
|
||||
>
|
||||
<Inbox sx={{ fontSize: 48, mb: 2, opacity: 0.5 }} />
|
||||
<Typography variant="h6">No ideas yet</Typography>
|
||||
<Typography variant="h6">Идей пока нет</Typography>
|
||||
<Typography variant="body2">
|
||||
Create your first idea to get started
|
||||
Создайте первую идею, чтобы начать
|
||||
</Typography>
|
||||
</Box>
|
||||
</TableCell>
|
||||
|
||||
@ -30,7 +30,7 @@ const priorityColors: Record<
|
||||
|
||||
export const createColumns = (onDelete: (id: string) => void) => [
|
||||
columnHelper.accessor('title', {
|
||||
header: 'Title',
|
||||
header: 'Название',
|
||||
cell: (info) => (
|
||||
<EditableCell
|
||||
idea={info.row.original}
|
||||
@ -44,7 +44,7 @@ export const createColumns = (onDelete: (id: string) => void) => [
|
||||
size: 250,
|
||||
}),
|
||||
columnHelper.accessor('status', {
|
||||
header: 'Status',
|
||||
header: 'Статус',
|
||||
cell: (info) => {
|
||||
const status = info.getValue();
|
||||
const label =
|
||||
@ -65,7 +65,7 @@ export const createColumns = (onDelete: (id: string) => void) => [
|
||||
size: 140,
|
||||
}),
|
||||
columnHelper.accessor('priority', {
|
||||
header: 'Priority',
|
||||
header: 'Приоритет',
|
||||
cell: (info) => {
|
||||
const priority = info.getValue();
|
||||
const label =
|
||||
@ -91,7 +91,7 @@ export const createColumns = (onDelete: (id: string) => void) => [
|
||||
size: 120,
|
||||
}),
|
||||
columnHelper.accessor('module', {
|
||||
header: 'Module',
|
||||
header: 'Модуль',
|
||||
cell: (info) => (
|
||||
<EditableCell
|
||||
idea={info.row.original}
|
||||
@ -103,7 +103,7 @@ export const createColumns = (onDelete: (id: string) => void) => [
|
||||
size: 120,
|
||||
}),
|
||||
columnHelper.accessor('targetAudience', {
|
||||
header: 'Target Audience',
|
||||
header: 'Целевая аудитория',
|
||||
cell: (info) => (
|
||||
<EditableCell
|
||||
idea={info.row.original}
|
||||
@ -115,7 +115,7 @@ export const createColumns = (onDelete: (id: string) => void) => [
|
||||
size: 150,
|
||||
}),
|
||||
columnHelper.accessor('description', {
|
||||
header: 'Description',
|
||||
header: 'Описание',
|
||||
cell: (info) => {
|
||||
const value = info.getValue();
|
||||
return (
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import type { IdeaStatus, IdeaPriority } from '../../types/idea';
|
||||
|
||||
export const statusOptions: { value: IdeaStatus; label: string }[] = [
|
||||
{ value: 'backlog', label: 'Backlog' },
|
||||
{ value: 'todo', label: 'To Do' },
|
||||
{ value: 'in_progress', label: 'In Progress' },
|
||||
{ value: 'done', label: 'Done' },
|
||||
{ value: 'cancelled', label: 'Cancelled' },
|
||||
{ value: 'backlog', label: 'Бэклог' },
|
||||
{ value: 'todo', label: 'К выполнению' },
|
||||
{ value: 'in_progress', label: 'В работе' },
|
||||
{ value: 'done', label: 'Готово' },
|
||||
{ value: 'cancelled', label: 'Отменено' },
|
||||
];
|
||||
|
||||
export const priorityOptions: { value: IdeaPriority; label: string }[] = [
|
||||
{ value: 'low', label: 'Low' },
|
||||
{ value: 'medium', label: 'Medium' },
|
||||
{ value: 'high', label: 'High' },
|
||||
{ value: 'critical', label: 'Critical' },
|
||||
{ value: 'low', label: 'Низкий' },
|
||||
{ value: 'medium', label: 'Средний' },
|
||||
{ value: 'high', label: 'Высокий' },
|
||||
{ value: 'critical', label: 'Критичный' },
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user