feat(client): update titles of cards used on search and sources page
This commit is contained in:
parent
fc66495da0
commit
325b9321fc
|
|
@ -24,6 +24,68 @@
|
||||||
.search-chip {
|
.search-chip {
|
||||||
font-size: 0.7rem !important;
|
font-size: 0.7rem !important;
|
||||||
height: 18px !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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -601,19 +601,21 @@ const SearchPage: React.FC = () => {
|
||||||
flexWrap: 'wrap',
|
flexWrap: 'wrap',
|
||||||
gap: 2,
|
gap: 2,
|
||||||
}}>
|
}}>
|
||||||
<Stack direction="row" spacing={2} alignItems="center">
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, alignItems: 'center' }}>
|
||||||
<Chip
|
<Chip
|
||||||
icon={<TrendingIcon />}
|
icon={<TrendingIcon />}
|
||||||
label={`${totalResults} results`}
|
label={`${totalResults} results`}
|
||||||
size="small"
|
size="small"
|
||||||
color="primary"
|
color="primary"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
sx={{ flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
<Chip
|
<Chip
|
||||||
icon={<TimeIcon />}
|
icon={<TimeIcon />}
|
||||||
label={`${queryTime}ms`}
|
label={`${queryTime}ms`}
|
||||||
size="small"
|
size="small"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
sx={{ flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
{advancedSettings.useEnhancedSearch && (
|
{advancedSettings.useEnhancedSearch && (
|
||||||
<Chip
|
<Chip
|
||||||
|
|
@ -622,9 +624,10 @@ const SearchPage: React.FC = () => {
|
||||||
size="small"
|
size="small"
|
||||||
color="success"
|
color="success"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
sx={{ flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Box>
|
||||||
|
|
||||||
{/* Simplified Search Mode Selector */}
|
{/* Simplified Search Mode Selector */}
|
||||||
<ToggleButtonGroup
|
<ToggleButtonGroup
|
||||||
|
|
@ -647,7 +650,7 @@ const SearchPage: React.FC = () => {
|
||||||
<Typography variant="body2" color="text.secondary" gutterBottom>
|
<Typography variant="body2" color="text.secondary" gutterBottom>
|
||||||
Quick suggestions:
|
Quick suggestions:
|
||||||
</Typography>
|
</Typography>
|
||||||
<Stack direction="row" spacing={1} flexWrap="wrap">
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>
|
||||||
{quickSuggestions.map((suggestion, index) => (
|
{quickSuggestions.map((suggestion, index) => (
|
||||||
<Chip
|
<Chip
|
||||||
key={index}
|
key={index}
|
||||||
|
|
@ -658,6 +661,7 @@ const SearchPage: React.FC = () => {
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="primary"
|
color="primary"
|
||||||
sx={{
|
sx={{
|
||||||
|
flexShrink: 0,
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
backgroundColor: 'primary.main',
|
backgroundColor: 'primary.main',
|
||||||
color: 'primary.contrastText',
|
color: 'primary.contrastText',
|
||||||
|
|
@ -665,7 +669,7 @@ const SearchPage: React.FC = () => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Stack>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -675,7 +679,7 @@ const SearchPage: React.FC = () => {
|
||||||
<Typography variant="body2" color="text.secondary" gutterBottom>
|
<Typography variant="body2" color="text.secondary" gutterBottom>
|
||||||
Related searches:
|
Related searches:
|
||||||
</Typography>
|
</Typography>
|
||||||
<Stack direction="row" spacing={1} flexWrap="wrap">
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>
|
||||||
{suggestions.map((suggestion, index) => (
|
{suggestions.map((suggestion, index) => (
|
||||||
<Chip
|
<Chip
|
||||||
key={index}
|
key={index}
|
||||||
|
|
@ -685,6 +689,7 @@ const SearchPage: React.FC = () => {
|
||||||
clickable
|
clickable
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
sx={{
|
sx={{
|
||||||
|
flexShrink: 0,
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
backgroundColor: 'primary.light',
|
backgroundColor: 'primary.light',
|
||||||
color: 'primary.contrastText',
|
color: 'primary.contrastText',
|
||||||
|
|
@ -692,7 +697,7 @@ const SearchPage: React.FC = () => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Stack>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -771,9 +776,22 @@ const SearchPage: React.FC = () => {
|
||||||
onChange={handleTagsChange}
|
onChange={handleTagsChange}
|
||||||
input={<OutlinedInput label="Select Tags" />}
|
input={<OutlinedInput label="Select Tags" />}
|
||||||
renderValue={(selected) => (
|
renderValue={(selected) => (
|
||||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5, overflow: 'hidden' }}>
|
||||||
{selected.map((value) => (
|
{selected.map((value) => (
|
||||||
<Chip key={value} label={value} size="small" />
|
<Chip
|
||||||
|
key={value}
|
||||||
|
label={value}
|
||||||
|
size="small"
|
||||||
|
sx={{
|
||||||
|
flexShrink: 0,
|
||||||
|
maxWidth: '100px',
|
||||||
|
'& .MuiChip-label': {
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
@ -1060,15 +1078,15 @@ const SearchPage: React.FC = () => {
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<CardContent className="search-card" sx={{ flexGrow: 1 }}>
|
<CardContent className="search-card" sx={{ flexGrow: 1, overflow: 'hidden' }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1 }}>
|
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1, width: '100%' }}>
|
||||||
{viewMode === 'list' && (
|
{viewMode === 'list' && (
|
||||||
<Box sx={{ mr: 1, mt: 0.5 }}>
|
<Box sx={{ mr: 1, mt: 0.5 }}>
|
||||||
{getFileIcon(doc.mime_type)}
|
{getFileIcon(doc.mime_type)}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Box sx={{ flexGrow: 1, minWidth: 0, pr: 1 }}>
|
<Box sx={{ flexGrow: 1, minWidth: 0, overflow: 'hidden' }}>
|
||||||
<Typography
|
<Typography
|
||||||
variant="h6"
|
variant="h6"
|
||||||
sx={{
|
sx={{
|
||||||
|
|
@ -1078,24 +1096,28 @@ const SearchPage: React.FC = () => {
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
textOverflow: 'ellipsis',
|
textOverflow: 'ellipsis',
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: 'nowrap',
|
||||||
|
display: 'block',
|
||||||
|
width: '100%',
|
||||||
}}
|
}}
|
||||||
title={doc.original_filename}
|
title={doc.original_filename}
|
||||||
>
|
>
|
||||||
{doc.original_filename}
|
{doc.original_filename}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<Stack direction="row" spacing={1} sx={{ mb: 1, flexWrap: 'wrap', gap: 0.5 }}>
|
<Box sx={{ mb: 1, display: 'flex', flexWrap: 'wrap', gap: 0.5, overflow: 'hidden' }}>
|
||||||
<Chip
|
<Chip
|
||||||
className="search-chip"
|
className="search-chip"
|
||||||
label={formatFileSize(doc.file_size)}
|
label={formatFileSize(doc.file_size)}
|
||||||
size="small"
|
size="small"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
sx={{ flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
<Chip
|
<Chip
|
||||||
className="search-chip"
|
className="search-chip"
|
||||||
label={formatDate(doc.created_at)}
|
label={formatDate(doc.created_at)}
|
||||||
size="small"
|
size="small"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
sx={{ flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
{doc.has_ocr_text && (
|
{doc.has_ocr_text && (
|
||||||
<Chip
|
<Chip
|
||||||
|
|
@ -1104,12 +1126,13 @@ const SearchPage: React.FC = () => {
|
||||||
size="small"
|
size="small"
|
||||||
color="success"
|
color="success"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
sx={{ flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Box>
|
||||||
|
|
||||||
{doc.tags.length > 0 && (
|
{doc.tags.length > 0 && (
|
||||||
<Stack direction="row" spacing={0.5} sx={{ mb: 1, flexWrap: 'wrap' }}>
|
<Box sx={{ mb: 1, display: 'flex', flexWrap: 'wrap', gap: 0.5, overflow: 'hidden' }}>
|
||||||
{doc.tags.slice(0, 2).map((tag, index) => (
|
{doc.tags.slice(0, 2).map((tag, index) => (
|
||||||
<Chip
|
<Chip
|
||||||
key={index}
|
key={index}
|
||||||
|
|
@ -1118,7 +1141,17 @@ const SearchPage: React.FC = () => {
|
||||||
size="small"
|
size="small"
|
||||||
color="primary"
|
color="primary"
|
||||||
variant="outlined"
|
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 && (
|
{doc.tags.length > 2 && (
|
||||||
|
|
@ -1127,10 +1160,10 @@ const SearchPage: React.FC = () => {
|
||||||
label={`+${doc.tags.length - 2}`}
|
label={`+${doc.tags.length - 2}`}
|
||||||
size="small"
|
size="small"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
sx={{ fontSize: '0.7rem', height: '18px' }}
|
sx={{ fontSize: '0.7rem', height: '18px', flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Enhanced Search Snippets */}
|
{/* Enhanced Search Snippets */}
|
||||||
|
|
@ -1150,37 +1183,49 @@ const SearchPage: React.FC = () => {
|
||||||
|
|
||||||
{/* Search Rank */}
|
{/* Search Rank */}
|
||||||
{doc.search_rank && (
|
{doc.search_rank && (
|
||||||
<Box sx={{ mt: 1 }}>
|
<Box sx={{ mt: 1, overflow: 'hidden' }}>
|
||||||
<Chip
|
<Chip
|
||||||
className="search-chip"
|
className="search-chip"
|
||||||
label={`Relevance: ${(doc.search_rank * 100).toFixed(1)}%`}
|
label={`Relevance: ${(doc.search_rank * 100).toFixed(1)}%`}
|
||||||
size="small"
|
size="small"
|
||||||
color="info"
|
color="info"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
sx={{ fontSize: '0.7rem', height: '18px' }}
|
sx={{
|
||||||
|
fontSize: '0.7rem',
|
||||||
|
height: '18px',
|
||||||
|
flexShrink: 0,
|
||||||
|
maxWidth: '150px',
|
||||||
|
'& .MuiChip-label': {
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Tooltip title="View Details">
|
<Box sx={{ display: 'flex', flexShrink: 0, ml: 'auto' }}>
|
||||||
<IconButton
|
<Tooltip title="View Details">
|
||||||
className="search-filter-button search-focusable"
|
<IconButton
|
||||||
size="small"
|
className="search-filter-button search-focusable"
|
||||||
onClick={() => navigate(`/documents/${doc.id}`)}
|
size="small"
|
||||||
>
|
onClick={() => navigate(`/documents/${doc.id}`)}
|
||||||
<ViewIcon />
|
>
|
||||||
</IconButton>
|
<ViewIcon />
|
||||||
</Tooltip>
|
</IconButton>
|
||||||
<Tooltip title="Download">
|
</Tooltip>
|
||||||
<IconButton
|
<Tooltip title="Download">
|
||||||
className="search-filter-button search-focusable"
|
<IconButton
|
||||||
size="small"
|
className="search-filter-button search-focusable"
|
||||||
onClick={() => handleDownload(doc)}
|
size="small"
|
||||||
>
|
onClick={() => handleDownload(doc)}
|
||||||
<DownloadIcon />
|
>
|
||||||
</IconButton>
|
<DownloadIcon />
|
||||||
</Tooltip>
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
||||||
|
|
@ -572,75 +572,84 @@ const SourcesPage: React.FC = () => {
|
||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
|
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;
|
icon: React.ReactNode;
|
||||||
label: string;
|
label: string;
|
||||||
value: string | number;
|
value: string | number;
|
||||||
color?: 'primary' | 'success' | 'warning' | 'error' | 'info'
|
color?: 'primary' | 'success' | 'warning' | 'error' | 'info';
|
||||||
}) => (
|
tooltip?: string;
|
||||||
<Box
|
}) => {
|
||||||
sx={{
|
const card = (
|
||||||
p: 2.5,
|
<Box
|
||||||
borderRadius: 3,
|
sx={{
|
||||||
background: `linear-gradient(135deg, ${alpha(theme.palette[color].main, 0.1)} 0%, ${alpha(theme.palette[color].main, 0.05)} 100%)`,
|
p: 2.5,
|
||||||
border: `1px solid ${alpha(theme.palette[color].main, 0.2)}`,
|
borderRadius: 3,
|
||||||
position: 'relative',
|
background: `linear-gradient(135deg, ${alpha(theme.palette[color].main, 0.1)} 0%, ${alpha(theme.palette[color].main, 0.05)} 100%)`,
|
||||||
overflow: 'hidden',
|
border: `1px solid ${alpha(theme.palette[color].main, 0.2)}`,
|
||||||
height: '100px',
|
position: 'relative',
|
||||||
display: 'flex',
|
overflow: 'hidden',
|
||||||
alignItems: 'center',
|
height: '100px',
|
||||||
'&::before': {
|
display: 'flex',
|
||||||
content: '""',
|
alignItems: 'center',
|
||||||
position: 'absolute',
|
'&::before': {
|
||||||
top: 0,
|
content: '""',
|
||||||
left: 0,
|
position: 'absolute',
|
||||||
right: 0,
|
top: 0,
|
||||||
height: '3px',
|
left: 0,
|
||||||
background: `linear-gradient(90deg, ${theme.palette[color].main}, ${theme.palette[color].light})`,
|
right: 0,
|
||||||
}
|
height: '3px',
|
||||||
}}
|
background: `linear-gradient(90deg, ${theme.palette[color].main}, ${theme.palette[color].light})`,
|
||||||
>
|
}
|
||||||
<Stack direction="row" alignItems="center" spacing={2} sx={{ width: '100%', overflow: 'hidden' }}>
|
}}
|
||||||
<Avatar
|
>
|
||||||
sx={{
|
<Stack direction="row" alignItems="center" spacing={2} sx={{ width: '100%', overflow: 'hidden' }}>
|
||||||
bgcolor: alpha(theme.palette[color].main, 0.15),
|
<Avatar
|
||||||
color: theme.palette[color].main,
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
flexShrink: 0
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{icon}
|
|
||||||
</Avatar>
|
|
||||||
<Box sx={{ minWidth: 0, flex: 1 }}>
|
|
||||||
<Typography
|
|
||||||
variant="h5"
|
|
||||||
fontWeight="bold"
|
|
||||||
color={theme.palette[color].main}
|
|
||||||
sx={{
|
sx={{
|
||||||
overflow: 'hidden',
|
bgcolor: alpha(theme.palette[color].main, 0.15),
|
||||||
textOverflow: 'ellipsis',
|
color: theme.palette[color].main,
|
||||||
whiteSpace: 'nowrap'
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
flexShrink: 0
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{typeof value === 'number' ? value.toLocaleString() : value}
|
{icon}
|
||||||
</Typography>
|
</Avatar>
|
||||||
<Typography
|
<Box sx={{ minWidth: 0, flex: 1 }}>
|
||||||
variant="body2"
|
<Typography
|
||||||
color="text.secondary"
|
variant="h5"
|
||||||
sx={{
|
fontWeight="bold"
|
||||||
overflow: 'hidden',
|
color={theme.palette[color].main}
|
||||||
textOverflow: 'ellipsis',
|
sx={{
|
||||||
whiteSpace: 'nowrap',
|
overflow: 'hidden',
|
||||||
fontSize: '0.75rem'
|
textOverflow: 'ellipsis',
|
||||||
}}
|
whiteSpace: 'nowrap'
|
||||||
>
|
}}
|
||||||
{label}
|
>
|
||||||
</Typography>
|
{typeof value === 'number' ? value.toLocaleString() : value}
|
||||||
</Box>
|
</Typography>
|
||||||
</Stack>
|
<Typography
|
||||||
</Box>
|
variant="body2"
|
||||||
);
|
color="text.secondary"
|
||||||
|
sx={{
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
fontSize: '0.75rem'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
return tooltip ? (
|
||||||
|
<Tooltip title={tooltip} arrow>
|
||||||
|
{card}
|
||||||
|
</Tooltip>
|
||||||
|
) : card;
|
||||||
|
};
|
||||||
|
|
||||||
const renderSourceCard = (source: Source) => (
|
const renderSourceCard = (source: Source) => (
|
||||||
<Fade in={true} key={source.id}>
|
<Fade in={true} key={source.id}>
|
||||||
|
|
@ -808,9 +817,10 @@ const SourcesPage: React.FC = () => {
|
||||||
<Grid item xs={6} sm={4} md={3}>
|
<Grid item xs={6} sm={4} md={3}>
|
||||||
<StatCard
|
<StatCard
|
||||||
icon={<TrendingUpIcon />}
|
icon={<TrendingUpIcon />}
|
||||||
label="Files Synced"
|
label="Files Processed"
|
||||||
value={source.total_files_synced}
|
value={source.total_files_synced}
|
||||||
color="success"
|
color="success"
|
||||||
|
tooltip="Files attempted to be synced, including duplicates and skipped files"
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6} sm={4} md={3}>
|
<Grid item xs={6} sm={4} md={3}>
|
||||||
|
|
@ -819,14 +829,7 @@ const SourcesPage: React.FC = () => {
|
||||||
label="Files Pending"
|
label="Files Pending"
|
||||||
value={source.total_files_pending}
|
value={source.total_files_pending}
|
||||||
color="warning"
|
color="warning"
|
||||||
/>
|
tooltip="Files discovered but not yet processed during sync"
|
||||||
</Grid>
|
|
||||||
<Grid item xs={6} sm={4} md={3}>
|
|
||||||
<StatCard
|
|
||||||
icon={<AssessmentIcon />}
|
|
||||||
label="OCR Processed"
|
|
||||||
value={source.total_files_synced}
|
|
||||||
color="info"
|
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6} sm={4} md={3}>
|
<Grid item xs={6} sm={4} md={3}>
|
||||||
|
|
@ -835,6 +838,7 @@ const SourcesPage: React.FC = () => {
|
||||||
label="Total Size (Downloaded)"
|
label="Total Size (Downloaded)"
|
||||||
value={formatBytes(source.total_size_bytes)}
|
value={formatBytes(source.total_size_bytes)}
|
||||||
color="primary"
|
color="primary"
|
||||||
|
tooltip="Total size of files successfully downloaded from this source"
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6} sm={4} md={3}>
|
<Grid item xs={6} sm={4} md={3}>
|
||||||
|
|
@ -845,6 +849,7 @@ const SourcesPage: React.FC = () => {
|
||||||
? formatDistanceToNow(new Date(source.last_sync_at), { addSuffix: true })
|
? formatDistanceToNow(new Date(source.last_sync_at), { addSuffix: true })
|
||||||
: 'Never'}
|
: 'Never'}
|
||||||
color="primary"
|
color="primary"
|
||||||
|
tooltip="When this source was last synchronized"
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue