mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboard-Scene: Add and remove Panel Editor queries and expressions (#81027)
* wip * Functionality for adding and deleting queries and expressions * Remove console.log * handle counter updates * revert unintended change * Revert tsconfig.json * revert
This commit is contained in:
parent
26e71953a4
commit
fc82b0286f
@ -2387,6 +2387,9 @@ exports[`better eslint`] = {
|
||||
"public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataPane.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/panel-edit/VizPanelManager.test.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
|
@ -5,11 +5,11 @@ import { SceneObjectBase, SceneComponentProps } from '@grafana/scenes';
|
||||
|
||||
import { VizPanelManager } from '../VizPanelManager';
|
||||
|
||||
import { PanelDataPaneTabState, PanelDataPaneTab } from './types';
|
||||
import { PanelDataPaneTabState, PanelDataPaneTab, TabId } from './types';
|
||||
|
||||
export class PanelDataAlertingTab extends SceneObjectBase<PanelDataPaneTabState> implements PanelDataPaneTab {
|
||||
static Component = PanelDataAlertingTabRendered;
|
||||
tabId = 'alert';
|
||||
tabId = TabId.Alert;
|
||||
icon: IconName = 'bell';
|
||||
private _panelManager: VizPanelManager;
|
||||
|
||||
@ -22,10 +22,6 @@ export class PanelDataAlertingTab extends SceneObjectBase<PanelDataPaneTabState>
|
||||
return 'Alert';
|
||||
}
|
||||
|
||||
getItemsCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
get panelManager() {
|
||||
return this._panelManager;
|
||||
}
|
||||
|
@ -19,11 +19,11 @@ import { VizPanelManager } from '../VizPanelManager';
|
||||
import { PanelDataAlertingTab } from './PanelDataAlertingTab';
|
||||
import { PanelDataQueriesTab } from './PanelDataQueriesTab';
|
||||
import { PanelDataTransformationsTab } from './PanelDataTransformationsTab';
|
||||
import { PanelDataPaneTab } from './types';
|
||||
import { PanelDataPaneTab, TabId } from './types';
|
||||
|
||||
export interface PanelDataPaneState extends SceneObjectState {
|
||||
tabs?: PanelDataPaneTab[];
|
||||
tab?: string;
|
||||
tab?: TabId;
|
||||
}
|
||||
|
||||
export class PanelDataPane extends SceneObjectBase<PanelDataPaneState> {
|
||||
@ -44,13 +44,13 @@ export class PanelDataPane extends SceneObjectBase<PanelDataPaneState> {
|
||||
return;
|
||||
}
|
||||
if (typeof values.tab === 'string') {
|
||||
this.setState({ tab: values.tab });
|
||||
this.setState({ tab: values.tab as TabId });
|
||||
}
|
||||
}
|
||||
|
||||
constructor(panelMgr: VizPanelManager) {
|
||||
super({
|
||||
tab: 'queries',
|
||||
tab: TabId.Queries,
|
||||
});
|
||||
|
||||
this.panelManager = panelMgr;
|
||||
@ -135,6 +135,7 @@ export class PanelDataPane extends SceneObjectBase<PanelDataPaneState> {
|
||||
function PanelDataPaneRendered({ model }: SceneComponentProps<PanelDataPane>) {
|
||||
const { tab, tabs } = model.useState();
|
||||
const styles = useStyles2(getStyles);
|
||||
const { queries } = model.panelManager.queryRunner.useState();
|
||||
|
||||
if (!tabs) {
|
||||
return;
|
||||
@ -142,6 +143,12 @@ function PanelDataPaneRendered({ model }: SceneComponentProps<PanelDataPane>) {
|
||||
|
||||
const currentTab = tabs.find((t) => t.tabId === tab);
|
||||
|
||||
const tabCounters = {
|
||||
[TabId.Queries]: queries.length,
|
||||
[TabId.Transformations]: 0, //TODO
|
||||
[TabId.Alert]: 0, //TODO
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<TabsBar hideBorder={true} className={styles.tabsBar}>
|
||||
@ -151,7 +158,7 @@ function PanelDataPaneRendered({ model }: SceneComponentProps<PanelDataPane>) {
|
||||
key={`${t.getTabLabel()}-${index}`}
|
||||
label={t.getTabLabel()}
|
||||
icon={t.icon}
|
||||
counter={t.getItemsCount?.()}
|
||||
counter={tabCounters[t.tabId]}
|
||||
active={t.tabId === tab}
|
||||
onChangeTab={() => model.onChangeTab(t)}
|
||||
/>
|
||||
|
@ -1,17 +1,24 @@
|
||||
import React from 'react';
|
||||
|
||||
import { DataSourceApi, DataSourceInstanceSettings, IconName } from '@grafana/data';
|
||||
import { CoreApp, DataSourceApi, DataSourceInstanceSettings, IconName } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { SceneObjectBase, SceneComponentProps, sceneGraph } from '@grafana/scenes';
|
||||
import { DataQuery } from '@grafana/schema';
|
||||
import { Button, HorizontalGroup } from '@grafana/ui';
|
||||
import { addQuery } from 'app/core/utils/query';
|
||||
import { dataSource as expressionDatasource } from 'app/features/expressions/ExpressionDatasource';
|
||||
import { GroupActionComponents } from 'app/features/query/components/QueryActionComponent';
|
||||
import { QueryEditorRows } from 'app/features/query/components/QueryEditorRows';
|
||||
import { QueryGroupTopSection } from 'app/features/query/components/QueryGroup';
|
||||
import { isSharedDashboardQuery } from 'app/plugins/datasource/dashboard';
|
||||
import { GrafanaQuery } from 'app/plugins/datasource/grafana/types';
|
||||
import { QueryGroupOptions } from 'app/types';
|
||||
|
||||
import { PanelTimeRange } from '../../scene/PanelTimeRange';
|
||||
import { VizPanelManager } from '../VizPanelManager';
|
||||
|
||||
import { PanelDataPaneTabState, PanelDataPaneTab } from './types';
|
||||
import { PanelDataPaneTabState, PanelDataPaneTab, TabId } from './types';
|
||||
|
||||
interface PanelDataQueriesTabState extends PanelDataPaneTabState {
|
||||
datasource?: DataSourceApi;
|
||||
@ -19,7 +26,8 @@ interface PanelDataQueriesTabState extends PanelDataPaneTabState {
|
||||
}
|
||||
export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabState> implements PanelDataPaneTab {
|
||||
static Component = PanelDataQueriesTabRendered;
|
||||
tabId = 'queries';
|
||||
|
||||
tabId = TabId.Queries;
|
||||
icon: IconName = 'database';
|
||||
private _panelManager: VizPanelManager;
|
||||
|
||||
@ -102,6 +110,49 @@ export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabStat
|
||||
return this._panelManager.queryRunner.state.queries;
|
||||
}
|
||||
|
||||
newQuery(): Partial<DataQuery> {
|
||||
const { dsSettings, datasource } = this._panelManager.state;
|
||||
|
||||
const ds = !dsSettings?.meta.mixed ? dsSettings : datasource;
|
||||
|
||||
return {
|
||||
...datasource?.getDefaultQuery?.(CoreApp.PanelEditor),
|
||||
datasource: { uid: ds?.uid, type: ds?.type },
|
||||
};
|
||||
}
|
||||
|
||||
addQueryClick = () => {
|
||||
const queries = this.getQueries();
|
||||
this.onQueriesChange(addQuery(queries, this.newQuery()));
|
||||
};
|
||||
|
||||
onAddQuery = (query: Partial<DataQuery>) => {
|
||||
const queries = this.getQueries();
|
||||
const dsSettings = this._panelManager.state.dsSettings;
|
||||
this.onQueriesChange(addQuery(queries, query, { type: dsSettings?.type, uid: dsSettings?.uid }));
|
||||
};
|
||||
|
||||
isExpressionsSupported(dsSettings: DataSourceInstanceSettings): boolean {
|
||||
return (dsSettings.meta.alerting || dsSettings.meta.mixed) === true;
|
||||
}
|
||||
|
||||
onAddExpressionClick = () => {
|
||||
const queries = this.getQueries();
|
||||
this.onQueriesChange(addQuery(queries, expressionDatasource.newQuery()));
|
||||
};
|
||||
|
||||
renderExtraActions() {
|
||||
return GroupActionComponents.getAllExtraRenderAction()
|
||||
.map((action, index) =>
|
||||
action({
|
||||
onAddQuery: this.onAddQuery,
|
||||
onChangeDataSource: this.onChangeDataSource,
|
||||
key: index,
|
||||
})
|
||||
)
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
get panelManager() {
|
||||
return this._panelManager;
|
||||
}
|
||||
@ -115,6 +166,8 @@ function PanelDataQueriesTabRendered({ model }: SceneComponentProps<PanelDataQue
|
||||
return null;
|
||||
}
|
||||
|
||||
const showAddButton = !isSharedDashboardQuery(dsSettings.name);
|
||||
|
||||
return (
|
||||
<>
|
||||
<QueryGroupTopSection
|
||||
@ -131,10 +184,34 @@ function PanelDataQueriesTabRendered({ model }: SceneComponentProps<PanelDataQue
|
||||
data={data}
|
||||
queries={model.getQueries()}
|
||||
dsSettings={dsSettings}
|
||||
onAddQuery={() => {}}
|
||||
onAddQuery={model.onAddQuery}
|
||||
onQueriesChange={model.onQueriesChange}
|
||||
onRunQueries={model.onRunQueries}
|
||||
/>
|
||||
|
||||
<HorizontalGroup spacing="md" align="flex-start">
|
||||
{showAddButton && (
|
||||
<Button
|
||||
icon="plus"
|
||||
onClick={model.addQueryClick}
|
||||
variant="secondary"
|
||||
data-testid={selectors.components.QueryTab.addQuery}
|
||||
>
|
||||
Add query
|
||||
</Button>
|
||||
)}
|
||||
{config.expressionsEnabled && model.isExpressionsSupported(dsSettings) && (
|
||||
<Button
|
||||
icon="plus"
|
||||
onClick={model.onAddExpressionClick}
|
||||
variant="secondary"
|
||||
data-testid="query-tab-add-expression"
|
||||
>
|
||||
<span>Expression </span>
|
||||
</Button>
|
||||
)}
|
||||
{model.renderExtraActions()}
|
||||
</HorizontalGroup>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import { VizPanelManager } from '../VizPanelManager';
|
||||
|
||||
import { EmptyTransformationsMessage } from './EmptyTransformationsMessage';
|
||||
import { TransformationsDrawer } from './TransformationsDrawer';
|
||||
import { PanelDataPaneTabState, PanelDataPaneTab } from './types';
|
||||
import { PanelDataPaneTabState, PanelDataPaneTab, TabId } from './types';
|
||||
|
||||
interface PanelDataTransformationsTabState extends PanelDataPaneTabState {}
|
||||
|
||||
@ -21,7 +21,7 @@ export class PanelDataTransformationsTab
|
||||
implements PanelDataPaneTab
|
||||
{
|
||||
static Component = PanelDataTransformationsTabRendered;
|
||||
tabId = 'transformations';
|
||||
tabId = TabId.Transformations;
|
||||
icon: IconName = 'process';
|
||||
private _panelManager: VizPanelManager;
|
||||
|
||||
@ -29,10 +29,6 @@ export class PanelDataTransformationsTab
|
||||
return 'Transformations';
|
||||
}
|
||||
|
||||
getItemsCount() {
|
||||
return this._panelManager.dataTransformer.state.transformations.length;
|
||||
}
|
||||
|
||||
constructor(panelManager: VizPanelManager) {
|
||||
super({});
|
||||
|
||||
|
@ -3,9 +3,14 @@ import { SceneObject, SceneObjectState } from '@grafana/scenes';
|
||||
|
||||
export interface PanelDataPaneTabState extends SceneObjectState {}
|
||||
|
||||
export enum TabId {
|
||||
Queries = 'queries',
|
||||
Transformations = 'transformations',
|
||||
Alert = 'alert',
|
||||
}
|
||||
|
||||
export interface PanelDataPaneTab extends SceneObject {
|
||||
getTabLabel(): string;
|
||||
getItemsCount?(): number | null;
|
||||
tabId: string;
|
||||
tabId: TabId;
|
||||
icon: IconName;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user