feat: persistent indicator for overridden secrets#935
Open
tomaskir wants to merge 2 commits into
Open
Conversation
Surface active personal overrides in the environment view instead of relying solely on the hover-gated amber Override button. - Persistent "Overridden" chip on overridden secret rows. A left-to-right gradient dissolves long values into the row background before the chip (mirrors the action-button overlay from phasehq#752) instead of overlapping it, and the chip carries a tooltip noting your value differs from the team value. - Active-override count and a filter toggle in the environment toolbar to show only overridden secrets. - Extract secretHasActiveOverride / countActiveOverrides / overrideValueDiffers helpers into utils/secrets with unit tests. Closes phasehq#929
rohan-chaturvedi
requested changes
Jun 30, 2026
rohan-chaturvedi
left a comment
Member
There was a problem hiding this comment.
Thanks for the PR @tomaskir! A couple of suggestions
- toned down the visual noise of the persistent chip by removing the FULL CAPS label. It was a bit much, and not in line with the rest of our design language.
- lets move the filter action into a broader filter menu that will allow filtering by other secret properties as well, such as secret type. We can handle this in a separate PR
| } | ||
| className={clsx( | ||
| 'absolute right-2 top-1/2 -translate-y-1/2 z-30 cursor-help transition ease', | ||
| 'flex items-center gap-1 shrink-0 rounded-full px-2 py-0.5', |
Member
There was a problem hiding this comment.
Suggested change
| 'flex items-center gap-1 shrink-0 rounded-full px-2 py-0.5', | |
| 'flex items-center gap-1 shrink-0 rounded-full px-2 py-1', |
| 'absolute right-2 top-1/2 -translate-y-1/2 z-30 cursor-help transition ease', | ||
| 'flex items-center gap-1 shrink-0 rounded-full px-2 py-0.5', | ||
| 'bg-amber-400/10 text-amber-500 ring-1 ring-inset ring-amber-400/30', | ||
| 'text-2xs font-medium uppercase tracking-wider', |
Member
There was a problem hiding this comment.
Suggested change
| 'text-2xs font-medium uppercase tracking-wider', | |
| 'text-2xs', |
| )} | ||
| > | ||
| <FaUserEdit className="shrink-0" /> | ||
| <span>Overridden</span> |
Member
There was a problem hiding this comment.
Suggested change
| <span>Overridden</span> |
Member
Comment on lines
+1390
to
+1409
| {activeOverrideCount > 0 && ( | ||
| <button | ||
| type="button" | ||
| onClick={() => setShowOverriddenOnly((prev) => !prev)} | ||
| title={ | ||
| showOverriddenOnly | ||
| ? 'Show all secrets' | ||
| : 'Show only secrets with an active personal override' | ||
| } | ||
| className={clsx( | ||
| 'bg-zinc-100 dark:bg-zinc-800 transition ease px-2 py-1.5 text-2xs 2xl:text-sm rounded-md flex items-center gap-2', | ||
| showOverriddenOnly | ||
| ? 'text-amber-500' | ||
| : 'text-neutral-500 hover:text-neutral-900 dark:hover:text-neutral-100' | ||
| )} | ||
| > | ||
| <FaUserEdit /> | ||
| {activeOverrideCount} {activeOverrideCount === 1 ? 'Override' : 'Overrides'} | ||
| </button> | ||
| )} |
Member
There was a problem hiding this comment.
Rather than a dedicated button here to filter by override, I would rather we add a proper filter menu with options to filter secrets by:
- Sealed type
- Secret type
- Config type
- Booleans
- Overrides
- Dynamic
- Rotating
For this PR, I'd suggest we remove this button entirely and add this filter in a separate PR with broader utility
Member
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Overview
When a secret has an active personal override, the only cue in the environment view is the Override button's icon turning amber - and that button lives in the row's hover-gated action zone, so it is effectively invisible until you hover, and below
2xlit has no text label at all. For a feature whose whole point is "you are running a different value than your team," the active state is too easy to miss. There is no row-level indicator, no count, and no way to filter to overridden secrets.This surfaces the override state persistently. Closes #929.
Proposed Changes
N Override(s); clicking it filters the list to only overridden secrets and turns amber while active. Rendered only when at least one active override exists, and it auto-clears if the last override is removed.secretHasActiveOverride,countActiveOverrides, andoverrideValueDiffersintofrontend/utils/secrets.ts, with unit tests. Both the row and the page consume them.No schema/API work:
GetSecretsalready returnsoverride { value isActive }and it is decrypted on the environment page, so this is a pure frontend surfacing change.Screenshots or Demo
Release Notes
Overridden secrets now show a persistent "Overridden" badge in the environment view, and the toolbar shows a count of active overrides with a one-click filter to view only overridden secrets. Previously the only indication was an amber icon visible on hover.
Open Questions
zinc-100/200light,zinc-800/700dark). Rows with modified/new/staged tints keep their tint behind the fade; called out in case you want the fade tint-aware.Testing
personal override helperssuite infrontend/tests/utils/secrets.test.tscoveringsecretHasActiveOverride(active/inactive/absent),countActiveOverrides(mixed list + empty), andoverrideValueDiffers(all four branches). Full file: 96/96 pass.eslintclean on all changed files (one pre-existing unrelatedreact-hooks/exhaustive-depswarning onpage.tsx).yarn build) succeeds.Reviewer Focus
frontend/components/environments/secrets/SecretRow.tsx- the chip + decorative gradient layer. Note the split (gradient ispointer-events-none/aria-hidden, chip is its own sibling so its nativetitleis not suppressed; bothz-30over thez-20field wrapper). Visibility is driven by avalueFocusedstate tied to the textarea's own focus/blur, deliberately notgroup-focus-within- the latter also fires when atabIndex=-1toolbar button is clicked, which would make the chip vanish.frontend/app/[team]/apps/[app]/environments/[environment]/[[...path]]/page.tsx-showOverriddenOnlystate, the count memo, the filter folded intofilteredSecrets/folders/dynamic, and the toolbar button.frontend/utils/secrets.ts- the three helpers.Additional Context
Closes #929. Fade technique follows #752 (app secrets home improvements).
How to Test the Changes Locally
docker compose --env-file .env.dev -f dev-docker-compose.yml up -d).1 Overridenext to Sort; clicking it filters to overridden secrets only. Add a second override to see the count increment.Did You...