Feature Highlights: Refactor report nav highlight (#44765)

* Remove UpgradeBox from report nav

* Add children prop

* Update icon

* Update styles

* Update text

* Add pro badge to main nav

* Remove redundant span

* Update secondaryAction
pull/45042/head
Alex Khomenko 3 years ago committed by GitHub
parent 9e1cb8c12a
commit d21abdfe77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      public/app/core/components/NavBar/NavBarItemMenuItem.tsx
  2. 26
      public/app/core/components/NavBar/NavBarItemMenuTrigger.tsx
  3. 1
      public/app/core/components/Page/Page.tsx
  4. 20
      public/app/core/components/PageHeader/PageHeader.tsx
  5. 42
      public/app/core/components/Upgrade/UpgradeBox.tsx

@ -9,7 +9,6 @@ import { mergeProps } from '@react-aria/utils';
import { Node } from '@react-types/shared';
import { useNavBarItemMenuContext } from './context';
import { UpgradeBox } from '../Upgrade/UpgradeBox';
export interface NavBarItemMenuItemProps {
item: Node<NavModelItem>;
@ -61,11 +60,6 @@ export function NavBarItemMenuItem({ item, state, onNavigate }: NavBarItemMenuIt
<li {...mergeProps(menuItemProps, focusProps, keyboardProps)} ref={ref} className={styles.menuItem}>
{rendered}
</li>
{item.value.highlightText && (
<li className={styles.upgradeBoxContainer}>
<UpgradeBox text={item.value.highlightText} className={styles.upgradeBox} size={'sm'} />
</li>
)}
</>
);
}

@ -73,12 +73,14 @@ export function NavBarItemMenuTrigger(props: NavBarItemMenuTriggerProps): ReactE
// Get props for the button based on the trigger props from useMenuTrigger
const { buttonProps } = useButton(menuTriggerProps, ref);
const buttonContent = (
<span className={styles.icon}>
{item?.icon && <Icon name={item.icon as IconName} size="xl" />}
{item?.img && <img src={item.img} alt={`${item.text} logo`} />}
</span>
const Wrapper = item.highlightText ? NavFeatureHighlight : React.Fragment;
const itemContent = (
<Wrapper>
<span className={styles.icon}>
{item?.icon && <Icon name={item.icon as IconName} size="xl" />}
{item?.img && <img src={item.img} alt={`${item.text} logo`} />}
</span>
</Wrapper>
);
let element = (
<button
@ -89,7 +91,7 @@ export function NavBarItemMenuTrigger(props: NavBarItemMenuTriggerProps): ReactE
onClick={item?.onClick}
aria-label={label}
>
{item.highlightText ? <NavFeatureHighlight>{buttonContent}</NavFeatureHighlight> : buttonContent}
{itemContent}
</button>
);
@ -106,10 +108,7 @@ export function NavBarItemMenuTrigger(props: NavBarItemMenuTriggerProps): ReactE
className={styles.element}
aria-label={label}
>
<span className={styles.icon}>
{item?.icon && <Icon name={item.icon as IconName} size="xl" />}
{item?.img && <img src={item.img} alt={`${item.text} logo`} />}
</span>
{itemContent}
</Link>
) : (
<a
@ -122,10 +121,7 @@ export function NavBarItemMenuTrigger(props: NavBarItemMenuTriggerProps): ReactE
className={styles.element}
aria-label={label}
>
<span className={styles.icon}>
{item?.icon && <Icon name={item.icon as IconName} size="xl" />}
{item?.img && <img src={item.img} alt={`${item.text} logo`} />}
</span>
{itemContent}
</a>
);
}

@ -55,7 +55,6 @@ const getStyles = (theme: GrafanaTheme2) => ({
wrapper: css`
width: 100%;
flex-grow: 1;
width: 100%;
min-height: 0;
`,
});

