mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugin signing: UI information (#28469)
* first pass * return list * types and cleanup * add to plugin page and add styles * update comment * update comment * fix component path * simplify error component * simplify error struct * fix tests * don't export and fix string() * update naming * remove frontend * introduce phantom loader * track single error * remove error from base * remove unused struct * remove unnecessary filter * add errors endpoint * Update set log to use id field Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * skip adding BE plugins * remove errs from plugin + ds list * remove unnecessary fields * add signature state to panels * Fetch plugins errors * grafana/ui component tweaks * DS Picker - add unsigned badge * VizPicker - add unsigned badge * PluginSignatureBadge tweaks * Plugins list - add signatures info box * New datasource page - add signatures info box * Plugin page - add signatures info box * Fix test * Do not show Core label in viz picker * Update public/app/features/plugins/PluginsErrorsInfo.tsx Co-authored-by: Torkel Ödegaard <torkel@grafana.org> * Update public/app/features/plugins/PluginListPage.test.tsx Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update public/app/features/plugins/PluginListPage.tsx Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update public/app/features/datasources/NewDataSourcePage.tsx Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Review comments 1 * Review comments 2 * Update public/app/features/plugins/PluginsErrorsInfo.tsx * Update public/app/features/plugins/PluginPage.tsx * Prettier fix * remove stale backend code * Docs issues fix Co-authored-by: Will Browne <will.browne@grafana.com> Co-authored-by: Will Browne <wbrowne@users.noreply.github.com> Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> Co-authored-by: Torkel Ödegaard <torkel@grafana.org> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useTheme } from '../../themes';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { IconName } from '../../types/icon';
|
||||
import { getColorsFromSeverity } from '../../utils/colors';
|
||||
|
||||
export type AlertVariant = 'success' | 'warning' | 'error' | 'info';
|
||||
|
||||
@@ -76,21 +77,11 @@ export const Alert: FC<Props> = ({
|
||||
};
|
||||
|
||||
const getStyles = (theme: GrafanaTheme, severity: AlertVariant, outline: boolean) => {
|
||||
const { redBase, redShade, greenBase, greenShade, blue80, blue77, white } = theme.palette;
|
||||
const backgrounds = {
|
||||
error: css`
|
||||
background: linear-gradient(90deg, ${redBase}, ${redShade});
|
||||
`,
|
||||
warning: css`
|
||||
background: linear-gradient(90deg, ${redBase}, ${redShade});
|
||||
`,
|
||||
info: css`
|
||||
background: linear-gradient(100deg, ${blue80}, ${blue77});
|
||||
`,
|
||||
success: css`
|
||||
background: linear-gradient(100deg, ${greenBase}, ${greenShade});
|
||||
`,
|
||||
};
|
||||
const { white } = theme.palette;
|
||||
const severityColors = getColorsFromSeverity(severity, theme);
|
||||
const background = css`
|
||||
background: linear-gradient(90deg, ${severityColors[0]}, ${severityColors[0]});
|
||||
`;
|
||||
|
||||
return {
|
||||
container: css`
|
||||
@@ -106,7 +97,7 @@ const getStyles = (theme: GrafanaTheme, severity: AlertVariant, outline: boolean
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
${backgrounds[severity]}
|
||||
${background}
|
||||
`,
|
||||
icon: css`
|
||||
padding: 0 ${theme.spacing.md} 0 0;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { HTMLAttributes } from 'react';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { useTheme } from '../../themes/ThemeContext';
|
||||
import { stylesFactory } from '../../themes/stylesFactory';
|
||||
@@ -6,23 +6,23 @@ import { IconName } from '../../types';
|
||||
import { Tooltip } from '../Tooltip/Tooltip';
|
||||
import { getColorForTheme, GrafanaTheme } from '@grafana/data';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import { css } from 'emotion';
|
||||
import { HorizontalGroup } from '..';
|
||||
import { css, cx } from 'emotion';
|
||||
import { HorizontalGroup } from '../Layout/Layout';
|
||||
|
||||
export type BadgeColor = 'blue' | 'red' | 'green' | 'orange' | 'purple';
|
||||
|
||||
export interface BadgeProps {
|
||||
export interface BadgeProps extends HTMLAttributes<HTMLDivElement> {
|
||||
text: string;
|
||||
color: BadgeColor;
|
||||
icon?: IconName;
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
export const Badge = React.memo<BadgeProps>(({ icon, color, text, tooltip }) => {
|
||||
export const Badge = React.memo<BadgeProps>(({ icon, color, text, tooltip, className, ...otherProps }) => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyles(theme, color);
|
||||
const badge = (
|
||||
<div className={styles.wrapper}>
|
||||
<div className={cx(styles.wrapper, className)} {...otherProps}>
|
||||
<HorizontalGroup align="center" spacing="xs">
|
||||
{icon && <Icon name={icon} size="sm" />}
|
||||
<span>{text}</span>
|
||||
|
||||
@@ -7,13 +7,22 @@ import { IconButton } from '../IconButton/IconButton';
|
||||
import { HorizontalGroup } from '../Layout/Layout';
|
||||
import panelArtDark from './panelArt_dark.svg';
|
||||
import panelArtLight from './panelArt_light.svg';
|
||||
import { AlertVariant } from '../Alert/Alert';
|
||||
import { getColorsFromSeverity } from '../../utils/colors';
|
||||
|
||||
export interface InfoBoxProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
|
||||
children: React.ReactNode;
|
||||
/** Title of the box */
|
||||
title?: string | JSX.Element;
|
||||
/** Url of the read more link */
|
||||
url?: string;
|
||||
/** Text of the read more link */
|
||||
urlTitle?: string;
|
||||
/** Indicates whether or not box should be rendered with Grafana branding background */
|
||||
branded?: boolean;
|
||||
/** Color variant of the box */
|
||||
severity?: AlertVariant;
|
||||
/** Call back to be performed when box is dismissed */
|
||||
onDismiss?: () => void;
|
||||
}
|
||||
|
||||
@@ -24,9 +33,9 @@ export interface InfoBoxProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
|
||||
*/
|
||||
export const InfoBox = React.memo(
|
||||
React.forwardRef<HTMLDivElement, InfoBoxProps>(
|
||||
({ title, className, children, branded, url, urlTitle, onDismiss, ...otherProps }, ref) => {
|
||||
({ title, className, children, branded, url, urlTitle, onDismiss, severity = 'info', ...otherProps }, ref) => {
|
||||
const theme = useTheme();
|
||||
const styles = getInfoBoxStyles(theme);
|
||||
const styles = getInfoBoxStyles(theme, severity);
|
||||
const wrapperClassName = branded ? cx(styles.wrapperBranded, className) : cx(styles.wrapper, className);
|
||||
|
||||
return (
|
||||
@@ -49,18 +58,15 @@ export const InfoBox = React.memo(
|
||||
)
|
||||
);
|
||||
|
||||
const getInfoBoxStyles = stylesFactory((theme: GrafanaTheme) => ({
|
||||
const getInfoBoxStyles = stylesFactory((theme: GrafanaTheme, severity: AlertVariant) => ({
|
||||
wrapper: css`
|
||||
position: relative;
|
||||
padding: ${theme.spacing.md};
|
||||
background-color: ${theme.colors.bg2};
|
||||
border-top: 3px solid ${theme.palette.blue80};
|
||||
border-top: 3px solid ${getColorsFromSeverity(severity, theme)[0]};
|
||||
margin-bottom: ${theme.spacing.md};
|
||||
flex-grow: 1;
|
||||
|
||||
ul {
|
||||
padding-left: ${theme.spacing.lg};
|
||||
}
|
||||
color: ${theme.colors.textSemiWeak};
|
||||
|
||||
code {
|
||||
@include font-family-monospace();
|
||||
@@ -109,5 +115,6 @@ const getInfoBoxStyles = stylesFactory((theme: GrafanaTheme) => ({
|
||||
display: inline-block;
|
||||
margin-top: ${theme.spacing.md};
|
||||
font-size: ${theme.typography.size.sm};
|
||||
color: ${theme.colors.textSemiWeak};
|
||||
`,
|
||||
}));
|
||||
|
||||
@@ -20,7 +20,7 @@ export interface SelectCommonProps<T> {
|
||||
filterOption?: (option: SelectableValue, searchQuery: string) => boolean;
|
||||
/** Function for formatting the text that is displayed when creating a new value*/
|
||||
formatCreateLabel?: (input: string) => string;
|
||||
getOptionLabel?: (item: SelectableValue<T>) => string;
|
||||
getOptionLabel?: (item: SelectableValue<T>) => React.ReactNode;
|
||||
getOptionValue?: (item: SelectableValue<T>) => string;
|
||||
inputValue?: string;
|
||||
invalid?: boolean;
|
||||
|
||||
@@ -6,6 +6,8 @@ import zip from 'lodash/zip';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import lightTheme from '../themes/light';
|
||||
import darkTheme from '../themes/dark';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { AlertVariant } from '../components/Alert/Alert';
|
||||
|
||||
export const PALETTE_ROWS = 4;
|
||||
export const PALETTE_COLUMNS = 14;
|
||||
@@ -101,3 +103,21 @@ export function getTextColorForBackground(color: string) {
|
||||
}
|
||||
|
||||
export let sortedColors = sortColorsByHue(colors);
|
||||
|
||||
/**
|
||||
* Returns colors used for severity color coding. Use for single color retrievel(0 index) or gradient definition
|
||||
* @internal
|
||||
**/
|
||||
export function getColorsFromSeverity(severity: AlertVariant, theme: GrafanaTheme): [string, string] {
|
||||
switch (severity) {
|
||||
case 'error':
|
||||
case 'warning':
|
||||
return [theme.palette.redBase, theme.palette.redShade];
|
||||
case 'info':
|
||||
return [theme.palette.blue80, theme.palette.blue77];
|
||||
case 'success':
|
||||
return [theme.palette.greenBase, theme.palette.greenShade];
|
||||
default:
|
||||
return [theme.palette.blue80, theme.palette.blue77];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user