From 9ccb39eb0487a22ca40b75deea136ec5252d0009 Mon Sep 17 00:00:00 2001 From: Matej Kubinec Date: Fri, 19 Jan 2024 14:01:59 +0100 Subject: [PATCH 1/2] PMM-12840 Move PT Summary to main repo --- package.json | 1 + pkg/plugins/pfs/corelist/corelist_load_gen.go | 2 + .../app/features/plugins/built_in_plugins.ts | 9 ++ .../services/actions/Actions.service.ts | 9 ++ .../shared/services/actions/Actions.types.ts | 15 +++ .../shared/services/actions/Actions.utils.ts | 50 ++++++++++ .../PTSummary.service.ts | 33 +++++++ .../PTSummary.types.ts | 19 ++++ .../PTSummaryDataSource.test.ts | 99 +++++++++++++++++++ .../PTSummaryDataSource.ts | 61 ++++++++++++ .../QueryEditor/QueryEditor.constants.ts | 23 +++++ .../QueryEditor/QueryEditor.messages.ts | 15 +++ .../QueryEditor/QueryEditor.tsx | 59 +++++++++++ .../pmm-pt-summary-datasource/module.ts | 7 ++ .../pmm-pt-summary-datasource/plugin.json | 6 ++ .../pmm-pt-summary-panel/PTSummary.styles.ts | 18 ++++ .../pmm-pt-summary-panel/PTSummary.test.tsx | 28 ++++++ .../panel/pmm-pt-summary-panel/PTSummary.tsx | 21 ++++ .../pmm-pt-summary-panel/PTSummary.types.ts | 4 + .../panel/pmm-pt-summary-panel/module.ts | 5 + .../panel/pmm-pt-summary-panel/plugin.json | 5 + yarn.lock | 8 ++ 22 files changed, 497 insertions(+) create mode 100644 public/app/percona/shared/services/actions/Actions.service.ts create mode 100644 public/app/percona/shared/services/actions/Actions.types.ts create mode 100644 public/app/percona/shared/services/actions/Actions.utils.ts create mode 100644 public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummary.service.ts create mode 100644 public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummary.types.ts create mode 100644 public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummaryDataSource.test.ts create mode 100644 public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummaryDataSource.ts create mode 100644 public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.constants.ts create mode 100644 public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.messages.ts create mode 100644 public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.tsx create mode 100644 public/app/plugins/datasource/pmm-pt-summary-datasource/module.ts create mode 100644 public/app/plugins/datasource/pmm-pt-summary-datasource/plugin.json create mode 100644 public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.styles.ts create mode 100644 public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.test.tsx create mode 100644 public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.tsx create mode 100644 public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.types.ts create mode 100644 public/app/plugins/panel/pmm-pt-summary-panel/module.ts create mode 100755 public/app/plugins/panel/pmm-pt-summary-panel/plugin.json diff --git a/package.json b/package.json index 9b3bc55bf5546..f049a70a81e7f 100644 --- a/package.json +++ b/package.json @@ -333,6 +333,7 @@ "diff": "^5.1.0", "emotion": "11.0.0", "eventemitter3": "5.0.1", + "exponential-backoff": "^3.1.1", "fast-deep-equal": "^3.1.3", "fast-json-patch": "3.1.1", "file-saver": "2.0.5", diff --git a/pkg/plugins/pfs/corelist/corelist_load_gen.go b/pkg/plugins/pfs/corelist/corelist_load_gen.go index 3ee84de51de37..c0c005f2c82d0 100644 --- a/pkg/plugins/pfs/corelist/corelist_load_gen.go +++ b/pkg/plugins/pfs/corelist/corelist_load_gen.go @@ -48,6 +48,7 @@ func corePlugins(rt *thema.Runtime) []pfs.ParsedPlugin { parsePluginOrPanic("public/app/plugins/datasource/mssql", "mssql", rt), parsePluginOrPanic("public/app/plugins/datasource/mysql", "mysql", rt), parsePluginOrPanic("public/app/plugins/datasource/parca", "parca", rt), + parsePluginOrPanic("public/app/plugins/datasource/pmm-pt-summary-datasource", "pmm_pt_summary_datasource", rt), parsePluginOrPanic("public/app/plugins/datasource/prometheus", "prometheus", rt), parsePluginOrPanic("public/app/plugins/datasource/tempo", "tempo", rt), parsePluginOrPanic("public/app/plugins/datasource/zipkin", "zipkin", rt), @@ -74,6 +75,7 @@ func corePlugins(rt *thema.Runtime) []pfs.ParsedPlugin { parsePluginOrPanic("public/app/plugins/panel/nodeGraph", "nodeGraph", rt), parsePluginOrPanic("public/app/plugins/panel/piechart", "piechart", rt), parsePluginOrPanic("public/app/plugins/panel/pmm-check", "pmm_check_panel", rt), + parsePluginOrPanic("public/app/plugins/panel/pmm-pt-summary-panel", "pmm_pt_summary_panel", rt), parsePluginOrPanic("public/app/plugins/panel/pmm-update", "pmm_update_panel", rt), parsePluginOrPanic("public/app/plugins/panel/stat", "stat", rt), parsePluginOrPanic("public/app/plugins/panel/state-timeline", "state_timeline", rt), diff --git a/public/app/features/plugins/built_in_plugins.ts b/public/app/features/plugins/built_in_plugins.ts index b928631a2d875..461d126271abb 100644 --- a/public/app/features/plugins/built_in_plugins.ts +++ b/public/app/features/plugins/built_in_plugins.ts @@ -41,6 +41,11 @@ const pyroscopePlugin = async () => await import(/* webpackChunkName: "pyroscopePlugin" */ 'app/plugins/datasource/grafana-pyroscope-datasource/module'); const parcaPlugin = async () => await import(/* webpackChunkName: "parcaPlugin" */ 'app/plugins/datasource/parca/module'); +// @PERCONA +const pmmPTSummaryDatasource = async () => + await import( + /* webpackChunkName: "pmmPTSummaryDatasource" */ 'app/plugins/datasource/pmm-pt-summary-datasource/module' + ); import * as alertGroupsPanel from 'app/plugins/panel/alertGroups/module'; import * as alertListPanel from 'app/plugins/panel/alertlist/module'; @@ -62,6 +67,7 @@ import * as nodeGraph from 'app/plugins/panel/nodeGraph/module'; import * as pieChartPanel from 'app/plugins/panel/piechart/module'; // @PERCONA import * as pmmCheckPanel from 'app/plugins/panel/pmm-check/module'; +import * as pmmPTSummaryPanel from 'app/plugins/panel/pmm-pt-summary-panel/module'; import * as pmmUpdatePanel from 'app/plugins/panel/pmm-update/module'; import * as statPanel from 'app/plugins/panel/stat/module'; import * as stateTimelinePanel from 'app/plugins/panel/state-timeline/module'; @@ -107,6 +113,8 @@ const builtInPlugins: Record Promise Promise(body: ActionRequest) { + return apiManagement.post, ActionRequest>('/Actions/Get', body); + }, +}; diff --git a/public/app/percona/shared/services/actions/Actions.types.ts b/public/app/percona/shared/services/actions/Actions.types.ts new file mode 100644 index 0000000000000..62ca598275e80 --- /dev/null +++ b/public/app/percona/shared/services/actions/Actions.types.ts @@ -0,0 +1,15 @@ +export interface ActionResult { + error: string; + loading: boolean; + value: T | null; +} + +export interface ActionRequest { + action_id: string; +} + +export interface ActionResponse { + done: boolean; + error: string; + output: T; +} diff --git a/public/app/percona/shared/services/actions/Actions.utils.ts b/public/app/percona/shared/services/actions/Actions.utils.ts new file mode 100644 index 0000000000000..2949ac4ed3d74 --- /dev/null +++ b/public/app/percona/shared/services/actions/Actions.utils.ts @@ -0,0 +1,50 @@ +import { backOff } from 'exponential-backoff'; + +import { ActionsService } from './Actions.service'; +import { ActionResult } from './Actions.types'; + +const INTERVAL = 500; + +export const getActionResult = async (actionId: string): Promise> => { + const getData = async () => { + const result = await ActionsService.getActionResult({ + action_id: actionId, + }); + + if (!result.done && !result.error) { + throw Error(''); + } + + return result; + }; + + let requestResult; + + try { + requestResult = await backOff(() => getData(), { + startingDelay: INTERVAL, + numOfAttempts: 10, + delayFirstAttempt: false, + }); + } catch (e) { + return { + loading: false, + value: null, + error: 'Unknown error', + }; + } + + if (requestResult.error) { + return { + loading: false, + value: requestResult.output, + error: requestResult.error, + }; + } + + return { + loading: false, + value: requestResult.output, + error: '', + }; +}; diff --git a/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummary.service.ts b/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummary.service.ts new file mode 100644 index 0000000000000..eff4cda71c83c --- /dev/null +++ b/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummary.service.ts @@ -0,0 +1,33 @@ +import { getTemplateSrv } from '@grafana/runtime'; +import { apiManagement } from 'app/percona/shared/helpers/api'; + +import { PTSummaryRequest, PTSummaryResponse, DatabaseSummaryRequest } from './PTSummary.types'; + +export const PTSummaryService = { + async getPTSummary(variableName: string) { + const body: PTSummaryRequest = { node_id: getTemplateSrv().replace(`$${variableName || 'node_id'}`) }; + + return apiManagement.post('/Actions/StartPTSummary', body, true); + }, + async getMysqlPTSummary(variableName: string) { + const body: DatabaseSummaryRequest = { + service_id: getTemplateSrv().replace(`$${variableName || 'service_name'}`), + }; + + return apiManagement.post('/Actions/StartPTMySQLSummary', body, true); + }, + async getPostgresqlPTSummary(variableName: string) { + const body: DatabaseSummaryRequest = { + service_id: getTemplateSrv().replace(`$${variableName || 'service_name'}`), + }; + + return apiManagement.post('/Actions/StartPTPgSummary', body, true); + }, + async getMongodbPTSummary(variableName: string) { + const body: DatabaseSummaryRequest = { + service_id: getTemplateSrv().replace(`$${variableName || 'service-name'}`), + }; + + return apiManagement.post('/Actions/StartPTMongoDBSummary', body, true); + }, +}; diff --git a/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummary.types.ts b/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummary.types.ts new file mode 100644 index 0000000000000..2015f4c2dbd14 --- /dev/null +++ b/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummary.types.ts @@ -0,0 +1,19 @@ +export interface PTSummaryRequest { + node_id: string; +} + +export interface DatabaseSummaryRequest { + service_id: string; +} + +export interface PTSummaryResponse { + action_id: string; + pmm_agent_id: string; +} + +export enum DatasourceType { + postgresql = 'postgresql', + mongodb = 'mongodb', + mysql = 'mysql', + node = 'node', +} diff --git a/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummaryDataSource.test.ts b/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummaryDataSource.test.ts new file mode 100644 index 0000000000000..4ea3d277025b0 --- /dev/null +++ b/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummaryDataSource.test.ts @@ -0,0 +1,99 @@ +import { FieldType, toDataFrame } from '@grafana/data'; +import { ActionResult } from 'app/percona/shared/services/actions/Actions.types'; + +import { PTSummaryService } from './PTSummary.service'; +import { PTSummaryDataSource } from './PTSummaryDataSource'; + +jest.mock('@grafana/runtime', () => ({ + getTemplateSrv: () => ({ + replace: () => 'node', + }), +})); +jest.mock('app/percona/shared/services/actions/Actions.utils', () => ({ + getActionResult: async (): Promise> => + new Promise((resolve) => { + resolve({ + loading: false, + value: 'Test data', + error: '', + }); + }), +})); + +describe('PTSummaryDatasource::', () => { + it('Returns correct data for Node summary', async () => { + const expected = { + data: [ + toDataFrame({ + fields: [{ name: 'summary', values: ['Test data'], type: FieldType.string }], + }), + ], + }; + const instance = new PTSummaryDataSource({}); + + PTSummaryService.getPTSummary = jest.fn().mockResolvedValueOnce({ value: 'Test data' }); + + const result = await instance.query({ + targets: [{ refId: 'A', queryType: { type: 'node', variableName: undefined } }], + } as any); + + expect(result).toEqual(expected); + }); + + it('Returns correct data for MySQL summary', async () => { + const expected = { + data: [ + toDataFrame({ + fields: [{ name: 'summary', values: ['Test data'], type: FieldType.string }], + }), + ], + }; + const instance = new PTSummaryDataSource({}); + + PTSummaryService.getMysqlPTSummary = jest.fn().mockResolvedValueOnce({ value: 'Test data' }); + + const result = await instance.query({ + targets: [{ refId: 'A', queryType: { type: 'mysql', variableName: undefined } }], + } as any); + + expect(result).toEqual(expected); + }); + + it('Returns correct data for MongoDB summary', async () => { + const expected = { + data: [ + toDataFrame({ + fields: [{ name: 'summary', values: ['Test data'], type: FieldType.string }], + }), + ], + }; + const instance = new PTSummaryDataSource({}); + + PTSummaryService.getMongodbPTSummary = jest.fn().mockResolvedValueOnce({ value: 'Test data' }); + + const result = await instance.query({ + targets: [{ refId: 'A', queryType: { type: 'mongodb', variableName: undefined } }], + } as any); + + expect(result).toEqual(expected); + }); + + it('Returns correct data for PostgreSQL summary', async () => { + const expected = { + data: [ + toDataFrame({ + fields: [{ name: 'summary', values: ['Test data'], type: FieldType.string }], + }), + ], + }; + const instance = new PTSummaryDataSource({}); + + PTSummaryService.getPostgresqlPTSummary = jest.fn().mockResolvedValueOnce({ value: 'Test data' }); + + const result = await instance.query({ + targets: [{ refId: 'A', queryType: { type: 'postgresql', variableName: undefined } }], + } as any); + + expect(result).toEqual(expected); + }); +}); diff --git a/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummaryDataSource.ts b/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummaryDataSource.ts new file mode 100644 index 0000000000000..94cca97410d6d --- /dev/null +++ b/public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummaryDataSource.ts @@ -0,0 +1,61 @@ +import { DataQueryResponse, DataSourceApi, toDataFrame, FieldType } from '@grafana/data'; +import { getActionResult } from 'app/percona/shared/services/actions/Actions.utils'; + +import { PTSummaryService } from './PTSummary.service'; +import { DatasourceType, PTSummaryResponse } from './PTSummary.types'; + +export class PTSummaryDataSource extends DataSourceApi { + constructor(instanceSettings: any) { + super(instanceSettings); + } + + async query(options: any): Promise { + const { variableName, type } = options.targets[0]?.queryType || {}; + + const getRequest = (type: DatasourceType) => { + switch (type) { + case DatasourceType.node: + return PTSummaryService.getPTSummary(variableName); + case DatasourceType.mysql: + return PTSummaryService.getMysqlPTSummary(variableName); + case DatasourceType.mongodb: + return PTSummaryService.getMongodbPTSummary(variableName); + case DatasourceType.postgresql: + return PTSummaryService.getPostgresqlPTSummary(variableName); + default: + return PTSummaryService.getPTSummary(variableName); + } + }; + + return getRequest(type) + .then(async (response) => { + const result = await getActionResult((response as PTSummaryResponse).action_id); + + return this.newDataFrame(result.value ? result.value : result.error); + }) + .catch((error) => this.newDataFrame(error.response.data.message)); + } + + async testDatasource() { + return { + status: 'success', + message: 'Success', + }; + } + + newDataFrame(value: string) { + return { + data: [ + toDataFrame({ + fields: [ + { + name: 'summary', + values: [value], + type: FieldType.string, + }, + ], + }), + ], + }; + } +} diff --git a/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.constants.ts b/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.constants.ts new file mode 100644 index 0000000000000..b89e706280e77 --- /dev/null +++ b/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.constants.ts @@ -0,0 +1,23 @@ +import { DatasourceType } from '../PTSummary.types'; + +import { Messages } from './QueryEditor.messages'; + + +export const DATASOURCES = [ + { + value: DatasourceType.node, + label: Messages.labels.nodePTSummary, + }, + { + value: DatasourceType.mysql, + label: Messages.labels.mysqlPTSummary, + }, + { + value: DatasourceType.postgresql, + label: Messages.labels.postgresqlPTSummary, + }, + { + value: DatasourceType.mongodb, + label: Messages.labels.mongodbPTSummary, + }, +]; diff --git a/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.messages.ts b/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.messages.ts new file mode 100644 index 0000000000000..201280281c427 --- /dev/null +++ b/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.messages.ts @@ -0,0 +1,15 @@ +export const Messages = { + labels: { + postgresqlPTSummary: 'PostgreSQL PT Summary', + mongodbPTSummary: 'MongoDB PT Summary', + mysqlPTSummary: 'MySQL PT Summary', + nodePTSummary: 'Node PT Summary', + field: { + datasourceType: 'Datasource type', + variableName: 'Grafana variable name', + }, + }, + placeholders: { + variableName: 'Variable name', + }, +}; diff --git a/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.tsx b/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.tsx new file mode 100644 index 0000000000000..8f0c358fb80f8 --- /dev/null +++ b/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.tsx @@ -0,0 +1,59 @@ +import React, { useEffect, useState } from 'react'; + +import { SelectableValue } from '@grafana/data'; +import { getTemplateSrv } from '@grafana/runtime'; +import { Select, Field, FieldSet } from '@grafana/ui'; + +import { DATASOURCES } from './QueryEditor.constants'; +import { Messages } from './QueryEditor.messages'; + +export const QueryEditor = (props: any) => { + const { + query: { queryType }, + onChange, + } = props; + + const variablesOptions = getTemplateSrv() + .getVariables() + .map((variable) => ({ value: variable.name, label: variable.label || undefined })); + + const selectedOption = variablesOptions.find((variable) => variable.value === queryType?.variableName); + const selectedTypeOption = DATASOURCES.find((datasource) => datasource.value === queryType?.type); + + const [selectedVariable, selectVariable] = useState | undefined>(selectedOption); + const [type, setType] = useState>(selectedTypeOption || DATASOURCES[0]); + + useEffect(() => { + const newQuery = { ...queryType }; + + if (selectedVariable?.value) { + newQuery.variableName = selectedVariable?.value; + } + + if (type?.value) { + newQuery.type = type?.value; + } + + onChange({ + queryType: newQuery, + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedVariable, type]); + + return ( + <> +
+
+ + + +
+
+ + ); +}; + +export default QueryEditor; diff --git a/public/app/plugins/datasource/pmm-pt-summary-datasource/module.ts b/public/app/plugins/datasource/pmm-pt-summary-datasource/module.ts new file mode 100644 index 0000000000000..382677cdbe3a0 --- /dev/null +++ b/public/app/plugins/datasource/pmm-pt-summary-datasource/module.ts @@ -0,0 +1,7 @@ +import { DataSourcePlugin } from '@grafana/data'; + +import { PTSummaryDataSource } from './PTSummaryDataSource'; +import { QueryEditor } from './QueryEditor/QueryEditor'; + +export const plugin = new DataSourcePlugin(PTSummaryDataSource) + .setQueryEditor(QueryEditor); diff --git a/public/app/plugins/datasource/pmm-pt-summary-datasource/plugin.json b/public/app/plugins/datasource/pmm-pt-summary-datasource/plugin.json new file mode 100644 index 0000000000000..96a5abfe98921 --- /dev/null +++ b/public/app/plugins/datasource/pmm-pt-summary-datasource/plugin.json @@ -0,0 +1,6 @@ +{ + "type": "datasource", + "name": "PTSummary", + "id": "pmm-pt-summary-datasource", + "metrics": true +} \ No newline at end of file diff --git a/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.styles.ts b/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.styles.ts new file mode 100644 index 0000000000000..d9f1ba019d64f --- /dev/null +++ b/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.styles.ts @@ -0,0 +1,18 @@ +import { css } from '@emotion/css'; + +import { GrafanaTheme2 } from '@grafana/data'; + +export const getStyles = (theme: GrafanaTheme2) => ({ + ptSummaryWrapper: css` + border: 1px solid ${theme.colors.background.canvas}; + border-radius: ${theme.shape.radius.default}; + font-size: ${theme.typography.body.fontSize}; + height: 100%; + `, + ptSummary: css` + border: none; + color: ${theme.colors.text}; + height: 100%; + margin: 0; + `, +}); diff --git a/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.test.tsx b/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.test.tsx new file mode 100644 index 0000000000000..3d0e15340f60d --- /dev/null +++ b/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.test.tsx @@ -0,0 +1,28 @@ +import { render, screen } from '@testing-library/react'; +import React from 'react'; + +import { PTSummaryPanel } from './PTSummary'; + +describe('PTSummaryPanel::', () => { + it('Renders correctly with props', () => { + const props: any = { + data: { + series: [{ fields: [{ name: 'summary', values: ['Test data'] }] }], + }, + }; + render(); + + expect(screen.getByTestId('pt-summary-fingerprint')?.textContent).toBe('Test data'); + }); + + it('Renders correctly without data', () => { + const props: any = { + data: { + series: [], + }, + }; + render(); + + expect(screen.getByTestId('pt-summary-fingerprint')?.textContent).toBe(''); + }); +}); diff --git a/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.tsx b/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.tsx new file mode 100644 index 0000000000000..7d5bb0db625b7 --- /dev/null +++ b/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.tsx @@ -0,0 +1,21 @@ +import React, { FC } from 'react'; + +import { PanelProps } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + +import { getStyles } from './PTSummary.styles'; + +export const PTSummaryPanel: FC = ({ data }) => { + const styles = useStyles2(getStyles); + const series = data.series[0]; + const summary = series?.fields.find((f) => f.name === 'summary'); + const fingerprint = (summary?.values || [])[0]; + + return ( +
+
+        {fingerprint}
+      
+
+ ); +}; diff --git a/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.types.ts b/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.types.ts new file mode 100644 index 0000000000000..572fe6527177d --- /dev/null +++ b/public/app/plugins/panel/pmm-pt-summary-panel/PTSummary.types.ts @@ -0,0 +1,4 @@ +export interface PTSummaryData { + name: string; + values: string[]; +} diff --git a/public/app/plugins/panel/pmm-pt-summary-panel/module.ts b/public/app/plugins/panel/pmm-pt-summary-panel/module.ts new file mode 100644 index 0000000000000..f898fe46775f2 --- /dev/null +++ b/public/app/plugins/panel/pmm-pt-summary-panel/module.ts @@ -0,0 +1,5 @@ +import { PanelPlugin } from '@grafana/data'; + +import { PTSummaryPanel } from './PTSummary'; + +export const plugin = new PanelPlugin(PTSummaryPanel); diff --git a/public/app/plugins/panel/pmm-pt-summary-panel/plugin.json b/public/app/plugins/panel/pmm-pt-summary-panel/plugin.json new file mode 100755 index 0000000000000..d41521cb61c32 --- /dev/null +++ b/public/app/plugins/panel/pmm-pt-summary-panel/plugin.json @@ -0,0 +1,5 @@ +{ + "type": "panel", + "name": "PTSummary", + "id": "pmm-pt-summary-panel" +} diff --git a/yarn.lock b/yarn.lock index e3a658494ad4e..0c45ced9f9c24 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16061,6 +16061,13 @@ __metadata: languageName: node linkType: hard +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 2d9bbb6473de7051f96790d5f9a678f32e60ed0aa70741dc7fdc96fec8d631124ec3374ac144387604f05afff9500f31a1d45bd9eee4cdc2e4f9ad2d9b9d5dbd + languageName: node + linkType: hard + "expose-loader@npm:4.1.0": version: 4.1.0 resolution: "expose-loader@npm:4.1.0" @@ -17700,6 +17707,7 @@ __metadata: eslint-plugin-react-hooks: "npm:4.6.0" eslint-webpack-plugin: "npm:4.0.1" eventemitter3: "npm:5.0.1" + exponential-backoff: "npm:^3.1.1" expose-loader: "npm:4.1.0" fast-deep-equal: "npm:^3.1.3" fast-json-patch: "npm:3.1.1" From 7fb6455a28a85ae57f6804c3650675fae5c52ffe Mon Sep 17 00:00:00 2001 From: Matej Kubinec Date: Fri, 19 Jan 2024 14:16:51 +0100 Subject: [PATCH 2/2] PMM-12840 Fix code style issues --- .../QueryEditor/QueryEditor.constants.ts | 1 - .../app/plugins/datasource/pmm-pt-summary-datasource/module.ts | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.constants.ts b/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.constants.ts index b89e706280e77..3e746ac641ebb 100644 --- a/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.constants.ts +++ b/public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.constants.ts @@ -2,7 +2,6 @@ import { DatasourceType } from '../PTSummary.types'; import { Messages } from './QueryEditor.messages'; - export const DATASOURCES = [ { value: DatasourceType.node, diff --git a/public/app/plugins/datasource/pmm-pt-summary-datasource/module.ts b/public/app/plugins/datasource/pmm-pt-summary-datasource/module.ts index 382677cdbe3a0..ea90d531f51fc 100644 --- a/public/app/plugins/datasource/pmm-pt-summary-datasource/module.ts +++ b/public/app/plugins/datasource/pmm-pt-summary-datasource/module.ts @@ -3,5 +3,4 @@ import { DataSourcePlugin } from '@grafana/data'; import { PTSummaryDataSource } from './PTSummaryDataSource'; import { QueryEditor } from './QueryEditor/QueryEditor'; -export const plugin = new DataSourcePlugin(PTSummaryDataSource) - .setQueryEditor(QueryEditor); +export const plugin = new DataSourcePlugin(PTSummaryDataSource).setQueryEditor(QueryEditor);