Scenes: Refactor panel editor tab counts (#81777)

* refactor editor tab counts

* Capitalize tab component property since it's a component
This commit is contained in:
Oscar Kilhed
2024-02-02 16:04:23 +01:00
committed by GitHub
parent 75c2d39f79
commit bdb592d9ec
5 changed files with 101 additions and 25 deletions
@@ -1,25 +1,25 @@
import React from 'react';
import { IconName } from '@grafana/data';
import { SceneObjectBase, SceneComponentProps } from '@grafana/scenes';
import { Alert, LoadingPlaceholder } from '@grafana/ui';
import { Alert, LoadingPlaceholder, Tab } from '@grafana/ui';
import { RulesTable } from 'app/features/alerting/unified/components/rules/RulesTable';
import { usePanelCombinedRules } from 'app/features/alerting/unified/hooks/usePanelCombinedRules';
import { getDashboardSceneFor, getPanelIdForVizPanel } from '../../utils/utils';
import { VizPanelManager } from '../VizPanelManager';
import { PanelDataPaneTabState, PanelDataPaneTab, TabId } from './types';
import { PanelDataPaneTabState, PanelDataPaneTab, TabId, PanelDataTabHeaderProps } from './types';
export class PanelDataAlertingTab extends SceneObjectBase<PanelDataPaneTabState> implements PanelDataPaneTab {
static Component = PanelDataAlertingTabRendered;
TabComponent: (props: PanelDataTabHeaderProps) => React.JSX.Element;
tabId = TabId.Alert;
icon: IconName = 'bell';
private _panelManager: VizPanelManager;
constructor(panelManager: VizPanelManager) {
super({});
this.TabComponent = (props: PanelDataTabHeaderProps) => AlertingTab({ ...props, model: this });
this._panelManager = panelManager;
}
getTabLabel() {
@@ -78,3 +78,28 @@ function PanelDataAlertingTabRendered(props: SceneComponentProps<PanelDataAlerti
</div>
);
}
interface PanelDataAlertingTabHeaderProps extends PanelDataTabHeaderProps {
model: PanelDataAlertingTab;
}
function AlertingTab(props: PanelDataAlertingTabHeaderProps) {
const { model } = props;
const { rules } = usePanelCombinedRules({
dashboardUID: model.getDashboardUID(),
panelId: model.getPanelId(),
poll: false,
});
return (
<Tab
key={props.key}
label={model.getTabLabel()}
icon="bell"
counter={rules.length}
active={props.active}
onChangeTab={props.onChangeTab}
/>
);
}
@@ -11,7 +11,7 @@ import {
SceneObjectUrlValues,
VizPanel,
} from '@grafana/scenes';
import { Container, CustomScrollbar, Tab, TabContent, TabsBar, useStyles2 } from '@grafana/ui';
import { Container, CustomScrollbar, TabContent, TabsBar, useStyles2 } from '@grafana/ui';
import { shouldShowAlertingTab } from 'app/features/dashboard/components/PanelEditor/state/selectors';
import { VizPanelManager } from '../VizPanelManager';
@@ -135,7 +135,6 @@ 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;
@@ -143,25 +142,16 @@ 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}>
{tabs.map((t, index) => {
return (
<Tab
<t.TabComponent
key={`${t.getTabLabel()}-${index}`}
label={t.getTabLabel()}
icon={t.icon}
counter={tabCounters[t.tabId]}
active={t.tabId === tab}
onChangeTab={() => model.onChangeTab(t)}
/>
></t.TabComponent>
);
})}
</TabsBar>
@@ -3,9 +3,9 @@ import React from 'react';
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 { SceneObjectBase, SceneComponentProps, sceneGraph, SceneQueryRunner } from '@grafana/scenes';
import { DataQuery } from '@grafana/schema';
import { Button, HorizontalGroup } from '@grafana/ui';
import { Button, HorizontalGroup, Tab } 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';
@@ -18,7 +18,7 @@ import { QueryGroupOptions } from 'app/types';
import { PanelTimeRange } from '../../scene/PanelTimeRange';
import { VizPanelManager } from '../VizPanelManager';
import { PanelDataPaneTabState, PanelDataPaneTab, TabId } from './types';
import { PanelDataPaneTabState, PanelDataPaneTab, TabId, PanelDataTabHeaderProps } from './types';
interface PanelDataQueriesTabState extends PanelDataPaneTabState {
datasource?: DataSourceApi;
@@ -26,6 +26,7 @@ interface PanelDataQueriesTabState extends PanelDataPaneTabState {
}
export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabState> implements PanelDataPaneTab {
static Component = PanelDataQueriesTabRendered;
TabComponent: (props: PanelDataTabHeaderProps) => React.JSX.Element;
tabId = TabId.Queries;
icon: IconName = 'database';
@@ -41,6 +42,9 @@ export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabStat
constructor(panelManager: VizPanelManager) {
super({});
this.TabComponent = (props: PanelDataTabHeaderProps) => {
return QueriesTab({ ...props, model: this });
};
this._panelManager = panelManager;
}
@@ -153,6 +157,10 @@ export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabStat
.filter(Boolean);
}
get queryRunner(): SceneQueryRunner {
return this._panelManager.queryRunner;
}
get panelManager() {
return this._panelManager;
}
@@ -215,3 +223,24 @@ function PanelDataQueriesTabRendered({ model }: SceneComponentProps<PanelDataQue
</>
);
}
interface QueriesTabProps extends PanelDataTabHeaderProps {
model: PanelDataQueriesTab;
}
function QueriesTab(props: QueriesTabProps) {
const { model } = props;
const queryRunnerState = model.queryRunner.useState();
return (
<Tab
key={props.key}
label={model.getTabLabel()}
icon="database"
counter={queryRunnerState.queries.length}
active={props.active}
onChangeTab={props.onChangeTab}
/>
);
}
@@ -5,14 +5,14 @@ import { DragDropContext, DropResult, Droppable } from 'react-beautiful-dnd';
import { DataTransformerConfig, GrafanaTheme2, IconName, PanelData } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { SceneObjectBase, SceneComponentProps, SceneDataTransformer, SceneQueryRunner } from '@grafana/scenes';
import { Button, ButtonGroup, ConfirmModal, useStyles2 } from '@grafana/ui';
import { Button, ButtonGroup, ConfirmModal, Tab, useStyles2 } from '@grafana/ui';
import { TransformationOperationRows } from 'app/features/dashboard/components/TransformationsEditor/TransformationOperationRows';
import { VizPanelManager } from '../VizPanelManager';
import { EmptyTransformationsMessage } from './EmptyTransformationsMessage';
import { TransformationsDrawer } from './TransformationsDrawer';
import { PanelDataPaneTabState, PanelDataPaneTab, TabId } from './types';
import { PanelDataPaneTabState, PanelDataPaneTab, TabId, PanelDataTabHeaderProps } from './types';
interface PanelDataTransformationsTabState extends PanelDataPaneTabState {}
@@ -21,6 +21,8 @@ export class PanelDataTransformationsTab
implements PanelDataPaneTab
{
static Component = PanelDataTransformationsTabRendered;
TabComponent: (props: PanelDataTabHeaderProps) => React.JSX.Element;
tabId = TabId.Transformations;
icon: IconName = 'process';
private _panelManager: VizPanelManager;
@@ -31,6 +33,7 @@ export class PanelDataTransformationsTab
constructor(panelManager: VizPanelManager) {
super({});
this.TabComponent = (props: PanelDataTabHeaderProps) => TransformationsTab({ ...props, model: this });
this._panelManager = panelManager;
}
@@ -46,6 +49,10 @@ export class PanelDataTransformationsTab
public onChangeTransformations(transformations: DataTransformerConfig[]) {
this._panelManager.changeTransformations(transformations);
}
get panelManager() {
return this._panelManager;
}
}
export function PanelDataTransformationsTabRendered({ model }: SceneComponentProps<PanelDataTransformationsTab>) {
@@ -186,3 +193,23 @@ const getStyles = (theme: GrafanaTheme2) => ({
marginLeft: theme.spacing(2),
}),
});
interface TransformationsTabProps extends PanelDataTabHeaderProps {
model: PanelDataTransformationsTab;
}
function TransformationsTab(props: TransformationsTabProps) {
const { model } = props;
const transformerState = model.getDataTransformer().useState();
return (
<Tab
key={props.key}
label={model.getTabLabel()}
icon="process"
counter={transformerState.transformations.length}
active={props.active}
onChangeTab={props.onChangeTab}
/>
);
}
@@ -1,4 +1,3 @@
import { IconName } from '@grafana/data';
import { SceneObject, SceneObjectState } from '@grafana/scenes';
export interface PanelDataPaneTabState extends SceneObjectState {}
@@ -9,8 +8,14 @@ export enum TabId {
Alert = 'alert',
}
export interface PanelDataTabHeaderProps {
key: string;
active: boolean;
onChangeTab?: (event: React.MouseEvent<HTMLElement>) => void;
}
export interface PanelDataPaneTab extends SceneObject {
TabComponent: (props: PanelDataTabHeaderProps) => React.JSX.Element;
getTabLabel(): string;
tabId: TabId;
icon: IconName;
}