fix(FN-1801): plugin settings UX and theme awareness improvements
- Add new input types for plugin settings (password, textarea, array fields) - Render toggle switch inside .toggle-switch label for theme-aware styling - Update STATE_COLORS to use CSS variable references instead of hardcoded hex values - Add SSE live updates for plugin lifecycle events (enabled, disabled, uninstalled, settings-updated) - Project-scoped SSE subscription when projectId is provided - Expand PluginManager tests with 32 passing tests covering new functionality
This commit is contained in:
@@ -39,12 +39,12 @@ interface PluginManagerProps {
|
||||
projectId?: string;
|
||||
}
|
||||
|
||||
const STATE_COLORS: Record<string, string> = {
|
||||
started: "var(--color-success, #22c55e)",
|
||||
loaded: "var(--color-warning, #eab308)",
|
||||
error: "var(--color-error, #ef4444)",
|
||||
stopped: "var(--color-muted, #6b7280)",
|
||||
installed: "var(--color-info, #3b82f6)",
|
||||
export const STATE_COLORS: Record<string, string> = {
|
||||
started: "var(--color-success)",
|
||||
loaded: "var(--color-warning)",
|
||||
error: "var(--color-error)",
|
||||
stopped: "var(--color-muted)",
|
||||
installed: "var(--color-info)",
|
||||
};
|
||||
|
||||
export function PluginManager({ addToast, projectId }: PluginManagerProps) {
|
||||
|
||||
@@ -81,7 +81,7 @@ vi.mock("../../api", () => ({
|
||||
}));
|
||||
|
||||
// Import after vi.mock so the mock is in place
|
||||
import { PluginManager } from "../PluginManager";
|
||||
import { PluginManager, STATE_COLORS } from "../PluginManager";
|
||||
import {
|
||||
fetchPlugins,
|
||||
installPlugin,
|
||||
@@ -886,4 +886,52 @@ describe("PluginManager", () => {
|
||||
expect(numberInputs.length).toBeGreaterThanOrEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("toggle switch rendering", () => {
|
||||
it("renders enabled toggle switch inside .toggle-switch label", async () => {
|
||||
vi.mocked(fetchPlugins).mockResolvedValueOnce([{ ...mockPlugins[0], enabled: true }]);
|
||||
|
||||
render(<PluginManager addToast={addToast} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Test Plugin A")).toBeTruthy();
|
||||
});
|
||||
|
||||
// Find the toggle-switch label
|
||||
const toggleSwitch = screen.getByText("Test Plugin A").closest(".plugin-item")?.querySelector(".toggle-switch");
|
||||
expect(toggleSwitch).toBeTruthy();
|
||||
|
||||
// Find the checkbox inside
|
||||
const checkbox = toggleSwitch?.querySelector('input[type="checkbox"]');
|
||||
expect(checkbox).toBeTruthy();
|
||||
expect(checkbox?.checked).toBe(true);
|
||||
});
|
||||
|
||||
it("renders disabled toggle switch inside .toggle-switch label", async () => {
|
||||
vi.mocked(fetchPlugins).mockResolvedValueOnce([{ ...mockPlugins[0], enabled: false }]);
|
||||
|
||||
render(<PluginManager addToast={addToast} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Test Plugin A")).toBeTruthy();
|
||||
});
|
||||
|
||||
// Find the toggle-switch label
|
||||
const toggleSwitch = screen.getByText("Test Plugin A").closest(".plugin-item")?.querySelector(".toggle-switch");
|
||||
expect(toggleSwitch).toBeTruthy();
|
||||
|
||||
// Find the checkbox inside
|
||||
const checkbox = toggleSwitch?.querySelector('input[type="checkbox"]');
|
||||
expect(checkbox).toBeTruthy();
|
||||
expect(checkbox?.checked).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("STATE_COLORS", () => {
|
||||
it("contains only CSS variable references with no hardcoded hex values", () => {
|
||||
const values = Object.values(STATE_COLORS);
|
||||
const allUseCssVars = values.every((v) => /^var\(--[a-z-]+\)$/.test(v));
|
||||
expect(allUseCssVars).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user