grafana/public/app/features/explore/QueryRows.tsx
Haris Rozajac 649c456eab
Explore: Nested Content Outline (#80688)
* indentation levels

* Highlight parent section when child is selected

* Fix context, add rotation to toggle button

* Merge single child logic; fix styling

* Fix collapsed logic, make elipsis work, reorganize for better readability;

* Add connector

* Tooltip placement

* Update tests so they test components the same way users would interact with them

* Clean up indendation levels

* Support collapsing logic for multiple section; highlight all items in a section of an active child - parent is active only when section is collapsed and child inside of it is active

* Simplify making ellipsis work

* Show tooltip if the text overflows in expanded mode

* The whole button container should have same background when section is expanded in mini view

* Fix a bug where root items were not being sorted by document position

* Update query order when query rows are changed through dragging and dropping

* Fix the issue where chaning the title of a query row would remove the query
2024-03-28 09:06:52 -06:00

107 lines
3.3 KiB
TypeScript

import { createSelector } from '@reduxjs/toolkit';
import React, { useCallback, useMemo } from 'react';
import { CoreApp } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime';
import { DataQuery } from '@grafana/schema';
import { getNextRefIdChar } from 'app/core/utils/query';
import { useDispatch, useSelector } from 'app/types';
import { getDatasourceSrv } from '../plugins/datasource_srv';
import { QueryEditorRows } from '../query/components/QueryEditorRows';
import { ContentOutlineItem } from './ContentOutline/ContentOutlineItem';
import { changeQueries, runQueries } from './state/query';
import { getExploreItemSelector } from './state/selectors';
interface Props {
exploreId: string;
}
const makeSelectors = (exploreId: string) => {
const exploreItemSelector = getExploreItemSelector(exploreId);
return {
getQueries: createSelector(exploreItemSelector, (s) => s!.queries),
getQueryResponse: createSelector(exploreItemSelector, (s) => s!.queryResponse),
getHistory: createSelector(exploreItemSelector, (s) => s!.history),
getEventBridge: createSelector(exploreItemSelector, (s) => s!.eventBridge),
getDatasourceInstanceSettings: createSelector(
exploreItemSelector,
(s) => getDatasourceSrv().getInstanceSettings(s!.datasourceInstance?.uid)!
),
};
};
export const QueryRows = ({ exploreId }: Props) => {
const dispatch = useDispatch();
const { getQueries, getDatasourceInstanceSettings, getQueryResponse, getHistory, getEventBridge } = useMemo(
() => makeSelectors(exploreId),
[exploreId]
);
const queries = useSelector(getQueries);
const dsSettings = useSelector(getDatasourceInstanceSettings);
const queryResponse = useSelector(getQueryResponse);
const history = useSelector(getHistory);
const eventBridge = useSelector(getEventBridge);
const onRunQueries = useCallback(() => {
dispatch(runQueries({ exploreId }));
}, [dispatch, exploreId]);
const onChange = useCallback(
(newQueries: DataQuery[]) => {
dispatch(changeQueries({ exploreId, queries: newQueries }));
},
[dispatch, exploreId]
);
const onAddQuery = useCallback(
(query: DataQuery) => {
onChange([...queries, { ...query, refId: getNextRefIdChar(queries) }]);
},
[onChange, queries]
);
const onQueryCopied = () => {
reportInteraction('grafana_explore_query_row_copy');
};
const onQueryRemoved = () => {
reportInteraction('grafana_explore_query_row_remove');
};
const onQueryToggled = (queryStatus?: boolean) => {
reportInteraction('grafana_query_row_toggle', queryStatus === undefined ? {} : { queryEnabled: queryStatus });
};
return (
<QueryEditorRows
dsSettings={dsSettings}
queries={queries}
onQueriesChange={onChange}
onAddQuery={onAddQuery}
onRunQueries={onRunQueries}
onQueryCopied={onQueryCopied}
onQueryRemoved={onQueryRemoved}
onQueryToggled={onQueryToggled}
data={queryResponse}
app={CoreApp.Explore}
history={history}
eventBus={eventBridge}
queryRowWrapper={(children, refId) => (
<ContentOutlineItem
title={refId}
icon="arrow"
key={refId}
panelId="Queries"
customTopOffset={-10}
level="child"
>
{children}
</ContentOutlineItem>
)}
/>
);
};