From 6a1c2a1493479b442a4c051471324d32d8c5cdc5 Mon Sep 17 00:00:00 2001
From: alexm <alexm@verdnatura.es>
Date: Fri, 4 Apr 2025 13:39:59 +0200
Subject: [PATCH] feat: refs #6958 add RoutesMonitor page and related
 components for route monitoring

---
 src/components/ui/VnPaginate.vue              |  14 +--
 src/css/app.scss                              |   3 +
 src/pages/Route/Monitor/RouteMonitor.vue      |  11 ++
 src/pages/Route/Monitor/RouteMonitorStops.vue |  19 +++
 src/pages/Route/Monitor/RouteMonitorTable.vue | 114 ++++++++++++++++++
 src/pages/Route/Monitor/locale/en.yml         |  17 +++
 src/pages/Route/Monitor/locale/es.yml         |  17 +++
 src/router/modules/route.js                   |  12 +-
 8 files changed, 196 insertions(+), 11 deletions(-)
 create mode 100644 src/pages/Route/Monitor/RouteMonitor.vue
 create mode 100644 src/pages/Route/Monitor/RouteMonitorStops.vue
 create mode 100644 src/pages/Route/Monitor/RouteMonitorTable.vue
 create mode 100644 src/pages/Route/Monitor/locale/en.yml
 create mode 100644 src/pages/Route/Monitor/locale/es.yml

