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"
/>