AddPanel: Design polish (#31484)

* AddPanel: Design fixes

* More design updates

* More tweaks

* Updated snapshot

* Modal fixes

* Updated field labels

* Move icon to left again
This commit is contained in:
Torkel Ödegaard 2021-02-26 12:29:28 +01:00 committed by GitHub
parent 14e7f70eac
commit eddc163e78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 57 deletions

View File

@ -224,6 +224,9 @@ export const getCardStyles = stylesFactory((theme: GrafanaTheme) => {
media: css`
margin-right: ${theme.spacing.md};
width: 40px;
display: flex;
align-items: center;
& > * {
width: 100%;
}

View File

@ -4,7 +4,7 @@ import { css, cx, keyframes } from 'emotion';
import _ from 'lodash';
import tinycolor from 'tinycolor2';
import { LocationUpdate } from '@grafana/runtime';
import { Icon, IconButton, styleMixins, stylesFactory, useStyles, useTheme } from '@grafana/ui';
import { Icon, IconButton, styleMixins, useStyles } from '@grafana/ui';
import { selectors } from '@grafana/e2e-selectors';
import { DateTimeInput, GrafanaTheme } from '@grafana/data';
@ -142,7 +142,7 @@ export const AddPanelWidgetUnconnected: React.FC<Props> = ({ panel, dashboard, u
return (
<div className={cx('panel-container', styles.wrapper)}>
<AddPanelWidgetHandle onCancel={onCancelAddPanel} onBack={addPanelView ? onBack : undefined}>
<AddPanelWidgetHandle onCancel={onCancelAddPanel} onBack={addPanelView ? onBack : undefined} styles={styles}>
{addPanelView ? 'Add panel from panel library' : 'Add panel'}
</AddPanelWidgetHandle>
{addPanelView ? (
@ -194,26 +194,30 @@ interface AddPanelWidgetHandleProps {
onCancel: (e: React.MouseEvent<HTMLButtonElement>) => void;
onBack?: () => void;
children?: string;
styles: AddPanelStyles;
}
const AddPanelWidgetHandle: React.FC<AddPanelWidgetHandleProps> = ({ children, onBack, onCancel }) => {
const theme = useTheme();
const styles = getAddPanelWigetHandleStyles(theme);
const AddPanelWidgetHandle: React.FC<AddPanelWidgetHandleProps> = ({ children, onBack, onCancel, styles }) => {
return (
<div className={cx(styles.handle, 'grid-drag-handle')}>
<div className={styles.backButton}>
{onBack && (
<IconButton name="arrow-left" onClick={onBack} surface="header" size="xl" className={styles.noMargin} />
)}
</div>
<div className={cx(styles.headerRow, 'grid-drag-handle')}>
{onBack && (
<div className={styles.backButton}>
<IconButton name="arrow-left" onClick={onBack} surface="header" size="xl" />
</div>
)}
{!onBack && (
<div className={styles.backButton}>
<Icon name="panel-add" size="md" />
</div>
)}
{children && <span>{children}</span>}
<IconButton name="times" onClick={onCancel} surface="header" className={styles.pushRight} />
<div className="flex-grow-1" />
<IconButton name="times" onClick={onCancel} surface="header" />
</div>
);
};
const getStyles = stylesFactory((theme: GrafanaTheme) => {
const getStyles = (theme: GrafanaTheme) => {
const pulsate = keyframes`
0% {box-shadow: 0 0 0 2px ${theme.colors.bodyBg}, 0 0 0px 4px ${theme.colors.formFocusOutline};}
50% {box-shadow: 0 0 0 2px ${theme.colors.bodyBg}, 0 0 0px 4px ${tinycolor(theme.colors.formFocusOutline)
@ -221,6 +225,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
.toHexString()};}
100% {box-shadow: 0 0 0 2px ${theme.colors.bodyBg}, 0 0 0px 4px ${theme.colors.formFocusOutline};}
`;
return {
wrapper: css`
overflow: hidden;
@ -261,43 +266,28 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
display: flex;
flex-direction: column;
row-gap: ${theme.spacing.sm};
padding: 0 ${theme.spacing.sm} ${theme.spacing.sm} ${theme.spacing.sm};
height: 100%;
margin-left: ${theme.spacing.xl};
margin-right: ${theme.spacing.xl};
margin-top: ${theme.spacing.base * 4}px;
margin-bottom: ${theme.spacing.base * 5}px;
`,
buttonMargin: css`
margin-right: ${theme.spacing.sm};
`,
libraryPanelsWrapper: css`
padding: ${theme.spacing.base * 4}px ${theme.spacing.xl};
padding: ${theme.spacing.sm};
`,
};
});
const getAddPanelWigetHandleStyles = stylesFactory((theme: GrafanaTheme) => {
return {
handle: css`
position: absolute;
headerRow: css`
display: flex;
align-items: center;
height: ${theme.spacing.gutter};
height: 38px;
flex-shrink: 0;
width: 100%;
font-size: ${theme.typography.size.md};
font-weight: ${theme.typography.weight.semibold};
padding-left: ${theme.spacing.sm};
transition: background-color 0.1s ease-in-out;
cursor: move;
&:hover {
background: ${theme.colors.bg2};
}
`,
pushRight: css`
margin-left: auto;
`,
leftPad: css`
padding-left: ${theme.spacing.xl};
`,
backButton: css`
display: flex;
align-items: center;
@ -309,4 +299,6 @@ const getAddPanelWigetHandleStyles = stylesFactory((theme: GrafanaTheme) => {
margin: 0;
`,
};
});
};
type AddPanelStyles = ReturnType<typeof getStyles>;

