diff --git a/src/components/CommandPalette.tsx b/src/components/CommandPalette.tsx
index a5d9dc65..20c399aa 100644
--- a/src/components/CommandPalette.tsx
+++ b/src/components/CommandPalette.tsx
@@ -9,7 +9,6 @@ import {
} from "@components/UI/Command.tsx";
import { useAppStore } from "@core/stores/appStore.ts";
import { useDevice, useDeviceStore } from "@core/stores/deviceStore.ts";
-import { use } from "chai";
import { useCommandState } from "cmdk";
import {
ArrowLeftRightIcon,
@@ -33,8 +32,6 @@ import {
XCircleIcon,
} from "lucide-react";
import { useEffect } from "react";
-import { useMap } from "react-map-gl/maplibre";
-import { useMessageStore } from "@core/stores/messageStore.ts";
export interface Group {
label: string;
@@ -64,7 +61,6 @@ export const CommandPalette = () => {
selectedDevice,
} = useAppStore();
const { getDevices } = useDeviceStore();
- const { clearAllMessages } = useMessageStore();
const { setDialogOpen, setActivePage, connection } = useDevice();
const groups: Group[] = [
@@ -228,7 +224,7 @@ export const CommandPalette = () => {
label: "Clear All Stored Message",
icon: EraserIcon,
action() {
- void clearAllMessages();
+ setDialogOpen("clearMessages", true);
},
},
],
diff --git a/src/components/Dialog/ClearMessagesDialog/ClearMessagesDialog.test.tsx b/src/components/Dialog/ClearMessagesDialog/ClearMessagesDialog.test.tsx
new file mode 100644
index 00000000..cf317589
--- /dev/null
+++ b/src/components/Dialog/ClearMessagesDialog/ClearMessagesDialog.test.tsx
@@ -0,0 +1,53 @@
+import { render, screen, fireEvent } from '@testing-library/react';
+import { beforeEach, describe, expect, it, vi } from 'vitest';
+import { useMessageStore } from "@core/stores/messageStore.ts";
+import { ClearMessagesDialog } from "@components/Dialog/ClearMessagesDialog/ClearMessagesDialog.tsx";
+
+vi.mock('@core/stores/messageStore.ts', () => ({
+ useMessageStore: vi.fn(() => ({
+ clearAllMessages: vi.fn(),
+ })),
+}));
+
+describe('ClearMessagesDialog', () => {
+ const mockOnOpenChange = vi.fn();
+ const mockClearAllMessages = vi.fn();
+
+ beforeEach(() => {
+ vi.mocked(useMessageStore).mockReturnValue({ clearAllMessages: mockClearAllMessages });
+ mockOnOpenChange.mockClear();
+ mockClearAllMessages.mockClear();
+ });
+
+ it('renders the dialog when open is true', () => {
+ render();
+ expect(screen.getByText('Clear All Messages')).toBeVisible();
+ expect(screen.getByText(/This action will clear all message history./)).toBeVisible();
+ expect(screen.getByRole('button', { name: 'Dismiss' })).toBeVisible();
+ expect(screen.getByRole('button', { name: 'Clear Messages' })).toBeVisible();
+ });
+
+ it('does not render the dialog when open is false', () => {
+ render();
+ expect(screen.queryByText('Clear All Messages')).toBeNull();
+ });
+
+ it('calls onOpenChange with false when the close button is clicked', () => {
+ render();
+ fireEvent.click(screen.getByRole('button', { name: 'Close' }));
+ expect(mockOnOpenChange).toHaveBeenCalledWith(false);
+ });
+
+ it('calls onOpenChange with false when the dismiss button is clicked', () => {
+ render();
+ fireEvent.click(screen.getByRole('button', { name: 'Dismiss' }));
+ expect(mockOnOpenChange).toHaveBeenCalledWith(false);
+ });
+
+ it('calls clearAllMessages and onOpenChange with false when the clear messages button is clicked', () => {
+ render();
+ fireEvent.click(screen.getByRole('button', { name: 'Clear Messages' }));
+ expect(mockClearAllMessages).toHaveBeenCalledTimes(1);
+ expect(mockOnOpenChange).toHaveBeenCalledWith(false);
+ });
+});
\ No newline at end of file
diff --git a/src/components/Dialog/ClearMessagesDialog/ClearMessagesDialog.tsx b/src/components/Dialog/ClearMessagesDialog/ClearMessagesDialog.tsx
new file mode 100644
index 00000000..4bb27b82
--- /dev/null
+++ b/src/components/Dialog/ClearMessagesDialog/ClearMessagesDialog.tsx
@@ -0,0 +1,63 @@
+
+import { Button } from "@components/UI/Button.tsx";
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "@components/UI/Dialog.tsx";
+import { AlertTriangleIcon } from "lucide-react";
+import { useMessageStore } from "@core/stores/messageStore.ts";
+
+export interface ClearMessagesDialogProps {
+ open: boolean;
+ onOpenChange: (open: boolean) => void;
+}
+
+export const ClearMessagesDialog = ({
+ open,
+ onOpenChange,
+}: ClearMessagesDialogProps) => {
+ const { clearAllMessages } = useMessageStore();
+ const handleCloseDialog = () => {
+ onOpenChange(false);
+ };
+
+ return (
+
+ );
+};
diff --git a/src/components/Dialog/DialogManager.tsx b/src/components/Dialog/DialogManager.tsx
index 1cfbcb3e..07432c18 100644
--- a/src/components/Dialog/DialogManager.tsx
+++ b/src/components/Dialog/DialogManager.tsx
@@ -9,6 +9,7 @@ import { ShutdownDialog } from "@components/Dialog/ShutdownDialog.tsx";
import { NodeDetailsDialog } from "@components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx";
import { UnsafeRolesDialog } from "@components/Dialog/UnsafeRolesDialog/UnsafeRolesDialog.tsx";
import { RefreshKeysDialog } from "@components/Dialog/RefreshKeysDialog/RefreshKeysDialog.tsx";
+import { ClearMessagesDialog } from "@components/Dialog/ClearMessagesDialog/ClearMessagesDialog.tsx";
export const DialogManager = () => {
const { channels, config, dialog, setDialogOpen } = useDevice();
@@ -77,6 +78,12 @@ export const DialogManager = () => {
setDialogOpen("refreshKeys", open);
}}
/>
+ {
+ setDialogOpen("clearMessages", open);
+ }}
+ />
>
);
};
diff --git a/src/core/stores/deviceStore.ts b/src/core/stores/deviceStore.ts
index 148e9f0b..62b6e4c8 100644
--- a/src/core/stores/deviceStore.ts
+++ b/src/core/stores/deviceStore.ts
@@ -28,7 +28,8 @@ export type DialogVariant =
| "pkiBackup"
| "nodeDetails"
| "unsafeRoles"
- | "refreshKeys";
+ | "refreshKeys"
+ | "clearMessages";
type NodeError = {
node: number;
@@ -69,6 +70,7 @@ export interface Device {
nodeDetails: boolean;
unsafeRoles: boolean;
refreshKeys: boolean;
+ clearMessages: boolean;
};