diff --git a/.betterer.results b/.betterer.results
index b8eba4d816f..aa617b9bcb8 100644
--- a/.betterer.results
+++ b/.betterer.results
@@ -6339,18 +6339,6 @@ exports[`better eslint`] = {
"public/app/plugins/panel/logs/LogsPanel.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
- "public/app/plugins/panel/news/component/News.tsx:5381": [
- [0, 0, 0, "Styles should be written using objects.", "0"],
- [0, 0, 0, "Styles should be written using objects.", "1"],
- [0, 0, 0, "Styles should be written using objects.", "2"],
- [0, 0, 0, "Styles should be written using objects.", "3"],
- [0, 0, 0, "Styles should be written using objects.", "4"],
- [0, 0, 0, "Styles should be written using objects.", "5"],
- [0, 0, 0, "Styles should be written using objects.", "6"],
- [0, 0, 0, "Styles should be written using objects.", "7"],
- [0, 0, 0, "Styles should be written using objects.", "8"],
- [0, 0, 0, "Styles should be written using objects.", "9"]
- ],
"public/app/plugins/panel/nodeGraph/Edge.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
diff --git a/public/app/core/components/AppChrome/News/NewsWrapper.tsx b/public/app/core/components/AppChrome/News/NewsWrapper.tsx
index 022a18e4f1c..f7a36884c8e 100644
--- a/public/app/core/components/AppChrome/News/NewsWrapper.tsx
+++ b/public/app/core/components/AppChrome/News/NewsWrapper.tsx
@@ -3,7 +3,7 @@ import React, { useEffect } from 'react';
import { useMeasure } from 'react-use';
import { GrafanaTheme2 } from '@grafana/data';
-import { LoadingPlaceholder, useStyles2 } from '@grafana/ui';
+import { useStyles2 } from '@grafana/ui';
import { News } from 'app/plugins/panel/news/component/News';
import { useNewsFeed } from 'app/plugins/panel/news/useNewsFeed';
@@ -19,25 +19,28 @@ export function NewsWrapper({ feedUrl }: NewsWrapperProps) {
getNews();
}, [getNews]);
- if (state.loading || state.error) {
- return (
-
- {state.loading && }
- {state.error && state.error.message}
-
- );
- }
-
- if (!state.value) {
- return null;
+ if (state.error) {
+ return {state.error && state.error.message}
;
}
return (
- {widthMeasure.width > 0 &&
- state.value.map((_, index) => (
-
- ))}
+ {state.loading ? (
+ <>
+
+
+
+
+
+ >
+ ) : (
+ <>
+ {widthMeasure.width > 0 &&
+ state.value?.map((_, index) => (
+
+ ))}
+ >
+ )}
diff --git a/public/app/plugins/panel/news/component/News.tsx b/public/app/plugins/panel/news/component/News.tsx
index 3395ff4b50e..2dbebeebf73 100644
--- a/public/app/plugins/panel/news/component/News.tsx
+++ b/public/app/plugins/panel/news/component/News.tsx
@@ -1,5 +1,6 @@
import { css, cx } from '@emotion/css';
import React from 'react';
+import Skeleton from 'react-loading-skeleton';
import { DataFrameView, GrafanaTheme2, textUtil, dateTimeFormat } from '@grafana/data';
import { useStyles2 } from '@grafana/ui';
@@ -45,68 +46,93 @@ export function News({ width, showImage, data, index }: NewsItemProps) {
);
}
-const getStyles = (theme: GrafanaTheme2) => ({
- container: css`
- height: 100%;
- `,
- item: css`
- display: flex;
- padding: ${theme.spacing(1)};
- position: relative;
- margin-bottom: 4px;
- margin-right: ${theme.spacing(1)};
- border-bottom: 2px solid ${theme.colors.border.weak};
- background: ${theme.colors.background.primary};
- flex-direction: column;
- flex-shrink: 0;
- `,
- itemWide: css`
- flex-direction: row;
- `,
- body: css`
- display: flex;
- flex-direction: column;
- `,
- socialImage: css`
- display: flex;
- align-items: center;
- margin-bottom: ${theme.spacing(1)};
- > img {
- width: 100%;
- border-radius: ${theme.shape.radius.default} ${theme.shape.radius.default} 0 0;
- }
- `,
- socialImageWide: css`
- margin-right: ${theme.spacing(2)};
- margin-bottom: 0;
- > img {
- width: 250px;
- border-radius: ${theme.shape.radius.default};
- }
- `,
- link: css`
- color: ${theme.colors.text.link};
- display: inline-block;
+const NewsSkeleton = ({ width, showImage }: Pick) => {
+ const styles = useStyles2(getStyles);
+ const useWideLayout = width > 600;
- &:hover {
- color: ${theme.colors.text.link};
- text-decoration: underline;
- }
- `,
- title: css`
- font-size: 16px;
- margin-bottom: ${theme.spacing(0.5)};
- `,
- content: css`
- p {
- margin-bottom: 4px;
- color: ${theme.colors.text};
- }
- `,
- date: css`
- margin-bottom: ${theme.spacing(0.5)};
- font-weight: 500;
- border-radius: 0 0 0 ${theme.shape.radius.default};
- color: ${theme.colors.text.secondary};
- `,
+ return (
+
+ {showImage && (
+
+ )}
+
+
+
+
+
+
+ );
+};
+
+News.Skeleton = NewsSkeleton;
+
+const getStyles = (theme: GrafanaTheme2) => ({
+ container: css({
+ height: '100%',
+ }),
+ item: css({
+ display: 'flex',
+ padding: theme.spacing(1),
+ position: 'relative',
+ marginBottom: theme.spacing(0.5),
+ marginRight: theme.spacing(1),
+ borderBottom: `2px solid ${theme.colors.border.weak}`,
+ background: theme.colors.background.primary,
+ flexDirection: 'column',
+ flexShrink: 0,
+ }),
+ itemWide: css({
+ flexDirection: 'row',
+ }),
+ body: css({
+ display: 'flex',
+ flexDirection: 'column',
+ flex: 1,
+ }),
+ socialImage: css({
+ display: 'flex',
+ alignItems: 'center',
+ marginBottom: theme.spacing(1),
+ '> img': {
+ width: '100%',
+ borderRadius: `${theme.shape.radius.default} ${theme.shape.radius.default} 0 0`,
+ },
+ }),
+ socialImageWide: css({
+ marginRight: theme.spacing(2),
+ marginBottom: 0,
+ '> img': {
+ width: '250px',
+ borderRadius: theme.shape.radius.default,
+ },
+ }),
+ link: css({
+ color: theme.colors.text.link,
+ display: 'inline-block',
+
+ '&:hover': {
+ color: theme.colors.text.link,
+ textDecoration: 'underline',
+ },
+ }),
+ title: css({
+ fontSize: '16px',
+ marginBottom: theme.spacing(0.5),
+ }),
+ content: css({
+ p: {
+ marginBottom: theme.spacing(0.5),
+ color: theme.colors.text.primary,
+ },
+ }),
+ date: css({
+ marginBottom: theme.spacing(0.5),
+ fontWeight: 500,
+ borderRadius: `0 0 0 ${theme.shape.radius.default}`,
+ color: theme.colors.text.secondary,
+ }),
});