mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
NewsDrawer: Add grot to news drawer (after news items) (#68173)
* NewsDrawer: Add grot to drawer header * Update * Move to bottom * Updates * reverted unrelated change * Update * fixing test
This commit is contained in:
parent
3869d2f239
commit
c8fd3c20cd
@ -1463,6 +1463,9 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "6"]
|
||||
],
|
||||
"public/app/core/components/AppChrome/News/NewsContainer.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
||||
],
|
||||
"public/app/core/components/AppChrome/SectionNav/SectionNavItem.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
||||
],
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import fs from 'fs';
|
||||
import React from 'react';
|
||||
|
||||
import { NewsContainer } from './NewsContainer';
|
||||
@ -12,17 +11,10 @@ const setup = () => {
|
||||
};
|
||||
|
||||
describe('News', () => {
|
||||
const result = fs.readFileSync(`${__dirname}/fixtures/news.xml`, 'utf8');
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
window.fetch = jest.fn().mockResolvedValue({ text: () => result });
|
||||
});
|
||||
|
||||
it('should render the drawer when the drawer button is clicked', async () => {
|
||||
setup();
|
||||
|
||||
await userEvent.click(screen.getByRole('button'));
|
||||
expect(screen.getByRole('article')).toBeInTheDocument();
|
||||
expect(screen.getByRole('link')).toHaveAttribute('href', 'https://www.example.net/2022/02/10/something-fake/');
|
||||
expect(screen.getByText('Latest from the blog')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,11 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
import { useToggle } from 'react-use';
|
||||
|
||||
import { Drawer, ToolbarButton } from '@grafana/ui';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Button, Drawer, ToolbarButton, useStyles2 } from '@grafana/ui';
|
||||
import { H3 } from '@grafana/ui/src/unstable';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { DEFAULT_FEED_URL } from 'app/plugins/panel/news/constants';
|
||||
|
||||
@ -13,17 +17,36 @@ interface NewsContainerProps {
|
||||
|
||||
export function NewsContainer({ className }: NewsContainerProps) {
|
||||
const [showNewsDrawer, onToggleShowNewsDrawer] = useToggle(false);
|
||||
|
||||
const onChildClick = () => {
|
||||
onToggleShowNewsDrawer(true);
|
||||
};
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ToolbarButton className={className} onClick={onChildClick} iconOnly icon="rss" aria-label="News" />
|
||||
<ToolbarButton className={className} onClick={onToggleShowNewsDrawer} iconOnly icon="rss" aria-label="News" />
|
||||
{showNewsDrawer && (
|
||||
<Drawer
|
||||
title={t('news.title', 'Latest from the blog')}
|
||||
title={
|
||||
<div className={styles.title}>
|
||||
<H3>{t('news.title', 'Latest from the blog')}</H3>
|
||||
<a
|
||||
href="https://grafana.com/blog/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
title="Go to Grafana labs blog"
|
||||
className={styles.grot}
|
||||
>
|
||||
<img src="public/img/grot-news.svg" alt="Grot reading news" />
|
||||
</a>
|
||||
<div className={styles.actions}>
|
||||
<Button
|
||||
icon="times"
|
||||
variant="secondary"
|
||||
fill="text"
|
||||
onClick={onToggleShowNewsDrawer}
|
||||
aria-label={selectors.components.Drawer.General.close}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
scrollableContent
|
||||
onClose={onToggleShowNewsDrawer}
|
||||
size="md"
|
||||
@ -34,3 +57,31 @@ export function NewsContainer({ className }: NewsContainerProps) {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => {
|
||||
return {
|
||||
title: css({
|
||||
display: `flex`,
|
||||
alignItems: `center`,
|
||||
justifyContent: `center`,
|
||||
gap: theme.spacing(2),
|
||||
borderBottom: `1px solid ${theme.colors.border.weak}`,
|
||||
}),
|
||||
grot: css({
|
||||
display: `flex`,
|
||||
alignItems: `center`,
|
||||
justifyContent: `center`,
|
||||
padding: theme.spacing(2, 0),
|
||||
|
||||
img: {
|
||||
width: `75px`,
|
||||
height: `75px`,
|
||||
},
|
||||
}),
|
||||
actions: css({
|
||||
position: 'absolute',
|
||||
right: theme.spacing(1),
|
||||
top: theme.spacing(2),
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useEffect } from 'react';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import { useMeasure } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { LoadingPlaceholder, useStyles2 } from '@grafana/ui';
|
||||
@ -13,6 +13,8 @@ interface NewsWrapperProps {
|
||||
export function NewsWrapper({ feedUrl }: NewsWrapperProps) {
|
||||
const styles = useStyles2(getStyles);
|
||||
const { state, getNews } = useNewsFeed(feedUrl);
|
||||
const [widthRef, widthMeasure] = useMeasure<HTMLDivElement>();
|
||||
|
||||
useEffect(() => {
|
||||
getNews();
|
||||
}, [getNews]);
|
||||
@ -31,15 +33,17 @@ export function NewsWrapper({ feedUrl }: NewsWrapperProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<AutoSizer>
|
||||
{({ width }) => (
|
||||
<div style={{ width: `${width}px` }}>
|
||||
{state.value.map((_, index) => (
|
||||
<News key={index} index={index} showImage width={width} data={state.value} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</AutoSizer>
|
||||
<div ref={widthRef}>
|
||||
{widthMeasure.width > 0 &&
|
||||
state.value.map((_, index) => (
|
||||
<News key={index} index={index} showImage width={widthMeasure.width} data={state.value} />
|
||||
))}
|
||||
<div className={styles.grot}>
|
||||
<a href="https://grafana.com/blog/" target="_blank" rel="noreferrer" title="Go to Grafana labs blog">
|
||||
<img src="public/img/grot-news.svg" alt="Grot reading news" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -52,5 +56,16 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`,
|
||||
grot: css({
|
||||
display: `flex`,
|
||||
alignItems: `center`,
|
||||
justifyContent: `center`,
|
||||
padding: theme.spacing(5, 0),
|
||||
|
||||
img: {
|
||||
width: `186px`,
|
||||
height: `186px`,
|
||||
},
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
46
public/img/grot-news.svg
Normal file
46
public/img/grot-news.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 18 KiB |
Loading…
Reference in New Issue
Block a user