avansando más
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
using Entidades.Dto;
|
||||
|
||||
namespace AlquilaFacil.Builder;
|
||||
public class GrupoDtoBuilder : Builder<GrupoDto>
|
||||
{
|
||||
public GrupoDtoBuilder ConNombre(string nombre)
|
||||
{
|
||||
data.Nombre = nombre;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GrupoDtoBuilder ConIdGrupo(int id)
|
||||
{
|
||||
data.idgrupo = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GrupoDtoBuilder ConGruposIncluidos(HashSet<string> grupos)
|
||||
{
|
||||
data.GruposIncluidos = grupos;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GrupoDtoBuilder ConPermisos(List<PermisoDto> permisos)
|
||||
{
|
||||
data.Permisos = permisos;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public class PermisoDtoBuilder : Builder<PermisoDto>
|
||||
{
|
||||
public PermisoDtoBuilder ConId(int id)
|
||||
{
|
||||
data.Id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PermisoDtoBuilder ConDescripcion(string descripcion)
|
||||
{
|
||||
data.Descripcion = descripcion;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,36 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Modelo;
|
||||
using AlquilaFacil.Builder;
|
||||
using Entidades;
|
||||
|
||||
namespace AlquilaFacil.Controllers;
|
||||
|
||||
[ApiController]
|
||||
public class GruposController : ControllerBase
|
||||
{
|
||||
[HttpPost("api/admin/grupos")]
|
||||
[HttpGet("api/admin/grupos")]
|
||||
public IActionResult ObtenerGrupos([FromHeader(Name = "Auth")] string Auth)
|
||||
{//WIP
|
||||
{
|
||||
var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18);
|
||||
if (ret == false) return BadRequest(new { message = "No tiene permiso para Gestionar grupos" });
|
||||
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
|
||||
if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" });
|
||||
|
||||
var grupos = RepositorioGrupos.Singleton.ListarTodosLosGrupos()
|
||||
.Select(g => new GrupoDtoBuilder()
|
||||
.ConNombre(g.Nombre)
|
||||
.ConIdGrupo(g.Id)
|
||||
.ConGruposIncluidos(new HashSet<string>(g.IdGrupoHijos
|
||||
.Select(id => id.ToString() ?? "")))
|
||||
.ConPermisos(g.Idpermisos.Select(p => new PermisoDtoBuilder()
|
||||
.ConId(p.Id)
|
||||
.ConDescripcion(p.Descripcion)
|
||||
.Build())
|
||||
.ToList())
|
||||
.Build())
|
||||
.ToList();
|
||||
|
||||
return Ok(grupos);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Modelo;
|
||||
using Entidades.Dto;
|
||||
namespace AlquilaFacil.Controllers;
|
||||
|
||||
[ApiController]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"usr": "nwFNMLJcn5m0owbzeXMs",
|
||||
"scrt":"Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70"
|
||||
"scrt": "Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70",
|
||||
"connectiondb": "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"usr": "nwFNMLJcn5m0owbzeXMs",
|
||||
"scrt":"Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70"
|
||||
"scrt": "Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70",
|
||||
"connectiondb": "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Entidades;
|
||||
@@ -53,9 +54,16 @@ public partial class AlquilaFacilContext : DbContext
|
||||
|
||||
public virtual DbSet<Venta> Ventas { get; set; }
|
||||
|
||||
private class context
|
||||
{
|
||||
public string connectiondb { get; set; } = "";
|
||||
}
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263.
|
||||
=> optionsBuilder.UseMySQL("Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none");
|
||||
{
|
||||
context connection = JsonSerializer.Deserialize<context>(File.ReadAllText("settings.json")) ?? new();
|
||||
optionsBuilder.UseMySQL(connection.connectiondb);
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
namespace Entidades.Dto;
|
||||
public class GrupoDto
|
||||
{
|
||||
public int idgrupo { get; set; }
|
||||
|
||||
+11
-7
@@ -1,10 +1,10 @@
|
||||
<script lang="ts">
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
import "bootstrap/dist/css/bootstrap.min.css";
|
||||
import Login from "./paginas/login.svelte";
|
||||
import { Router, Route, link } from 'svelte-routing';
|
||||
import MenuPage from './paginas/menu.svelte';
|
||||
import ProteRoute from './Componentes/RutaProtegida.svelte';
|
||||
import InfoPage from './paginas/info.svelte';
|
||||
import { Router, Route, link } from "svelte-routing";
|
||||
import MenuPage from "./paginas/menu.svelte";
|
||||
import ProteRoute from "./Componentes/RutaProtegida.svelte";
|
||||
import InfoPage from "./paginas/info.svelte";
|
||||
import InqPage from "./paginas/inquilino.svelte";
|
||||
import PropPage from "./paginas/propietario.svelte";
|
||||
import MisPropiedades from "./paginas/MisPropiedades.svelte";
|
||||
@@ -30,6 +30,7 @@
|
||||
import ContratoAdmin from "./paginas/ContratoAdmin.svelte";
|
||||
import BuscarVentas from "./paginas/BuscarVentas.svelte";
|
||||
import MisPropiedadesEnVenta from "./paginas/MisPropiedadesEnVenta.svelte";
|
||||
import AdminGrupos from "./paginas/AdminGrupos.svelte";
|
||||
</script>
|
||||
|
||||
<Router>
|
||||
@@ -42,7 +43,6 @@
|
||||
<Route path="/" component={Login} />
|
||||
<Route path="/Info" component={InfoPage} />
|
||||
|
||||
|
||||
<Route path="/Menu">
|
||||
<ProteRoute componente={MenuPage} />
|
||||
</Route>
|
||||
@@ -128,6 +128,11 @@
|
||||
<ProteRoute componente={BuscarVentas} />
|
||||
</Route>
|
||||
|
||||
<!-- Gestion Grupos -->
|
||||
<Route path="/accion/18">
|
||||
<ProteRoute componente={AdminGrupos} />
|
||||
</Route>
|
||||
|
||||
<!-- Pagina Ventas -->
|
||||
<Route path="/Ventas">
|
||||
<ProteRoute componente={Ventas} />
|
||||
@@ -167,4 +172,3 @@
|
||||
<ProteRoute componente={ContratoAdmin} />
|
||||
</Route>
|
||||
</Router>
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<Navbar container="xxl" expand="md" color="dark-subtle">
|
||||
<Navbar class="border-bottom" container="xxl" expand="md" color="dark-subtle">
|
||||
<NavbarBrand href="/">AlquilaFacil</NavbarBrand>
|
||||
<div class="d-flex gap-2">
|
||||
<div class="badge" style="background-color: turquoise;" use:links>
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { Navbar, NavbarBrand, NavbarToggler, NavItem, Nav, NavLink, Collapse } from "@sveltestrap/sveltestrap";
|
||||
import {
|
||||
Navbar,
|
||||
NavbarBrand,
|
||||
NavbarToggler,
|
||||
NavItem,
|
||||
Nav,
|
||||
NavLink,
|
||||
Collapse,
|
||||
} from "@sveltestrap/sveltestrap";
|
||||
|
||||
let isOpen: boolean = $state(false);
|
||||
let theme = $state(localStorage.getItem("theme") ?? "light");
|
||||
@@ -10,13 +18,14 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<Navbar container="xxl" expand="md" color="dark-subtle">
|
||||
<NavbarBrand href="/">
|
||||
AlquilaFacil
|
||||
</NavbarBrand>
|
||||
<Navbar class="border-bottom" container="xxl" expand="md" color="dark-subtle">
|
||||
<NavbarBrand href="/">AlquilaFacil</NavbarBrand>
|
||||
<div>
|
||||
<button class="badge btn" onclick={toggleTheme} style="background-color: cadetblue;">
|
||||
<button
|
||||
class="badge btn"
|
||||
onclick={toggleTheme}
|
||||
style="background-color: cadetblue;"
|
||||
>
|
||||
{#if theme === "light"}
|
||||
<img src="/toggle-left.svg" alt="" />
|
||||
{:else}
|
||||
@@ -25,7 +34,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<NavbarToggler on:click={() => (isOpen = !isOpen)} />
|
||||
<Collapse isOpen={isOpen} navbar expand="md">
|
||||
<Collapse {isOpen} navbar expand="md">
|
||||
<Nav class="ms-auto" navbar>
|
||||
<NavItem>
|
||||
<NavLink href="/">Login</NavLink>
|
||||
|
||||
@@ -1,6 +1,103 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
|
||||
import type { GrupoDto } from "../types";
|
||||
import { urlG } from "../stores/urlStore";
|
||||
|
||||
const token: string = sessionStorage.getItem("token") || "";
|
||||
|
||||
let grupos: GrupoDto[] = $state([]);
|
||||
let modaldat: string = $state("");
|
||||
onMount(() => {
|
||||
ObtenerGrupos();
|
||||
});
|
||||
async function ObtenerGrupos() {
|
||||
try {
|
||||
const ret = await fetch($urlG + "/api/admin/grupos", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Auth: token,
|
||||
},
|
||||
});
|
||||
if (!ret.ok) {
|
||||
modaldat = "Fallo Al intentar hacer la request";
|
||||
return;
|
||||
}
|
||||
grupos = await ret.json();
|
||||
} catch {
|
||||
modaldat = "Fallo Al intentar hacer la request";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<NavBarAutocompletable />
|
||||
<div class="container-fluid"></div>
|
||||
<div class="container-fluid">
|
||||
{#if grupos.length == 0}
|
||||
<div class="text-center">
|
||||
<div class="spinner-border" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
{#each grupos as grupo}
|
||||
<div class="accordion mt-2">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button
|
||||
class="accordion-button collapsed"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target={`#${grupo.idgrupo}`}
|
||||
aria-expanded="false"
|
||||
aria-controls={grupo.idgrupo}
|
||||
>
|
||||
{grupo.nombre}
|
||||
</button>
|
||||
</h2>
|
||||
<div id={grupo.idgrupo} class="accordion-collapse collapse">
|
||||
<div class="accordion-body">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<h5>Grupos Incluidos</h5>
|
||||
<ul class="list-group">
|
||||
{#if grupo.gruposIncluidos.length == 0}
|
||||
<li class="list-group-item">
|
||||
No hay grupos incluidos
|
||||
</li>
|
||||
{:else}
|
||||
{#each grupo.gruposIncluidos as grupoIncluido}
|
||||
<li class="list-group-item">
|
||||
{grupoIncluido}
|
||||
</li>
|
||||
{/each}
|
||||
{/if}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<h5>Permisos</h5>
|
||||
<ul class="list-group">
|
||||
{#if grupo.permisos.length == 0}
|
||||
<li class="list-group-item">
|
||||
No hay grupos incluidos
|
||||
</li>
|
||||
{:else}
|
||||
{#each grupo.permisos as permiso}
|
||||
<li class="list-group-item">
|
||||
{permiso.descripcion}
|
||||
</li>
|
||||
{/each}
|
||||
{/if}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="d-flex justify-content-between">
|
||||
<button class="btn btn-primary">Editar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
const r = await fetch($urlG + "/api/Logs/cantPag", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Auth": token,
|
||||
}
|
||||
Auth: token,
|
||||
},
|
||||
});
|
||||
let data = await r.json();
|
||||
if (r.ok) {
|
||||
@@ -45,8 +45,8 @@
|
||||
const r = await fetch($urlG + "/api/Logs?pag=" + pagina, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Auth": token,
|
||||
}
|
||||
Auth: token,
|
||||
},
|
||||
});
|
||||
let data = await r.json();
|
||||
if (r.ok) {
|
||||
@@ -81,6 +81,10 @@
|
||||
|
||||
<div class="container-fluid mt-2">
|
||||
<BarraHorizontalConTexto text={"Logs"} />
|
||||
<div
|
||||
class="table-container"
|
||||
style="height: 80vh; overflow-y: auto; margin-bottom: 2.5rem;"
|
||||
>
|
||||
<table class="table table-responsive table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -97,7 +101,10 @@
|
||||
<td>{l.dniusuario}</td>
|
||||
<td>{l.accion}</td>
|
||||
<td>
|
||||
<button class="btn btn-primary" onclick={()=>prepararModal(l)}>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
onclick={() => prepararModal(l)}
|
||||
>
|
||||
Ver
|
||||
</button>
|
||||
</td>
|
||||
@@ -105,7 +112,16 @@
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="d-flex justify-content-center">
|
||||
<PaginacionStepper currentPag={pagina} {cantpag} {queryPag} centrado={true}/>
|
||||
<div
|
||||
class="fixed-bottom w-100 d-flex justify-content-center border-top py-2"
|
||||
style="background-color: rgba(0,0,0,0.5);"
|
||||
>
|
||||
<PaginacionStepper
|
||||
currentPag={pagina}
|
||||
{cantpag}
|
||||
{queryPag}
|
||||
centrado={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Vendored
+11
@@ -219,3 +219,14 @@ export type PatchPropiedad = {
|
||||
monto:number,
|
||||
iddivisa:number
|
||||
}
|
||||
|
||||
export type GrupoDto = {
|
||||
idgrupo:number,
|
||||
nombre:string,
|
||||
gruposIncluidos:string[],
|
||||
permisos:PermisoDto[]
|
||||
}
|
||||
export type PermisoDto = {
|
||||
id:number,
|
||||
descripcion:string
|
||||
}
|
||||
|
||||
@@ -3,24 +3,35 @@ using Entidades.Admin;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Modelo;
|
||||
public class RepositorioGrupos: RepositorioBase<RepositorioGrupos> {
|
||||
public class RepositorioGrupos : RepositorioBase<RepositorioGrupos>
|
||||
{
|
||||
|
||||
public IQueryable<Permiso> ListarPermisosDeGrupo(string grupo) {
|
||||
public IQueryable<Grupo> ListarTodosLosGrupos()
|
||||
{
|
||||
var con = Context;
|
||||
var grupos = con.Grupos.Include(x => x.IdGrupoHijos).ThenInclude(x => x.Idpermisos).Include(x => x.Idpermisos);
|
||||
return grupos;
|
||||
}
|
||||
public IQueryable<Permiso> ListarPermisosDeGrupo(string grupo)
|
||||
{
|
||||
var con = Context; //WIP Revisar esto
|
||||
return con.Grupos.Where(x => x.Nombre == grupo).SelectMany(x => x.Idpermisos);
|
||||
}
|
||||
|
||||
public IQueryable<GrupoAdmin> ObtenerGruposPorDni(long Dni) {
|
||||
public IQueryable<GrupoAdmin> ObtenerGruposPorDni(long Dni)
|
||||
{
|
||||
var con = Context;
|
||||
var grupos = con.Clientes.Where(x => x.Dni == Dni).SelectMany(x => x.Idgrupos)
|
||||
.Select(x=> new GrupoAdmin{
|
||||
.Select(x => new GrupoAdmin
|
||||
{
|
||||
Id = x.Id,
|
||||
Descripcion = x.Nombre,
|
||||
});
|
||||
return grupos;
|
||||
}
|
||||
|
||||
public bool CheckGrupos(string token, string grupo){
|
||||
public bool CheckGrupos(string token, string grupo)
|
||||
{
|
||||
var con = Context;
|
||||
Cliente? cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Token == token);
|
||||
if (cli == null) return false;
|
||||
|
||||
@@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
namespace Modelo;
|
||||
public class RepositorioPermisos : RepositorioBase<RepositorioPermisos>
|
||||
{
|
||||
public object? ListarPermisos(string email)
|
||||
public IQueryable<Grupo>? ListarPermisos(string email)
|
||||
{
|
||||
var con = Context;
|
||||
Cliente? cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(c => c.Email == email);
|
||||
@@ -21,31 +21,20 @@ public class RepositorioPermisos : RepositorioBase<RepositorioPermisos>
|
||||
|
||||
public bool CheckPermisos(string token, int idpermiso)
|
||||
{
|
||||
// Aca tengo que modificar esto para que haga una busqueda de profundidad para los permisos
|
||||
//WIP Aca tengo que modificar esto para que haga una busqueda de profundidad para los permisos
|
||||
//
|
||||
var con = Context;
|
||||
bool tienePermiso = false;
|
||||
|
||||
//checkeo que el token corresponda a un usuario
|
||||
Cliente? cli = con.Clientes.FirstOrDefault(x => x.Token == token);
|
||||
if (cli == null || cli.Dni == 0) return false;
|
||||
|
||||
// obtengo una lista de los permisos
|
||||
var permisos = con.Clientes
|
||||
.Where(x => x.Dni == cli.Dni)
|
||||
.SelectMany(x => x.Idgrupos)
|
||||
.SelectMany(x => x.Idpermisos)
|
||||
.Distinct();
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//Esto esta comentado porque antes pasaba el string del path de la url, es una mala idea a muchos niveles
|
||||
// abajo un comentario viejo mio
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//me inspiré y hice un regex pero si eliminaba los primeros 8(?) caracteres del string era lo mismo
|
||||
//Match match = Regex.Match(path, @"^/accion/(\d+)$");
|
||||
//int.TryParse(match.Groups[1].Value, out int idpermiso);
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
Parallel.ForEach(permisos, (x, i) =>
|
||||
{
|
||||
if (x.Id == idpermiso)
|
||||
|
||||
Reference in New Issue
Block a user