termine el contador de dias
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import Header from "./componentes/header.svelte";
|
||||||
|
import CalcularDias from "./componentes/paginas/CalcularDias.svelte";
|
||||||
import Tarjeta from "./componentes/tarjeta.svelte";
|
import Tarjeta from "./componentes/tarjeta.svelte";
|
||||||
import html2canvas from "html2canvas";
|
import html2canvas from "html2canvas";
|
||||||
|
|
||||||
|
let pagina = $state(0);
|
||||||
let issues: any[] = $state([]);
|
let issues: any[] = $state([]);
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
obtener_issues();
|
obtener_issues();
|
||||||
@@ -50,8 +53,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<button onclick={() => exportAllToPNG(issues)} class="btn btn-primary mt-3"
|
<Header bind:pagina></Header>
|
||||||
>Exportar a PNG</button
|
{#if pagina == 0}
|
||||||
|
<button
|
||||||
|
onclick={() => exportAllToPNG(issues)}
|
||||||
|
class="btn btn-primary mt-3">Exportar a PNG</button
|
||||||
>
|
>
|
||||||
{#if issues.length == 0}
|
{#if issues.length == 0}
|
||||||
<p>Cargando...</p>
|
<p>Cargando...</p>
|
||||||
@@ -70,4 +76,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{:else if pagina === 1}
|
||||||
|
<CalcularDias {issues} />
|
||||||
|
{/if}
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -874,25 +874,6 @@
|
|||||||
"updated_on": "2025-10-22T23:05:58Z",
|
"updated_on": "2025-10-22T23:05:58Z",
|
||||||
"closed_on": "2025-10-22T21:24:48Z"
|
"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,
|
"id": 6,
|
||||||
"project": { "id": 1, "name": "AlquilaFacil" },
|
"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