Initial
This commit is contained in:
168
src/views/AssignmentsView.vue
Normal file
168
src/views/AssignmentsView.vue
Normal file
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<section class="content-grid">
|
||||
<v-card class="metric span-3">
|
||||
<div class="metric-label">Assigned</div>
|
||||
<div class="metric-value">{{ summary.active_assignments || 0 }}</div>
|
||||
<div class="metric-subtle">Assets with active custody</div>
|
||||
</v-card>
|
||||
<v-card class="metric span-3">
|
||||
<div class="metric-label">Unassigned</div>
|
||||
<div class="metric-value">{{ summary.unassigned_assets || 0 }}</div>
|
||||
<div class="metric-subtle">Need owner/location review</div>
|
||||
</v-card>
|
||||
<v-card class="metric span-3">
|
||||
<div class="metric-label">Employees</div>
|
||||
<div class="metric-value">{{ employees.length }}</div>
|
||||
<div class="metric-subtle">Manual or Workday synced</div>
|
||||
</v-card>
|
||||
<v-card class="metric span-3">
|
||||
<div class="metric-label">Locations</div>
|
||||
<div class="metric-value">{{ summary.assigned_locations || 0 }}</div>
|
||||
<div class="metric-subtle">Active assignment sites</div>
|
||||
</v-card>
|
||||
|
||||
<v-card class="span-5 panel-pad">
|
||||
<h2 class="section-title mb-4">Assign asset</h2>
|
||||
<v-select v-model="assignmentForm.asset_id" :items="assetOptions" item-title="title" item-value="value" label="Asset" />
|
||||
<v-select v-model="assignmentForm.employee_id" :items="employeeOptions" item-title="title" item-value="value" clearable label="Employee" @update:model-value="applyEmployeeDefaults" />
|
||||
<v-text-field v-model="assignmentForm.department" label="Department" />
|
||||
<v-text-field v-model="assignmentForm.location" label="Location" />
|
||||
<v-textarea v-model="assignmentForm.notes" label="Notes" rows="2" />
|
||||
<v-btn color="primary" prepend-icon="mdi-account-check" :loading="assignmentSaving" @click="$emit('assign-asset', assignmentForm)">Assign asset</v-btn>
|
||||
</v-card>
|
||||
|
||||
<v-card class="span-7 panel-pad">
|
||||
<div class="toolbar-row mb-4">
|
||||
<h2 class="section-title">Employees</h2>
|
||||
<v-spacer />
|
||||
<v-btn variant="tonal" prepend-icon="mdi-account-plus" @click="employeeDialog = true">Add employee</v-btn>
|
||||
</div>
|
||||
<v-list lines="two">
|
||||
<v-list-item v-for="employee in employees" :key="employee.id" prepend-icon="mdi-account">
|
||||
<v-list-item-title>{{ employee.name }}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ employee.email || employee.employee_number }} · {{ employee.department || 'No department' }} · {{ employee.location || 'No location' }}</v-list-item-subtitle>
|
||||
<template #append>
|
||||
<v-chip size="small" variant="tonal">{{ employee.source }}</v-chip>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card>
|
||||
|
||||
<v-card class="span-12 panel-pad">
|
||||
<div class="toolbar-row mb-4">
|
||||
<h2 class="section-title">Traceability</h2>
|
||||
<v-spacer />
|
||||
<v-btn variant="tonal" prepend-icon="mdi-refresh" @click="$emit('reload')">Refresh</v-btn>
|
||||
</div>
|
||||
<div style="overflow-x:auto">
|
||||
<table class="asset-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Asset</th>
|
||||
<th>Employee</th>
|
||||
<th>Department</th>
|
||||
<th>Location</th>
|
||||
<th>Assigned</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="assignment in assignments" :key="assignment.id">
|
||||
<td>
|
||||
<strong>{{ assignment.asset_code }}</strong><br />
|
||||
<span class="quiet">{{ assignment.asset_description }}</span>
|
||||
</td>
|
||||
<td>{{ assignment.employee_name || 'Unassigned employee' }}</td>
|
||||
<td>{{ assignment.department || '-' }}</td>
|
||||
<td>{{ assignment.location || '-' }}</td>
|
||||
<td>{{ shortDate(assignment.assigned_at) }}</td>
|
||||
<td><span :class="['status-chip', assignment.active ? 'status-in_service' : 'status-disposed']">{{ assignment.status }}</span></td>
|
||||
<td class="text-right">
|
||||
<v-btn v-if="assignment.active" size="small" variant="text" color="warning" @click="$emit('release-assignment', assignment)">Release</v-btn>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</v-card>
|
||||
|
||||
<v-dialog v-model="employeeDialog" max-width="480">
|
||||
<v-card>
|
||||
<v-card-title>Add employee</v-card-title>
|
||||
<v-card-text>
|
||||
<v-text-field v-model="employeeForm.name" label="Name" />
|
||||
<v-text-field v-model="employeeForm.email" label="Email" />
|
||||
<v-text-field v-model="employeeForm.employee_number" label="Employee number" />
|
||||
<v-text-field v-model="employeeForm.department" label="Department" />
|
||||
<v-text-field v-model="employeeForm.location" label="Location" />
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn variant="text" @click="employeeDialog = false">Cancel</v-btn>
|
||||
<v-btn color="primary" @click="saveEmployee">Save employee</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
assignments: { type: Array, required: true },
|
||||
assets: { type: Array, required: true },
|
||||
assignmentSaving: { type: Boolean, default: false },
|
||||
employees: { type: Array, required: true },
|
||||
shortDate: { type: Function, required: true },
|
||||
summary: { type: Object, required: true }
|
||||
},
|
||||
emits: ['add-employee', 'assign-asset', 'release-assignment', 'reload'],
|
||||
data() {
|
||||
return {
|
||||
assignmentForm: {
|
||||
asset_id: null,
|
||||
employee_id: null,
|
||||
department: '',
|
||||
location: '',
|
||||
notes: ''
|
||||
},
|
||||
employeeDialog: false,
|
||||
employeeForm: {
|
||||
name: '',
|
||||
email: '',
|
||||
employee_number: '',
|
||||
department: '',
|
||||
location: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
assetOptions() {
|
||||
return this.assets.map((asset) => ({
|
||||
title: `${asset.asset_id} · ${asset.description}`,
|
||||
value: asset.id
|
||||
}));
|
||||
},
|
||||
employeeOptions() {
|
||||
return this.employees.map((employee) => ({
|
||||
title: `${employee.name}${employee.department ? ` · ${employee.department}` : ''}`,
|
||||
value: employee.id
|
||||
}));
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
applyEmployeeDefaults(id) {
|
||||
const employee = this.employees.find((item) => item.id === id);
|
||||
if (!employee) return;
|
||||
this.assignmentForm.department = employee.department || '';
|
||||
this.assignmentForm.location = employee.location || '';
|
||||
},
|
||||
saveEmployee() {
|
||||
this.$emit('add-employee', { ...this.employeeForm });
|
||||
this.employeeDialog = false;
|
||||
this.employeeForm = { name: '', email: '', employee_number: '', department: '', location: '' };
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user