diff --git a/public/app/core/utils/richHistory.ts b/public/app/core/utils/richHistory.ts index 76d038c07bf..deb77f6a95e 100644 --- a/public/app/core/utils/richHistory.ts +++ b/public/app/core/utils/richHistory.ts @@ -13,9 +13,9 @@ import { ExploreUrlState, RichHistoryQuery } from 'app/types/explore'; const RICH_HISTORY_KEY = 'grafana.explore.richHistory'; export const RICH_HISTORY_SETTING_KEYS = { - retentionPeriod: `${RICH_HISTORY_KEY}.retentionPeriod`, - starredTabAsFirstTab: `${RICH_HISTORY_KEY}.starredTabAsFirstTab`, - activeDatasourceOnly: `${RICH_HISTORY_KEY}.activeDatasourceOnly`, + retentionPeriod: 'grafana.explore.richHistory.retentionPeriod', + starredTabAsFirstTab: 'grafana.explore.richHistory.starredTabAsFirstTab', + activeDatasourceOnly: 'grafana.explore.richHistory.activeDatasourceOnly', }; /* @@ -60,8 +60,14 @@ export function addToRichHistory( ]; /* Combine all queries of a datasource type into one rich history */ - store.setObject(RICH_HISTORY_KEY, newHistory); - return newHistory; + const isSaved = store.setObject(RICH_HISTORY_KEY, newHistory); + + /* If newHistory is succesfully saved, return it. Otherwise return not updated richHistory. */ + if (isSaved) { + return newHistory; + } else { + return richHistory; + } } return richHistory; diff --git a/public/app/features/explore/Explore.tsx b/public/app/features/explore/Explore.tsx index 65de938cf59..469df73ae15 100644 --- a/public/app/features/explore/Explore.tsx +++ b/public/app/features/explore/Explore.tsx @@ -322,7 +322,6 @@ export class Explore extends React.PureComponent { ['explore-active-button']: showRichHistory, })} onClick={this.toggleShowRichHistory} - disabled={isLive} > {'\xA0' + 'Query history'} @@ -382,7 +381,13 @@ export class Explore extends React.PureComponent { )} )} - {showRichHistory && } + {showRichHistory && ( + + )} ); diff --git a/public/app/features/explore/RichHistory/RichHistory.tsx b/public/app/features/explore/RichHistory/RichHistory.tsx index 699a50457a2..906373a4fed 100644 --- a/public/app/features/explore/RichHistory/RichHistory.tsx +++ b/public/app/features/explore/RichHistory/RichHistory.tsx @@ -35,7 +35,9 @@ interface RichHistoryProps extends Themeable { activeDatasourceInstance: string; firstTab: Tabs; exploreId: ExploreId; + height: number; deleteRichHistory: () => void; + onClose: () => void; } interface RichHistoryState { @@ -60,6 +62,11 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => { background-color: ${tabContentBg}; padding: ${theme.spacing.md}; `, + close: css` + position: absolute; + right: ${theme.spacing.sm}; + cursor: pointer; + `, tabs: css` background-color: ${tabBarBg}; padding-top: ${theme.spacing.sm}; @@ -142,15 +149,8 @@ class UnThemedRichHistory extends PureComponent ), icon: 'fa fa-history', @@ -205,8 +206,7 @@ class UnThemedRichHistory extends PureComponent @@ -219,6 +219,9 @@ class UnThemedRichHistory extends PureComponent ))} +
+ +
{ - const bgColor = theme.isLight ? theme.colors.gray5 : theme.colors.dark4; + const borderColor = theme.isLight ? theme.colors.gray5 : theme.colors.dark4; const cardBottomPadding = hasComment ? theme.spacing.sm : theme.spacing.xs; return { @@ -30,7 +30,6 @@ const getStyles = stylesFactory((theme: GrafanaTheme, hasComment?: boolean) => { display: flex; padding: ${theme.spacing.sm} ${theme.spacing.sm} ${cardBottomPadding}; margin: ${theme.spacing.sm} 0; - .starred { color: ${theme.colors.orange}; } @@ -42,6 +41,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme, hasComment?: boolean) => { `, queryCardRight: css` width: 150px; + height: ${theme.height.sm}; display: flex; justify-content: flex-end; @@ -51,7 +51,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme, hasComment?: boolean) => { } `, queryRow: css` - border-top: 1px solid ${bgColor}; + border-top: 1px solid ${borderColor}; word-break: break-all; padding: 4px 2px; :first-child { @@ -82,7 +82,6 @@ export function RichHistoryCard(props: Props) { clearQueries, datasourceInstance, } = props; - const [starred, setStared] = useState(query.starred); const [activeUpdateComment, setActiveUpdateComment] = useState(false); const [comment, setComment] = useState(query.comment); @@ -109,7 +108,7 @@ export function RichHistoryCard(props: Props) { return (
-
onChangeQuery(query)}> +
onChangeQuery(query)}> {query.queries.map((q, i) => { return (
@@ -123,12 +122,18 @@ export function RichHistoryCard(props: Props) { setComment(e.currentTarget.value)} + onChange={e => { + setComment(e.currentTarget.value); + }} + onClick={e => { + e.stopPropagation(); + }} />
{ e.preventDefault(); + e.stopPropagation(); updateRichHistory(query.ts, 'comment', comment); toggleActiveUpdateComment(); }} @@ -140,7 +145,8 @@ export function RichHistoryCard(props: Props) { className={css` margin-left: 8px; `} - onClick={() => { + onClick={e => { + e.stopPropagation(); toggleActiveUpdateComment(); setComment(query.comment); }} @@ -179,10 +185,9 @@ export function RichHistoryCard(props: Props) { title="Copy link to clipboard" > { updateRichHistory(query.ts, 'starred'); - setStared(!starred); }} title={query.starred ? 'Unstar query' : 'Star query'} > diff --git a/public/app/features/explore/RichHistory/RichHistoryContainer.tsx b/public/app/features/explore/RichHistory/RichHistoryContainer.tsx index bec1b8957bb..51366b53c9e 100644 --- a/public/app/features/explore/RichHistory/RichHistoryContainer.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryContainer.tsx @@ -22,33 +22,33 @@ import { RichHistory, Tabs } from './RichHistory'; import { deleteRichHistory } from '../state/actions'; const getStyles = stylesFactory((theme: GrafanaTheme) => { - const bgColor = theme.isLight ? theme.colors.gray5 : theme.colors.gray15; - const bg = theme.isLight ? theme.colors.gray7 : theme.colors.dark2; - const borderColor = theme.isLight ? theme.colors.gray5 : theme.colors.dark6; - const handleHover = theme.isLight ? theme.colors.gray10 : theme.colors.gray33; + const containerBackground = theme.isLight ? theme.colors.gray7 : theme.colors.dark2; + const containerBorderColor = theme.isLight ? theme.colors.gray5 : theme.colors.dark6; + const handleBackground = theme.isLight ? theme.colors.gray5 : theme.colors.gray15; const handleDots = theme.isLight ? theme.colors.gray70 : theme.colors.gray33; - const handleDotsHover = theme.isLight ? theme.colors.gray33 : theme.colors.dark7; + const handleBackgroundHover = theme.isLight ? theme.colors.gray70 : theme.colors.gray33; + const handleDotsHover = theme.isLight ? theme.colors.gray5 : theme.colors.dark7; return { container: css` position: fixed !important; bottom: 0; - background: ${bg}; - border-top: 1px solid ${borderColor}; + background: ${containerBackground}; + border-top: 1px solid ${containerBorderColor}; margin: 0px; margin-right: -${theme.spacing.md}; margin-left: -${theme.spacing.md}; `, drawerActive: css` opacity: 1; - transition: transform 0.3s ease-in; + transition: transform 0.5s ease-in; `, drawerNotActive: css` opacity: 0; - transform: translateY(150px); + transform: translateY(400px); `, rzHandle: css` - background: ${bgColor}; + background: ${handleBackground}; transition: 0.3s background ease-in-out; position: relative; width: 200px !important; @@ -57,7 +57,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => { border-radius: 4px; &:hover { - background-color: ${handleHover}; + background-color: ${handleBackgroundHover}; &:after { border-color: ${handleDotsHover}; @@ -84,18 +84,20 @@ interface Props { richHistory: RichHistoryQuery[]; firstTab: Tabs; deleteRichHistory: typeof deleteRichHistory; + onClose: () => void; } function RichHistoryContainer(props: Props) { const [visible, setVisible] = useState(false); + const [height, setHeight] = useState(400); /* To create sliding animation for rich history drawer */ useEffect(() => { - const timer = setTimeout(() => setVisible(true), 100); + const timer = setTimeout(() => setVisible(true), 10); return () => clearTimeout(timer); }, []); - const { richHistory, width, firstTab, activeDatasourceInstance, exploreId, deleteRichHistory } = props; + const { richHistory, width, firstTab, activeDatasourceInstance, exploreId, deleteRichHistory, onClose } = props; const theme = useTheme(); const styles = getStyles(theme); const drawerWidth = `${width + 31.5}px`; @@ -118,6 +120,9 @@ function RichHistoryContainer(props: Props) { maxHeight="100vh" maxWidth={drawerWidth} minWidth={drawerWidth} + onResize={(e, dir, ref) => { + setHeight(Number(ref.style.height.slice(0, -2))); + }} > ); diff --git a/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx b/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx index 7a4e581b1a7..fb65f2d933c 100644 --- a/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx @@ -30,15 +30,17 @@ interface Props { datasourceFilters: SelectableValue[] | null; retentionPeriod: number; exploreId: ExploreId; + height: number; onChangeSortOrder: (sortOrder: SortOrder) => void; onSelectDatasourceFilters: (value: SelectableValue[] | null) => void; } -const getStyles = stylesFactory((theme: GrafanaTheme) => { +const getStyles = stylesFactory((theme: GrafanaTheme, height: number) => { const bgColor = theme.isLight ? theme.colors.gray5 : theme.colors.dark4; /* 134px is based on the width of the Query history tabs bar, so the content is aligned to right side of the tab */ const cardWidth = '100% - 134px'; + const sliderHeight = `${height - 200}px`; return { container: css` display: flex; @@ -61,9 +63,9 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => { margin-right: ${theme.spacing.sm}; .slider { bottom: 10px; - height: 200px; + height: ${sliderHeight}; width: 127px; - padding: ${theme.spacing.xs} 0; + padding: ${theme.spacing.sm} 0; } `, slider: css` @@ -127,12 +129,13 @@ export function RichHistoryQueriesTab(props: Props) { activeDatasourceOnly, retentionPeriod, exploreId, + height, } = props; const [sliderRetentionFilter, setSliderRetentionFilter] = useState<[number, number]>([0, retentionPeriod]); const theme = useTheme(); - const styles = getStyles(theme); + const styles = getStyles(theme, height); const listOfDsNamesWithQueries = uniqBy(queries, 'datasourceName').map(d => d.datasourceName); /* Display only explore datasoources, that have saved queries */ @@ -192,13 +195,14 @@ export function RichHistoryQueriesTab(props: Props) { isMulti={true} options={datasources} value={datasourceFilters} - placeholder="Filter queries for specific datasources(s)" + placeholder="Filter queries for specific data sources(s)" onChange={onSelectDatasourceFilters} />
)}
order.value === sortOrder)} placeholder="Sort queries by" onChange={e => onChangeSortOrder(e.value as SortOrder)} />