diff --git a/src/components/ui/VnPaginate.vue b/src/components/ui/VnPaginate.vue
index 8fbfb067f..4590bd46f 100644
--- a/src/components/ui/VnPaginate.vue
+++ b/src/components/ui/VnPaginate.vue
@@ -220,19 +220,13 @@ defineExpose({
 </script>
 
 <template>
-    <div class="full-width">
-        <div
-            v-if="!store.data && !store.data?.length && !isLoading"
-            class="info-row q-pa-md text-center"
-        >
+    <div class="full-width" v-if="!store.data?.length">
+        <div v-if="!isLoading" class="info-row q-pa-md text-center">
             <h5>
                 {{ t('No data to display') }}
             </h5>
         </div>
-        <div
-            v-if="props.skeleton && props.autoLoad && !store.data"
-            class="card-list q-gutter-y-md"
-        >
+        <div v-if="props.skeleton && props.autoLoad" class="card-list q-gutter-y-md">
             <QCard class="card" v-for="$index in props.limit" :key="$index">
                 <QItem v-ripple class="q-pa-none items-start cursor-pointer q-hoverable">
                     <QItemSection class="q-pa-md">
@@ -253,7 +247,7 @@ defineExpose({
         </div>
     </div>
     <QInfiniteScroll
-        v-if="store.data"
+        v-else
         @load="onLoad"
         :offset="offset"
         :class="['full-width', props.class]"
diff --git a/src/css/app.scss b/src/css/app.scss
index b299973d1..7c3111559 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -280,6 +280,9 @@ input::-webkit-inner-spin-button {
             border-collapse: collapse;
         }
     }
+    .one {
+        max-width: 10px;
+    }
     .shrink {
         max-width: 75px;
     }
diff --git a/src/pages/Route/Monitor/RouteMonitor.vue b/src/pages/Route/Monitor/RouteMonitor.vue
new file mode 100644
index 000000000..10ac229e6
--- /dev/null
+++ b/src/pages/Route/Monitor/RouteMonitor.vue
@@ -0,0 +1,11 @@
+<script setup>
+import RouteMonitorTable from './RouteMonitorTable.vue';
+import RouteMonitorStops from './RouteMonitorStops.vue';
+</script>
+
+<template>
+    <div class="row no-wrap">
+        <RouteMonitorTable />
+        <RouteMonitorStops />
+    </div>
+</template>
diff --git a/src/pages/Route/Monitor/RouteMonitorStops.vue b/src/pages/Route/Monitor/RouteMonitorStops.vue
new file mode 100644
index 000000000..8277c2a1e
--- /dev/null
+++ b/src/pages/Route/Monitor/RouteMonitorStops.vue
@@ -0,0 +1,19 @@
+<script setup>
+import VnTable from 'src/components/VnTable/VnTable.vue';
+import { computed } from 'vue';
+
+const columns = computed(() => []);
+</script>
+
+<template>
+    <VnTable
+        data-key="roadmapStop"
+        url="RoadmapStops"
+        :columns="columns"
+        :right-search="false"
+        default-mode="table"
+        :disable-option="{ card: true }"
+        dense
+        auto-load
+    />
+</template>
diff --git a/src/pages/Route/Monitor/RouteMonitorTable.vue b/src/pages/Route/Monitor/RouteMonitorTable.vue
new file mode 100644
index 000000000..f5d0df5e0
--- /dev/null
+++ b/src/pages/Route/Monitor/RouteMonitorTable.vue
@@ -0,0 +1,114 @@
+<script setup>
+import VnTable from 'src/components/VnTable/VnTable.vue';
+import { computed } from 'vue';
+import { useI18n } from 'vue-i18n';
+
+const { t } = useI18n();
+
+const columns = computed(() => [
+    {
+        align: 'left',
+        name: 'dated',
+        label: t('globals.date'),
+    },
+    {
+        align: 'left',
+        name: 'etd',
+        label: t('route.monitor.etd'),
+    },
+    {
+        align: 'left',
+        name: 'stop',
+        label: t('route.monitor.stop'),
+        format: (row) => row.roadmapStop?.description,
+    },
+    {
+        align: 'left',
+        name: 'bufferFk',
+        label: t('route.monitor.buffer'),
+    },
+    {
+        align: 'left',
+        name: 'beachFk',
+        label: t('route.monitor.beach'),
+    },
+    {
+        align: 'left',
+        name: 'isPickingAllowed',
+        label: t('route.monitor.isPickingAllowed'),
+        component: 'VnCheckbox',
+    },
+    {
+        align: 'left',
+        name: 'routeFk',
+        label: t('route.monitor.route'),
+    },
+    {
+        align: 'left',
+        name: 'log',
+        label: t('route.monitor.log'),
+    },
+    {
+        align: 'left',
+        name: 'priority',
+        label: t('route.monitor.priority'),
+        columnClass: 'one',
+    },
+    {
+        align: 'left',
+        name: 'routeName',
+        label: t('route.monitor.routeName'),
+        format: (row) => row.route?.name,
+    },
+    {
+        align: 'left',
+        name: 'm3',
+        label: t('route.monitor.m3'),
+    },
+    {
+        align: 'left',
+        name: 'ticketFree',
+        label: t('route.monitor.ticketFree'),
+    },
+    {
+        align: 'left',
+        name: 'ticketProduction',
+        label: t('route.monitor.ticketProduction'),
+    },
+    {
+        align: 'left',
+        name: 'ticketPacked',
+        label: t('route.monitor.ticketPacked'),
+    },
+    {
+        align: 'left',
+        name: 'packages',
+        label: t('route.monitor.packages'),
+    },
+    {
+        align: 'left',
+        name: 'note',
+        label: t('route.monitor.note'),
+    },
+]);
+</script>
+
+<template>
+    <VnTable
+        data-key="routesMonitor"
+        url="RoutesMonitors"
+        :user-filter="{
+            include: [
+                { relation: 'roadmapStop' },
+                { relation: 'beach' },
+                { relation: 'route' },
+            ],
+        }"
+        :columns="columns"
+        :right-search="false"
+        default-mode="table"
+        :disable-option="{ card: true }"
+        dense
+        auto-load
+    />
+</template>
diff --git a/src/pages/Route/Monitor/locale/en.yml b/src/pages/Route/Monitor/locale/en.yml
new file mode 100644
index 000000000..5bc4c0f25
--- /dev/null
+++ b/src/pages/Route/Monitor/locale/en.yml
@@ -0,0 +1,17 @@
+route:
+    monitor:
+        etd: ETD
+        stop: Stop
+        buffer: Buffer
+        beach: Beach
+        isPickingAllowed: Picking allowed
+        route: Route
+        log: Log
+        priority: Priority
+        routeName: Route name
+        m3: Cubic meters
+        ticketFree: Free ticket
+        ticketProduction: Production ticket
+        ticketPacked: Packed ticket
+        packages: Packages
+        note: Note
diff --git a/src/pages/Route/Monitor/locale/es.yml b/src/pages/Route/Monitor/locale/es.yml
new file mode 100644
index 000000000..dc2379d7b
--- /dev/null
+++ b/src/pages/Route/Monitor/locale/es.yml
@@ -0,0 +1,17 @@
+route:
+    monitor:
+        etd: Salida estimada
+        stop: Parada
+        buffer: Buffer
+        beach: Playa
+        isPickingAllowed: Permite preparar
+        route: Ruta
+        log: Registro
+        priority: Prioridad
+        routeName: Nombre de ruta
+        m3: Metros cúbicos
+        ticketFree: Ticket libre
+        ticketProduction: Ticket de producción
+        ticketPacked: Ticket empaquetado
+        packages: Bultos
+        note: Nota
diff --git a/src/router/modules/route.js b/src/router/modules/route.js
index 0dd41c86e..c89a1f582 100644
--- a/src/router/modules/route.js
+++ b/src/router/modules/route.js
@@ -195,7 +195,7 @@ const vehicleCard = {
                 icon: 'vn:notes',
             },
             component: () => import('src/pages/Route/Vehicle/Card/VehicleNotes.vue'),
-        }
+        },
     ],
 };
 
@@ -214,6 +214,7 @@ export default {
             'CmrList',
             'AgencyList',
             'VehicleList',
+            'RoutesMonitor',
         ],
     },
     component: RouterView,
@@ -347,6 +348,15 @@ export default {
                         vehicleCard,
                     ],
                 },
+                {
+                    path: 'monitor',
+                    name: 'RoutesMonitor',
+                    meta: {
+                        title: 'routesMonitor',
+                        icon: 'grid_view',
+                    },
+                    component: () => import('src/pages/Route/Monitor/RouteMonitor.vue'),
+                },
             ],
         },
     ],