mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* WIP
* Use splitpanewrapper for drawer
* Get rich history pulling from multiple datasources
* highlight pane
* Fix datasource data handling
* create ds/explore map, move around ds lookup
* Handle no filters
* Fix tests and some errors
* Fix context menu issue
* (Poorly) enable scrolling, fix onClose to function
* Remove highlighting, use legacy key, fix casing
* fix filtering to handle non-simple data
* Fix linter, add translations
* Fixing tests~~
* Move to explore drawer and fix some more tests
* Kinda fix drawer stuff?
* Fix remaining card tests
* Fix test
* Fix tests
* Partially fix starred tab tests
* Fix integration tests
* Fix remaining tests 🤞
* Add a test and a clarifying comment behind a couple hooks
* Remove unused code
* Fix button styling and fix animation (but break width)
* Make Drawer using parent width (100%)
* Fix tests and some small catches
* Add tests for selectExploreDSMaps selector
---------
Co-authored-by: Piotr Jamroz <pm.jamroz@gmail.com>
89 lines
3.3 KiB
TypeScript
89 lines
3.3 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
import { connect } from 'react-redux';
|
|
|
|
import { EventBusSrv, getTimeZone } from '@grafana/data';
|
|
import { selectors } from '@grafana/e2e-selectors';
|
|
import { CustomScrollbar } from '@grafana/ui';
|
|
import { stopQueryState } from 'app/core/utils/explore';
|
|
import { StoreState, useSelector } from 'app/types';
|
|
|
|
import Explore from './Explore';
|
|
import ExploreQueryInspector from './ExploreQueryInspector';
|
|
import { getExploreItemSelector } from './state/selectors';
|
|
|
|
const containerStyles = css({
|
|
label: 'explorePaneContainer',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
minWidth: '600px',
|
|
height: '100%',
|
|
});
|
|
|
|
interface Props {
|
|
exploreId: string;
|
|
}
|
|
|
|
/*
|
|
Connected components subscribe to the store before function components (using hooks) and can react to store changes. Thus, this connector function is called before the parent component (ExplorePage) is rerendered.
|
|
This means that child components' mapStateToProps will be executed with a zombie `exploreId` that is not present anymore in the store if the pane gets closed.
|
|
By connecting this component and returning the pane we workaround the zombie children issue here instead of modifying every children.
|
|
This is definitely not the ideal solution and we should in the future invest more time in exploring other approaches to better handle this scenario, potentially by refactoring panels to be function components
|
|
(therefore immune to this behaviour), or by forbidding them to access the store directly and instead pass them all the data they need via props or context.
|
|
|
|
You can read more about this issue here: https://react-redux.js.org/api/hooks#stale-props-and-zombie-children
|
|
*/
|
|
function ExplorePaneContainerUnconnected({ exploreId }: Props) {
|
|
useStopQueries(exploreId);
|
|
const eventBus = useRef(new EventBusSrv());
|
|
const ref = useRef(null);
|
|
const [showQueryInspector, setShowQueryInspector] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const bus = eventBus.current;
|
|
return () => bus.removeAllListeners();
|
|
}, []);
|
|
|
|
return (
|
|
<CustomScrollbar hideVerticalTrack>
|
|
<div className={containerStyles} ref={ref} data-testid={selectors.pages.Explore.General.container}>
|
|
<Explore
|
|
exploreId={exploreId}
|
|
eventBus={eventBus.current}
|
|
showQueryInspector={showQueryInspector}
|
|
setShowQueryInspector={setShowQueryInspector}
|
|
/>
|
|
{showQueryInspector && (
|
|
<ExploreQueryInspector
|
|
exploreId={exploreId}
|
|
onClose={() => setShowQueryInspector(false)}
|
|
timeZone={getTimeZone()}
|
|
/>
|
|
)}
|
|
</div>
|
|
</CustomScrollbar>
|
|
);
|
|
}
|
|
|
|
function mapStateToProps(state: StoreState, props: Props) {
|
|
const pane = state.explore.panes[props.exploreId];
|
|
|
|
return { pane };
|
|
}
|
|
|
|
const connector = connect(mapStateToProps);
|
|
|
|
export const ExplorePaneContainer = connector(ExplorePaneContainerUnconnected);
|
|
|
|
function useStopQueries(exploreId: string) {
|
|
const paneSelector = useMemo(() => getExploreItemSelector(exploreId), [exploreId]);
|
|
const paneRef = useRef<ReturnType<typeof paneSelector>>();
|
|
paneRef.current = useSelector(paneSelector);
|
|
|
|
useEffect(() => {
|
|
return () => {
|
|
stopQueryState(paneRef.current?.querySubscription);
|
|
};
|
|
}, []);
|
|
}
|