Skip to content

✨ Add ImpersonateBanner navigation component#24

Merged
damienlagae merged 2 commits into
mainfrom
feat/impersonate-banner-component
May 28, 2026
Merged

✨ Add ImpersonateBanner navigation component#24
damienlagae merged 2 commits into
mainfrom
feat/impersonate-banner-component

Conversation

@damienlagae
Copy link
Copy Markdown
Member

Summary

  • Adds an ImpersonateBanner navigation component, a 28 px fixed-top warning band shown when a user is impersonating someone via Symfony's IS_IMPERSONATOR feature.
  • Ships the CSS pair that makes the rest of the layout cooperate with the banner: .impersonate-banner ~ .navbar.fixed-top { top: 28px; } and body:has(.impersonate-banner) { --app-navbar-offset: 108px; }. Without these, the navbar ends up either crammed under the banner or leaves a 28 px gap.
  • The component is meant to be gated at the call site with {% if is_granted('IS_IMPERSONATOR') %} — when there's no impersonation, no banner is rendered and the layout offset stays at its default.
  • Renders the icon through ux_icon() (default fa6-solid:user-secret), and message through |raw so the call site can wrap the impersonated username in <strong>.

API

Param Type Required Default
message string yes
exitUrl string yes
exitLabel string no 'Exit impersonation'
icon string no 'fa6-solid:user-secret'

CSS shipping

The component inlines the ~15 lines of CSS inside a <style> tag in the template — same pattern as the markup, no additional importmap:require step for the consumer. If the banner ever ends up rendered twice on the same page (improbable), the duplicate <style> is harmless.

Pairs with

Test plan

  • PHPUnit: 226/226 (9 new tests: required params, defaults, missing required, type validation)
  • php-cs-fixer: clean
  • phpstan: no errors
  • Manual smoke test in a consumer app (Impala or SymfonyBase) — confirm the navbar offset and the --app-navbar-offset variable cooperate with the project layout

Closes #16.

Closes #16.

A fixed-top warning banner that signals the current user is
impersonating someone, with a clear exit link. Ships the CSS trick
that adjusts a Bootstrap fixed-top navbar to sit 28 px below the
banner and bumps --app-navbar-offset to 108 px via body:has().

Pairs with the upcoming Enabel:Ux:ImpersonateDropdown (#15).
@damienlagae
Copy link
Copy Markdown
Member Author

Smoke-tested in Impala — rendered four variants including the navbar cooperation test the PR explicitly asks for.

What I verified

Variant Setup Result
default required params only 28 px yellow band, user-secret icon, bold username via `
custom-icon icon: 'fa6-solid:user-large-slash', exitLabel: 'Quit' Both overrides applied cleanly
html-message message: '<em>Admin mode</em> — viewing as <strong>damien.lagae@enabel.be</strong>' <em> and <strong> render as actual markup — confirms `
with-navbar banner + Impala's Enabel:Ux:Navbar fixed-top + body content The key one. Banner at top, dark navbar pushed down to top: 28px, body content offset by --app-navbar-offset: 108px. Zero overlap, zero gap
  • Missing message or exitUrl correctly throws MissingOptionsException (verified the route returns 500 with the expected message)
  • The inline <style> ships the CSS cooperation, so a consumer adopting the component gets the navbar offset behaviour without any extra CSS work

Note for Impala (not a PR comment)

Impala already carries the same CSS rules in assets/styles/app.css (lines 16-22 and 125-148 in our current stage branch) plus a hand-rolled <div class="impersonate-banner"> in base.html.twig. Adopting this component lets us drop both the bespoke template block and the duplicated CSS — net negative LOC.

One small docs idea (optional)

The "CSS shipping" section mentions duplicate <style> is harmless. Worth also noting the inverse for adopters: if you already had your own .impersonate-banner CSS (like Impala does), the component's inline style wins because it loads after the stylesheet, so you can safely drop the duplicate rules without a flicker.

LGTM, ready to tag.

@damienlagae
Copy link
Copy Markdown
Member Author

Doc updated in efca92b — added an "Adopting the component when you already have impersonate-banner CSS" section explaining that the inline <style> loads after <head> stylesheets, so consumer-side hand-rolled rules are safely overridden without a transition flicker. That should give Impala a clean path to drop the duplicated rules from assets/styles/app.css in the same MR as the adoption.

@damienlagae damienlagae merged commit 5049fe2 into main May 28, 2026
7 checks passed
@damienlagae damienlagae deleted the feat/impersonate-banner-component branch May 28, 2026 19:45
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.

Add an ImpersonateBanner component (paired with #15)

1 participant