From 325b9321fce685ea08ca0f5cd0178b3a7abc6bdd Mon Sep 17 00:00:00 2001 From: perf3ct Date: Thu, 26 Jun 2025 16:46:19 +0000 Subject: [PATCH] feat(client): update titles of cards used on search and sources page --- frontend/src/index.css | 62 ++++++++++++ frontend/src/pages/SearchPage.tsx | 119 ++++++++++++++++------- frontend/src/pages/SourcesPage.tsx | 149 +++++++++++++++-------------- 3 files changed, 221 insertions(+), 109 deletions(-) diff --git a/frontend/src/index.css b/frontend/src/index.css index a6f39b7..5e001a1 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -24,6 +24,68 @@ .search-chip { font-size: 0.7rem !important; height: 18px !important; + max-width: 100px; + } +} + +/* Prevent text overflow in search components */ +.search-result-card { + overflow: hidden; +} + +.search-result-card .MuiCardContent-root { + overflow: hidden; +} + +/* Ensure proper flex behavior for narrow windows */ +@media (max-width: 1024px) { + /* Prevent horizontal overflow in search results */ + .search-result-card { + min-width: 0; + } + + /* Ensure chips wrap properly */ + .MuiChip-root { + flex-shrink: 0; + margin: 2px; + } + + /* Prevent button groups from overflowing */ + .MuiToggleButtonGroup-root { + flex-wrap: wrap; + gap: 4px; + } + + /* Ensure search stats wrap on narrow screens */ + .search-stats-container { + flex-wrap: wrap; + gap: 8px; + } +} + +/* Extra small screens */ +@media (max-width: 480px) { + /* Stack search mode buttons vertically */ + .MuiToggleButtonGroup-root { + flex-direction: column; + width: 100%; + } + + .MuiToggleButtonGroup-root .MuiToggleButton-root { + width: 100%; + } + + /* Reduce chip sizes further */ + .search-chip { + font-size: 0.65rem !important; + height: 16px !important; + padding: 0 6px !important; + } + + /* Stack action buttons vertically in cards */ + .search-card-actions { + flex-direction: column; + gap: 4px; } } diff --git a/frontend/src/pages/SearchPage.tsx b/frontend/src/pages/SearchPage.tsx index d7e2c9f..b3db44a 100644 --- a/frontend/src/pages/SearchPage.tsx +++ b/frontend/src/pages/SearchPage.tsx @@ -601,19 +601,21 @@ const SearchPage: React.FC = () => { flexWrap: 'wrap', gap: 2, }}> - + } label={`${totalResults} results`} size="small" color="primary" variant="outlined" + sx={{ flexShrink: 0 }} /> } label={`${queryTime}ms`} size="small" variant="outlined" + sx={{ flexShrink: 0 }} /> {advancedSettings.useEnhancedSearch && ( { size="small" color="success" variant="outlined" + sx={{ flexShrink: 0 }} /> )} - + {/* Simplified Search Mode Selector */} { Quick suggestions: - + {quickSuggestions.map((suggestion, index) => ( { variant="outlined" color="primary" sx={{ + flexShrink: 0, '&:hover': { backgroundColor: 'primary.main', color: 'primary.contrastText', @@ -665,7 +669,7 @@ const SearchPage: React.FC = () => { }} /> ))} - + )} @@ -675,7 +679,7 @@ const SearchPage: React.FC = () => { Related searches: - + {suggestions.map((suggestion, index) => ( { clickable variant="outlined" sx={{ + flexShrink: 0, '&:hover': { backgroundColor: 'primary.light', color: 'primary.contrastText', @@ -692,7 +697,7 @@ const SearchPage: React.FC = () => { }} /> ))} - + )} @@ -771,9 +776,22 @@ const SearchPage: React.FC = () => { onChange={handleTagsChange} input={} renderValue={(selected) => ( - + {selected.map((value) => ( - + ))} )} @@ -1060,15 +1078,15 @@ const SearchPage: React.FC = () => { )} - - + + {viewMode === 'list' && ( {getFileIcon(doc.mime_type)} )} - + { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', + display: 'block', + width: '100%', }} title={doc.original_filename} > {doc.original_filename} - + {doc.has_ocr_text && ( { size="small" color="success" variant="outlined" + sx={{ flexShrink: 0 }} /> )} - + {doc.tags.length > 0 && ( - + {doc.tags.slice(0, 2).map((tag, index) => ( { size="small" color="primary" variant="outlined" - sx={{ fontSize: '0.7rem', height: '18px' }} + sx={{ + fontSize: '0.7rem', + height: '18px', + flexShrink: 0, + maxWidth: '120px', + '& .MuiChip-label': { + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + } + }} /> ))} {doc.tags.length > 2 && ( @@ -1127,10 +1160,10 @@ const SearchPage: React.FC = () => { label={`+${doc.tags.length - 2}`} size="small" variant="outlined" - sx={{ fontSize: '0.7rem', height: '18px' }} + sx={{ fontSize: '0.7rem', height: '18px', flexShrink: 0 }} /> )} - + )} {/* Enhanced Search Snippets */} @@ -1150,37 +1183,49 @@ const SearchPage: React.FC = () => { {/* Search Rank */} {doc.search_rank && ( - + )} - - navigate(`/documents/${doc.id}`)} - > - - - - - handleDownload(doc)} - > - - - + + + navigate(`/documents/${doc.id}`)} + > + + + + + handleDownload(doc)} + > + + + + diff --git a/frontend/src/pages/SourcesPage.tsx b/frontend/src/pages/SourcesPage.tsx index 76a3ecd..2621a74 100644 --- a/frontend/src/pages/SourcesPage.tsx +++ b/frontend/src/pages/SourcesPage.tsx @@ -572,75 +572,84 @@ const SourcesPage: React.FC = () => { return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; }; - const StatCard = ({ icon, label, value, color = 'primary' }: { + const StatCard = ({ icon, label, value, color = 'primary', tooltip }: { icon: React.ReactNode; label: string; value: string | number; - color?: 'primary' | 'success' | 'warning' | 'error' | 'info' - }) => ( - - - - {icon} - - - { + const card = ( + + + - {typeof value === 'number' ? value.toLocaleString() : value} - - - {label} - - - - - ); + {icon} + + + + {typeof value === 'number' ? value.toLocaleString() : value} + + + {label} + + + + + ); + + return tooltip ? ( + + {card} + + ) : card; + }; const renderSourceCard = (source: Source) => ( @@ -808,9 +817,10 @@ const SourcesPage: React.FC = () => { } - label="Files Synced" + label="Files Processed" value={source.total_files_synced} color="success" + tooltip="Files attempted to be synced, including duplicates and skipped files" /> @@ -819,14 +829,7 @@ const SourcesPage: React.FC = () => { label="Files Pending" value={source.total_files_pending} color="warning" - /> - - - } - label="OCR Processed" - value={source.total_files_synced} - color="info" + tooltip="Files discovered but not yet processed during sync" /> @@ -835,6 +838,7 @@ const SourcesPage: React.FC = () => { label="Total Size (Downloaded)" value={formatBytes(source.total_size_bytes)} color="primary" + tooltip="Total size of files successfully downloaded from this source" /> @@ -845,6 +849,7 @@ const SourcesPage: React.FC = () => { ? formatDistanceToNow(new Date(source.last_sync_at), { addSuffix: true }) : 'Never'} color="primary" + tooltip="When this source was last synchronized" />