Mejora 2: Implementada edición en línea para el texto de los titulares.
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
// frontend/src/components/TablaTitulares.tsx
|
||||
|
||||
import {
|
||||
Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Chip, IconButton, Typography, Link
|
||||
} from '@mui/material';
|
||||
import { useState } from 'react';
|
||||
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Chip, IconButton, Typography, Link, TextField } from '@mui/material';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import DragHandleIcon from '@mui/icons-material/DragHandle';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
@@ -10,19 +9,27 @@ import { DndContext, closestCenter, PointerSensor, useSensor, useSensors, type D
|
||||
import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
||||
import { CSS } from '@dnd-kit/utilities';
|
||||
import type { Titular } from '../types';
|
||||
import type { ActualizarTitularPayload } from '../services/apiService';
|
||||
|
||||
interface SortableRowProps {
|
||||
titular: Titular;
|
||||
onDelete: (id: number) => void;
|
||||
onSave: (id: number, payload: ActualizarTitularPayload) => void;
|
||||
onEdit: (titular: Titular) => void;
|
||||
}
|
||||
|
||||
const SortableRow = ({ titular, onDelete, onEdit }: SortableRowProps) => {
|
||||
const SortableRow = ({ titular, onDelete, onSave, onEdit }: SortableRowProps) => {
|
||||
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: titular.id });
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const [editText, setEditText] = useState(titular.texto);
|
||||
|
||||
const style = {
|
||||
transform: CSS.Transform.toString(transform),
|
||||
transition,
|
||||
const style = { transform: CSS.Transform.toString(transform), transition };
|
||||
|
||||
const handleSave = () => {
|
||||
if (editText.trim() && editText.trim() !== titular.texto) {
|
||||
onSave(titular.id, { texto: editText.trim(), viñeta: titular.viñeta });
|
||||
}
|
||||
setIsEditing(false);
|
||||
};
|
||||
|
||||
const getChipColor = (tipo: Titular['tipo']): "success" | "warning" | "info" => {
|
||||
@@ -30,7 +37,7 @@ const SortableRow = ({ titular, onDelete, onEdit }: SortableRowProps) => {
|
||||
if (tipo === 'Manual') return 'info';
|
||||
return 'success';
|
||||
};
|
||||
|
||||
|
||||
const formatFuente = (fuente: string | null) => {
|
||||
if (!fuente) return 'N/A';
|
||||
try {
|
||||
@@ -46,7 +53,22 @@ const SortableRow = ({ titular, onDelete, onEdit }: SortableRowProps) => {
|
||||
<TableCell sx={{ cursor: 'grab', verticalAlign: 'middle' }} {...listeners}>
|
||||
<DragHandleIcon sx={{ color: 'text.secondary' }} />
|
||||
</TableCell>
|
||||
<TableCell sx={{ verticalAlign: 'middle' }}>{titular.texto}</TableCell>
|
||||
<TableCell sx={{ verticalAlign: 'middle' }} onClick={() => setIsEditing(true)}>
|
||||
{isEditing ? (
|
||||
<TextField
|
||||
fullWidth
|
||||
autoFocus
|
||||
variant="standard"
|
||||
value={editText}
|
||||
onChange={(e) => setEditText(e.target.value)}
|
||||
onBlur={handleSave}
|
||||
onKeyDown={(e) => { if (e.key === 'Enter') handleSave(); }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
/>
|
||||
) : (
|
||||
<Typography variant="body2">{titular.texto}</Typography>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell sx={{ verticalAlign: 'middle' }}>
|
||||
<Chip label={titular.tipo || 'Scraped'} color={getChipColor(titular.tipo)} size="small" />
|
||||
</TableCell>
|
||||
@@ -76,9 +98,10 @@ interface TablaTitularesProps {
|
||||
onReorder: (titulares: Titular[]) => void;
|
||||
onDelete: (id: number) => void;
|
||||
onEdit: (titular: Titular) => void;
|
||||
onSave: (id: number, payload: ActualizarTitularPayload) => void;
|
||||
}
|
||||
|
||||
const TablaTitulares = ({ titulares, onReorder, onDelete, onEdit }: TablaTitularesProps) => {
|
||||
const TablaTitulares = ({ titulares, onReorder, onDelete, onEdit, onSave }: TablaTitularesProps) => {
|
||||
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 8 } }));
|
||||
|
||||
const handleDragEnd = (event: DragEndEvent) => {
|
||||
@@ -115,7 +138,7 @@ const TablaTitulares = ({ titulares, onReorder, onDelete, onEdit }: TablaTitular
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{titulares.map((titular) => (
|
||||
<SortableRow key={titular.id} titular={titular} onDelete={onDelete} onEdit={onEdit} />
|
||||
<SortableRow key={titular.id} titular={titular} onDelete={onDelete} onEdit={onEdit} onSave={onSave} />
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
Reference in New Issue
Block a user