fix(history): unify History filter bar with Jail and IP inputs
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
import {
|
||||
Divider,
|
||||
Input,
|
||||
Text,
|
||||
ToggleButton,
|
||||
Toolbar,
|
||||
@@ -35,6 +36,14 @@ export interface DashboardFilterBarProps {
|
||||
originFilter: BanOriginFilter;
|
||||
/** Called when the user selects a different origin filter. */
|
||||
onOriginFilterChange: (value: BanOriginFilter) => void;
|
||||
/** Jail filter value (optional). */
|
||||
jail?: string;
|
||||
/** Called when the jail filter text changes (optional). */
|
||||
onJailChange?: (value: string) => void;
|
||||
/** IP address filter value (optional). */
|
||||
ip?: string;
|
||||
/** Called when the IP address filter text changes (optional). */
|
||||
onIpChange?: (value: string) => void;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -92,6 +101,10 @@ export function DashboardFilterBar({
|
||||
onTimeRangeChange,
|
||||
originFilter,
|
||||
onOriginFilterChange,
|
||||
jail,
|
||||
onJailChange,
|
||||
ip,
|
||||
onIpChange,
|
||||
}: DashboardFilterBarProps): React.JSX.Element {
|
||||
const styles = useStyles();
|
||||
const cardStyles = useCardStyles();
|
||||
@@ -146,6 +159,48 @@ export function DashboardFilterBar({
|
||||
))}
|
||||
</Toolbar>
|
||||
</div>
|
||||
|
||||
{onJailChange && (
|
||||
<>
|
||||
<div className={styles.divider}>
|
||||
<Divider vertical />
|
||||
</div>
|
||||
<div className={styles.group}>
|
||||
<Text weight="semibold" size={300}>
|
||||
Jail
|
||||
</Text>
|
||||
<Input
|
||||
placeholder="e.g. sshd"
|
||||
size="small"
|
||||
value={jail ?? ""}
|
||||
onChange={(_ev, data): void => {
|
||||
onJailChange(data.value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{onIpChange && (
|
||||
<>
|
||||
<div className={styles.divider}>
|
||||
<Divider vertical />
|
||||
</div>
|
||||
<div className={styles.group}>
|
||||
<Text weight="semibold" size={300}>
|
||||
IP Address
|
||||
</Text>
|
||||
<Input
|
||||
placeholder="e.g. 192.168"
|
||||
size="small"
|
||||
value={ip ?? ""}
|
||||
onChange={(_ev, data): void => {
|
||||
onIpChange(data.value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -125,4 +125,47 @@ describe("DashboardFilterBar", () => {
|
||||
expect(onTimeRangeChange).toHaveBeenCalledOnce();
|
||||
expect(onTimeRangeChange).toHaveBeenCalledWith("24h");
|
||||
});
|
||||
|
||||
it("renders jail and ip input controls when provided", async () => {
|
||||
const onJailChange = vi.fn();
|
||||
const onIpChange = vi.fn();
|
||||
|
||||
render(
|
||||
<FluentProvider theme={webLightTheme}>
|
||||
<DashboardFilterBar
|
||||
timeRange="24h"
|
||||
onTimeRangeChange={vi.fn()}
|
||||
originFilter="all"
|
||||
onOriginFilterChange={vi.fn()}
|
||||
jail=""
|
||||
onJailChange={onJailChange}
|
||||
ip=""
|
||||
onIpChange={onIpChange}
|
||||
/>
|
||||
</FluentProvider>,
|
||||
);
|
||||
|
||||
expect(screen.getByText(/Jail/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/IP Address/i)).toBeInTheDocument();
|
||||
expect(screen.getByPlaceholderText(/e.g. sshd/i)).toBeInTheDocument();
|
||||
expect(screen.getByPlaceholderText(/e.g. 192.168/i)).toBeInTheDocument();
|
||||
|
||||
const jailInput = screen.getByPlaceholderText(/e.g. sshd/i);
|
||||
const ipInput = screen.getByPlaceholderText(/e.g. 192.168/i);
|
||||
const user = userEvent.setup();
|
||||
|
||||
await user.clear(jailInput);
|
||||
await user.type(jailInput, "x");
|
||||
expect(onJailChange).toHaveBeenLastCalledWith("x");
|
||||
|
||||
await user.clear(ipInput);
|
||||
await user.type(ipInput, "1");
|
||||
expect(onIpChange).toHaveBeenLastCalledWith("1");
|
||||
});
|
||||
|
||||
it("does not render jail or ip inputs when handlers are missing", () => {
|
||||
renderBar();
|
||||
expect(screen.queryByText(/Jail/i)).toBeNull();
|
||||
expect(screen.queryByText(/IP Address/i)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user