1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-25 00:09:40 +02:00

fix(ui): fix ui bugs [EE-3847] (#7453)

This commit is contained in:
Chaim Lev-Ari 2022-08-12 06:47:56 +03:00 committed by GitHub
parent dd372637cb
commit 95fb5a4baa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 246 additions and 448 deletions

View file

@ -1,12 +0,0 @@
.breadcrumb-links {
font-size: 10px;
}
.breadcrumb-links a {
color: var(--ui-blue-8);
}
.breadcrumb-links a:hover {
text-decoration: underline;
color: var(--ui-blue-9);
}

View file

@ -8,8 +8,9 @@ test('should display a Breadcrumbs, breadcrumbs should be separated by >', async
{ label: 'bread2' },
{ label: 'bread3' },
];
const { queryByText } = render(<Breadcrumbs breadcrumbs={breadcrumbs} />);
const { container } = render(<Breadcrumbs breadcrumbs={breadcrumbs} />);
const heading = queryByText(breadcrumbs.map((b) => b.label).join(' > '));
expect(heading).toBeVisible();
expect(container.firstChild?.textContent).toEqual(
breadcrumbs.map((b) => b.label).join('>')
);
});

View file

@ -2,8 +2,6 @@ import { Fragment } from 'react';
import { Link } from '@@/Link';
import './Breadcrumbs.css';
export interface Crumb {
label: string;
link?: string;
@ -19,11 +17,11 @@ export function Breadcrumbs({ breadcrumbs }: Props) {
: [breadcrumbs];
return (
<div className="breadcrumb-links">
<div className="text-sm font-medium text-gray-7 th-dark:text-gray-5 th-highcontrast:text-white space-x-2">
{breadcrumbsArray.map((crumb, index) => (
<Fragment key={index}>
{renderCrumb(crumb)}
{index !== breadcrumbsArray.length - 1 ? ' > ' : ''}
<span>{renderCrumb(crumb)}</span>
{index !== breadcrumbsArray.length - 1 && <span>&gt;</span>}
</Fragment>
))}
</div>
@ -44,7 +42,7 @@ function renderCrumb(crumb: Crumb | string) {
<Link
to={crumb.link}
params={crumb.linkParams}
className="text-blue-9 hover:underline"
className="text-blue-9 hover:underline hover:text-blue-11 th-dark:text-blue-7 th-dark:hover:text-blue-9 th-highcontrast:text-blue-5"
>
{crumb.label}
</Link>

View file

@ -1,33 +1,29 @@
.row.header .meta .page {
padding-top: 7px;
.header {
min-height: 60px;
margin-bottom: 15px;
background-color: var(--bg-body-color);
margin-bottom: 5px !important;
}
.row.header {
min-height: 60px;
background: var(--bg-row-header-color);
margin-bottom: 15px;
}
.row.header > div:last-child {
.header > div:last-child {
padding-right: 0;
}
.row.header .meta .page {
font-size: 17px;
padding-top: 11px;
}
.row.header .meta div {
.header .meta div {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.row.header .login a {
.header .login a {
padding: 18px;
display: block;
}
.row.header .user {
.header .user {
min-width: 130px;
}
.row.header .user > .item {
.header .user > .item {
width: 65px;
height: 60px;
float: right;
@ -35,36 +31,36 @@
text-align: center;
vertical-align: middle;
}
.row.header .user > .item a {
.header .user > .item a {
color: #919191;
display: block;
}
.row.header .user > .item i {
.header .user > .item i {
font-size: 20px;
line-height: 55px;
}
.row.header .user > .item img {
.header .user > .item img {
width: 40px;
height: 40px;
margin-top: 10px;
border-radius: 2px;
}
.row.header .user > .item ul.dropdown-menu {
.header .user > .item ul.dropdown-menu {
border-radius: 2px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.05);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.05);
}
.row.header .user > .item ul.dropdown-menu .dropdown-header {
.header .user > .item ul.dropdown-menu .dropdown-header {
text-align: center;
}
.row.header .user > .item ul.dropdown-menu li.link {
.header .user > .item ul.dropdown-menu li.link {
text-align: left;
}
.row.header .user > .item ul.dropdown-menu li.link a {
.header .user > .item ul.dropdown-menu li.link a {
padding-left: 7px;
padding-right: 7px;
}
.row.header .user > .item ul.dropdown-menu:before {
.header .user > .item ul.dropdown-menu:before {
position: absolute;
top: -7px;
right: 23px;
@ -74,7 +70,7 @@
border-left: 7px solid transparent;
content: '';
}
.row.header .user > .item ul.dropdown-menu:after {
.header .user > .item ul.dropdown-menu:after {
position: absolute;
top: -6px;
right: 24px;

View file

@ -7,7 +7,6 @@ import { UserViewModel } from '@/portainer/models/user';
import { HeaderContainer } from './HeaderContainer';
import { Breadcrumbs } from './Breadcrumbs';
import { HeaderTitle } from './HeaderTitle';
import { HeaderContent } from './HeaderContent';
export default {
component: HeaderContainer,
@ -28,14 +27,13 @@ function Template({ title }: StoryProps) {
<UserContext.Provider value={state}>
<HeaderContainer>
<HeaderTitle title={title} />
<HeaderContent>
<Breadcrumbs
breadcrumbs={[
{ link: 'example', label: 'crumb1' },
{ label: 'crumb2' },
]}
/>
</HeaderContent>
<Breadcrumbs
breadcrumbs={[
{ link: 'example', label: 'crumb1' },
{ label: 'crumb2' },
]}
/>
</HeaderContainer>
</UserContext.Provider>
);

View file

@ -1,6 +1,7 @@
import { PropsWithChildren, createContext, useContext } from 'react';
import clsx from 'clsx';
import './HeaderContainer.css';
import styles from './HeaderContainer.module.css';
const Context = createContext<null | boolean>(null);
@ -15,10 +16,10 @@ export function useHeaderContext() {
export function HeaderContainer({ children }: PropsWithChildren<unknown>) {
return (
<Context.Provider value>
<div className="row header">
<div className={clsx('row', styles.header)}>
<div id="loadingbar-placeholder" />
<div className="col-xs-12">
<div className="meta">{children}</div>
<div className={styles.meta}>{children}</div>
</div>
</div>
</Context.Provider>

View file

@ -1,31 +0,0 @@
import { renderWithQueryClient } from '@/react-tools/test-utils';
import { HeaderContainer } from './HeaderContainer';
import { HeaderContent } from './HeaderContent';
test('should not render without a wrapping HeaderContainer', async () => {
const consoleErrorFn = jest
.spyOn(console, 'error')
.mockImplementation(() => jest.fn());
function renderComponent() {
return renderWithQueryClient(<HeaderContent />);
}
expect(renderComponent).toThrowErrorMatchingSnapshot();
consoleErrorFn.mockRestore();
});
test('should display a HeaderContent', async () => {
const content = 'content';
const { queryByText } = renderWithQueryClient(
<HeaderContainer>
<HeaderContent>{content}</HeaderContent>
</HeaderContainer>
);
const contentElement = queryByText(content);
expect(contentElement).toBeVisible();
});

View file

@ -1,13 +0,0 @@
import { PropsWithChildren } from 'react';
import { useHeaderContext } from './HeaderContainer';
export function HeaderContent({ children }: PropsWithChildren<unknown>) {
useHeaderContext();
return (
<div className="breadcrumb-links">
<div className="pull-left">{children}</div>
</div>
);
}

View file

@ -24,13 +24,17 @@ export function HeaderTitle({ title, children }: PropsWithChildren<Props>) {
const { user } = useUser();
return (
<div className="page white-space-normal">
{title}
<span className="header_title_content">{children}</span>
<div className="flex justify-between whitespace-normal pt-3">
<div className="flex items-center gap-2">
<div className="font-medium text-3xl text-gray-11 th-dark:text-white th-highcontrast:text-white">
{title}
</div>
{children && <span>{children}</span>}
</div>
<Menu>
<MenuButton
className={clsx(
'pull-right flex items-center gap-1',
'ml-auto flex items-center gap-1 self-start',
styles.menuButton
)}
data-cy="userMenu-button"

View file

@ -6,7 +6,6 @@ import { Button } from '../buttons';
import { Breadcrumbs } from './Breadcrumbs';
import { Crumb } from './Breadcrumbs/Breadcrumbs';
import { HeaderContainer } from './HeaderContainer';
import { HeaderContent } from './HeaderContent';
import { HeaderTitle } from './HeaderTitle';
import styles from './PageHeader.module.css';
@ -33,9 +32,8 @@ export function PageHeader({
return (
<HeaderContainer>
<HeaderContent>
<Breadcrumbs breadcrumbs={breadcrumbs} />
</HeaderContent>
<Breadcrumbs breadcrumbs={breadcrumbs} />
<HeaderTitle title={title}>
{reload && (
<Button

View file

@ -1,3 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should not render without a wrapping HeaderContainer 1`] = `"Should be nested inside a HeaderContainer component"`;

View file

@ -1,7 +1 @@
import { Breadcrumbs } from './Breadcrumbs';
import { PageHeader } from './PageHeader';
import { HeaderContainer } from './HeaderContainer';
import { HeaderContent } from './HeaderContent';
import { HeaderTitle } from './HeaderTitle';
export { PageHeader, Breadcrumbs, HeaderContainer, HeaderContent, HeaderTitle };
export { PageHeader } from './PageHeader';