@ -3,6 +3,7 @@ import { css } from '@emotion/css';
import { Tab, TabsBar, Icon, IconName, useStyles2 } from '@grafana/ui';
import { NavModel, NavModelItem, NavModelBreadcrumb, GrafanaTheme2 } from '@grafana/data';
import { PanelHeaderMenuItem } from 'app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem';
import { ProBadge } from '../Upgrade/ProBadge';
export interface Props {
model: NavModel;
@ -81,7 +82,6 @@ export const PageHeader: FC<Props> = ({ model }) => {
const main = model.main;
const children = main.children;
return (
<div className={styles.headerCanvas}>
<div className="page-container">
@ -105,20 +105,32 @@ function renderHeaderTitle(main: NavModelItem) {
</span>
<div className="page-header__info-block">
{renderTitle(main.text, main.breadcrumbs ?? [])}
{renderTitle(main.text, main.breadcrumbs ?? [], main.highlightText)}
{main.subTitle && <div className="page-header__sub-title">{main.subTitle}</div>}
</div>
</div>
);
}
function renderTitle(title: string, breadcrumbs: NavModelBreadcrumb[]) {
function renderTitle(title: string, breadcrumbs: NavModelBreadcrumb[], highlightText: NavModelItem['highlightText']) {
if (!title && (!breadcrumbs || breadcrumbs.length === 0)) {
return null;
}
if (!breadcrumbs || breadcrumbs.length === 0) {
return <h1 className="page-header__title">{title}</h1>;
return (
<h1 className="page-header__title">
{title}
{highlightText && (
<ProBadge
text={highlightText}
className={css`
vertical-align: middle;
`}
/>
)}
</h1>
);
}
const breadcrumbsResult = [];

@ -1,4 +1,4 @@
import React, { HTMLAttributes } from 'react';
import React, { ReactNode, HTMLAttributes } from 'react';
import { css, cx } from '@emotion/css';
import { Icon, LinkButton, useStyles2 } from '@grafana/ui';
import { GrafanaTheme2 } from '@grafana/data';
@ -6,19 +6,25 @@ import { GrafanaTheme2 } from '@grafana/data';
type ComponentSize = 'sm' | 'md';
export interface Props extends HTMLAttributes<HTMLOrSVGElement> {
text: string;
text?: string;
size?: ComponentSize;
children?: ReactNode;
secondaryAction?: {
url: string;
text: string;
};
}
export const UpgradeBox = ({ text, className, size = 'md', ...htmlProps }: Props) => {
export const UpgradeBox = ({ text, className, children, secondaryAction, size = 'md', ...htmlProps }: Props) => {
const styles = useStyles2((theme) => getUpgradeBoxStyles(theme, size));
return (
<div className={cx(styles.box, className)} {...htmlProps}>
<Icon name={'arrow-up'} className={styles.icon} />
<Icon name={'rocket'} className={styles.icon} />
<div>
<h6>Youve found a Pro feature!</h6>
<p className={styles.text}>{text}</p>
<h4>Youve found a Pro feature!</h4>
{text && <p className={styles.text}>{text}</p>}
{children}
<LinkButton
variant="primary"
size={size}
@ -29,6 +35,19 @@ export const UpgradeBox = ({ text, className, size = 'md', ...htmlProps }: Props
>
Upgrade to Pro
</LinkButton>
{secondaryAction && (
<LinkButton
variant="link"
size={size}
className={cx(styles.button, styles.buttonSecondary)}
href={secondaryAction.url}
target="__blank"
rel="noopener noreferrer"
>
{secondaryAction.text}
</LinkButton>
)}
</div>
</div>
);
@ -53,19 +72,26 @@ const getUpgradeBoxStyles = (theme: GrafanaTheme2, size: ComponentSize) => {
`,
text: css`
margin-bottom: 0;
padding: ${theme.spacing(2, 0)};
line-height: 1.5;
`,
button: css`
margin-top: ${theme.spacing(2)};
&:first-of-type {
margin-right: ${theme.spacing(1)};
}
&:focus-visible {
box-shadow: none;
color: ${theme.colors.text.primary};
outline: 2px solid ${theme.colors.primary.main};
}
`,
buttonSecondary: css`
color: ${theme.colors.text.secondary};
`,
icon: css`
border: 1px solid ${theme.colors.primary.shade};
border-radius: 50%;
margin: ${theme.spacing(0.5, 1, 0.5, 0.5)};
`,
};

Loading…
Cancel
Save