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">{{ asset.asset_tag ?? '—' }}</td>
|
||||||
<td class="px-4 py-4">
|
<td class="px-4 py-4">
|
||||||
<template v-if="asset.active_assignment">
|
<template v-if="asset.active_assignment">
|
||||||
<p class="font-medium">{{ asset.active_assignment.employee.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 }}</p>
|
<p class="text-xs text-surface-500">{{ asset.active_assignment.employee?.department?.name ?? (asset.active_assignment as any).external_company ?? '' }}</p>
|
||||||
</template>
|
</template>
|
||||||
<span v-else class="text-surface-400">Sin asignar</span>
|
<span v-else class="text-surface-400">Sin asignar</span>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@ -49,7 +49,7 @@ const loadAsset = async () => {
|
|||||||
residual_value: asset.residual_value ? parseFloat(asset.residual_value) : null,
|
residual_value: asset.residual_value ? parseFloat(asset.residual_value) : null,
|
||||||
asset_tag: asset.asset_tag ?? '',
|
asset_tag: asset.asset_tag ?? '',
|
||||||
warranty_days: asset.warranty_days,
|
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 ?? '';
|
currentProductName.value = asset.inventory_warehouse?.product?.name ?? '';
|
||||||
} catch {
|
} catch {
|
||||||
@ -140,7 +140,8 @@ const saveAsset = async () => {
|
|||||||
<template #content>
|
<template #content>
|
||||||
<div class="space-y-1">
|
<div class="space-y-1">
|
||||||
<p class="text-sm text-surface-500">Producto</p>
|
<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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Card>
|
</Card>
|
||||||
@ -153,12 +154,8 @@ const saveAsset = async () => {
|
|||||||
|
|
||||||
<div class="flex flex-wrap items-center justify-end gap-3">
|
<div class="flex flex-wrap items-center justify-end gap-3">
|
||||||
<Button label="Cancelar" text severity="secondary" @click="cancel" />
|
<Button label="Cancelar" text severity="secondary" @click="cancel" />
|
||||||
<Button
|
<Button :label="isEditing ? 'Guardar Cambios' : 'Guardar Registro'" icon="pi pi-save" :loading="saving"
|
||||||
:label="isEditing ? 'Guardar Cambios' : 'Guardar Registro'"
|
@click="saveAsset" />
|
||||||
icon="pi pi-save"
|
|
||||||
:loading="saving"
|
|
||||||
@click="saveAsset"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -8,6 +8,13 @@ interface Props {
|
|||||||
employees: AssignmentEmployeeOption[];
|
employees: AssignmentEmployeeOption[];
|
||||||
searchTerm: string;
|
searchTerm: string;
|
||||||
selectedEmployeeId: number | null;
|
selectedEmployeeId: number | null;
|
||||||
|
assigneeType: 1 | 2;
|
||||||
|
externalName: string;
|
||||||
|
externalPaternal: string;
|
||||||
|
externalMaternal: string;
|
||||||
|
externalCompany: string;
|
||||||
|
externalPhone: string;
|
||||||
|
externalEmail: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>();
|
const props = defineProps<Props>();
|
||||||
@ -15,6 +22,13 @@ const props = defineProps<Props>();
|
|||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:searchTerm', value: string): void;
|
(e: 'update:searchTerm', value: string): void;
|
||||||
(e: 'update:selectedEmployeeId', value: number): 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(() => {
|
const visibleEmployees = computed(() => {
|
||||||
@ -31,13 +45,38 @@ const visibleEmployees = computed(() => {
|
|||||||
<template>
|
<template>
|
||||||
<Card class="shadow-sm">
|
<Card class="shadow-sm">
|
||||||
<template #title>
|
<template #title>
|
||||||
<div class="flex items-center gap-2 text-xl">
|
<div class="flex items-center justify-between gap-2">
|
||||||
<i class="pi pi-users text-primary"></i>
|
<div class="flex items-center gap-2 text-xl">
|
||||||
<span>Seleccionar Colaborador</span>
|
<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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="space-y-4">
|
<!-- Empleado interno -->
|
||||||
|
<div v-if="assigneeType === 1" class="space-y-4">
|
||||||
<InputText
|
<InputText
|
||||||
:model-value="searchTerm"
|
:model-value="searchTerm"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
@ -75,6 +114,66 @@ const visibleEmployees = computed(() => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</template>
|
||||||
</Card>
|
</Card>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -28,7 +28,14 @@ const users = ref<UserOption[]>([]);
|
|||||||
|
|
||||||
const form = ref<FixedAssetAssignmentFormData>({
|
const form = ref<FixedAssetAssignmentFormData>({
|
||||||
assetId: null,
|
assetId: null,
|
||||||
|
assigneeType: 1,
|
||||||
employeeId: null,
|
employeeId: null,
|
||||||
|
externalName: '',
|
||||||
|
externalPaternal: '',
|
||||||
|
externalMaternal: '',
|
||||||
|
externalCompany: '',
|
||||||
|
externalPhone: '',
|
||||||
|
externalEmail: '',
|
||||||
authorizedById: null,
|
authorizedById: null,
|
||||||
deliveredById: null,
|
deliveredById: null,
|
||||||
assignedAt: new Date().toISOString().slice(0, 10),
|
assignedAt: new Date().toISOString().slice(0, 10),
|
||||||
@ -81,11 +88,16 @@ onMounted(async () => {
|
|||||||
const cancel = () => router.push('/fixed-assets/assignments');
|
const cancel = () => router.push('/fixed-assets/assignments');
|
||||||
|
|
||||||
const save = async () => {
|
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({
|
toast.add({
|
||||||
severity: 'warn',
|
severity: 'warn',
|
||||||
summary: 'Campos pendientes',
|
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
|
life: 3000
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -94,7 +106,17 @@ const save = async () => {
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
await fixedAssetsService.assignAsset(form.value.assetId, {
|
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,
|
assigned_at: form.value.assignedAt,
|
||||||
receipt_folio: form.value.receiptFolio || undefined,
|
receipt_folio: form.value.receiptFolio || undefined,
|
||||||
authorized_by: form.value.authorizedById ?? undefined,
|
authorized_by: form.value.authorizedById ?? undefined,
|
||||||
@ -125,10 +147,10 @@ const save = async () => {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-3xl font-black tracking-tight text-surface-900 dark:text-surface-0">
|
<h1 class="text-3xl font-black tracking-tight text-surface-900 dark:text-surface-0">
|
||||||
Asignacion de Activo a Empleado
|
Asignacion de Activo
|
||||||
</h1>
|
</h1>
|
||||||
<p class="mt-1 text-surface-500 dark:text-surface-400">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -145,8 +167,22 @@ const save = async () => {
|
|||||||
:employees="employees"
|
:employees="employees"
|
||||||
:search-term="employeeSearch"
|
:search-term="employeeSearch"
|
||||||
:selected-employee-id="form.employeeId"
|
: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:search-term="employeeSearch = $event"
|
||||||
@update:selected-employee-id="form.employeeId = $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" />
|
<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' });
|
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;
|
const e = assignment.employee;
|
||||||
if (!e) return '—';
|
if (!e) return '—';
|
||||||
return `${e.name} ${e.paternal} ${e.maternal ?? ''}`.trim();
|
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 () => {
|
const loadAssignments = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
@ -139,7 +148,7 @@ onMounted(loadAssignments);
|
|||||||
<thead>
|
<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">
|
<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">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 Entrega</th>
|
||||||
<th class="px-4 py-3">Fecha Devolucion</th>
|
<th class="px-4 py-3">Fecha Devolucion</th>
|
||||||
<th class="px-4 py-3">Estado</th>
|
<th class="px-4 py-3">Estado</th>
|
||||||
@ -168,10 +177,10 @@ onMounted(loadAssignments);
|
|||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-3">
|
<td class="px-4 py-3">
|
||||||
<p class="font-semibold text-surface-900 dark:text-surface-0">
|
<p class="font-semibold text-surface-900 dark:text-surface-0">
|
||||||
{{ employeeFullName(assignment) }}
|
{{ assigneeName(assignment) }}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-xs text-surface-500 dark:text-surface-400">
|
<p class="text-xs text-surface-500 dark:text-surface-400">
|
||||||
{{ assignment.employee?.department?.name ?? '—' }}
|
{{ assigneeSubtitle(assignment) }}
|
||||||
</p>
|
</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-3">{{ formatDate(assignment.assigned_at) }}</td>
|
<td class="px-4 py-3">{{ formatDate(assignment.assigned_at) }}</td>
|
||||||
|
|||||||
@ -86,7 +86,14 @@ interface AssetFilters {
|
|||||||
export interface AssetAssignment {
|
export interface AssetAssignment {
|
||||||
id: number;
|
id: number;
|
||||||
asset_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;
|
assigned_at: string;
|
||||||
returned_at: string | null;
|
returned_at: string | null;
|
||||||
receipt_folio: string | null;
|
receipt_folio: string | null;
|
||||||
@ -133,7 +140,14 @@ export interface UsersResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface AssignAssetData {
|
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;
|
assigned_at?: string;
|
||||||
receipt_folio?: string;
|
receipt_folio?: string;
|
||||||
authorized_by?: number;
|
authorized_by?: number;
|
||||||
|
|||||||
@ -16,7 +16,14 @@ export interface AssignmentEmployeeOption {
|
|||||||
|
|
||||||
export interface FixedAssetAssignmentFormData {
|
export interface FixedAssetAssignmentFormData {
|
||||||
assetId: number | null;
|
assetId: number | null;
|
||||||
|
assigneeType: 1 | 2;
|
||||||
employeeId: number | null;
|
employeeId: number | null;
|
||||||
|
externalName: string;
|
||||||
|
externalPaternal: string;
|
||||||
|
externalMaternal: string;
|
||||||
|
externalCompany: string;
|
||||||
|
externalPhone: string;
|
||||||
|
externalEmail: string;
|
||||||
authorizedById: number | null;
|
authorizedById: number | null;
|
||||||
deliveredById: number | null;
|
deliveredById: number | null;
|
||||||
assignedAt: string;
|
assignedAt: string;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user