Add missing translations for project templates and task details
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
Adds new translation keys for project templates and task details in `en.json` and `de.json`, and updates `ProjectTemplate.tsx` to use these translations. Replit-Commit-Author: Agent Replit-Commit-Session-Id: ceced2fc-aa46-458d-ba87-ddd4b7bb1518 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/659922a9-0087-461c-90dd-6d9a58b81d4d/ceced2fc-aa46-458d-ba87-ddd4b7bb1518/iGgwDyZ
This commit is contained in:
@@ -30,10 +30,6 @@ externalPort = 3000
|
||||
localPort = 44261
|
||||
externalPort = 3003
|
||||
|
||||
[[ports]]
|
||||
localPort = 46755
|
||||
externalPort = 4200
|
||||
|
||||
[env]
|
||||
PORT = "5000"
|
||||
|
||||
|
||||
@@ -677,7 +677,7 @@ export default function ProjectTemplate({
|
||||
{/* Closed Projects Section */}
|
||||
<div className="space-y-4 mt-8">
|
||||
<div className="flex items-center justify-between">
|
||||
<h3 className="text-lg font-semibold">Closed Projects</h3>
|
||||
<h3 className="text-lg font-semibold">{t('projectTemplate.closedProjects')}</h3>
|
||||
<Input
|
||||
placeholder="Filter closed projects..."
|
||||
value={closedProjectsFilter}
|
||||
@@ -1124,25 +1124,25 @@ export default function ProjectTemplate({
|
||||
{/* Project Details */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium">Project Name</label>
|
||||
<label className="text-sm font-medium">{t('projectTemplate.projectName')}</label>
|
||||
<Input
|
||||
value={selectedProject.name}
|
||||
onChange={(e) => setSelectedProject({ ...selectedProject, name: e.target.value })}
|
||||
placeholder="Enter project name"
|
||||
placeholder={t('projectTemplate.projectNamePlaceholder')}
|
||||
data-testid="input-edit-project-name"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium">Description (Optional)</label>
|
||||
<label className="text-sm font-medium">{t('projectTemplate.projectDescription')}</label>
|
||||
<Input
|
||||
value={selectedProject.description || ''}
|
||||
onChange={(e) => setSelectedProject({ ...selectedProject, description: e.target.value })}
|
||||
placeholder="Enter project description"
|
||||
placeholder={t('projectTemplate.projectDescriptionPlaceholder')}
|
||||
data-testid="input-edit-project-description"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium">Status</label>
|
||||
<label className="text-sm font-medium">{t('projectTemplate.status')}</label>
|
||||
<Select
|
||||
value={selectedProject.status}
|
||||
onValueChange={(value: Project['status']) =>
|
||||
@@ -1153,9 +1153,9 @@ export default function ProjectTemplate({
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="planning">Planning</SelectItem>
|
||||
<SelectItem value="active">Active</SelectItem>
|
||||
<SelectItem value="finished">Finished</SelectItem>
|
||||
<SelectItem value="planning">{t('projectTemplate.planning')}</SelectItem>
|
||||
<SelectItem value="active">{t('projectTemplate.active')}</SelectItem>
|
||||
<SelectItem value="finished">{t('projectTemplate.finished')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
@@ -1163,7 +1163,7 @@ export default function ProjectTemplate({
|
||||
|
||||
{/* Planned End Date */}
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium">Planned End Date (Optional)</label>
|
||||
<label className="text-sm font-medium">{t('projectTemplate.plannedEndDate')}</label>
|
||||
<Popover open={isPlannedEndDateCalendarOpen} onOpenChange={setIsPlannedEndDateCalendarOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
@@ -1174,7 +1174,7 @@ export default function ProjectTemplate({
|
||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
||||
{selectedProject.plannedEndDate
|
||||
? selectedProject.plannedEndDate.toLocaleDateString()
|
||||
: "Select planned end date"}
|
||||
: t('projectTemplate.selectPlannedEndDate')}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
@@ -1198,7 +1198,7 @@ export default function ProjectTemplate({
|
||||
className="text-xs text-muted-foreground hover:text-destructive"
|
||||
data-testid="button-clear-planned-end-date"
|
||||
>
|
||||
Clear date
|
||||
{t('projectTemplate.clearDate')}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
@@ -1206,7 +1206,7 @@ export default function ProjectTemplate({
|
||||
{/* Tasks Section */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<h3 className="text-lg font-semibold">Project Tasks</h3>
|
||||
<h3 className="text-lg font-semibold">{t('projectTemplate.projectTasks')}</h3>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
@@ -1214,7 +1214,7 @@ export default function ProjectTemplate({
|
||||
data-testid="button-add-task-edit"
|
||||
>
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
Add Task
|
||||
{t('projectTemplate.addTask')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -1227,29 +1227,29 @@ export default function ProjectTemplate({
|
||||
<div className="space-y-3">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<div className="space-y-1">
|
||||
<label className="text-xs font-medium text-muted-foreground">Task Title</label>
|
||||
<label className="text-xs font-medium text-muted-foreground">{t('projectTemplate.taskTitle')}</label>
|
||||
<Input
|
||||
value={taskForm.title || ''}
|
||||
onChange={(e) => setTaskForm({...taskForm, title: e.target.value})}
|
||||
placeholder="Enter task title"
|
||||
placeholder={t('projectTemplate.enterTaskTitle')}
|
||||
className="text-sm"
|
||||
data-testid={`input-inline-task-title-${index}`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
<label className="text-xs font-medium text-muted-foreground">Description</label>
|
||||
<label className="text-xs font-medium text-muted-foreground">{t('projectTemplate.description')}</label>
|
||||
<Input
|
||||
value={taskForm.description || ''}
|
||||
onChange={(e) => setTaskForm({...taskForm, description: e.target.value})}
|
||||
placeholder="Enter task description"
|
||||
placeholder={t('projectTemplate.enterTaskDescription')}
|
||||
className="text-sm"
|
||||
data-testid={`input-inline-task-description-${index}`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
<label className="text-xs font-medium text-muted-foreground">Priority</label>
|
||||
<label className="text-xs font-medium text-muted-foreground">{t('projectTemplate.priority')}</label>
|
||||
<Select
|
||||
value={taskForm.priority || 'medium'}
|
||||
onValueChange={(value: ProjectTask['priority']) =>
|
||||
@@ -1260,15 +1260,15 @@ export default function ProjectTemplate({
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="low">Low</SelectItem>
|
||||
<SelectItem value="medium">Medium</SelectItem>
|
||||
<SelectItem value="high">High</SelectItem>
|
||||
<SelectItem value="low">{t('priority.low')}</SelectItem>
|
||||
<SelectItem value="medium">{t('priority.medium')}</SelectItem>
|
||||
<SelectItem value="high">{t('priority.high')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
<label className="text-xs font-medium text-muted-foreground">Status</label>
|
||||
<label className="text-xs font-medium text-muted-foreground">{t('projectTemplate.status')}</label>
|
||||
<Select
|
||||
value={taskForm.status || 'todo'}
|
||||
onValueChange={(value: ProjectTask['status']) =>
|
||||
@@ -1279,15 +1279,15 @@ export default function ProjectTemplate({
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="todo">To Do</SelectItem>
|
||||
<SelectItem value="inProgress">In Progress</SelectItem>
|
||||
<SelectItem value="done">Done</SelectItem>
|
||||
<SelectItem value="todo">{t('status.todo')}</SelectItem>
|
||||
<SelectItem value="inProgress">{t('status.inProgress')}</SelectItem>
|
||||
<SelectItem value="done">{t('status.done')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1 md:col-span-2">
|
||||
<label className="text-xs font-medium text-muted-foreground">Estimated Hours</label>
|
||||
<label className="text-xs font-medium text-muted-foreground">{t('projectTemplate.estimatedHours')}</label>
|
||||
<Input
|
||||
type="number"
|
||||
value={taskForm.estimatedHours || ''}
|
||||
@@ -1307,7 +1307,7 @@ export default function ProjectTemplate({
|
||||
onClick={handleCancelTaskEdit}
|
||||
data-testid={`button-cancel-inline-edit-${index}`}
|
||||
>
|
||||
Cancel
|
||||
{t('projectTemplate.cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
@@ -1315,7 +1315,7 @@ export default function ProjectTemplate({
|
||||
disabled={!taskForm.title?.trim()}
|
||||
data-testid={`button-save-inline-edit-${index}`}
|
||||
>
|
||||
Save Changes
|
||||
{t('projectTemplate.save')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1345,13 +1345,13 @@ export default function ProjectTemplate({
|
||||
) : null}
|
||||
{task.timeTracked && task.timeTracked > 0 && (
|
||||
<Badge variant="outline" className="text-xs bg-blue-50 text-blue-700 border-blue-200">
|
||||
{Math.floor(task.timeTracked / 60)}h {task.timeTracked % 60}m tracked
|
||||
{Math.floor(task.timeTracked / 60)}h {task.timeTracked % 60}m {t('projectTemplate.tracked')}
|
||||
</Badge>
|
||||
)}
|
||||
{task.notes && task.notes.trim() && (
|
||||
<Badge variant="outline" className="text-xs bg-green-50 text-green-700 border-green-200">
|
||||
<FileText className="w-3 h-3 mr-1" />
|
||||
Notes
|
||||
{t('projectTemplate.notesLabel')}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
@@ -1365,7 +1365,7 @@ export default function ProjectTemplate({
|
||||
handleOpenTaskDetails(task);
|
||||
}}
|
||||
data-testid={`button-details-task-${index}`}
|
||||
title="View task details"
|
||||
title={t('projectTemplate.viewTaskDetails')}
|
||||
>
|
||||
<FileText className="w-3 h-3" />
|
||||
</Button>
|
||||
@@ -1377,7 +1377,7 @@ export default function ProjectTemplate({
|
||||
handleEditTask(index);
|
||||
}}
|
||||
data-testid={`button-edit-task-edit-${index}`}
|
||||
title="Edit task"
|
||||
title={t('projectTemplate.editTaskTooltip')}
|
||||
>
|
||||
<Edit className="w-3 h-3" />
|
||||
</Button>
|
||||
@@ -1389,7 +1389,7 @@ export default function ProjectTemplate({
|
||||
handleRemoveTask(index);
|
||||
}}
|
||||
data-testid={`button-remove-task-edit-${index}`}
|
||||
title="Remove task"
|
||||
title={t('projectTemplate.removeTask')}
|
||||
>
|
||||
<Trash2 className="w-3 h-3" />
|
||||
</Button>
|
||||
@@ -1401,7 +1401,7 @@ export default function ProjectTemplate({
|
||||
|
||||
{projectTasks.length === 0 && (
|
||||
<div className="text-center text-muted-foreground text-sm py-8 border-2 border-dashed border-muted rounded-lg">
|
||||
No tasks in this project yet. Click "Add Task" to get started.
|
||||
{t('projectTemplate.noTasksInProject')}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -253,7 +253,14 @@
|
||||
"projectDescriptionPlaceholder": "Projektbeschreibung eingeben (optional)",
|
||||
"plannedEndDate": "Geplantes Enddatum",
|
||||
"selectPlannedEndDate": "Geplantes Enddatum wählen",
|
||||
"clearDate": "Datum löschen"
|
||||
"clearDate": "Datum löschen",
|
||||
"noTasksInProject": "Noch keine Aufgaben in diesem Projekt. Klicken Sie auf \"Aufgabe hinzufügen\", um zu beginnen.",
|
||||
"closedProjects": "Abgeschlossene Projekte",
|
||||
"viewTaskDetails": "Aufgabendetails anzeigen",
|
||||
"editTaskTooltip": "Aufgabe bearbeiten",
|
||||
"removeTask": "Aufgabe entfernen",
|
||||
"tracked": "verfolgt",
|
||||
"notesLabel": "Notizen"
|
||||
},
|
||||
"timeCompletion": {
|
||||
"title": "Aufgabe abgeschlossen!",
|
||||
|
||||
@@ -253,7 +253,14 @@
|
||||
"projectDescriptionPlaceholder": "Enter project description (optional)",
|
||||
"plannedEndDate": "Planned End Date",
|
||||
"selectPlannedEndDate": "Select planned end date",
|
||||
"clearDate": "Clear date"
|
||||
"clearDate": "Clear date",
|
||||
"noTasksInProject": "No tasks in this project yet. Click \"Add Task\" to get started.",
|
||||
"closedProjects": "Closed Projects",
|
||||
"viewTaskDetails": "View task details",
|
||||
"editTaskTooltip": "Edit task",
|
||||
"removeTask": "Remove task",
|
||||
"tracked": "tracked",
|
||||
"notesLabel": "Notes"
|
||||
},
|
||||
"timeCompletion": {
|
||||
"title": "Task Completed!",
|
||||
|
||||
Reference in New Issue
Block a user