forked from TDTP/admin_transporte_frontend
Merge remote-tracking branch 'origin/develop/Ronald' into merge/ronald
commit
fff8692f86
|
@ -5,7 +5,7 @@
|
|||
<p class="mb-0">
|
||||
<a class="text-muted" href="https://www.empresa.com/"
|
||||
target="_blank" rel="noreferrer">
|
||||
<strong>EMPRESA S.A.</strong>
|
||||
<strong>.</strong>
|
||||
</a> ©
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -36,6 +36,13 @@
|
|||
<i class="align-middle bi bi-map fs-4" />
|
||||
<span class="align-middle">Rutas</span>
|
||||
</SideLink>
|
||||
|
||||
<li class="sidebar-header">GTFS</li>
|
||||
|
||||
<SideLink to="/gtfs_archivo">
|
||||
<i class="align-middle bi bi-bus-front fs-4" />
|
||||
<span class="align-middle">Listado Archivos GTFS</span>
|
||||
</SideLink>
|
||||
|
||||
<li class="sidebar-header">Mantenedores</li>
|
||||
|
||||
|
@ -49,6 +56,16 @@
|
|||
<span class="align-middle">Aplicaciones</span>
|
||||
</SideLink>
|
||||
|
||||
<SideLink to="/red-transporte">
|
||||
<i class="align-middle bi bi-sign-turn-right fs-4"></i>
|
||||
<span class="align-middle">Red de Transporte</span>
|
||||
</SideLink>
|
||||
|
||||
<SideLink to="/operadores">
|
||||
<i class="align-middle bi bi-sign-turn-right fs-4"></i>
|
||||
<span class="align-middle">Operadores</span>
|
||||
</SideLink>
|
||||
|
||||
<SideLink to="/rutas">
|
||||
<i class="align-middle bi bi-sign-turn-right fs-4"></i>
|
||||
<span class="align-middle">Servicios de Buses</span>
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
<script>
|
||||
import Paginate from "$/components/Paginate.svelte";
|
||||
import { getGtfsArchivo,getGtfsArchivoId } from "$/services/gtfs_archivo";
|
||||
import PageTitle from "$/components/PageTitle.svelte";
|
||||
import { useLocation } from "svelte-navigator";
|
||||
import { getPermisosPath } from "$/services/usuarios";
|
||||
|
||||
const limit = 15;
|
||||
let page = 1;
|
||||
let offset = 0;
|
||||
let count = 0;
|
||||
let ordering = 'id_archivo'
|
||||
let redes = []
|
||||
let red = null
|
||||
let lista_gtfs = []
|
||||
let gtfs = null
|
||||
let location = useLocation()
|
||||
|
||||
getPermisosPath($location.pathname)
|
||||
.then(data => escritura = data.escritura)
|
||||
.catch(error => console.log({ error }))
|
||||
|
||||
$: onPage(page)
|
||||
|
||||
async function onPage(p) {
|
||||
try {
|
||||
loading = true
|
||||
offset = (p - 1) * limit;
|
||||
const data = await getGtfsArchivo({ offset, limit, ordering })
|
||||
lista_gtfs = data.results;
|
||||
count = data.count;
|
||||
} catch (error) {
|
||||
globalThis.toast.error(error)
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function onOrderBy(field) {
|
||||
ordering = ordering === field ? '-' + field : field;
|
||||
onPage(page)
|
||||
}
|
||||
</script>
|
||||
|
||||
<PageTitle {loading}>Listado Archivos GTFS</PageTitle>
|
||||
|
||||
<div class="card">
|
||||
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered">
|
||||
<thead>
|
||||
<tr class="table-light">
|
||||
<th style="width: 5%">Nro</th>
|
||||
<th style="width: 5%">
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('id_gtfs')}>ID</a>
|
||||
{#if ordering === 'id_gtfs'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-id_gtfs'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('nombre_red')}>Archivo</a>
|
||||
{#if ordering === 'archivo'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-archivo'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('created')}>Creado el</a>
|
||||
{#if ordering === 'created'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-created'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('status')}>Estado</a>
|
||||
{#if ordering === 'status'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-status'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('vigente')}>Vigente</a>
|
||||
{#if ordering === 'vigente'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-vigente'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each lista_gtfs as app, index}
|
||||
<tr>
|
||||
<td class="table-light">{offset + index + 1}</td>
|
||||
<td>{app.id_red}</td>
|
||||
<td><a href={app.archivo}>{app.archivo}</a></td>
|
||||
<td>{app.created}</td>
|
||||
<td>{app.status}</td>
|
||||
<td>{app.vigente ? '✅':'🚫'}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer d-flex">
|
||||
|
||||
<Paginate
|
||||
forcePage={page}
|
||||
{limit}
|
||||
{count}
|
||||
on:page={ev => page = ev.detail}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
.table-responsive {
|
||||
max-height: calc(100vh - 300px);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,54 @@
|
|||
<script>
|
||||
import { getRedTransporte } from "$/services/red_transporte";
|
||||
import { getGtfsArchivo } from "$/services/gtfs_archivo";
|
||||
export let id_red;
|
||||
export let id_archivo;
|
||||
|
||||
export let loading = false;
|
||||
|
||||
|
||||
let redes= []
|
||||
let archivos = []
|
||||
let redes_archivos = []
|
||||
|
||||
getRedTransporte({ vigente: 1 })
|
||||
.then(data => data.sort((a,b) => a.nombre_red < b.nombre_red? -1 : 1))
|
||||
.then(data => redes = data)
|
||||
.catch(error => globalThis.toast.error(error))
|
||||
|
||||
getGtfsArchivo()
|
||||
.then(data => data.sort((a,b) => a.archivo < b.archivo? -1 : 1))
|
||||
.then(data => redes= data)
|
||||
.catch(error => globalThis.toast.error(error))
|
||||
|
||||
function onChangeRed() {
|
||||
id_archivo = ''
|
||||
if (!id_archivo) {
|
||||
redes_archivos = []
|
||||
} else {
|
||||
const archivos_filtrados = archivos.filter(el => el.id_red === id_red);
|
||||
const archivos_ordenados = archivos_filtrados.sort((a,b) => a.archivo < b.archivo ? -1 : 1);
|
||||
redes_archivos = archivos_ordenados;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-text">Redes de Transporte</div>
|
||||
<select bind:value={id_red} class="form-select" on:change={onChangeRed}>
|
||||
<option value=""></option>
|
||||
{#each redes as rt}
|
||||
<option value={rt.id_red}>{rt.nombre_red}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,127 @@
|
|||
<script>
|
||||
import Paginate from "$/components/Paginate.svelte";
|
||||
import { getOperadores } from "$/services/operadores";
|
||||
import PageTitle from "$/components/PageTitle.svelte";
|
||||
import ModalOperador from "./ModalOperador.svelte";
|
||||
import { useLocation } from "svelte-navigator";
|
||||
import { getPermisosPath } from "$/services/usuarios";
|
||||
|
||||
const limit = 15;
|
||||
let page = 1;
|
||||
let offset = 0;
|
||||
let count = 0;
|
||||
let ordering = 'id_operador'
|
||||
let operadores = []
|
||||
let operador = null
|
||||
let loading = false;
|
||||
let escritura = false;
|
||||
let location = useLocation()
|
||||
|
||||
getPermisosPath($location.pathname)
|
||||
.then(data => escritura = data.escritura)
|
||||
.catch(error => console.log({ error }))
|
||||
|
||||
$: onPage(page)
|
||||
|
||||
async function onPage(p) {
|
||||
try {
|
||||
loading = true
|
||||
offset = (p - 1) * limit;
|
||||
const data = await getOperadores({ offset, limit, ordering })
|
||||
operadores = data.results;
|
||||
count = data.count;
|
||||
} catch (error) {
|
||||
globalThis.toast.error(error)
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
function onEdita(item) {
|
||||
operador = item;
|
||||
}
|
||||
|
||||
function onNuevo() {
|
||||
operador = {}
|
||||
}
|
||||
|
||||
function onOrderBy(field) {
|
||||
ordering = ordering === field ? '-' + field : field;
|
||||
onPage(page)
|
||||
}
|
||||
</script>
|
||||
|
||||
<PageTitle {loading}>Operadores</PageTitle>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
{#if escritura}
|
||||
<button class="btn btn-primary" on:click|preventDefault={onNuevo}>
|
||||
<i class="bi bi-plus-lg"></i> Nuevo
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered">
|
||||
<thead>
|
||||
<tr class="table-light">
|
||||
<th style="width:5%">Nro</th>
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('id_operador')}>ID</a>
|
||||
{#if ordering === 'id_operador'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-id_operador'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('nombre_operador')}>Nombre</a>
|
||||
{#if ordering === 'nombre_operador'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-nombre_operador'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('vigente')}>Vigente</a>
|
||||
{#if ordering === 'vigente'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-vigente'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each operadores as app, index}
|
||||
<tr key={index}>
|
||||
<td class="table-light">{offset + index + 1}</td>
|
||||
<td>{app.id_operador}</td>
|
||||
<td><a href={"#"} on:click|preventDefault={() => onEdita(app)}>{app.nombre_operador}</a></td>
|
||||
<td>{app.vigente ? '✅':'🚫'}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer d-flex">
|
||||
<a href={"#"} class="btn btn-outline-secondary me-3" on:click|preventDefault={() => onPage(page)}>
|
||||
<i class="bi bi-arrow-repeat"></i>
|
||||
</a>
|
||||
<Paginate
|
||||
{limit}
|
||||
{count}
|
||||
on:page={ev => page = ev.detail}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{#if operador}
|
||||
<ModalOperador
|
||||
{operador}
|
||||
{escritura}
|
||||
on:close={() => operador = null}
|
||||
on:refresh={() => onPage(page)}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.table-responsive {
|
||||
max-height: calc(100vh - 300px);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,101 @@
|
|||
<script>
|
||||
import Modal from "../../components/Modal.svelte";
|
||||
import { getOperador, createOperador, updateOperador, deleteOperador } from "$/services/operadores";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let operador = {};
|
||||
export let escritura = false;
|
||||
let form = {}
|
||||
let loading = false;
|
||||
|
||||
$: begin(operador.id_operador)
|
||||
|
||||
async function begin(id) {
|
||||
try {
|
||||
if (!id) return;
|
||||
form = await getOperador(id) || {}
|
||||
} catch (error) {
|
||||
globalThis.toast.success(error.detail || error)
|
||||
}
|
||||
}
|
||||
|
||||
async function onSave() {
|
||||
try {
|
||||
loading = true;
|
||||
if (operador.id_operador) {
|
||||
form = await updateOperador(form)
|
||||
} else {
|
||||
form = await createOperador(form)
|
||||
}
|
||||
globalThis.toast.success('Se ha guardado el Operador')
|
||||
dispatch('refresh')
|
||||
dispatch('close')
|
||||
} catch (error) {
|
||||
if (error.detail) {
|
||||
globalThis.toast.success(error.detail)
|
||||
} else {
|
||||
globalThis.toast.success(JSON.stringify(error))
|
||||
}
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function onDelete() {
|
||||
try {
|
||||
if (!confirm('Eliminará el registro?')) return;
|
||||
loading = true;
|
||||
await deleteOperador(form.id_operador)
|
||||
globalThis.toast.success('Se ha eliminado el Operador')
|
||||
dispatch('refresh')
|
||||
dispatch('close')
|
||||
} catch (error) {
|
||||
globalThis.toast.error(error.detail || error)
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<form action="" on:submit|preventDefault={onSave}>
|
||||
<Modal title={'Operador #' + (operador.id_operador || 'Nuevo')}
|
||||
size="lg"
|
||||
on:close={() => dispatch('close')}>
|
||||
<div class={"form" + (escritura ? '' : ' disabled')}>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-3">ID</div>
|
||||
<div class="col-md">
|
||||
{#if operador.id_operador}
|
||||
<input type="text" value={form.id_operador} disabled class="form-control">
|
||||
{:else}
|
||||
<input type="text" bind:value={form.id_operador} required class="form-control">
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-3">Nombre</div>
|
||||
<div class="col-md">
|
||||
<input type="text" bind:value={form.nombre_operador} required class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" bind:checked={form.vigente} role="switch" id="vigente">
|
||||
<label class="form-check-label" for="vigente">Vigente</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<svelte:fragment slot="buttons">
|
||||
{#if escritura}
|
||||
<button class="btn btn-primary"type="submit" disabled={loading}>Guardar</button>
|
||||
<button class="btn btn-danger" on:click|preventDefault={onDelete} disabled={loading}>Eliminar</button>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</Modal>
|
||||
</form>
|
||||
|
||||
<style>
|
||||
.disabled { pointer-events: none !important; }
|
||||
</style>
|
|
@ -0,0 +1,146 @@
|
|||
<script>
|
||||
import Paginate from "$/components/Paginate.svelte";
|
||||
import { getRedTransporte } from "$/services/red_transporte";
|
||||
import PageTitle from "$/components/PageTitle.svelte";
|
||||
import ModalRedTransporte from "./ModalRedTransporte.svelte";
|
||||
import { useLocation } from "svelte-navigator";
|
||||
import { getPermisosPath } from "$/services/usuarios";
|
||||
|
||||
const limit = 15;
|
||||
let page = 1;
|
||||
let offset = 0;
|
||||
let count = 0;
|
||||
let ordering = 'id_red'
|
||||
let redes = []
|
||||
let red = null
|
||||
let loading = false;
|
||||
let escritura = false;
|
||||
let location = useLocation()
|
||||
|
||||
getPermisosPath($location.pathname)
|
||||
.then(data => escritura = data.escritura)
|
||||
.catch(error => console.log({ error }))
|
||||
|
||||
$: onPage(page)
|
||||
|
||||
async function onPage(p) {
|
||||
try {
|
||||
loading = true
|
||||
offset = (p - 1) * limit;
|
||||
const data = await getRedTransporte({ offset, limit, ordering })
|
||||
redes = data.results;
|
||||
count = data.count;
|
||||
} catch (error) {
|
||||
globalThis.toast.error(error)
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
function onEdita(item) {
|
||||
red = item;
|
||||
}
|
||||
|
||||
function onNuevo() {
|
||||
red = {}
|
||||
}
|
||||
|
||||
function onOrderBy(field) {
|
||||
ordering = ordering === field ? '-' + field : field;
|
||||
onPage(page)
|
||||
}
|
||||
</script>
|
||||
|
||||
<PageTitle {loading}>Redes de Transporte</PageTitle>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
{#if escritura}
|
||||
<button class="btn btn-primary" on:click|preventDefault={onNuevo}>
|
||||
<i class="bi bi-plus-lg"></i> Nuevo
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered">
|
||||
<thead>
|
||||
<tr class="table-light">
|
||||
<th style="width: 5%">Nro</th>
|
||||
<th style="width: 5%">
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('id_red')}>ID</a>
|
||||
{#if ordering === 'id_red'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-id_red'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('nombre_red')}>Nombre</a>
|
||||
{#if ordering === 'nombre_red'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-nombre_red'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('descripcion')}>Descripcion</a>
|
||||
{#if ordering === 'descripcion'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-descripcion'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('url_gtfs_rt')}>URL_GTFS_RT</a>
|
||||
{#if ordering === 'url_gtfs_rt'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-url_gtfs_rt'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('api_key')}>api_key</a>
|
||||
{#if ordering === 'api_key'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-api_key'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
<th>
|
||||
<a href={"#"} on:click|preventDefault={() => onOrderBy('vigente')}>Vigente</a>
|
||||
{#if ordering === 'vigente'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||
{#if ordering === '-vigente'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each redes as app, index}
|
||||
<tr>
|
||||
<td class="table-light">{offset + index + 1}</td>
|
||||
<td>{app.id_red}</td>
|
||||
<td><a href={"#"} on:click|preventDefault={() => onEdita(app)}>{app.nombre_red}</a></td>
|
||||
<td>{app.descripcion}</td>
|
||||
<td>{app.url_gtfs_rt}</td>
|
||||
<td>{app.api_key}</td>
|
||||
<td>{app.vigente ? '✅':'🚫'}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer d-flex">
|
||||
<a href={"#"} class="btn btn-outline-secondary me-3" on:click|preventDefault={() => onPage(page)}>
|
||||
<i class="bi bi-arrow-repeat"></i>
|
||||
</a>
|
||||
<Paginate
|
||||
forcePage={page}
|
||||
{limit}
|
||||
{count}
|
||||
on:page={ev => page = ev.detail}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if red}
|
||||
<ModalRedTransporte
|
||||
{red}
|
||||
{escritura}
|
||||
on:close={() => red = null}
|
||||
on:refresh={() => onPage(page)}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.table-responsive {
|
||||
max-height: calc(100vh - 300px);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,119 @@
|
|||
<script>
|
||||
import Modal from "../../components/Modal.svelte";
|
||||
import { getRedTransporte, createRedTransporte, updateRedTransporte, deleteRedTransporte, getRedTransporteId } from "$/services/red_transporte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let red = {};
|
||||
export let escritura = false;
|
||||
let form = {}
|
||||
let loading = false;
|
||||
|
||||
$: begin(red.id_red)
|
||||
|
||||
async function begin(id) {
|
||||
try {
|
||||
if (!id) return;
|
||||
form = await getRedTransporteId(id) || {}
|
||||
} catch (error) {
|
||||
globalThis.toast.success(error.detail || error)
|
||||
}
|
||||
}
|
||||
|
||||
async function onSave() {
|
||||
try {
|
||||
|
||||
loading = true;
|
||||
if (red.id_red) {
|
||||
form = await updateRedTransporte(form)
|
||||
} else {
|
||||
form = await createRedTransporte(form)
|
||||
}
|
||||
globalThis.toast.success('Se ha guardado la Red de Transporte')
|
||||
dispatch('refresh')
|
||||
dispatch('close')
|
||||
} catch (error) {
|
||||
if (error.detail) {
|
||||
globalThis.toast.success(error.detail)
|
||||
} else {
|
||||
globalThis.toast.success(JSON.stringify(error))
|
||||
}
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function onDelete() {
|
||||
try {
|
||||
if (!confirm('Eliminará el registro?')) return;
|
||||
loading = true;
|
||||
await deleteRedTransporte(form.id_red)
|
||||
globalThis.toast.success('Se ha eliminado la Red de Transporte')
|
||||
dispatch('refresh')
|
||||
dispatch('close')
|
||||
} catch (error) {
|
||||
globalThis.toast.error(error.detail || error)
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<form action="" on:submit|preventDefault={onSave}>
|
||||
<Modal title={'Red de Transporte #' + (red.id_red || 'Nuevo')}
|
||||
size="lg"
|
||||
on:close={() => dispatch('close')}>
|
||||
<div class={"form" + (escritura ? '' : ' disabled')}>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-3">ID</div>
|
||||
<div class="col-md">
|
||||
{#if red.id_red}
|
||||
<input type="number" value={form.id_red} disabled class="form-control">
|
||||
{:else}
|
||||
<input type="number" bind:value={form.id_red} required class="form-control">
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-3">Nombre</div>
|
||||
<div class="col-md">
|
||||
<input type="text" bind:value={form.nombre_red} required class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="col-md-3">Descripcion</div>
|
||||
<div class="col-md">
|
||||
<input type="text" bind:value={form.descripcion} class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<div class="col-md-3">URL GTFS-RT</div>
|
||||
<div class="col-md">
|
||||
<input type="text" bind:value={form.url_gtfs_rt} class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
<div class="col-md-3">API Key</div>
|
||||
<div class="col-md">
|
||||
<input type="text" bind:value={form.api_key} class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" bind:checked={form.vigente} role="switch" id="vigente">
|
||||
<label class="form-check-label" for="vigente">Vigente</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<svelte:fragment slot="buttons">
|
||||
{#if escritura}
|
||||
<button class="btn btn-primary"type="submit" disabled={loading}>Guardar</button>
|
||||
<button class="btn btn-danger" on:click|preventDefault={onDelete} disabled={loading}>Eliminar</button>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</Modal>
|
||||
</form>
|
||||
|
||||
<style>
|
||||
.disabled { pointer-events: none !important; }
|
||||
</style>
|
|
@ -2,6 +2,9 @@ import PageHome from '$/pages/site/Home.svelte'
|
|||
import PagePerfil from '$/pages/usuarios/Perfil.svelte'
|
||||
import PageError from '$/pages/site/Error.svelte'
|
||||
import PageAplicaciones from '$/pages/aplicaciones/Admin.svelte'
|
||||
import PageOperador from '$/pages/operadores/Admin.svelte'
|
||||
import PageRedTransporte from '$/pages/red_transporte/Admin.svelte'
|
||||
import PageArchivoGTFS from '$/pages/gtfs_archivo/Admin.svelte'
|
||||
import PageUsuarios from '$/pages/usuarios/Admin.svelte'
|
||||
import PageUsuarioCreate from '$/pages/usuarios/Usuario.svelte'
|
||||
import PageUsuarioModifica from '$/pages/usuarios/Usuario.svelte'
|
||||
|
@ -21,6 +24,9 @@ export const routes_base = [
|
|||
{ path: '/', component: PageHome, public: true },
|
||||
{ path: '/perfil', component: PagePerfil, public: true },
|
||||
{ path: '/aplicaciones', component: PageAplicaciones },
|
||||
{ path: '/red-transporte', component: PageRedTransporte },
|
||||
{ path: '/gtfs-archivo', component: PageArchivoGTFS },
|
||||
{ path: '/operadores', component: PageOperador },
|
||||
{ path: '/usuarios', component: PageUsuarios },
|
||||
{ path: '/usuarios/nuevo', component: PageUsuarioCreate },
|
||||
{ path: '/usuarios/:login', component: PageUsuarioModifica },
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import { base, getToken } from './_config'
|
||||
|
||||
export async function getGtfsArchivo(params) {
|
||||
const query = !params ? '' : '?' + (new URLSearchParams(params).toString());
|
||||
const res = await fetch(`${base}/gtfs-archivo/${query}`, {
|
||||
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||
})
|
||||
if (!res.ok) throw await res.json()
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function getGtfsArchivoId(id) {
|
||||
const res = await fetch(`${base}/gtfs-archivo/${id}/`, {
|
||||
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||
})
|
||||
if (!res.ok) throw await res.json()
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function createGtfsArchivo(data) {
|
||||
const res = await fetch(`${base}/gtfs-archivo/`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||
})
|
||||
if (!res.ok) throw await res.json()
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function updateGtfsArchivo({ id_red: id = null, ...data }) {
|
||||
const res = await fetch(`${base}/gtfs-archivo/${id}/`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||
})
|
||||
if (!res.ok) throw await res.json()
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function deleteGtfsArchivo(id) {
|
||||
const res = await fetch(`${base}/gtfs-archivo/${id}/`, {
|
||||
method: 'DELETE',
|
||||
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||
})
|
||||
if (!res.ok) throw await res.json()
|
||||
return res.text()
|
||||
}
|
|
@ -44,5 +44,5 @@ export async function deleteOperador(id) {
|
|||
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||
})
|
||||
if (!res.ok) throw await res.text()
|
||||
return res.json()
|
||||
return res.text()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import { base, getToken } from './_config'
|
||||
|
||||
export async function getRedTransporte(params) {
|
||||
const query = !params ? '' : '?' + (new URLSearchParams(params).toString());
|
||||
const res = await fetch(`${base}/red-transporte/${query}`, {
|
||||
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||
})
|
||||
if (!res.ok) throw await res.json()
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function getRedTransporteId(id) {
|
||||
const res = await fetch(`${base}/red-transporte/${id}/`, {
|
||||
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||
})
|
||||
if (!res.ok) throw await res.json()
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function createRedTransporte(data) {
|
||||
const res = await fetch(`${base}/red-transporte/`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||
})
|
||||
if (!res.ok) throw await res.json()
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function updateRedTransporte({ id_red: id = null, ...data }) {
|
||||
const res = await fetch(`${base}/red-transporte/${id}/`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||
})
|
||||
if (!res.ok) throw await res.json()
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function deleteRedTransporte(id) {
|
||||
const res = await fetch(`${base}/red-transporte/${id}/`, {
|
||||
method: 'DELETE',
|
||||
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||
})
|
||||
if (!res.ok) throw await res.json()
|
||||
return res.text()
|
||||
}
|
Loading…
Reference in New Issue