improve colors
This commit is contained in:
@@ -16,7 +16,6 @@ import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { FileUpload } from "./FileUpload";
|
||||
import { DeleteConfirmDialog } from "./DeleteConfirmDialog";
|
||||
import { PDFPreviewModal } from "./PDFPreviewModal";
|
||||
import { CollectionVerifier } from "./CollectionVerifier";
|
||||
import { ChunkViewerModal } from "./ChunkViewerModal";
|
||||
import {
|
||||
ChunkingConfigModalLandingAI,
|
||||
@@ -31,6 +30,9 @@ import {
|
||||
Eye,
|
||||
MessageSquare,
|
||||
Scissors,
|
||||
Loader2,
|
||||
CheckCircle2,
|
||||
AlertCircle,
|
||||
} from "lucide-react";
|
||||
|
||||
interface DashboardProps {
|
||||
@@ -78,14 +80,77 @@ export function Dashboard({ onProcessingChange }: DashboardProps = {}) {
|
||||
const [chunkingCollectionName, setChunkingCollectionName] = useState("");
|
||||
const [processing, setProcessing] = useState(false);
|
||||
|
||||
// Collection status states
|
||||
const [isCheckingCollection, setIsCheckingCollection] = useState(false);
|
||||
const [collectionExists, setCollectionExists] = useState<boolean | null>(
|
||||
null,
|
||||
);
|
||||
const [collectionError, setCollectionError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
loadFiles();
|
||||
}, [selectedTema]);
|
||||
|
||||
// Check collection status when tema changes
|
||||
useEffect(() => {
|
||||
checkCollectionStatus();
|
||||
}, [selectedTema]);
|
||||
|
||||
const checkCollectionStatus = async () => {
|
||||
if (!selectedTema) {
|
||||
setCollectionExists(null);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsCheckingCollection(true);
|
||||
setCollectionError(null);
|
||||
|
||||
try {
|
||||
const result = await api.checkCollectionExists(selectedTema);
|
||||
setCollectionExists(result.exists);
|
||||
} catch (err) {
|
||||
console.error("Error checking collection:", err);
|
||||
setCollectionError(
|
||||
err instanceof Error ? err.message : "Error al verificar colección",
|
||||
);
|
||||
setCollectionExists(null);
|
||||
} finally {
|
||||
setIsCheckingCollection(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCreateCollection = async () => {
|
||||
if (!selectedTema) return;
|
||||
|
||||
setIsCheckingCollection(true);
|
||||
setCollectionError(null);
|
||||
|
||||
try {
|
||||
const result = await api.createCollection(selectedTema);
|
||||
if (result.success) {
|
||||
setCollectionExists(true);
|
||||
console.log(`Collection "${selectedTema}" created successfully`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Error creating collection:", err);
|
||||
setCollectionError(
|
||||
err instanceof Error ? err.message : "Error al crear colección",
|
||||
);
|
||||
} finally {
|
||||
setIsCheckingCollection(false);
|
||||
}
|
||||
};
|
||||
|
||||
const loadFiles = async () => {
|
||||
// Don't load files if no dataroom is selected
|
||||
if (!selectedTema) {
|
||||
setFiles([]);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await api.getFiles(selectedTema || undefined);
|
||||
const response = await api.getFiles(selectedTema);
|
||||
setFiles(response.files);
|
||||
} catch (error) {
|
||||
console.error("Error loading files:", error);
|
||||
@@ -311,13 +376,54 @@ export function Dashboard({ onProcessingChange }: DashboardProps = {}) {
|
||||
<div className="border-b border-gray-200 px-6 py-4">
|
||||
<div className="flex flex-wrap items-center justify-between gap-4">
|
||||
<div>
|
||||
<h2 className="text-2xl font-semibold text-gray-900">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<h2 className="text-2xl font-semibold text-gray-900">
|
||||
{selectedTema
|
||||
? `Dataroom: ${selectedTema}`
|
||||
: "Selecciona un dataroom"}
|
||||
</h2>
|
||||
{/* Collection Status Indicator */}
|
||||
{selectedTema && (
|
||||
<div className="flex items-center gap-2">
|
||||
{isCheckingCollection ? (
|
||||
<>
|
||||
<Loader2 className="w-4 h-4 animate-spin text-gray-500" />
|
||||
<span className="text-xs text-gray-500">
|
||||
Verificando...
|
||||
</span>
|
||||
</>
|
||||
) : collectionExists === true ? (
|
||||
<>
|
||||
<CheckCircle2 className="w-4 h-4 text-green-600" />
|
||||
<span className="text-xs text-green-600">
|
||||
Colección disponible
|
||||
</span>
|
||||
</>
|
||||
) : collectionExists === false ? (
|
||||
<>
|
||||
<AlertCircle className="w-4 h-4 text-yellow-600" />
|
||||
<button
|
||||
onClick={handleCreateCollection}
|
||||
className="text-xs text-yellow-600 hover:text-yellow-700 underline"
|
||||
>
|
||||
Crear colección
|
||||
</button>
|
||||
</>
|
||||
) : collectionError ? (
|
||||
<>
|
||||
<AlertCircle className="w-4 h-4 text-red-600" />
|
||||
<span className="text-xs text-red-600">
|
||||
Error de conexión
|
||||
</span>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-sm text-gray-600">
|
||||
{selectedTema
|
||||
? `Tema actual: ${selectedTema}`
|
||||
: "Todos los archivos"}
|
||||
</h2>
|
||||
<p className="mt-1 text-sm text-gray-600">
|
||||
{totalFiles} archivo{totalFiles !== 1 ? "s" : ""}
|
||||
? `${totalFiles} archivo${totalFiles !== 1 ? "s" : ""}`
|
||||
: "Selecciona un dataroom de la barra lateral para ver sus archivos"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -422,9 +528,11 @@ export function Dashboard({ onProcessingChange }: DashboardProps = {}) {
|
||||
<div className="flex flex-col items-center justify-center h-64">
|
||||
<FileText className="w-12 h-12 text-gray-400 mb-4" />
|
||||
<p className="text-gray-500">
|
||||
{searchTerm
|
||||
? "No se encontraron archivos"
|
||||
: "No hay archivos en este tema"}
|
||||
{!selectedTema
|
||||
? "Selecciona un dataroom para ver sus archivos"
|
||||
: searchTerm
|
||||
? "No se encontraron archivos"
|
||||
: "No hay archivos en este dataroom"}
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
@@ -579,14 +687,6 @@ export function Dashboard({ onProcessingChange }: DashboardProps = {}) {
|
||||
onDownload={handleDownloadFromPreview}
|
||||
/>
|
||||
|
||||
{/* Collection Verifier - Verifica/crea colección cuando se selecciona un tema */}
|
||||
<CollectionVerifier
|
||||
tema={selectedTema}
|
||||
onVerified={(exists) => {
|
||||
console.log(`Collection ${selectedTema} exists: ${exists}`);
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Chunk Viewer Modal */}
|
||||
<ChunkViewerModal
|
||||
isOpen={chunkViewerOpen}
|
||||
|
||||
@@ -92,14 +92,11 @@ export function Sidebar({
|
||||
setCreateError(null);
|
||||
|
||||
try {
|
||||
console.log("Creating dataroom:", trimmed);
|
||||
const result = await api.createDataroom({ name: trimmed });
|
||||
console.log("Dataroom created successfully:", result);
|
||||
|
||||
// Refresh the datarooms list (this will load all datarooms including the new one)
|
||||
console.log("Refreshing dataroom list...");
|
||||
|
||||
await loadTemas();
|
||||
console.log("Dataroom list refreshed");
|
||||
|
||||
// Select the newly created dataroom
|
||||
setSelectedTema(trimmed);
|
||||
@@ -126,7 +123,6 @@ export function Sidebar({
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await api.getDatarooms();
|
||||
console.log("Raw datarooms response:", response);
|
||||
|
||||
// Extract dataroom names from the response with better error handling
|
||||
let dataroomNames: string[] = [];
|
||||
@@ -137,18 +133,23 @@ export function Sidebar({
|
||||
}
|
||||
|
||||
setTemas(dataroomNames);
|
||||
console.log("Loaded datarooms:", dataroomNames);
|
||||
// Auto-select first dataroom if none is selected and datarooms are available
|
||||
if (!selectedTema && dataroomNames.length > 0) {
|
||||
setSelectedTema(dataroomNames[0]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading datarooms:", error);
|
||||
// Fallback to legacy getTemas if dataroom endpoint fails
|
||||
try {
|
||||
console.log("Falling back to legacy getTemas endpoint");
|
||||
const legacyResponse = await api.getTemas();
|
||||
const legacyTemas = Array.isArray(legacyResponse?.temas)
|
||||
? legacyResponse.temas.filter(Boolean)
|
||||
: [];
|
||||
setTemas(legacyTemas);
|
||||
console.log("Loaded legacy temas:", legacyTemas);
|
||||
// Auto-select first legacy tema if none is selected
|
||||
if (!selectedTema && legacyTemas.length > 0) {
|
||||
setSelectedTema(legacyTemas[0]);
|
||||
}
|
||||
} catch (legacyError) {
|
||||
console.error("Error loading legacy temas:", legacyError);
|
||||
// Ensure we always set an array, never undefined or null
|
||||
@@ -186,11 +187,9 @@ export function Sidebar({
|
||||
// 1. Delete the dataroom (this will also delete the vector collection)
|
||||
try {
|
||||
await api.deleteDataroom(tema);
|
||||
console.log(`Dataroom "${tema}" deleted successfully`);
|
||||
} catch (error) {
|
||||
console.error(`Error deleting dataroom "${tema}":`, error);
|
||||
// If dataroom deletion fails, fall back to legacy deletion
|
||||
console.log("Falling back to legacy deletion methods");
|
||||
|
||||
// Eliminar todos los archivos del tema en Azure Blob Storage
|
||||
await api.deleteTema(tema);
|
||||
@@ -200,7 +199,6 @@ export function Sidebar({
|
||||
const collectionExists = await api.checkCollectionExists(tema);
|
||||
if (collectionExists.exists) {
|
||||
await api.deleteCollection(tema);
|
||||
console.log(`Colección "${tema}" eliminada de Qdrant`);
|
||||
}
|
||||
} catch (collectionError) {
|
||||
console.warn(
|
||||
@@ -229,28 +227,28 @@ export function Sidebar({
|
||||
|
||||
return (
|
||||
<TooltipProvider delayDuration={100}>
|
||||
<div className="bg-white border-r border-gray-200 flex flex-col h-full transition-[width] duration-300">
|
||||
<div className="bg-slate-800 border-r border-slate-700 flex flex-col h-full transition-[width] duration-300">
|
||||
{/* Header */}
|
||||
<div
|
||||
className={cn(
|
||||
"border-b border-gray-200 flex items-center gap-3",
|
||||
"border-b border-slate-700 flex items-center gap-3",
|
||||
collapsed ? "p-4" : "p-6",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center gap-2 text-gray-900 flex-1",
|
||||
"flex items-center gap-2 text-slate-100 flex-1",
|
||||
collapsed ? "justify-center" : "justify-start",
|
||||
)}
|
||||
>
|
||||
<FileText className="h-6 w-6" />
|
||||
{!collapsed && <h1 className="text-xl font-semibold">DoRa Luma</h1>}
|
||||
{!collapsed && <h1 className="text-xl font-semibold">Luma</h1>}
|
||||
</div>
|
||||
{onToggleCollapse && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="text-gray-500 hover:text-gray-900"
|
||||
className="text-slate-400 hover:text-slate-100"
|
||||
onClick={onToggleCollapse}
|
||||
disabled={disabled}
|
||||
aria-label={
|
||||
@@ -277,7 +275,7 @@ export function Sidebar({
|
||||
>
|
||||
<h2
|
||||
className={cn(
|
||||
"text-sm font-medium text-gray-500",
|
||||
"text-sm font-medium text-slate-300",
|
||||
collapsed && "text-xs text-center",
|
||||
)}
|
||||
>
|
||||
@@ -286,10 +284,10 @@ export function Sidebar({
|
||||
{renderWithTooltip(
|
||||
"Crear dataroom",
|
||||
<Button
|
||||
variant="outline"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className={cn(
|
||||
"gap-2",
|
||||
"gap-2 bg-slate-700/50 text-slate-200 hover:bg-slate-600 hover:text-slate-100 border border-slate-600",
|
||||
collapsed
|
||||
? "h-10 w-10 p-0 justify-center rounded-full"
|
||||
: "",
|
||||
@@ -303,28 +301,9 @@ export function Sidebar({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Todos los archivos */}
|
||||
{renderWithTooltip(
|
||||
"Todos los archivos",
|
||||
<Button
|
||||
variant={selectedTema === null ? "secondary" : "ghost"}
|
||||
className={cn(
|
||||
"w-full justify-start",
|
||||
collapsed && "px-0 justify-center",
|
||||
)}
|
||||
onClick={() => handleTemaSelect(null)}
|
||||
disabled={disabled}
|
||||
>
|
||||
<FolderIcon className={cn("h-4 w-4", !collapsed && "mr-2")} />
|
||||
<span className={cn("truncate", collapsed && "sr-only")}>
|
||||
Todos los archivos
|
||||
</span>
|
||||
</Button>,
|
||||
)}
|
||||
|
||||
{/* Lista de temas */}
|
||||
{loading ? (
|
||||
<div className="text-sm text-gray-500 px-3 py-2 text-center">
|
||||
<div className="text-sm text-slate-400 px-3 py-2 text-center">
|
||||
{collapsed ? "..." : "Cargando..."}
|
||||
</div>
|
||||
) : Array.isArray(temas) && temas.length > 0 ? (
|
||||
@@ -335,7 +314,8 @@ export function Sidebar({
|
||||
<Button
|
||||
variant={selectedTema === tema ? "secondary" : "ghost"}
|
||||
className={cn(
|
||||
"w-full justify-start",
|
||||
"w-full justify-start text-slate-300 hover:bg-slate-700 hover:text-slate-100",
|
||||
selectedTema === tema && "bg-slate-700 text-slate-100",
|
||||
collapsed ? "px-0 justify-center" : "pr-10",
|
||||
)}
|
||||
onClick={() => handleTemaSelect(tema)}
|
||||
@@ -353,16 +333,16 @@ export function Sidebar({
|
||||
<button
|
||||
onClick={(e) => handleDeleteTema(tema, e)}
|
||||
disabled={deletingTema === tema || disabled}
|
||||
className="absolute right-2 top-1/2 -translate-y-1/2 p-1.5 rounded hover:bg-red-100 opacity-0 group-hover:opacity-100 transition-opacity disabled:opacity-50"
|
||||
className="absolute right-2 top-1/2 -translate-y-1/2 p-1.5 rounded hover:bg-red-500/20 opacity-0 group-hover:opacity-100 transition-opacity disabled:opacity-50"
|
||||
title="Eliminar dataroom y colección"
|
||||
>
|
||||
<Trash2 className="h-4 w-4 text-red-600" />
|
||||
<Trash2 className="h-4 w-4 text-red-400" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className="text-sm text-gray-500 px-3 py-2 text-center">
|
||||
<div className="text-sm text-slate-400 px-3 py-2 text-center">
|
||||
{Array.isArray(temas) && temas.length === 0
|
||||
? "No hay datarooms"
|
||||
: "Cargando datarooms..."}
|
||||
@@ -374,7 +354,7 @@ export function Sidebar({
|
||||
{/* Footer */}
|
||||
<div
|
||||
className={cn(
|
||||
"p-4 border-t border-gray-200 space-y-2",
|
||||
"p-4 border-t border-slate-700 space-y-2",
|
||||
collapsed && "flex flex-col items-center gap-2",
|
||||
)}
|
||||
>
|
||||
@@ -387,7 +367,7 @@ export function Sidebar({
|
||||
onClick={onNavigateToSchemas}
|
||||
disabled={disabled}
|
||||
className={cn(
|
||||
"w-full justify-start",
|
||||
"w-full justify-start bg-slate-700 text-slate-100 hover:bg-slate-600",
|
||||
collapsed && "px-0 justify-center",
|
||||
)}
|
||||
>
|
||||
@@ -400,12 +380,12 @@ export function Sidebar({
|
||||
{renderWithTooltip(
|
||||
"Actualizar datarooms",
|
||||
<Button
|
||||
variant="outline"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={loadTemas}
|
||||
disabled={loading || disabled}
|
||||
className={cn(
|
||||
"w-full justify-start",
|
||||
"w-full justify-start bg-slate-700/50 text-slate-200 hover:bg-slate-600 hover:text-slate-100 border border-slate-600",
|
||||
collapsed && "px-0 justify-center",
|
||||
)}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user