Modernize mitmweb tabs and footer - #8362
Conversation
| &.active { | ||
| background-color: var(--mitmweb-bg); | ||
| } |
There was a problem hiding this comment.
This style is obsolete because this exact background-color is already applied at https://github.com/lups2000/mitmproxy/blob/450190c650745923a42768a8a35a68059e063d3e/web/src/css/tabs.less#L21
So you can simply remove this.
| &:not(.active):not(.special):hover, | ||
| &:not(.active):not(.special):focus { |
There was a problem hiding this comment.
Nit:
These tabs are <a href="#">, so they hang onto focus after you click them and the hover background sticks around even once the mouse has moved away. :focus-visible would keep the highlight for keyboard users without that side effect.
&.special:focus a few lines down has the same issue. It leaves the File button looking permanently pressed.
| type BadgeProps = { | ||
| className?: string; | ||
| children: React.ReactNode; | ||
| title?: string; |
There was a problem hiding this comment.
Might be easier to just spread the span props here:
type BadgeProps = React.ComponentPropsWithoutRef<"span">;
export default function Badge({ className, children, ...props }: BadgeProps) {
return (
<span className={classnames("badge", className)} {...props}>
{children}
</span>
);
}Somewhat related: className="footer-badge footer-badge-success" is duplicated 11 times in Footer.tsx, and a typo in one of those would work fine but render an unstyled pill. A typed variant prop could catch that. But perhaps this is out of scope for this PR, up to you.
| color: var(--mitmweb-fg-muted); | ||
| } | ||
|
|
||
| .footer-badge { |
There was a problem hiding this comment.
Now that these replace them, the old .label* classes don't have any consumers anymore. The Footer.tsx component was the only one. Might as well delete them while you're in here: https://github.com/lups2000/mitmproxy/blob/450190c650745923a42768a8a35a68059e063d3e/web/src/css/global.less#L469-L499
The .eventlog .label class look unused too, but that one's been dead for a while, so no need to drag it into this PR unless you feel like it.
| [ | ||
| "regular,upstream:https://example.com", | ||
| "Intercept: ~q", | ||
| "ssl_insecure", | ||
| "showhost", | ||
| "no-upstream-cert", | ||
| "no-raw-tcp", | ||
| "no-http2", | ||
| "no-websocket", | ||
| "anticache", | ||
| "anticomp", | ||
| "stickyauth: ~u example.com", | ||
| "stickycookie: ~d example.com", | ||
| "stream: 1mb", | ||
| "1 of 5 flows selected", | ||
| "127.0.0.1:9090", | ||
| "mitmproxy 1.2.3", | ||
| ].forEach((text) => expect(screen.getByText(text)).toBeVisible()); |
There was a problem hiding this comment.
If I'm not mistaken jsdom doesn't load the stylesheet, so toBeVisible() is basically just toBeInTheDocument() here. The test checks that the labels render but not that they got the right colors, so if someone swapped every variant around this would still pass.
Probably worth asserting a few of them directly:
expect(screen.getByText("ssl_insecure")).toHaveClass("footer-badge-danger");
expect(screen.getByText("anticache")).toHaveClass("footer-badge-success");
expect(screen.getByText("127.0.0.1:9090")).toHaveClass("footer-badge-info");Also, every option in the fixture is set to whichever value renders a badge, so the other branch never gets exercised. One more test with http2: true checking that screen.queryByText("no-http2") is null would cover it.
| import { TStore } from "../ducks/tutils"; | ||
|
|
||
| test("renders active options as badges", () => { | ||
| const state = TStore().getState(); |
There was a problem hiding this comment.
Nit:
You could import testState from ../ducks/tutils directly and skip the round-trip through a throwaway store:
const store = TStore({
...testState,
options: { ...testState.options, /* ... */ },
});
Description
This PR slightly updates the mitmweb interface without changing its overall structure:
Badgecomponent, introduced in mitmweb: add status/method badges to the flow table #8335, for footer status indicators.Checklist