first commit
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
.assigned-route-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.actions-right {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--glm-surface);
|
||||
color: var(--glm-azul);
|
||||
border: 1px solid var(--glm-gris-medio);
|
||||
border-radius: 4px;
|
||||
padding: 8px 14px;
|
||||
font-size: 13px;
|
||||
font-family: Arial, sans-serif;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: var(--glm-verde-bg);
|
||||
border-color: var(--glm-verde);
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
background: transparent;
|
||||
border: 1px solid var(--glm-gris-medio);
|
||||
border-radius: 4px;
|
||||
color: var(--glm-azul);
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
padding: 6px 8px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.btn-icon:hover {
|
||||
background: var(--glm-verde);
|
||||
border-color: var(--glm-verde);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.table-caption {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.table-caption .font-bold {
|
||||
color: var(--glm-azul);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.table-caption .count {
|
||||
color: var(--glm-acero);
|
||||
font-size: 13px;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<div class="assigned-route-container">
|
||||
<div class="header-actions">
|
||||
<input
|
||||
pInputText
|
||||
type="text"
|
||||
placeholder="Buscar..."
|
||||
(input)="dt.filterGlobal($any($event.target).value, 'contains')"
|
||||
/>
|
||||
<div class="actions-right">
|
||||
<button type="button" class="btn-secondary" (click)="downloadCSV()">
|
||||
<i class="pi pi-download"></i> Descargar CSV
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-secondary"
|
||||
(click)="toggleRutas()"
|
||||
pTooltip="Mostrar u ocultar el detalle de rutas"
|
||||
tooltipPosition="top"
|
||||
>
|
||||
<i [class]="rutasExpandido ? 'pi pi-chevron-up' : 'pi pi-chevron-down'"></i>
|
||||
{{ rutasExpandido ? 'Ocultar rutas' : 'Ver rutas' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p-table
|
||||
#dt
|
||||
[value]="assignedRoutes"
|
||||
[loading]="isLoading"
|
||||
[paginator]="true"
|
||||
[rows]="10"
|
||||
size="small"
|
||||
[columns]="cols"
|
||||
[rowsPerPageOptions]="[10, 25, 50]"
|
||||
styleClass="p-datatable-sm text-sm"
|
||||
>
|
||||
<ng-template pTemplate="caption">
|
||||
<div class="table-caption">
|
||||
<span class="font-bold">Rutas asignadas</span>
|
||||
<span class="count">{{ assignedRoutes.length }} registros</span>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template pTemplate="header">
|
||||
<tr>
|
||||
<th *ngFor="let col of cols" pSortableColumn="{{ col.field }}">
|
||||
{{ col.header }}
|
||||
<p-sortIcon [field]="col.field"></p-sortIcon>
|
||||
<p-columnFilter
|
||||
[field]="col.field"
|
||||
display="menu"
|
||||
matchMode="contains"
|
||||
[showMatchModes]="false"
|
||||
[showOperator]="false"
|
||||
[showAddButton]="false"
|
||||
></p-columnFilter>
|
||||
</th>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
||||
<ng-template pTemplate="body" let-row>
|
||||
<tr>
|
||||
<td>{{ row.json.nombre_usuario }}</td>
|
||||
<td>{{ row.json.nombre_pdv }}</td>
|
||||
<td>{{ row.json.hora_laboral_semanal_usuario }}</td>
|
||||
<td>{{ row.json.hora_minima_semanal_pdv }}</td>
|
||||
<td>{{ row.json.horas_trabajo }}</td>
|
||||
<td>{{ row.json.dia }}</td>
|
||||
<td>{{ row.json.distancia }}</td>
|
||||
<td>{{ row.json.horas_desplazamiento }}</td>
|
||||
<td class="text-center">
|
||||
<button
|
||||
type="button"
|
||||
class="btn-icon"
|
||||
(click)="onShowMap(row)"
|
||||
pTooltip="Ver en mapa"
|
||||
tooltipPosition="top"
|
||||
>
|
||||
<i class="pi pi-map-marker"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
||||
<ng-template pTemplate="emptymessage">
|
||||
<tr>
|
||||
<td colspan="9" class="text-center">No hay rutas asignadas</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
</p-table>
|
||||
</div>
|
||||
@@ -0,0 +1,122 @@
|
||||
import { Component, ChangeDetectorRef, ViewChild } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Router } from '@angular/router';
|
||||
import { RouteAssignedResponse } from '../../../core/models/route.model';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { Table } from 'primeng/table';
|
||||
import { TableModule } from 'primeng/table';
|
||||
import { InputTextModule } from 'primeng/inputtext';
|
||||
import { TooltipModule } from 'primeng/tooltip';
|
||||
import { RouteState } from '../../../core/route-state/route';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-assigned-route',
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
TableModule,
|
||||
InputTextModule,
|
||||
TooltipModule
|
||||
],
|
||||
templateUrl: './assigned-route.component.html',
|
||||
styleUrl: './assigned-route.component.css'
|
||||
})
|
||||
export class AssignedRouteComponent {
|
||||
@ViewChild('dt') table!: Table;
|
||||
rutasExpandido = false;
|
||||
tablaRutas = '';
|
||||
assignedRoutes: RouteAssignedResponse[] = [];
|
||||
isLoading = false;
|
||||
cols: any[] = [];
|
||||
|
||||
constructor(
|
||||
private routesState: RouteState,
|
||||
private cdr: ChangeDetectorRef,
|
||||
private router: Router
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.routesState.resetLoading();
|
||||
this.routesState.loading$.subscribe(value => {
|
||||
this.isLoading = value;
|
||||
this.cdr.detectChanges();
|
||||
});
|
||||
this.routesState.assignedRoutes$.subscribe(data => {
|
||||
this.assignedRoutes = [...data];
|
||||
this.cdr.detectChanges();
|
||||
});
|
||||
this.cols = [
|
||||
{ field: 'json.nombre_usuario', header: 'Usuario' },
|
||||
{ field: 'json.nombre_pdv', header: 'PDV' },
|
||||
{ field: 'json.hora_laboral_semanal_usuario', header: 'Sem. Usuario (hr)' },
|
||||
{ field: 'json.hora_minima_semanal_pdv', header: 'Horas Min. PDV' },
|
||||
{ field: 'json.horas_trabajo', header: 'Horas Trabajo' },
|
||||
{ field: 'json.dia', header: 'Día' },
|
||||
{ field: 'json.distancia', header: 'Distancia (km)' },
|
||||
{ field: 'json.horas_desplazamiento', header: 'Duración (min)' },
|
||||
{ field: '', header: '' }
|
||||
];
|
||||
|
||||
}
|
||||
onShowMap(row: RouteAssignedResponse) {
|
||||
this.routesState.sendRoute(row);
|
||||
this.router.navigate(['/home/assigned-route']);
|
||||
}
|
||||
toggleRutas() {
|
||||
this.rutasExpandido = !this.rutasExpandido;
|
||||
}
|
||||
|
||||
downloadCSV() {
|
||||
const headers = [
|
||||
'Usuario ID',
|
||||
'Usuario',
|
||||
'Long Usuario',
|
||||
'Lat Usuario',
|
||||
'PDV ID',
|
||||
'PDV',
|
||||
'Long PDV',
|
||||
'Lat PDV',
|
||||
'Horas Usuario',
|
||||
'Horas PDV',
|
||||
'Horas Trabajo',
|
||||
'Día',
|
||||
'Distancia',
|
||||
'Duracion'
|
||||
];
|
||||
|
||||
const data =
|
||||
this.table.filteredValue && this.table.filteredValue.length
|
||||
? this.table.filteredValue
|
||||
: this.assignedRoutes;
|
||||
|
||||
const rows = data.map(r => [
|
||||
r.json.usuario_id,
|
||||
r.json.nombre_usuario,
|
||||
r.json.longitud_usuario,
|
||||
r.json.latitud_usuario,
|
||||
r.json.pdv_id,
|
||||
r.json.nombre_pdv,
|
||||
r.json.longitud_pdv,
|
||||
r.json.latitud_pdv,
|
||||
r.json.hora_laboral_semanal_usuario,
|
||||
r.json.hora_minima_semanal_pdv,
|
||||
r.json.horas_trabajo,
|
||||
r.json.dia,
|
||||
r.json.distancia,
|
||||
r.json.horas_desplazamiento
|
||||
]);
|
||||
|
||||
const csvContent =
|
||||
[headers, ...rows].map(r => r.join(',')).join('\n');
|
||||
|
||||
const bom = '\uFEFF';
|
||||
const blob = new Blob([bom + csvContent], {
|
||||
type: 'text/csv;charset=utf-8;'
|
||||
});
|
||||
|
||||
saveAs(blob, 'rutas_planificadas.csv');
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user