View File

@ -6,11 +6,22 @@ exports[`Render should render component 1`] = `
>
<AddPanelWidgetHandle
onCancel={[Function]}
styles={
Object {
"actionsRow": "css-txvz1e",
"actionsWrapper": "css-gxxmom",
"backButton": "css-1cdxa9p",
"headerRow": "css-1ka09x",
"libraryPanelsWrapper": "css-18m13of",
"noMargin": "css-u023fv",
"wrapper": "css-1sl7nld",
}
}
>
Add panel
</AddPanelWidgetHandle>
<div
className="css-t8cafv"
className="css-gxxmom"
>
<div
className="css-txvz1e"

View File

@ -20,10 +20,10 @@ export const AddLibraryPanelModal: React.FC<Props> = ({ isOpen = false, panel, i
return (
<Modal title="Add this panel to the panel library" isOpen={isOpen} onDismiss={props.onDismiss}>
<Field label="Please set a name for the new reusable panel:">
<Field label="Library panel name">
<Input name="name" value={panelTitle} onChange={(e) => setPanelTitle(e.currentTarget.value)} />
</Field>
<Field label="Your reusable panel will be saved in:">
<Field label="Save in folder" description="Library panel permissions are derived from the folder permissions">
<FolderPicker onChange={({ id }) => setFolderId(id)} initialFolderId={initialFolderId} />
</Field>

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { Icon, IconButton, stylesFactory, ConfirmModal, Tooltip, useStyles, Card } from '@grafana/ui';
import { Icon, IconButton, ConfirmModal, Tooltip, useStyles, Card } from '@grafana/ui';
import { css } from 'emotion';
import { GrafanaTheme } from '@grafana/data';
import { LibraryPanelDTO } from '../../state/api';
@ -32,7 +32,7 @@ export const LibraryPanelCard: React.FC<LibraryPanelCardProps & { children?: JSX
<>
<Card heading={libraryPanel.name} onClick={onClick ? () => onClick(libraryPanel) : undefined}>
<Card.Figure>
<Icon className={styles.panelIcon} name="book-open" />
<Icon className={styles.panelIcon} name="book-open" size="xl" />
</Card.Figure>
<Card.Meta>
<span>Reusable panel</span>
@ -42,17 +42,6 @@ export const LibraryPanelCard: React.FC<LibraryPanelCardProps & { children?: JSX
{libraryPanel.meta.connectedDashboards}
</div>
</Tooltip>
{/*
Commenting this out as obtaining the number of variables used by a panel
isn't implemetned yet.
<Tooltip content="Variables used" placement="bottom">
<div className={styles.tooltip}>
<Icon name="x" className={styles.detailIcon} />
{varCount}
</div>
</Tooltip> */}
<span>
Last edited {formatDate?.(libraryPanel.meta.updated ?? '') ?? libraryPanel.meta.updated} by{' '}
{libraryPanel.meta.updatedBy.name}
@ -94,7 +83,7 @@ export const LibraryPanelCard: React.FC<LibraryPanelCardProps & { children?: JSX
);
};
const getStyles = stylesFactory((theme: GrafanaTheme) => {
const getStyles = (theme: GrafanaTheme) => {
return {
tooltip: css`
display: inline;
@ -103,10 +92,10 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
margin-right: 0.5ch;
`,
panelIcon: css`
margin-right: ${theme.spacing.md};
color: ${theme.colors.textWeak};
`,
tagList: css`
align-self: center;
`,
};
});
};

View File

@ -62,12 +62,12 @@ export const LibraryPanelsView: React.FC<LibraryPanelViewProps> = ({
return (
<div className={cx(styles.container, className)}>
<span>Popular panels from the panel library</span>
<div className={styles.searchHeader}>
<Input
placeholder="Search the panel library"
prefix={<Icon name="search" />}
value={searchString}
autoFocus
onChange={(e) => setSearchString(e.currentTarget.value)}
></Input>
{/* <Select placeholder="Filter by" onChange={() => {}} width={35} /> */}