panels-origin/web-panel/components/padron/WorkerAssignments.vue
2026-08-21 16:55:01 -05:00

60 lines
3 KiB
Vue

<template>
<div class="detail-section">
<div class="section-title">Asignaciones a proyectos</div>
<div class="muted">Una persona puede trabajar en varios proyectos activos al mismo tiempo.</div>
<div class="assignment-create mt-3">
<Select v-model="projectId" :options="availableProjects" option-label="name" option-value="id" placeholder="Proyecto activo" class="w-full" />
<Button label="Asignar" icon="pi pi-plus" :disabled="!projectId" @click="assignProject" />
</div>
<DataTable :value="assignments" size="small" class="mt-3" empty-message="Sin historial de asignaciones">
<Column header="Proyecto">
<template #body="{ data }">
<div><span class="identifier">{{ data.project_code }}</span><div>{{ data.project_name }}</div></div>
</template>
</Column>
<Column field="start_date" header="Inicio" />
<Column header="Estado">
<template #body="{ data }"><Tag :value="data.active ? 'Activa' : 'Finalizada'" :severity="data.active ? 'success' : 'secondary'" /></template>
</Column>
<Column header="">
<template #body="{ data }">
<Button v-if="data.active" icon="pi pi-times" text rounded severity="danger" size="small" aria-label="Finalizar asignación" @click="deactivate(data)" />
<Button v-else icon="pi pi-refresh" text rounded size="small" aria-label="Reactivar asignación" @click="reactivate(data)" />
</template>
</Column>
</DataTable>
</div>
</template>
<script setup lang="ts">
import type { ProjectOption } from "~/types/padron";
type Assignment = { id: number; project_id: number; project_name: string; project_code: string; active: number; start_date: string; end_date?: string | null };
const props = defineProps<{ workerId: number; assignments: Assignment[]; projects: ProjectOption[] }>();
const emit = defineEmits<{ changed: [] }>();
const { api } = useApi();
const confirm = useConfirm();
const toast = useToast();
const projectId = ref<number | null>(null);
const availableProjects = computed(() => props.projects.filter((project) => !props.assignments.some((assignment) => assignment.project_id === project.id && assignment.active)));
async function setAssignment(id: number, active: boolean) {
await api(`/v1/workers/${props.workerId}/assign`, { method: "POST", json: { project_id: id, active } });
toast.add({ severity: "success", summary: active ? "Asignación activa" : "Asignación finalizada", life: 1800 });
projectId.value = null;
emit("changed");
}
function assignProject() { if (projectId.value) setAssignment(projectId.value, true); }
function reactivate(assignment: Assignment) { setAssignment(assignment.project_id, true); }
function deactivate(assignment: Assignment) {
confirm.require({
header: "Finalizar asignación",
message: `¿Quitar a esta persona de ${assignment.project_name}? Se conservará la fecha en el historial.`,
icon: "pi pi-exclamation-triangle",
acceptLabel: "Finalizar",
rejectLabel: "Cancelar",
accept: () => setAssignment(assignment.project_id, false),
});
}
</script>