feat: extrae TaskText y TaskMeta para TaskItem
Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>main
parent
415548cdce
commit
b02ca36383
@ -0,0 +1,31 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import TaskDueBadge from "$lib/ui/data/task/TaskDueBadge.svelte";
|
||||||
|
|
||||||
|
export let groupLabel: string;
|
||||||
|
export let gc: { border?: string; bg?: string; text?: string } | null = null;
|
||||||
|
export let due_date: string | null = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="group-badge"
|
||||||
|
title="Grupo"
|
||||||
|
style={gc
|
||||||
|
? `--gc-border: ${gc.border}; --gc-bg: ${gc.bg}; --gc-text: ${gc.text};`
|
||||||
|
: undefined}
|
||||||
|
>
|
||||||
|
{groupLabel}
|
||||||
|
</span>
|
||||||
|
{#if due_date}
|
||||||
|
<TaskDueBadge {due_date} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.group-badge {
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid var(--gc-border, var(--color-border));
|
||||||
|
background: var(--gc-bg, transparent);
|
||||||
|
color: var(--gc-text, inherit);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { tick, createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
|
export let description: string;
|
||||||
|
export let completed: boolean;
|
||||||
|
export let editing: boolean;
|
||||||
|
export let busy: boolean;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher<{
|
||||||
|
toggleEdit: void;
|
||||||
|
saveText: { text: string };
|
||||||
|
cancelText: void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
let el: HTMLElement | null = null;
|
||||||
|
|
||||||
|
// Mantener el DOM sincronizado cuando se cierra la edición o cambia la descripción
|
||||||
|
$: if (el && !editing) {
|
||||||
|
el.textContent = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enfocar al entrar en modo edición
|
||||||
|
$: if (editing) {
|
||||||
|
tick().then(() => {
|
||||||
|
if (el) {
|
||||||
|
el.focus();
|
||||||
|
placeCaretAtEnd(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function placeCaretAtEnd(node: HTMLElement) {
|
||||||
|
const range = document.createRange();
|
||||||
|
range.selectNodeContents(node);
|
||||||
|
range.collapse(false);
|
||||||
|
const sel = window.getSelection();
|
||||||
|
sel?.removeAllRanges();
|
||||||
|
sel?.addRange(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeText(s: string): string {
|
||||||
|
return s.replace(/\s+/g, " ").trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCurrentText(): string {
|
||||||
|
return normalizeText(el?.textContent || "");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
tabindex="0"
|
||||||
|
class="desc"
|
||||||
|
class:editing={editing}
|
||||||
|
class:completed
|
||||||
|
contenteditable={editing && !completed}
|
||||||
|
role="textbox"
|
||||||
|
aria-label="Descripción de la tarea"
|
||||||
|
spellcheck="true"
|
||||||
|
bind:this={el}
|
||||||
|
on:dblclick={() => !busy && !completed && dispatch('toggleEdit')}
|
||||||
|
on:keydown={(e) => {
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
e.preventDefault();
|
||||||
|
dispatch('cancelText');
|
||||||
|
} else if ((e.ctrlKey || e.metaKey) && e.key === "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
dispatch('saveText', { text: getCurrentText() });
|
||||||
|
} else if (e.key === "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{description}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.desc {
|
||||||
|
padding: 8px 4px;
|
||||||
|
grid-column: 1/3;
|
||||||
|
grid-row: 2/3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc.editing {
|
||||||
|
outline: 2px solid var(--color-primary);
|
||||||
|
outline-offset: 2px;
|
||||||
|
background: var(--color-surface);
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
white-space: normal;
|
||||||
|
text-overflow: clip;
|
||||||
|
grid-column: 1/3;
|
||||||
|
grid-row: 2/3;
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc.completed {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue