From a57b7f5b6a1f637a67fec0ec7302c9d9986185ea Mon Sep 17 00:00:00 2001 From: Anna Effort Date: Thu, 13 Aug 2026 19:57:04 -0700 Subject: [PATCH 1/5] removed redundant disabled status from details and filter Signed-off-by: Anna Effort --- src/components/plugins/PluginResults.tsx | 5 ----- src/i18n/locales/en-US/plugins.json | 1 - src/i18n/locales/es-ES/plugins.json | 1 - src/i18n/locales/pt-BR/plugins.json | 1 - src/pages/Plugins.test.tsx | 26 +++++++++++++++++++++++- src/pages/Plugins.tsx | 9 ++++++-- 6 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/components/plugins/PluginResults.tsx b/src/components/plugins/PluginResults.tsx index 7ca41e2..bbdfaec 100644 --- a/src/components/plugins/PluginResults.tsx +++ b/src/components/plugins/PluginResults.tsx @@ -183,11 +183,6 @@ export function PluginDetailsDialog({ {plugin.priority} - - {isEnabled(plugin) - ? intl.formatMessage({ id: "plugins.catalog.enabled" }) - : intl.formatMessage({ id: "plugins.catalog.disabled" })} - {plugin.hooks && plugin.hooks.length > 0 && ( diff --git a/src/i18n/locales/en-US/plugins.json b/src/i18n/locales/en-US/plugins.json index 8c9dfbb..e96b73e 100644 --- a/src/i18n/locales/en-US/plugins.json +++ b/src/i18n/locales/en-US/plugins.json @@ -20,7 +20,6 @@ "plugins.catalog.author": "Author", "plugins.catalog.version": "Version", "plugins.catalog.priority": "Priority", - "plugins.catalog.status": "Status", "plugins.catalog.hooks": "Hooks", "plugins.catalog.configuration": "Configuration", "plugins.catalog.resultCount": "{count, plural, =0 {No plugins shown} one {# plugin shown} other {# plugins shown}}", diff --git a/src/i18n/locales/es-ES/plugins.json b/src/i18n/locales/es-ES/plugins.json index 89701a0..8d8c47e 100644 --- a/src/i18n/locales/es-ES/plugins.json +++ b/src/i18n/locales/es-ES/plugins.json @@ -20,7 +20,6 @@ "plugins.catalog.author": "Autor", "plugins.catalog.version": "Versión", "plugins.catalog.priority": "Prioridad", - "plugins.catalog.status": "Estado", "plugins.catalog.hooks": "Hooks", "plugins.catalog.configuration": "Configuración", "plugins.catalog.resultCount": "{count, plural, =0 {No hay plugins mostrados} one {# plugin mostrado} other {# plugins mostrados}}", diff --git a/src/i18n/locales/pt-BR/plugins.json b/src/i18n/locales/pt-BR/plugins.json index 64aa809..5960197 100644 --- a/src/i18n/locales/pt-BR/plugins.json +++ b/src/i18n/locales/pt-BR/plugins.json @@ -20,7 +20,6 @@ "plugins.catalog.author": "Autor", "plugins.catalog.version": "Versão", "plugins.catalog.priority": "Prioridade", - "plugins.catalog.status": "Status", "plugins.catalog.hooks": "Hooks", "plugins.catalog.configuration": "Configuração", "plugins.catalog.resultCount": "{count, plural, =0 {Nenhum plugin exibido} one {# plugin exibido} other {# plugins exibidos}}", diff --git a/src/pages/Plugins.test.tsx b/src/pages/Plugins.test.tsx index ff94310..9c11cb3 100644 --- a/src/pages/Plugins.test.tsx +++ b/src/pages/Plugins.test.tsx @@ -33,7 +33,7 @@ const logging: PluginSummary = { description: "Logs request and response payloads for auditing", author: "Community", version: "0.4.1", - mode: "permissive", + mode: "disabled", priority: 50, hooks: ["http_pre_request"], tags: ["observability"], @@ -112,6 +112,9 @@ describe("Plugins", () => { expect(within(dialog).getByText("redact")).toBeInTheDocument(); expect(within(dialog).getByText("true")).toBeInTheDocument(); expect(within(dialog).getByText('["EMAIL","SSN"]')).toBeInTheDocument(); + // Status is derived from mode (status === "disabled" iff mode === "disabled"), + // so the dialog shows mode only. + expect(within(dialog).queryByText("Status")).not.toBeInTheDocument(); await user.keyboard("{Escape}"); expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); @@ -141,6 +144,27 @@ describe("Plugins", () => { expect(screen.queryByRole("heading", { name: "Request Logger" })).not.toBeInTheDocument(); }); + it("does not offer 'disabled' as a mode option", async () => { + const user = userEvent.setup(); + renderWithRouter(); + + await user.click(screen.getByRole("button", { name: /^Filters$/ })); + await user.click(screen.getByRole("combobox", { name: "Mode" })); + + expect(screen.getByRole("option", { name: "enforce" })).toBeInTheDocument(); + expect(screen.queryByRole("option", { name: "disabled" })).not.toBeInTheDocument(); + }); + + it("ignores mode=disabled from the URL", () => { + renderWithRouter(, "/app/plugins?mode=disabled"); + + expect(screen.getByRole("heading", { name: "PII Guardrails" })).toBeInTheDocument(); + expect(screen.getByRole("heading", { name: "Request Logger" })).toBeInTheDocument(); + // Accessible name stays "Filters" (not "Filters, 1 active") — the ignored + // mode must not count towards the active filter badge. + expect(screen.getByRole("button", { name: "Filters" })).toBeInTheDocument(); + }); + it("filters by hook and tag, then clears filters", async () => { const user = userEvent.setup(); renderWithRouter(); diff --git a/src/pages/Plugins.tsx b/src/pages/Plugins.tsx index 7a96462..0f046ed 100644 --- a/src/pages/Plugins.tsx +++ b/src/pages/Plugins.tsx @@ -16,6 +16,7 @@ import { useRouter } from "@/router"; const PLUGINS_PATH = "/v1/plugins"; const PAGE_PATH = "/app/plugins"; const ENABLED_STATUS = "enabled"; +const DISABLED_MODE = "disabled"; const PAGE_HEADING_ID = "plugins-catalog-heading"; interface PluginFilters { @@ -35,10 +36,14 @@ function getQuery(path: string): string { function parseFilters(path: string): PluginFilters { const params = new URLSearchParams(getQuery(path)); + // The mode select never offers "disabled" (the All/Enabled toggle covers that + // axis), so ignore it here too rather than showing a filter the select can't + // display or clear. + const mode = params.get("mode") ?? ""; return { search: params.get("search") ?? "", - mode: params.get("mode") ?? "", + mode: mode === DISABLED_MODE ? "" : mode, hook: params.get("hook") ?? "", tags: [...new Set(params.getAll("tags").filter(Boolean))], enabledOnly: params.get("status") === ENABLED_STATUS, @@ -151,7 +156,7 @@ export function Plugins() { [allPlugins, activeFilters], ); const modeOptions = useMemo( - () => sortedUnique(allPlugins.map((plugin) => plugin.mode)), + () => sortedUnique(allPlugins.map((plugin) => plugin.mode)).filter((m) => m !== DISABLED_MODE), [allPlugins], ); const hookOptions = useMemo( From 3dc17481960d90b54920f4c84624e734118e12c3 Mon Sep 17 00:00:00 2001 From: Anna Effort Date: Thu, 13 Aug 2026 20:23:15 -0700 Subject: [PATCH 2/5] feat: drop mode filter from plugin catalog The All/Enabled toggle already covers the enabled axis, and mode is still visible per-plugin in the details dialog, so the Mode select in the filters popover carried no distinct use case. Filters are now hook + tags. Signed-off-by: Anna Effort --- src/components/plugins/PluginToolbar.tsx | 33 +----------------------- src/i18n/locales/en-US/plugins.json | 1 - src/i18n/locales/es-ES/plugins.json | 1 - src/i18n/locales/pt-BR/plugins.json | 1 - src/pages/Plugins.test.tsx | 30 +++------------------ src/pages/Plugins.tsx | 22 ++-------------- 6 files changed, 6 insertions(+), 82 deletions(-) diff --git a/src/components/plugins/PluginToolbar.tsx b/src/components/plugins/PluginToolbar.tsx index 2e0a968..679c436 100644 --- a/src/components/plugins/PluginToolbar.tsx +++ b/src/components/plugins/PluginToolbar.tsx @@ -18,15 +18,13 @@ import { const ALL_FILTER_VALUE = "__all__"; -export type PluginSingleFilterKey = "mode" | "hook"; +export type PluginSingleFilterKey = "hook"; interface PluginToolbarProps { search: string; enabledOnly: boolean; - mode: string; hook: string; selectedTags: string[]; - modes: string[]; hooks: string[]; availableTags: string[]; activeFilterCount: number; @@ -75,10 +73,8 @@ function PluginViewToggle({ } function PluginFiltersPopover({ - mode, hook, selectedTags, - modes, hooks, availableTags, activeFilterCount, @@ -89,7 +85,6 @@ function PluginFiltersPopover({ const intl = useIntl(); const id = useId(); const filtersTitleId = `${id}-title`; - const modeTriggerId = `${id}-mode`; const hookTriggerId = `${id}-hook`; return ( @@ -126,32 +121,6 @@ function PluginFiltersPopover({ )} -
- - -
-