se termina crud de aplicaciones
parent
495de145ee
commit
9229cf80e3
|
@ -0,0 +1,44 @@
|
||||||
|
<script>
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
export let title = "modal title";
|
||||||
|
export let className = "";
|
||||||
|
export let classTitle = "";
|
||||||
|
export let classHeader = "";
|
||||||
|
export let size = "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Modal -->
|
||||||
|
<div
|
||||||
|
class={"modal show " + className}
|
||||||
|
tabindex="-1"
|
||||||
|
aria-hidden="true"
|
||||||
|
style="display: block; background-color: rgb(0 0 0 / 30%)"
|
||||||
|
>
|
||||||
|
<div class={"modal-dialog " + (size ? " modal-" + size : "")}>
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class={"modal-header " + classHeader}>
|
||||||
|
<h5 class={"modal-title " + classTitle}>{title}</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn-close"
|
||||||
|
aria-label="Close"
|
||||||
|
on:click|preventDefault={() => dispatch("close")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer py-2">
|
||||||
|
<slot name="buttons" />
|
||||||
|
<div class="me-auto" />
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-secondary border border-light"
|
||||||
|
on:click|preventDefault={() => dispatch("close")}>Cerrar</button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -6,7 +6,7 @@
|
||||||
let persona = {}
|
let persona = {}
|
||||||
|
|
||||||
$: persona = $storeSession
|
$: persona = $storeSession
|
||||||
$: avatar = $storeSession?.avatar_img || '/avatars/avatar1.jpg';
|
$: avatar = $storeSession?.avatar_img || '/avatars/avatar2.png';
|
||||||
|
|
||||||
function onLogout() {
|
function onLogout() {
|
||||||
sessionStorage.clear();
|
sessionStorage.clear();
|
||||||
|
|
|
@ -1,40 +1,81 @@
|
||||||
<script>
|
<script>
|
||||||
import Paginate from "$/components/Paginate.svelte";
|
import Paginate from "$/components/Paginate.svelte";
|
||||||
|
import { getAplicaciones } from "$/services/aplicaciones";
|
||||||
|
import ModalAplicacion from "./ModalAplicacion.svelte";
|
||||||
|
|
||||||
const limit = 15;
|
const limit = 15;
|
||||||
|
let page = 1;
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
let ordering = 'id_aplicacion'
|
||||||
|
let aplicaciones = []
|
||||||
|
let aplicacion = null
|
||||||
|
|
||||||
|
$: onPage(page)
|
||||||
|
|
||||||
async function onPage(p) {
|
async function onPage(p) {
|
||||||
try {
|
try {
|
||||||
offset = (p - 1) * limit;
|
offset = (p - 1) * limit;
|
||||||
|
const data = await getAplicaciones({ offset, limit, ordering })
|
||||||
|
aplicaciones = data.results;
|
||||||
|
count = data.count;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert(error)
|
alert(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPage(1)
|
function onEdita(item) {
|
||||||
|
aplicacion = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onNuevo() {
|
||||||
|
aplicacion = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onOrderBy(field) {
|
||||||
|
ordering = ordering === field ? '-' + field : field;
|
||||||
|
onPage(page)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1 class="h3 mb-3">Aplicaciones</h1>
|
<h1 class="h3 mb-3">Aplicaciones</h1>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<button class="btn btn-outline-secondary" on:click|preventDefault={onNuevo}><i class="bi bi-plus-lg"></i> Nuevo</button>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-sm">
|
<table class="table table-sm table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr class="table-secondary">
|
||||||
<th>ID</th>
|
<th style="width:5%">Nro</th>
|
||||||
<th>Nombre</th>
|
<th>
|
||||||
<th></th>
|
<a href={"#"} on:click|preventDefault={() => onOrderBy('id_aplicacion')}>ID</a>
|
||||||
|
{#if ordering === 'id_aplicacion'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||||
|
{#if ordering === '-id_aplicacion'}<i class="bi bi-caret-down-fill"></i>{/if}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a href={"#"} on:click|preventDefault={() => onOrderBy('app')}>Nombre</a>
|
||||||
|
{#if ordering === 'app'}<i class="bi bi-caret-up-fill"></i>{/if}
|
||||||
|
{#if ordering === '-app'}<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>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{#each aplicaciones as app, index}
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td class="table-secondary">{offset + index + 1}</td>
|
||||||
<td></td>
|
<td>{app.id_aplicacion}</td>
|
||||||
<td></td>
|
<td><a href={"#"} on:click|preventDefault={() => onEdita(app)}>{app.app}</a></td>
|
||||||
|
<td>{app.vigente}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -44,7 +85,15 @@
|
||||||
{offset}
|
{offset}
|
||||||
{limit}
|
{limit}
|
||||||
{count}
|
{count}
|
||||||
on:page={ev => onPage(ev.detail)}
|
on:page={ev => page = ev.detail}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if aplicacion}
|
||||||
|
<ModalAplicacion
|
||||||
|
{aplicacion}
|
||||||
|
on:close={() => aplicacion = null}
|
||||||
|
on:refresh={() => onPage(page)}
|
||||||
|
/>
|
||||||
|
{/if}
|
|
@ -0,0 +1,85 @@
|
||||||
|
<script>
|
||||||
|
import Modal from "../../components/Modal.svelte";
|
||||||
|
import { getAplicacion, createAplicacion, updateAplicacion, deleteAplicacion } from "$/services/aplicaciones";
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
export let aplicacion = {}
|
||||||
|
let form = {}
|
||||||
|
|
||||||
|
$: begin(aplicacion.id_aplicacion)
|
||||||
|
|
||||||
|
async function begin(id) {
|
||||||
|
try {
|
||||||
|
if (!id) return;
|
||||||
|
form = await getAplicacion(id) || {}
|
||||||
|
} catch (error) {
|
||||||
|
alert(error.detail || error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onSave() {
|
||||||
|
try {
|
||||||
|
if (aplicacion.id_aplicacion) {
|
||||||
|
form = await updateAplicacion(form)
|
||||||
|
} else {
|
||||||
|
form = await createAplicacion(form)
|
||||||
|
}
|
||||||
|
alert('Se ha guardado la aplicación')
|
||||||
|
dispatch('refresh')
|
||||||
|
dispatch('close')
|
||||||
|
} catch (error) {
|
||||||
|
if (error.detail) {
|
||||||
|
alert(error.detail)
|
||||||
|
} else {
|
||||||
|
alert(JSON.stringify(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onDelete() {
|
||||||
|
try {
|
||||||
|
if (!confirm('Eliminará el registro?')) return;
|
||||||
|
await deleteAplicacion(form.id_aplicacion)
|
||||||
|
alert('Se ha eliminado la aplicación')
|
||||||
|
dispatch('refresh')
|
||||||
|
dispatch('close')
|
||||||
|
} catch (error) {
|
||||||
|
alert(error.detail || error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal title={'Aplicacion #' + (aplicacion.id_aplicacion || 'Nuevo')}
|
||||||
|
size="lg"
|
||||||
|
on:close={() => dispatch('close')}
|
||||||
|
>
|
||||||
|
<div class="form">
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-3">ID</div>
|
||||||
|
<div class="col-md">
|
||||||
|
{#if aplicacion.id_aplicacion}
|
||||||
|
<input type="number" value={form.id_aplicacion} disabled class="form-control">
|
||||||
|
{:else}
|
||||||
|
<input type="number" bind:value={form.id_aplicacion} 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.app} 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">
|
||||||
|
<button class="btn btn-primary" on:click|preventDefault={onSave}>Guardar</button>
|
||||||
|
<button class="btn btn-danger" on:click|preventDefault={onDelete}>Eliminar</button>
|
||||||
|
</svelte:fragment>
|
||||||
|
</Modal>
|
|
@ -23,7 +23,7 @@
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="m-sm-4">
|
<div class="m-sm-4">
|
||||||
<div class="text-center mb-4">
|
<div class="text-center mb-4">
|
||||||
<img src="/avatars/avatar1.jpg" alt="Avatar"
|
<img src="/avatars/avatar2.png" alt="Avatar"
|
||||||
class="img-fluid rounded-circle" width="132" height="132"
|
class="img-fluid rounded-circle" width="132" height="132"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<img
|
<img
|
||||||
src="/avatars/avatar1.jpg"
|
src="/avatars/avatar2.png"
|
||||||
alt="Christina Mason"
|
alt={`${persona.nombres} ${persona.apellido_a} ${persona.apellido_b}`}
|
||||||
class="img-fluid rounded-circle mb-2"
|
class="img-fluid rounded-circle mb-2"
|
||||||
width="128"
|
width="128"
|
||||||
height="128"
|
height="128"
|
||||||
|
|
|
@ -1,6 +1,48 @@
|
||||||
|
|
||||||
import { getToken } from './_config'
|
import { base, getToken } from './_config'
|
||||||
|
|
||||||
export async function getAplicaciones(params) {
|
export async function getAplicaciones(params) {
|
||||||
//
|
const query = !params ? '' : '?' + (new URLSearchParams(params).toString());
|
||||||
|
const res = await fetch(`${base}/aplicaciones/${query}`, {
|
||||||
|
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
if (!res.ok) throw await res.json()
|
||||||
|
return res.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getAplicacion(id) {
|
||||||
|
const res = await fetch(`${base}/aplicaciones/${id}/`, {
|
||||||
|
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
if (!res.ok) throw await res.json()
|
||||||
|
return res.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createAplicacion(data) {
|
||||||
|
const res = await fetch(`${base}/aplicaciones/`, {
|
||||||
|
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 updateAplicacion({ id_aplicacion: id, ...data }) {
|
||||||
|
const res = await fetch(`${base}/aplicaciones/${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 deleteAplicacion(id) {
|
||||||
|
const res = await fetch(`${base}/aplicaciones/${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