termine el contador de dias
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
<script lang="ts">
|
||||
import Header from "./componentes/header.svelte";
|
||||
import CalcularDias from "./componentes/paginas/CalcularDias.svelte";
|
||||
import Tarjeta from "./componentes/tarjeta.svelte";
|
||||
import html2canvas from "html2canvas";
|
||||
|
||||
let pagina = $state(0);
|
||||
let issues: any[] = $state([]);
|
||||
$effect(() => {
|
||||
obtener_issues();
|
||||
@@ -50,24 +53,30 @@
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<button onclick={() => exportAllToPNG(issues)} class="btn btn-primary mt-3"
|
||||
>Exportar a PNG</button
|
||||
>
|
||||
{#if issues.length == 0}
|
||||
<p>Cargando...</p>
|
||||
{:else}
|
||||
<div class="d-flex justify-center flex-column align-items-center">
|
||||
{#each issues as issue}
|
||||
<div class="m-2 w-75">
|
||||
<Tarjeta {issue} />
|
||||
<!--
|
||||
<Header bind:pagina></Header>
|
||||
{#if pagina == 0}
|
||||
<button
|
||||
onclick={() => exportAllToPNG(issues)}
|
||||
class="btn btn-primary mt-3">Exportar a PNG</button
|
||||
>
|
||||
{#if issues.length == 0}
|
||||
<p>Cargando...</p>
|
||||
{:else}
|
||||
<div class="d-flex justify-center flex-column align-items-center">
|
||||
{#each issues as issue}
|
||||
<div class="m-2 w-75">
|
||||
<Tarjeta {issue} />
|
||||
<!--
|
||||
<button
|
||||
onclick={() => exportToPNG(issue)}
|
||||
class="btn btn-primary mt-3">Exportar a PNG</button
|
||||
>
|
||||
-->
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{:else if pagina === 1}
|
||||
<CalcularDias {issues} />
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
@@ -874,25 +874,6 @@
|
||||
"updated_on": "2025-10-22T23:05:58Z",
|
||||
"closed_on": "2025-10-22T21:24:48Z"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"project": { "id": 1, "name": "AlquilaFacil" },
|
||||
"tracker": { "id": 1, "name": "Caracteristica" },
|
||||
"status": { "id": 2, "name": "Cerrado", "is_closed": true },
|
||||
"priority": { "id": 2, "name": "Normal" },
|
||||
"author": { "id": 5, "name": "Federico Polidoro" },
|
||||
"subject": "Falta validacion de longitud campo nombre",
|
||||
"description": "\r\n\r\n\u003cimg width=\"389\" alt=\"image.png\" src=\"attachments/b6ed90ae-e622-4ab6-bbf2-dabd58b94717\"\u003e\r\n\r\n",
|
||||
"start_date": "2025-05-29",
|
||||
"due_date": "2025-05-29",
|
||||
"done_ratio": 100,
|
||||
"is_private": false,
|
||||
"estimated_hours": null,
|
||||
"total_estimated_hours": null,
|
||||
"created_on": "2025-10-22T20:58:54Z",
|
||||
"updated_on": "2025-10-22T23:07:19Z",
|
||||
"closed_on": "2025-10-22T21:24:48Z"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"project": { "id": 1, "name": "AlquilaFacil" },
|
||||
|
||||
29
src/componentes/header.svelte
Normal file
29
src/componentes/header.svelte
Normal file
@@ -0,0 +1,29 @@
|
||||
<script>
|
||||
let count = $state(0);
|
||||
|
||||
let { pagina = $bindable() } = $props();
|
||||
</script>
|
||||
|
||||
<header
|
||||
style="display: flex; justify-content: space-between; align-items: center; padding: 1rem; "
|
||||
>
|
||||
<div>
|
||||
<button class="btn btn-primary" onclick={() => (pagina = 0)}
|
||||
>Tarjetas</button
|
||||
>
|
||||
<button class="btn btn-primary" onclick={() => (pagina = 1)}
|
||||
>Dias de duracion</button
|
||||
>
|
||||
<button
|
||||
class="btn"
|
||||
aria-label="Cambiar tema"
|
||||
onclick={() =>
|
||||
document.body.setAttribute(
|
||||
"data-bs-theme",
|
||||
document.body.getAttribute("data-bs-theme") === "dark"
|
||||
? "light"
|
||||
: "dark",
|
||||
)}>AAAA me quema los ojos</button
|
||||
>
|
||||
</div>
|
||||
</header>
|
||||
107
src/componentes/paginas/CalcularDias.svelte
Normal file
107
src/componentes/paginas/CalcularDias.svelte
Normal file
@@ -0,0 +1,107 @@
|
||||
<script lang="ts">
|
||||
import type { Issue } from "../../types";
|
||||
|
||||
let { issues }: { issues: Issue[] } = $props();
|
||||
|
||||
$effect(() => {
|
||||
calcularDiasPorIssue();
|
||||
calcularDiasTotales();
|
||||
});
|
||||
|
||||
let diasCalculados = $state(0);
|
||||
|
||||
function calcularDiasTotales() {
|
||||
if (!issues || issues.length === 0) {
|
||||
diasCalculados = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
let totalDias = 0;
|
||||
|
||||
let primerIssue = issues.reduce((acc, issue) => {
|
||||
if (!acc.start_date) return issue;
|
||||
if (!issue.start_date) return acc;
|
||||
|
||||
const accDate = new Date(acc.start_date);
|
||||
const issueDate = new Date(issue.start_date);
|
||||
|
||||
return issueDate < accDate ? issue : acc;
|
||||
});
|
||||
|
||||
let ultimoIssue = issues.reduce((acc, issue) => {
|
||||
if (!acc.due_date) return issue;
|
||||
if (!issue.due_date) return acc;
|
||||
|
||||
const accDate = new Date(acc.due_date);
|
||||
const issueDate = new Date(issue.due_date);
|
||||
|
||||
return issueDate > accDate ? issue : acc;
|
||||
});
|
||||
|
||||
if (!primerIssue.start_date || !ultimoIssue.due_date) {
|
||||
diasCalculados = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const startDate = new Date(primerIssue.start_date);
|
||||
const endDate = new Date(ultimoIssue.due_date);
|
||||
|
||||
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
|
||||
diasCalculados = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const diffTime = endDate.getTime() - startDate.getTime();
|
||||
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
||||
diasCalculados = diffDays > 0 ? diffDays : 0;
|
||||
}
|
||||
|
||||
function calcularDiasPorIssue() {
|
||||
issues.forEach((issue) => {
|
||||
if (issue.start_date && issue.due_date) {
|
||||
const startDate = new Date(issue.start_date);
|
||||
const dueDate = new Date(issue.due_date);
|
||||
|
||||
if (!isNaN(startDate.getTime()) && !isNaN(dueDate.getTime())) {
|
||||
const diffTime = dueDate.getTime() - startDate.getTime();
|
||||
const diffDays = Math.ceil(
|
||||
diffTime / (1000 * 60 * 60 * 24),
|
||||
);
|
||||
issue.cantDias = diffDays;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="mb-0">Calculadora de Días</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{#if diasCalculados > 0}
|
||||
<div class="alert alert-info">
|
||||
<strong>Resultado:</strong>
|
||||
{diasCalculados} días calculados
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="mt-3">
|
||||
<h6>Issues:</h6>
|
||||
<ul class="list-group">
|
||||
{#each issues as issue}
|
||||
<li
|
||||
class="list-group-item d-flex justify-content-between align-items-center"
|
||||
>
|
||||
{`${issue.id} | ${issue.subject}`}
|
||||
<span class="badge bg-secondary"
|
||||
>{issue.cantDias || 0} días</span
|
||||
>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
20
src/types.d.ts
vendored
Normal file
20
src/types.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
export interface Issue {
|
||||
id: number;
|
||||
project: { id: number; name: string };
|
||||
tracker: { id: number; name: string };
|
||||
status: { id: number; name: string; is_closed: boolean };
|
||||
priority: { id: number; name: string };
|
||||
author: { id: number; name: string };
|
||||
subject: string;
|
||||
description: string;
|
||||
start_date: string;
|
||||
due_date: string;
|
||||
cantDias: number;
|
||||
done_ratio: number;
|
||||
is_private: boolean;
|
||||
estimated_hours: number | null;
|
||||
total_estimated_hours: number | null;
|
||||
created_on: string;
|
||||
updated_on: string;
|
||||
closed_on: string;
|
||||
}
|
||||
Reference in New Issue
Block a user