Aufgaben-Tabelle: inline bearbeitbar, Zuweisung direkt sichtbar
Enddatum und Status lassen sich jetzt direkt in der Tabelle ändern, Zuweisungen können entfernt werden und das Zuweisungsformular ist direkt in der Zugewiesen-Spalte statt versteckt im Verwalten-Bereich, damit auch bei bereits bestehenden Aufgaben nachträglich Mitarbeiter zugewiesen werden können. Zusätzlich verhindert ein Guard doppeltes Duplizieren durch Mehrfachklick.
This commit is contained in:
@@ -7,6 +7,7 @@ const newProject = reactive({ name: '', description: '', start_date: '', end_dat
|
||||
const newTask = reactive({});
|
||||
const newAssignment = reactive({});
|
||||
const newDuplicate = reactive({});
|
||||
const duplicating = reactive({});
|
||||
const expanded = reactive({});
|
||||
|
||||
async function addProject() {
|
||||
@@ -45,10 +46,16 @@ function duplicateForm(taskId) {
|
||||
}
|
||||
|
||||
async function duplicateTask(projectId, taskId) {
|
||||
if (duplicating[taskId]) return;
|
||||
const form = duplicateForm(taskId);
|
||||
if (!form.start_date || !form.end_date) return;
|
||||
duplicating[taskId] = true;
|
||||
try {
|
||||
await store.duplicateTask(projectId, taskId, { ...form });
|
||||
Object.assign(form, { start_date: '', end_date: '' });
|
||||
} finally {
|
||||
duplicating[taskId] = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -89,13 +96,41 @@ async function duplicateTask(projectId, taskId) {
|
||||
<tr v-for="task in project.tasks" :key="task.id">
|
||||
<td>{{ task.name }}</td>
|
||||
<td>{{ formatDate(task.start_date) }}</td>
|
||||
<td>{{ formatDate(task.end_date) }}</td>
|
||||
<td>
|
||||
<input
|
||||
type="date"
|
||||
:value="task.end_date"
|
||||
@change="store.updateTask(project.id, task.id, { end_date: $event.target.value })"
|
||||
/>
|
||||
</td>
|
||||
<td>{{ task.estimated_hours }}</td>
|
||||
<td>{{ task.status }}</td>
|
||||
<td>
|
||||
<select
|
||||
:value="task.status"
|
||||
@change="store.updateTask(project.id, task.id, { status: $event.target.value })"
|
||||
>
|
||||
<option value="geplant">geplant</option>
|
||||
<option value="in Arbeit">in Arbeit</option>
|
||||
<option value="erledigt">erledigt</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<span v-for="a in task.assignments" :key="a.id" class="tag">
|
||||
{{ a.employee_name }} ({{ a.allocated_hours_per_week }}h)
|
||||
<button
|
||||
class="tag-remove"
|
||||
title="Zuweisung entfernen"
|
||||
@click="store.unassignEmployee(project.id, task.id, a.id)"
|
||||
>×</button>
|
||||
</span>
|
||||
<div class="assign-inline">
|
||||
<select v-model="assignmentForm(task.id).employee_id">
|
||||
<option value="" disabled>Mitarbeiter wählen</option>
|
||||
<option v-for="e in store.employees" :key="e.id" :value="e.id">{{ fullName(e) }}</option>
|
||||
</select>
|
||||
<input v-model.number="assignmentForm(task.id).allocated_hours_per_week" type="number" style="width: 70px" placeholder="Std/Woche" />
|
||||
<button class="btn secondary" @click="addAssignment(project.id, task.id)">Zuweisen</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -118,19 +153,15 @@ async function duplicateTask(projectId, taskId) {
|
||||
|
||||
<div v-for="task in project.tasks" :key="'manage-' + task.id" style="border: 1px solid var(--border); border-radius: 6px; padding: 8px; margin-bottom: 8px">
|
||||
<strong>{{ task.name }}</strong>
|
||||
<div class="form-row">
|
||||
<select v-model="assignmentForm(task.id).employee_id">
|
||||
<option value="" disabled>Mitarbeiter wählen</option>
|
||||
<option v-for="e in store.employees" :key="e.id" :value="e.id">{{ fullName(e) }}</option>
|
||||
</select>
|
||||
<input v-model.number="assignmentForm(task.id).allocated_hours_per_week" type="number" style="width: 90px" placeholder="Std/Woche" />
|
||||
<button class="btn secondary" @click="addAssignment(project.id, task.id)">Zuweisen</button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<span class="muted">Aufgabe zu anderem Zeitraum wiederholen:</span>
|
||||
<input v-model="duplicateForm(task.id).start_date" type="date" />
|
||||
<input v-model="duplicateForm(task.id).end_date" type="date" />
|
||||
<button class="btn secondary" @click="duplicateTask(project.id, task.id)">Duplizieren</button>
|
||||
<button
|
||||
class="btn secondary"
|
||||
:disabled="duplicating[task.id]"
|
||||
@click="duplicateTask(project.id, task.id)"
|
||||
>Duplizieren</button>
|
||||
<button class="btn danger" @click="store.deleteTask(project.id, task.id)">Aufgabe löschen</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+31
-1
@@ -212,7 +212,9 @@ button.btn.danger {
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: inline-block;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
@@ -221,6 +223,34 @@ button.btn.danger {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.tag-remove {
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
font-size: 13px;
|
||||
line-height: 1;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.assign-inline {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.assign-inline select,
|
||||
.assign-inline input {
|
||||
padding: 4px 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.assign-inline button {
|
||||
padding: 4px 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.muted {
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
|
||||
Reference in New Issue
Block a user