feat(ui): Jira-style card detail, edit-mode column management, design polish
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState } from "preact/hooks";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { cardDragType, readCardDrag } from "../drag";
|
||||
import type { Card, ListWithCards } from "../types";
|
||||
import { CardItem } from "./CardItem";
|
||||
@@ -6,12 +6,13 @@ import { ConfirmDialog } from "./ConfirmDialog";
|
||||
|
||||
interface ListColumnProps {
|
||||
list: ListWithCards;
|
||||
managingLists: boolean;
|
||||
onEditList: (patch: { name?: string; position?: number }) => Promise<void>;
|
||||
onDeleteList: () => Promise<void>;
|
||||
onCreateCard: (title: string) => Promise<void>;
|
||||
onEditCard: (cardID: number, patch: { title?: string; description?: string; done?: boolean }) => Promise<void>;
|
||||
onDeleteCard: (cardID: number) => Promise<void>;
|
||||
onMoveCard: (cardID: number, sourceListID: number, targetListID: number, index: number) => Promise<void>;
|
||||
onOpenCard: (id: number) => void;
|
||||
}
|
||||
|
||||
interface DropZoneProps {
|
||||
@@ -49,8 +50,9 @@ export function ListColumn({
|
||||
onDeleteList,
|
||||
onCreateCard,
|
||||
onEditCard,
|
||||
onDeleteCard,
|
||||
onMoveCard
|
||||
onMoveCard,
|
||||
onOpenCard,
|
||||
managingLists
|
||||
}: ListColumnProps) {
|
||||
const [editingName, setEditingName] = useState(false);
|
||||
const [name, setName] = useState(list.name);
|
||||
@@ -59,6 +61,15 @@ export function ListColumn({
|
||||
const [confirming, setConfirming] = useState(false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!managingLists && editingName) {
|
||||
setName(list.name);
|
||||
setEditingName(false);
|
||||
} else if (!editingName) {
|
||||
setName(list.name);
|
||||
}
|
||||
}, [editingName, list.name, managingLists]);
|
||||
|
||||
const saveName = async () => {
|
||||
if (!name.trim() || name.trim() === list.name) {
|
||||
setName(list.name);
|
||||
@@ -101,7 +112,7 @@ export function ListColumn({
|
||||
|
||||
return (
|
||||
<>
|
||||
<section class="list-column">
|
||||
<section class={"list-column " + (managingLists ? "is-managing" : "")}>
|
||||
<div class="list-header">
|
||||
<div class="list-heading">
|
||||
{editingName ? (
|
||||
@@ -120,12 +131,14 @@ export function ListColumn({
|
||||
}}
|
||||
onBlur={() => void saveName()}
|
||||
/>
|
||||
) : (
|
||||
) : managingLists ? (
|
||||
<button type="button" class="list-name" onClick={() => setEditingName(true)}>{list.name}</button>
|
||||
) : (
|
||||
<h2 class="list-name-text">{list.name}</h2>
|
||||
)}
|
||||
<span class="count-badge">{list.cards.length}</span>
|
||||
</div>
|
||||
<button
|
||||
{managingLists ? <button
|
||||
type="button"
|
||||
class="icon-button list-delete"
|
||||
aria-label={"Delete " + list.name}
|
||||
@@ -133,7 +146,7 @@ export function ListColumn({
|
||||
onClick={() => setConfirming(true)}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</button> : null}
|
||||
</div>
|
||||
<div class="cards-stack">
|
||||
<DropZone index={0} onDropCard={(cardID, sourceListID, index) => onMoveCard(cardID, sourceListID, list.id, index)} />
|
||||
@@ -142,12 +155,12 @@ export function ListColumn({
|
||||
<CardItem
|
||||
card={card}
|
||||
onEdit={(patch) => onEditCard(card.id, patch)}
|
||||
onDelete={() => onDeleteCard(card.id)}
|
||||
onOpen={() => onOpenCard(card.id)}
|
||||
/>
|
||||
<DropZone index={index + 1} onDropCard={(cardID, sourceListID, dropIndex) => onMoveCard(cardID, sourceListID, list.id, dropIndex)} />
|
||||
</div>
|
||||
))}
|
||||
{!list.cards.length ? <p class="list-empty">Drop a card here or add the first task.</p> : null}
|
||||
{!list.cards.length ? <p class="list-empty">No cards yet. Drop one here or add the first task.</p> : null}
|
||||
</div>
|
||||
{addingCard ? (
|
||||
<form
|
||||
@@ -193,4 +206,3 @@ export function ListColumn({
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user