Skip to content

feat: secrets filter menu#940

Open
rohan-chaturvedi wants to merge 2 commits into
mainfrom
feat--secrets-filter-menu
Open

feat: secrets filter menu#940
rohan-chaturvedi wants to merge 2 commits into
mainfrom
feat--secrets-filter-menu

Conversation

@rohan-chaturvedi

Copy link
Copy Markdown
Member

🔍 Overview

The single-env and cross-env secret editors only offered sort + plain-text search, so there was no way to narrow a long list down to a particular kind of secret (e.g. only sealed secrets, only rotating ones, or everything tagged api). This PR adds a Filter menu and search-box qualifiers to both editors.

💡 Proposed Changes

  • New shared FilterMenu.tsx (Headless UI Popover, multi-select) next to the existing Sort menu, with three sections:
    • Typeconfig / secret / sealed
    • Managementrotating / dynamic / overridden (active personal override)
    • Tags — the tags actually present in the current view
      Each section shows its qualifier hint (type: / is: / tag:), and there's an active-count badge + Clear button.
  • Search-box qualifiers — GitHub-style tokens in the existing search box, e.g. redis type:config, is:rotating, tag:"db creds". Unknown keys/values fall back to free text so a typo never empties the list.
  • Faceted AND semantics — values within one facet OR (a secret has one type, so Config + Sealed = "either"); different facets AND (Config + Rotating = "both"). The menu and the search box are independent controls that AND together, and now share identical semantics.
  • All matching lives as pure, unit-tested predicates in frontend/utils/secrets.ts and is injected into the single filteredSecrets memo each editor already had, so rotating/dynamic grouping derives from it automatically. Dynamic secrets and folders (which have none of a regular secret's attributes) are gated as whole "kinds".
  • Filter menu state is not persisted (resets per visit); Sort still persists.
  • Incidental fixes: cross-env table now renders when only dynamic secrets match; cross-env page container gets h-full so a short (filtered) table no longer clips the open menu; single-env sticky toolbar is raised above row hover-menus while the menu is open.

🖼️ Screenshots or Demo

Screencast.From.2026-07-02.19-02-06.mp4

📝 Release Notes

You can now filter secrets in both the environment and cross-environment editors by type (secret/sealed/config), rotating, dynamic, overridden (active personal override), and tag — via a Filter menu or by typing qualifiers like type:config, is:rotating, or tag:api directly in the search box.

🧪 Testing

  • Added 30+ unit tests in frontend/tests/utils/secrets.test.ts covering the search parser and both matcher families (faceted AND, OR-within-facet, tag substring, dynamic/folder gating, quoted values, unknown-qualifier fallback, cross-env any-env matching). 115 tests pass.
  • npx tsc --noEmit is clean.
  • Pure frontend change — no backend, schema, or migrations touched.

🎯 Reviewer Focus

Start with the predicates in frontend/utils/secrets.ts (secretMatchesFilter / parseSecretSearch / secretMatchesSearch and the dynamic-secret gating), then FilterMenu.tsx, then how each editor wires them into its filteredSecrets / filteredDynamicSecrets / filteredFolders memos.

➕ Additional Context

Consistent with the existing E2EE model, all filtering/search happens client-side — the server never sees the query.

✨ How to Test the Changes Locally

  1. docker compose -f dev-docker-compose.yml up -d, open https://localhost.
  2. In an app/environment with a mix of secret kinds (some sealed/config, a rotating secret, a dynamic secret, a personal override, some tags):
    • Open Filter, toggle options, and confirm faceted AND (e.g. Config + Sealed = either; Sealed + Rotating = both).
    • In the search box try redis, redis type:config, is:rotating, is:dynamic, tag:api, and a quoted tag:"...".
    • Confirm the menu resets on reload and that a heavily-filtered cross-env table no longer clips the open menu.

💚 Did You...

  • Ensure linting passes (code style checks)? (tsc --noEmit clean)
  • Update dependencies and lockfiles (if required) (N/A)
  • Update migrations (if required) (N/A)
  • Regenerate graphql schema and types (if required) (N/A — no schema change)
  • Verify the app builds locally?
  • Manually test the changes on different browsers/devices?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant