Refactor code structure for improved readability and maintainability
This commit is contained in:
parent
817e6c76c4
commit
8632e5c34a
1923
pnpm-lock.yaml
generated
Normal file
1923
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -237,8 +237,8 @@ const handleDelete = (asset: Asset) => {
|
||||
<td class="px-4 py-4">{{ asset.asset_tag ?? '—' }}</td>
|
||||
<td class="px-4 py-4">
|
||||
<template v-if="asset.active_assignment">
|
||||
<p class="font-medium">{{ asset.active_assignment.employee.name }}</p>
|
||||
<p class="text-xs text-surface-500">{{ asset.active_assignment.employee.department?.name }}</p>
|
||||
<p class="font-medium">{{ asset.active_assignment.employee?.name ?? (asset.active_assignment as any).external_name ?? '—' }}</p>
|
||||
<p class="text-xs text-surface-500">{{ asset.active_assignment.employee?.department?.name ?? (asset.active_assignment as any).external_company ?? '' }}</p>
|
||||
</template>
|
||||
<span v-else class="text-surface-400">Sin asignar</span>
|
||||
</td>
|
||||
|
||||
@ -49,7 +49,7 @@ const loadAsset = async () => {
|
||||
residual_value: asset.residual_value ? parseFloat(asset.residual_value) : null,
|
||||
asset_tag: asset.asset_tag ?? '',
|
||||
warranty_days: asset.warranty_days,
|
||||
warranty_end_date: asset.warranty_end_date ?? ''
|
||||
warranty_end_date: asset.warranty_end_date?.slice(0, 10) ?? ''
|
||||
};
|
||||
currentProductName.value = asset.inventory_warehouse?.product?.name ?? '';
|
||||
} catch {
|
||||
@ -140,7 +140,8 @@ const saveAsset = async () => {
|
||||
<template #content>
|
||||
<div class="space-y-1">
|
||||
<p class="text-sm text-surface-500">Producto</p>
|
||||
<p class="font-semibold text-surface-900 dark:text-surface-0">{{ currentProductName || '—' }}</p>
|
||||
<p class="font-semibold text-surface-900 dark:text-surface-0">{{ currentProductName || '—' }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</Card>
|
||||
@ -153,12 +154,8 @@ const saveAsset = async () => {
|
||||
|
||||
<div class="flex flex-wrap items-center justify-end gap-3">
|
||||
<Button label="Cancelar" text severity="secondary" @click="cancel" />
|
||||
<Button
|
||||
:label="isEditing ? 'Guardar Cambios' : 'Guardar Registro'"
|
||||
icon="pi pi-save"
|
||||
:loading="saving"
|
||||
@click="saveAsset"
|
||||
/>
|
||||
<Button :label="isEditing ? 'Guardar Cambios' : 'Guardar Registro'" icon="pi pi-save" :loading="saving"
|
||||
@click="saveAsset" />
|
||||
</div>
|
||||
</template>
|
||||
</section>
|
||||
|
||||
@ -8,6 +8,13 @@ interface Props {
|
||||
employees: AssignmentEmployeeOption[];
|
||||
searchTerm: string;
|
||||
selectedEmployeeId: number | null;
|
||||
assigneeType: 1 | 2;
|
||||
externalName: string;
|
||||
externalPaternal: string;
|
||||
externalMaternal: string;
|
||||
externalCompany: string;
|
||||
externalPhone: string;
|
||||
externalEmail: string;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
@ -15,6 +22,13 @@ const props = defineProps<Props>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:searchTerm', value: string): void;
|
||||
(e: 'update:selectedEmployeeId', value: number): void;
|
||||
(e: 'update:assigneeType', value: 1 | 2): void;
|
||||
(e: 'update:externalName', value: string): void;
|
||||
(e: 'update:externalPaternal', value: string): void;
|
||||
(e: 'update:externalMaternal', value: string): void;
|
||||
(e: 'update:externalCompany', value: string): void;
|
||||
(e: 'update:externalPhone', value: string): void;
|
||||
(e: 'update:externalEmail', value: string): void;
|
||||
}>();
|
||||
|
||||
const visibleEmployees = computed(() => {
|
||||
@ -31,13 +45,38 @@ const visibleEmployees = computed(() => {
|
||||
<template>
|
||||
<Card class="shadow-sm">
|
||||
<template #title>
|
||||
<div class="flex items-center gap-2 text-xl">
|
||||
<i class="pi pi-users text-primary"></i>
|
||||
<span>Seleccionar Colaborador</span>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div class="flex items-center gap-2 text-xl">
|
||||
<i class="pi pi-users text-primary"></i>
|
||||
<span>Seleccionar Asignado</span>
|
||||
</div>
|
||||
<div class="flex overflow-hidden rounded-lg border border-surface-200 text-sm dark:border-surface-700">
|
||||
<button
|
||||
type="button"
|
||||
class="px-4 py-1.5 font-medium transition-colors"
|
||||
:class="assigneeType === 1
|
||||
? 'bg-primary text-white'
|
||||
: 'text-surface-600 hover:bg-surface-100 dark:text-surface-300 dark:hover:bg-surface-800'"
|
||||
@click="emit('update:assigneeType', 1)"
|
||||
>
|
||||
Colaborador Interno
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="px-4 py-1.5 font-medium transition-colors"
|
||||
:class="assigneeType === 2
|
||||
? 'bg-primary text-white'
|
||||
: 'text-surface-600 hover:bg-surface-100 dark:text-surface-300 dark:hover:bg-surface-800'"
|
||||
@click="emit('update:assigneeType', 2)"
|
||||
>
|
||||
Persona Externa
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #content>
|
||||
<div class="space-y-4">
|
||||
<!-- Empleado interno -->
|
||||
<div v-if="assigneeType === 1" class="space-y-4">
|
||||
<InputText
|
||||
:model-value="searchTerm"
|
||||
class="w-full"
|
||||
@ -75,6 +114,66 @@ const visibleEmployees = computed(() => {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Persona externa -->
|
||||
<div v-else class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col gap-1">
|
||||
<label class="text-sm font-medium text-surface-700 dark:text-surface-300">
|
||||
Nombre <span class="text-red-500">*</span>
|
||||
</label>
|
||||
<InputText
|
||||
:model-value="externalName"
|
||||
placeholder="Nombre"
|
||||
class="w-full"
|
||||
@update:model-value="emit('update:externalName', String($event ?? ''))"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<label class="text-sm font-medium text-surface-700 dark:text-surface-300">Apellido Paterno</label>
|
||||
<InputText
|
||||
:model-value="externalPaternal"
|
||||
placeholder="Apellido paterno"
|
||||
class="w-full"
|
||||
@update:model-value="emit('update:externalPaternal', String($event ?? ''))"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<label class="text-sm font-medium text-surface-700 dark:text-surface-300">Apellido Materno</label>
|
||||
<InputText
|
||||
:model-value="externalMaternal"
|
||||
placeholder="Apellido materno"
|
||||
class="w-full"
|
||||
@update:model-value="emit('update:externalMaternal', String($event ?? ''))"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<label class="text-sm font-medium text-surface-700 dark:text-surface-300">Empresa / Organización</label>
|
||||
<InputText
|
||||
:model-value="externalCompany"
|
||||
placeholder="Empresa u organización"
|
||||
class="w-full"
|
||||
@update:model-value="emit('update:externalCompany', String($event ?? ''))"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<label class="text-sm font-medium text-surface-700 dark:text-surface-300">Teléfono</label>
|
||||
<InputText
|
||||
:model-value="externalPhone"
|
||||
placeholder="Teléfono de contacto"
|
||||
class="w-full"
|
||||
@update:model-value="emit('update:externalPhone', String($event ?? ''))"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<label class="text-sm font-medium text-surface-700 dark:text-surface-300">Correo electrónico</label>
|
||||
<InputText
|
||||
:model-value="externalEmail"
|
||||
placeholder="correo@ejemplo.com"
|
||||
class="w-full"
|
||||
@update:model-value="emit('update:externalEmail', String($event ?? ''))"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
@ -28,7 +28,14 @@ const users = ref<UserOption[]>([]);
|
||||
|
||||
const form = ref<FixedAssetAssignmentFormData>({
|
||||
assetId: null,
|
||||
assigneeType: 1,
|
||||
employeeId: null,
|
||||
externalName: '',
|
||||
externalPaternal: '',
|
||||
externalMaternal: '',
|
||||
externalCompany: '',
|
||||
externalPhone: '',
|
||||
externalEmail: '',
|
||||
authorizedById: null,
|
||||
deliveredById: null,
|
||||
assignedAt: new Date().toISOString().slice(0, 10),
|
||||
@ -81,11 +88,16 @@ onMounted(async () => {
|
||||
const cancel = () => router.push('/fixed-assets/assignments');
|
||||
|
||||
const save = async () => {
|
||||
if (!form.value.assetId || !form.value.employeeId) {
|
||||
const isExternal = form.value.assigneeType === 2;
|
||||
const missingAssignee = isExternal ? !form.value.externalName.trim() : !form.value.employeeId;
|
||||
|
||||
if (!form.value.assetId || missingAssignee) {
|
||||
toast.add({
|
||||
severity: 'warn',
|
||||
summary: 'Campos pendientes',
|
||||
detail: 'Seleccione un activo y un colaborador para confirmar la asignacion.',
|
||||
detail: isExternal
|
||||
? 'Seleccione un activo e ingrese el nombre de la persona externa.'
|
||||
: 'Seleccione un activo y un colaborador para confirmar la asignacion.',
|
||||
life: 3000
|
||||
});
|
||||
return;
|
||||
@ -94,7 +106,17 @@ const save = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
await fixedAssetsService.assignAsset(form.value.assetId, {
|
||||
employee_id: form.value.employeeId,
|
||||
assignee_type: form.value.assigneeType,
|
||||
...(isExternal ? {
|
||||
external_name: form.value.externalName,
|
||||
external_paternal: form.value.externalPaternal || undefined,
|
||||
external_maternal: form.value.externalMaternal || undefined,
|
||||
external_company: form.value.externalCompany || undefined,
|
||||
external_phone: form.value.externalPhone || undefined,
|
||||
external_email: form.value.externalEmail || undefined,
|
||||
} : {
|
||||
employee_id: form.value.employeeId ?? undefined,
|
||||
}),
|
||||
assigned_at: form.value.assignedAt,
|
||||
receipt_folio: form.value.receiptFolio || undefined,
|
||||
authorized_by: form.value.authorizedById ?? undefined,
|
||||
@ -125,10 +147,10 @@ const save = async () => {
|
||||
|
||||
<div>
|
||||
<h1 class="text-3xl font-black tracking-tight text-surface-900 dark:text-surface-0">
|
||||
Asignacion de Activo a Empleado
|
||||
Asignacion de Activo
|
||||
</h1>
|
||||
<p class="mt-1 text-surface-500 dark:text-surface-400">
|
||||
Registre la entrega de una herramienta o equipo a un colaborador del almacen.
|
||||
Registre la entrega de una herramienta o equipo a un colaborador o persona externa.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -145,8 +167,22 @@ const save = async () => {
|
||||
:employees="employees"
|
||||
:search-term="employeeSearch"
|
||||
:selected-employee-id="form.employeeId"
|
||||
:assignee-type="form.assigneeType"
|
||||
:external-name="form.externalName"
|
||||
:external-paternal="form.externalPaternal"
|
||||
:external-maternal="form.externalMaternal"
|
||||
:external-company="form.externalCompany"
|
||||
:external-phone="form.externalPhone"
|
||||
:external-email="form.externalEmail"
|
||||
@update:search-term="employeeSearch = $event"
|
||||
@update:selected-employee-id="form.employeeId = $event"
|
||||
@update:assignee-type="form.assigneeType = $event; form.employeeId = null; form.externalName = ''"
|
||||
@update:external-name="form.externalName = $event"
|
||||
@update:external-paternal="form.externalPaternal = $event"
|
||||
@update:external-maternal="form.externalMaternal = $event"
|
||||
@update:external-company="form.externalCompany = $event"
|
||||
@update:external-phone="form.externalPhone = $event"
|
||||
@update:external-email="form.externalEmail = $event"
|
||||
/>
|
||||
|
||||
<AssignmentDetailsCard :form="form" :users="users" />
|
||||
|
||||
@ -38,12 +38,21 @@ const formatDate = (dateStr: string | null) => {
|
||||
return new Date(dateStr).toLocaleDateString('es-MX', { day: '2-digit', month: 'short', year: 'numeric' });
|
||||
};
|
||||
|
||||
const employeeFullName = (assignment: AssetAssignment) => {
|
||||
const assigneeName = (assignment: AssetAssignment) => {
|
||||
if (assignment.assignee_type?.id === 2) {
|
||||
return [assignment.external_name, assignment.external_paternal, assignment.external_maternal]
|
||||
.filter(Boolean).join(' ') || '—';
|
||||
}
|
||||
const e = assignment.employee;
|
||||
if (!e) return '—';
|
||||
return `${e.name} ${e.paternal} ${e.maternal ?? ''}`.trim();
|
||||
};
|
||||
|
||||
const assigneeSubtitle = (assignment: AssetAssignment) => {
|
||||
if (assignment.assignee_type?.id === 2) return assignment.external_company ?? 'Externo';
|
||||
return assignment.employee?.department?.name ?? '—';
|
||||
};
|
||||
|
||||
const loadAssignments = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
@ -139,7 +148,7 @@ onMounted(loadAssignments);
|
||||
<thead>
|
||||
<tr class="bg-surface-50 text-left text-xs font-semibold uppercase tracking-wide text-surface-500 dark:bg-surface-800 dark:text-surface-300">
|
||||
<th class="px-4 py-3">Activo</th>
|
||||
<th class="px-4 py-3">Empleado</th>
|
||||
<th class="px-4 py-3">Asignado a</th>
|
||||
<th class="px-4 py-3">Fecha Entrega</th>
|
||||
<th class="px-4 py-3">Fecha Devolucion</th>
|
||||
<th class="px-4 py-3">Estado</th>
|
||||
@ -168,10 +177,10 @@ onMounted(loadAssignments);
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<p class="font-semibold text-surface-900 dark:text-surface-0">
|
||||
{{ employeeFullName(assignment) }}
|
||||
{{ assigneeName(assignment) }}
|
||||
</p>
|
||||
<p class="text-xs text-surface-500 dark:text-surface-400">
|
||||
{{ assignment.employee?.department?.name ?? '—' }}
|
||||
{{ assigneeSubtitle(assignment) }}
|
||||
</p>
|
||||
</td>
|
||||
<td class="px-4 py-3">{{ formatDate(assignment.assigned_at) }}</td>
|
||||
|
||||
@ -86,7 +86,14 @@ interface AssetFilters {
|
||||
export interface AssetAssignment {
|
||||
id: number;
|
||||
asset_id: number;
|
||||
employee_id: number;
|
||||
employee_id: number | null;
|
||||
assignee_type: { id: number; name: string };
|
||||
external_name: string | null;
|
||||
external_paternal: string | null;
|
||||
external_maternal: string | null;
|
||||
external_company: string | null;
|
||||
external_phone: string | null;
|
||||
external_email: string | null;
|
||||
assigned_at: string;
|
||||
returned_at: string | null;
|
||||
receipt_folio: string | null;
|
||||
@ -133,7 +140,14 @@ export interface UsersResponse {
|
||||
}
|
||||
|
||||
interface AssignAssetData {
|
||||
employee_id: number;
|
||||
assignee_type: number;
|
||||
employee_id?: number;
|
||||
external_name?: string;
|
||||
external_paternal?: string;
|
||||
external_maternal?: string;
|
||||
external_company?: string;
|
||||
external_phone?: string;
|
||||
external_email?: string;
|
||||
assigned_at?: string;
|
||||
receipt_folio?: string;
|
||||
authorized_by?: number;
|
||||
|
||||
@ -16,7 +16,14 @@ export interface AssignmentEmployeeOption {
|
||||
|
||||
export interface FixedAssetAssignmentFormData {
|
||||
assetId: number | null;
|
||||
assigneeType: 1 | 2;
|
||||
employeeId: number | null;
|
||||
externalName: string;
|
||||
externalPaternal: string;
|
||||
externalMaternal: string;
|
||||
externalCompany: string;
|
||||
externalPhone: string;
|
||||
externalEmail: string;
|
||||
authorizedById: number | null;
|
||||
deliveredById: number | null;
|
||||
assignedAt: string;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user