refactor(ui/alerts): tighter inbox action bar, history uses global time range
Inbox: replace 4 parallel outlined buttons with 2 context-aware ones. When nothing is selected → "Acknowledge all firing" (primary) + "Mark all read" (secondary). When rows are selected → the same slots become "Acknowledge N" + "Mark N read" with counts inlined. Primary variant gives the foreground action proper visual weight; secondary is the supporting action. No more visually-identical disabled buttons cluttering the bar. History: drop the local DateRangePicker. The page now reads `timeRange` from `useGlobalFilters()` so the top-bar TimeRangeDropdown (1h / 3h / 6h / Today / 24h / 7d / custom) is the single source of truth, consistent with every other time-scoped page in the app.
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { useState } from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { History } from 'lucide-react';
|
||||
import {
|
||||
DataTable, EmptyState, DateRangePicker,
|
||||
DataTable, EmptyState, useGlobalFilters,
|
||||
} from '@cameleer/design-system';
|
||||
import type { Column } from '@cameleer/design-system';
|
||||
import { PageLoader } from '../../components/PageLoader';
|
||||
@@ -29,18 +28,16 @@ function formatDuration(from?: string | null, to?: string | null): string {
|
||||
}
|
||||
|
||||
export default function HistoryPage() {
|
||||
const [dateRange, setDateRange] = useState({
|
||||
start: new Date(Date.now() - 7 * 24 * 3600_000),
|
||||
end: new Date(),
|
||||
});
|
||||
const { timeRange } = useGlobalFilters();
|
||||
|
||||
// useAlerts doesn't accept a time range today; filter client-side.
|
||||
// useAlerts doesn't accept a time range today; filter client-side
|
||||
// against the global TimeRangeDropdown in the top bar.
|
||||
const { data, isLoading, error } = useAlerts({ state: 'RESOLVED', limit: 200 });
|
||||
|
||||
const filtered = (data ?? []).filter((a) => {
|
||||
if (!a.firedAt) return false;
|
||||
const t = new Date(a.firedAt).getTime();
|
||||
return t >= dateRange.start.getTime() && t <= dateRange.end.getTime();
|
||||
return t >= timeRange.start.getTime() && t <= timeRange.end.getTime();
|
||||
});
|
||||
|
||||
const columns: Column<AlertDto>[] = [
|
||||
@@ -95,9 +92,6 @@ export default function HistoryPage() {
|
||||
: `${filtered.length} resolved alert${filtered.length === 1 ? '' : 's'} in range`}
|
||||
</span>
|
||||
</div>
|
||||
<div className={css.pageActions}>
|
||||
<DateRangePicker value={dateRange} onChange={setDateRange} />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{filtered.length === 0 ? (
|
||||
|
||||
@@ -200,38 +200,47 @@ export default function InboxPage() {
|
||||
{allSelected ? 'Deselect all' : `Select all${rows.length ? ` (${rows.length})` : ''}`}
|
||||
</label>
|
||||
<span style={{ flex: 1 }} />
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => onBulkAck(selectedFiringIds)}
|
||||
disabled={selectedFiringIds.length === 0 || ack.isPending}
|
||||
>
|
||||
Acknowledge selected
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => onBulkAck(firingIds)}
|
||||
disabled={firingIds.length === 0 || ack.isPending}
|
||||
>
|
||||
Acknowledge all firing
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => onBulkRead(selectedIds)}
|
||||
disabled={selectedIds.length === 0 || bulkRead.isPending}
|
||||
>
|
||||
Mark selected read
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => onBulkRead(unreadIds)}
|
||||
disabled={unreadIds.length === 0 || bulkRead.isPending}
|
||||
>
|
||||
Mark all read
|
||||
</Button>
|
||||
{selectedIds.length > 0 ? (
|
||||
<>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => onBulkAck(selectedFiringIds)}
|
||||
disabled={selectedFiringIds.length === 0 || ack.isPending}
|
||||
>
|
||||
{selectedFiringIds.length > 0
|
||||
? `Acknowledge ${selectedFiringIds.length}`
|
||||
: 'Acknowledge selected'}
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => onBulkRead(selectedIds)}
|
||||
disabled={bulkRead.isPending}
|
||||
>
|
||||
Mark {selectedIds.length} read
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => onBulkAck(firingIds)}
|
||||
disabled={firingIds.length === 0 || ack.isPending}
|
||||
>
|
||||
Acknowledge all firing
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => onBulkRead(unreadIds)}
|
||||
disabled={unreadIds.length === 0 || bulkRead.isPending}
|
||||
>
|
||||
Mark all read
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{rows.length === 0 ? (
|
||||
|
||||
Reference in New Issue
Block a user