CreaRack-SL

QuickLinks — Vista dual Tarjetas / Listado

QuickLinks — Vista dual Tarjetas / Listado

Resumen

El módulo QuickLinks del Workspace permite a cada usuario gestionar y navegar sus enlaces rápidos. Desde el commit 6a1358e (2026-05-07, @Esquembri), la sección dispone de dos vistas intercambiables:

VistaClase CSS contenedorDescripción
Tarjetas (grid)tools-bento-gridBento cards agrupadas por categoría. Vista original.
Listado (list)tools-listFilas densas tipo Raycast con 5 columnas: icono · label · URL · descripción · acciones.

La elección se persiste en localStorage bajo la clave workspace.quicklinks.view y sobrevive a recargas de página.


Motivación

Edu solicitó tener ambas vistas disponibles simultáneamente: la vista de tarjetas bento ya existente (agrupada por categoría) y la del mockup del agente (lista densa, navegación rápida con más información visible a la vez).


Implementación técnica

Tipo View (reemplaza Density)

// QuickLinksPage.tsx
type View = 'grid' | 'list';
const VIEW_STORAGE_KEY = 'workspace.quicklinks.view';

Anteriormente el tipo era Density = 'cozy' | 'compact'. El estado density ha sido renombrado a view y su valor inicial se lee de localStorage:

const [view, setView] = useState<View>(() => {
  if (typeof window === 'undefined') return 'grid';
  return (localStorage.getItem(VIEW_STORAGE_KEY) as View) ?? 'grid';
});

Un useEffect escribe en localStorage cada vez que el usuario cambia la vista.

Toggle de vista (accesible)

El segmento de control ahora usa role="tablist" / role="tab" + aria-selected para cumplir con accesibilidad ARIA:

<div className="tools-seg" role="tablist" aria-label="Vista">
  <button role="tab" aria-selected={view === 'grid'} onClick={() => setView('grid')}>Tarjetas</button>
  <button role="tab" aria-selected={view === 'list'} onClick={() => setView('list')}>Listado</button>
</div>

QuickLinkCard — renderizado condicional

El componente recibe view: 'grid' | 'list' (antes density: 'cozy' | 'compact'). Ramifica su JSX según el valor:

  • view === 'list' → <a className="tools-list-row"> con grid de 5 columnas.
  • view === 'grid' → <a className="tools-bento"> con el bento original (simplificado: el modo compacto que ocultaba URL y descripción ha sido eliminado).

Los handlers handleEdit / handleDelete han sido extraídos como funciones nombradas compartidas entre ambas ramas, eliminando duplicación.

CSS — Vista listado

.tools-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-raised);
}

.tools-list-row {
  display: grid;
  grid-template-columns: 28px minmax(180px, 1fr) minmax(180px, 1.2fr) minmax(0, 2fr) auto;
  gap: 0.85rem;
  padding: 0.55rem 0.9rem;
}

Responsive (<900 px): las columnas row-url y row-desc se ocultan, el grid colapsa a 3 columnas (28px · 1fr · auto).

Las acciones (Editar / Borrar) aparecen con opacity: 0 y se muestran al hacer hover sobre la fila.

CSS eliminado

La clase .tools-bento.compact (y sus modificadores .bento-desc, .bento-url, .bento-label) ha sido retirada al quedar sin uso.


Columnas de la vista Listado

ColumnaClase CSSVisible <900px
Icono (favicon / iniciales).row-icon✅
Etiqueta (link.label).row-label✅
Host (hostnameOf(url)).row-url❌
Descripción.row-desc❌
Acciones (Editar / Borrar).row-actions✅

Persistencia

Clave localStorageValoresDefault
workspace.quicklinks.view'grid' | 'list''grid'

La lectura es lazy (función init de useState) para ser compatible con SSR / ventana no disponible.


Archivos afectados

ArchivoCambio
src/components/quicklinks/QuickLinksPage.tsxDensity → View, toggle renombrado, persistencia localStorage, container CSS condicional
src/components/quicklinks/QuickLinkCard.tsxProp density → view, rama JSX para vista listado, handlers refactorizados
src/styles/tools.cssElimina .tools-bento.compact; añade .tools-list + .tools-list-row + responsive

Véase también

  • [[workspace—que-es-workspace]]
  • [[workspace—informes]]